# ERC721Pool's mergeOrRemoveCollateral allows to remove collateral while auction is clearable

ERC721Pool.mergeOrRemoveCollateral lacks the _revertIfAuctionClearable guard, letting a lender remove collateral against stale pool state before auction settlement, mispricing LP shares.

- Payout: Contest reward
- Severity: high
- Program: Ajna
- Credited: hyh
- Disclosed: 2022-12-21
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-01-ajna-judging/issues/105
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-01-ajna%3AH-7
- Tags: domain:web3 impact:funds-loss kind:contest platform:sherlock sev:high tech:evm tech:solidity technique:incomplete-fix technique:source-review vuln:accounting-error vuln:business-logic vuln:liquidation

**Target:** ERC721Pool.mergeOrRemoveCollateral (Solidity lending pool)
**Root cause:** mergeOrRemoveCollateral() omits the _revertIfAuctionClearable() check that removeCollateral() enforces, so collateral can be withdrawn while an auction is clearable and settlement would still redistribute collateral across buckets.
**Steps:**
1. Observe removeCollateral() calls _revertIfAuctionClearable(auctions, loans) but mergeOrRemoveCollateral() does not.
2. Kick/await an auction that is clearable (kickTime >72h or borrower t0Debt!=0 with collateral==0).
3. Call `mergeOrRemoveCollateral(removalIndexes_, noOfNFTsToRemove_, toIndex_)` as a lender before settlement.
4. When collateralMerged_ == collateralAmount, _transferFromPoolToAddress sends NFTs out based on pre-settlement bucket state.
5. Auction settlement then changes collateral per bucket, so the caller's LP-share accounting diverges from actual pool state.
**How found:** Code review comparing the guarded removeCollateral() against the unguarded mergeOrRemoveCollateral() in ERC721Pool, noting both can move collateral out of buckets whose allocation auction settlement can change.
**Exploitation:** A lender times the call to when auction settlement would increase (or decrease) collateral in the buckets they spend LP shares on, removing NFTs at the stale favorable rate and leaving other bucket LPs to absorb the difference.
**Insight:** When a protocol gates one state-mutating entrypoint on 'auction not clearable', enumerate every sibling function that touches the same bucket accounting (merge/remove variants, ERC721 vs ERC20 pools) for the missing guard.
