# kickWithDeposit removes the deposit without HTP pool state check

Ajna's kickWithDeposit removes quote deposits to cover kick bond without enforcing LUP >= HTP, breaking the core pool invariant and freezing deposit operations.

- 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/86
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-04-ajna%3AH-2
- Tags: domain:web3 impact:dos impact:integrity kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Ajna Pool.sol kickWithDeposit / KickerActions
**Root cause:** kickWithDeposit removes deposits via Deposits.unscaledRemove but omits the LUP >= HTP final-state check that every other deposit-removal path enforces, allowing the pool to reach LUP < HTP.
**Steps:**
1. Call `kickWithDeposit(index_, npLimitIndex_)` on a pool where the target bucket's deposit is used to cover the kick bond.
2. KickerActions._kick runs, then Deposits.unscaledRemove debits the bucket without any LUP/HTP validation.
3. Pool ends in LUP < HTP state.
4. Subsequent deposit operations whose HTP checks run revert, freezing deposits that would not move LUP upward.
**How found:** Reviewer compared kickWithDeposit against other deposit-removal functions (e.g. removeQuoteToken) and noticed the missing LUP >= HTP check required by the Ajna whitepaper section 4.1.
**Exploitation:** Attacker triggers kickWithDeposit to drain a bucket's quote deposit covering the kick bond, pushing LUP below HTP; other lenders' deposit operations then revert, effectively freezing pool deposit functionality.
**Insight:** When auditing, enumerate every code path that mutates a shared invariant (here deposit removal) and diff their post-condition checks; a single path missing the LUP/HTP guard breaks the invariant for the whole pool.
