# Settlement can be called when auction period isn't concluded, allowing HPB depositors to game bad debt settlements

Off-by-one in Ajna settlePoolDebt allows settlement at exactly kickTime+72h, letting HPB depositors atomically remove/settle/re-add quote to shift bad debt onto others.

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

**Target:** Lending pool settlement / auction liquidation logic (SettlerActions.sol)
**Root cause:** settlePoolDebt uses `block.timestamp - kickTime < 72 hours` to revert, so at exactly kickTime+72h settlement is permitted, while _revertIfAuctionClearable uses `> 72 hours` treating that same timestamp as still within the auction period.
**Steps:**
1. Observe a liquidation with kickTime such that block.timestamp == kickTime + 72 hours is reachable.
2. Confirm at that timestamp both removeQuoteToken (guarded by _revertIfAuctionClearable, which only reverts when >72h) and settlePoolDebt (reverts only when <72h) are callable.
3. Atomically call `removeQuoteToken()` to pull the HPB position out.
4. Call `settlePoolDebt()` so bad debt is settled against remaining nearby buckets' funds.
5. Call `addQuoteToken()` to restore the yield-generating HPB position.
**How found:** Code reading comparing boundary conditions across settlePoolDebt (`< 72 hours` revert), _revertIfAuctionClearable (`> 72 hours` revert), and takeReserves (`<= 72 hours`), spotting the inconsistent treatment of the exact end-of-period timestamp.
**Exploitation:** HPB depositor monitors pool state; at exactly kickTime+72h executes removeQuoteToken -> settlePoolDebt -> addQuoteToken in one tx, keeping their position while bad debt is absorbed by other depositors' buckets.
**Insight:** When auditing time-window guards, diff every comparison operator across functions sharing the same period; an inclusive/exclusive mismatch at the exact boundary timestamp can let two mutually-exclusive actions (withdraw vs settle) coexist in one block.
