# The sorting logic is not strict enough

SIZE auction finalization sorts bids by a truncated quotePerBase ratio, letting a worse bid fill before a better one and the seller receive fewer quote tokens.

- Payout: Contest reward
- Severity: medium
- Program: SIZE
- Credited: hansfriese
- Disclosed: 2023-01-09
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-11-size-findings/issues/97
- Library page: https://bugbountylibrary.com/r/c4%3A2022-11-size%3AM-03
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:business-logic vuln:precision-loss

**Target:** SizeSealed auction finalization sorting logic
**Root cause:** Bids are compared via FixedPointMathLib.mulDivDown(b.quoteAmount, type(uint128).max, baseAmount), truncating the ratio; two distinct quote/base pairs can yield the same quotePerBase, so the earlier (worse) bid is treated as equal and filled first.
**Steps:**
1. Set K = 1<<64; baseToSell = K+2; create auction.
2. bidder1 bids (base K+1, quote K); bidder2 bids (base K+2, quote K+1) — bidder2 is better since (K+1)/(K+2) > K/(K+1).
3. Warp to endTime; call `seller.finalize([1,0], K+2, K+1)` — reverts InvalidSorting because truncated quotePerBase values are equal.
4. Call `seller.finalize([0,1], K+1, K)`; seller receives K quote instead of K+1.
**How found:** Reasoned that comparing bids through a single truncated fixed-point ratio loses ordering information; constructed near-equal ratios (K/(K+1) vs (K+1)/(K+2)) to show the collision and wrote a Foundry test.
**Exploitation:** Seller is forced to finalize in the order dictated by the truncated ratio, filling the earlier worse bid and losing the extra quote token the better bid would have paid.
**Insight:** When a protocol sorts or ranks by a single truncated fixed-point ratio, look for distinct numerator/denominator pairs that collide at that precision; cross-multiply (quote1*base2 vs quote2*base1) to test whether ordering is actually strict.
