# Short positions with minimum collateral can be liquidated even though canLiquidate() returns false

Boundary mismatch: canLiquidate() uses strict < while maxLiquidatableDebt() uses > 1e18, so minimum-collateral shorts report safe yet are half-liquidatable.

- Payout: Contest reward
- Severity: medium
- Program: Polynomial Protocol
- Credited: MiloTruck
- Disclosed: 2023-08-01
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-03-polynomial-findings/issues/146
- Library page: https://bugbountylibrary.com/r/c4%3A2023-03-polynomial%3AM-09
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:liquidation

**Target:** ShortCollateral / Exchange liquidation logic (Solidity)
**Root cause:** canLiquidate() liquidates only when collateralAmount < minCollateral, but maxLiquidatableDebt() treats safetyRatio == 1e18 as liquidatable (checks > 1e18 for safety), so the boundary position is inconsistent between the two functions.
**Steps:**
1. Open short with collateralAmount == minCollateral (safetyRatio == 1e18).
2. Call `shortCollateral.canLiquidate(positionId)` -> returns false.
3. Call `shortCollateral.maxLiquidatableDebt(positionId)` -> returns shortAmount/2.
4. Call `exchange.liquidate(positionId, shortAmount)` -> succeeds, reducing collateral.
**How found:** Compared the inequality in canLiquidate() (`<`) against the safety check in maxLiquidatableDebt() (`> 1e18`), spotting the off-by-one boundary at safetyRatio == 1e18.
**Exploitation:** A liquidator calls exchange.liquidate() on a position whose safetyRatio equals exactly 1e18; despite canLiquidate() returning false, maxLiquidatableDebt() returns half the debt, so the liquidation succeeds and the user loses collateral they believed safe.
**Insight:** When two functions encode the same health condition, diff their comparison operators and boundary equality; off-by-one at the exact threshold creates inconsistent liquidatability that integrators and users rely on.
