# Removing only the tail order from a limit does not reduce tree size, allowing order book to grow indefinitely

CLOB removes only the tail order from a full limit, leaving the limit node in the tree so the size cap is bypassed and the order book grows unbounded.

- Payout: Contest reward
- Severity: medium
- Program: GTE
- Credited: montecristo
- Disclosed: 2026-02-05
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-07-gte-spot-clob-and-router#m-03
- Library page: https://bugbountylibrary.com/r/c4%3A2025-07-gte-spot-clob-and-router%3AM-03
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:dos

**Target:** CLOB order book limit tree (Solidity smart contract)
**Root cause:** _removeNonCompetitiveOrder only deletes the limit node from the RedBlackTree when numOrders==1; removing a tail order from a multi-order limit leaves the node, so tree size is unchanged.
**Steps:**
1. Fill askTree to maxNumLimitsPerSide with a worst-price limit holding multiple orders.
2. Post a new order at a new price better than maxAskPrice; check `ds.askTree.size() == maxNumLimitsPerSide` passes.
3. _removeNonCompetitiveOrder removes only the tail order; limit node stays, size unchanged.
4. New limit is added, size increases by 1; subsequent posts bypass the `==` check since size > max.
**How found:** Code reading of the size-limit branch and Book.sol removal logic, noticing the numOrders==1 guard means multi-order limits are never removed from the tree.
**Escalation:** Once size exceeds the cap, the equality check at CLOB.sol:633 never triggers again, so the book grows without bound.
**Insight:** When a size cap is enforced with `==` against a container whose removal path is conditional, verify the removal actually decrements the counted unit; a partial removal silently disables the cap.
