# User can call liquidate() and steal all collateral due to arbitrary router call

PARMinerV2.liquidate() passes attacker-controlled dexTxnData to a router; swapExactTokensForETH reenters attacker, who deposits PAR to pass the balance check and steals collateral.

- Payout: Audit contest
- Severity: high
- Program: Mimo DeFi
- Found by: 0xDjango
- Disclosed: 2022-07-18
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2022-04-mimo-findings/issues/83
- Library page: https://bugbountylibrary.com/r/c4%3A2022-04-mimo%3AH-01
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:business-logic vuln:reentrancy

**Target:** PARMinerV2.liquidate() liquidation router call
**Root cause:** liquidate() forwards user-supplied dexTxnData to an arbitrary router function and only verifies PAR balance increased, allowing ETH-receiving callbacks to reenter and inflate balance via deposit().
**Steps:**
1. Monitor for an unhealthy position.
2. Call `PARMinerV2.liquidate()` supplying `dexTxnData` encoding `UniswapV2Router.swapExactTokensForETH(amountIn, amountOutMin, path, attackerContract, deadline)`.
3. Router swaps collateral to ETH and calls `TransferHelper.safeTransferETH(to, amount)` which does `to.call{value: value}(new bytes(0))`, handing control to attacker contract.
4. Attacker contract swaps received ETH to PAR, calls `PARMinerV2.deposit()` with PAR, then withdraws.
5. Final PAR balance check in liquidate() passes; attacker keeps collateral value.
**How found:** Code review of liquidate() flow: noticed user-controlled dexTxnData passed to router and that the only post-check was PAR balance increase, then traced UniswapV2Router swapExactTokensForETH to TransferHelper.safeTransferETH's external call as a reentry vector.
**Exploitation:** Attacker liquidates an unhealthy position, receives ETH via router callback, converts to PAR, deposits into PARMinerV2 to satisfy the balance-increase check, then withdraws the PAR, netting the full collateral. Self-liquidation of own risky position lets attacker borrow PAR and reclaim collateral.
**Escalation:** Attacker can repeat across all unhealthy positions, or open risky positions and self-liquidate to steal borrowed PAR.
**Insight:** When a contract passes user-supplied calldata to an external router and validates success only by a token balance delta, look for router functions that hand execution to a user-controlled address (ETH transfers, callbacks) and check whether deposit/withdraw paths can inflate that same balance.
