# If there is only one USDS borrower, he can never be liquidated

Salty.IO's liquidation reverts when removing the sole USDS borrower's collateral drops pool reserves below DUST, blocking liquidation and creating bad debt.

- Payout: Contest reward
- Severity: medium
- Program: Salty.IO
- Credited: J4X
- Disclosed: 2024-04-19
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2024-01-salty-findings/issues/912
- Library page: https://bugbountylibrary.com/r/c4%3A2024-01-salty%3AM-04
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:business-logic vuln:liquidation

**Target:** CollateralAndLiquidity / pools.removeLiquidity liquidation path
**Root cause:** pools.removeLiquidity() reverts if post-withdrawal reserves fall below PoolUtils.DUST, so liquidating the only borrower (whose collateral is the entire reserve) always reverts.
**Steps:**
1. Alice deposits WBTC/WETH collateral via depositCollateralAndIncreaseShare and borrows maxBorrowableUSDS.
2. Crash collateral price so Alice becomes liquidatable.
3. Bob calls liquidateUser(alice), which calls pools.removeLiquidity().
4. Reserves after withdrawal fall below DUST, require() reverts, liquidation fails.
**How found:** Code reading of liquidateUser -> pools.removeLiquidity and noticing the DUST reserve check conflicts with withdrawing a sole borrower's entire collateral.
**Exploitation:** Sole borrower takes max USDS against collateral; when price crashes, liquidation reverts due to DUST check, leaving uncollectible bad debt in the protocol.
**Insight:** When auditing liquidation paths, check reserve/minimum-balance guards in the withdrawal function against the edge case where the liquidated position is the pool's entire liquidity.
