# Some positions will get liquidated immediately

Rubicon Position borrows max liquidity, leaving no buffer; interest accrual next block makes position underwater and liquidatable.

- Payout: Contest reward
- Severity: high
- Program: Rubicon
- Credited: immeas
- Disclosed: 2025-02-17
- Write-up quality: 7/10
- Original: https://github.com/code-423n4/2023-04-rubicon-findings/issues/1180
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-rubicon%3AH-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:business-logic vuln:liquidation

**Target:** Position.sol _maxBorrow and leverage functions
**Root cause:** Borrowing up to max liquidity leaves no safety margin; interest accrual in the next block pushes the position underwater.
**Steps:**
1. Deploy Position and call sellAllAmountWithLeverage with amount 10e6 TUSDC and leverage 1e18.
2. Check getAccountLiquidity: liquidity=0, shortfall=0.
3. Advance block: vm.roll(block.number + 1).
4. Trigger interest: cTEST.borrowBalanceCurrent(position).
5. Check getAccountLiquidity: shortfall > 0.
6. Liquidate: cTEST.liquidateBorrow(position, borrowBalance/2, cTUSDC).
**How found:** Code review of _maxBorrow: it computes max borrow from current liquidity without safety factor; realized interest accrual next block would make position unhealthy.
**Exploitation:** Attacker monitors for newly opened leveraged positions at max borrow; after one block, interest accrual makes them underwater; attacker calls liquidateBorrow to seize collateral at a discount.
**Insight:** When a protocol computes max borrow from current liquidity, check if interest accrual or price movement in the next block can immediately make the position liquidatable; a safety factor is needed.
