# Pool's kickWithDeposit misses liquidation debt check

Ajna's kickWithDeposit lacked the auction-debt-locked check, letting HPB depositors withdraw quote funds frozen for liquidation debt coverage.

- Payout: Contest reward
- Severity: high
- Program: Ajna
- Credited: hyh
- Disclosed: 2023-04-20
- Write-up quality: 7/10
- Original: https://github.com/sherlock-audit/2023-04-ajna-judging/issues/82
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-04-ajna%3AH-1
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:incomplete-fix technique:source-review vuln:access-control vuln:business-logic

**Target:** Pool.sol kickWithDeposit / KickerActions
**Root cause:** kickWithDeposit removes quote tokens from a bucket via Deposits.unscaledRemove but omits _revertIfAuctionDebtLocked(), which moveQuoteToken and removeQuoteToken enforce to keep deposits locked while liquidation debt is outstanding.
**Steps:**
1. Deposit quote tokens into a high-price bucket (HPB) so it is covered by the liquidation debt accumulator.
2. Wait until the bucket is frozen by t0DebtInAuction (auction debt locked).
3. Call `kickWithDeposit(index_, npLimitIndex_)` on the HPB instead of removeQuoteToken/moveQuoteToken.
4. Observe Deposits.unscaledRemove executes without _revertIfAuctionDebtLocked, withdrawing quote funds despite the lock.
5. Accept the kicker bond penalty; funds are removed before bad debt coverage consumes them.
**How found:** Code review comparing access-control guards across Pool entry points: noticed _revertIfAuctionDebtLocked present in moveQuoteToken and removeQuoteToken but absent in kickWithDeposit, which also performs Deposits.unscaledRemove.
**Exploitation:** HPB depositor, knowing their funds may soon cover bad debt, calls kickWithDeposit() to pull quote tokens out of the frozen bucket, paying only the kicker bond penalty while shifting bad-debt write-off risk onto lower-bucket depositors.
**Escalation:** Repeated bad-faith auctions shift debt write-offs to unaware lower-bucket depositors, letting HPBs keep stable yield while offloading risk.
**Insight:** When a protocol enforces a lock/guard in multiple withdrawal paths, enumerate every function that mutates the same state (here Deposits.unscaledRemove) and check each for the guard — alternate removal paths like kick-with-deposit are easy to miss.
