# Bidders might fail to withdraw their unused funds after the auction was finalized because the contract doesn't have enough balance.

Rounding in SizeSealed finalize lets seller withdraw more quote tokens than bidders paid, leaving the last bidder unable to withdraw refunds.

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

**Target:** SizeSealed auction contract (Solidity)
**Root cause:** Seller's filledQuote is computed once via mulDivDown(clearingQuote, filledBase, clearingBase), while each bidder's quoteBought is recomputed per-bid with mulDivDown(baseAmount, lowestQuote, lowestBase); repeated per-bid rounding down makes the sum of bidder charges less than the seller's single rounded charge.
**Steps:**
1. Deploy auction with baseToSell=4K, K=1 ether.
2. bidder1 bids 3K base / 3K+2 quote; bidder2 bids 2K base / 2K+1 quote.
3. Warp to endTime; seller.finalize([0,1], 2K, 2K+1).
4. Observe seller balance = 4K+2, contract holds K+1.
5. bidder1.withdraw() succeeds, contract holds K.
6. bidder2.withdraw() reverts with TRANSFER_FAILED due to insufficient quote token balance.
**How found:** Code review comparing the seller's single aggregate mulDivDown in finalize against the per-bidder mulDivDown in withdraw, hypothesizing rounding discrepancies accumulate; validated with a Foundry PoC.
**Exploitation:** Seller finalizes auction and receives filledQuote computed from aggregate filledBase; per-bidder refunds recompute quoteBought with independent rounding-down, so total refunds owed exceed remaining contract balance, permanently locking the last bidder's unused quote tokens (or requiring other auctions' funds to cover).
**Insight:** When one aggregate value is computed with mulDivDown but per-user shares are recomputed independently with mulDivDown, the sum of per-user roundings can be less than the aggregate; check accounting invariants where seller payout and bidder refunds derive from the same clearing price.
