# Excess bid amount refund mechanism is redundant and makes it possible to steal all funds from BidderRegistry

openBid() refunds bid minus availableAmount without checking lockedFunds, letting a zero-deposit bidder drain BidderRegistry by bidding its TVL.

- Payout: Contest reward
- Severity: high
- Program: Primev
- Credited: bbl4de
- Disclosed: 2025-08-27
- Write-up quality: 7/10
- Original: https://cdn.cantina.xyz/reports/cantina_competition_primev_oct2024.pdf#3.1.1
- Library page: https://bugbountylibrary.com/r/cantina%3Aprimev_oct2024%3A3.1.1
- Tags: domain:web3 impact:funds-loss kind:contest platform:cantina sev:high tech:solidity technique:source-review vuln:business-logic

**Target:** BidderRegistry.openBid() bid escrow contract
**Root cause:** openBid() sends bidder `bid - availableAmount` ether without verifying it against lockedFunds, so a bidder with zero deposits and zero availableAmount receives the full bid amount back from contract balance.
**Steps:**
1. Register as provider and stake so you can commit your own bid.
2. Make no deposit for the target window (windowAmount=0, usedAmount=0, availableAmount=0).
3. Call openBid() with bid = BidderRegistry TVL; availableAmount < bid triggers refund of bid - 0.
4. Contract sends entire TVL to bidder; bid is then set to availableAmount=0.
5. Win the block via your own provider to finalize the theft.
**How found:** Code review of openBid() refund branch: noticed the transfer of bid - availableAmount is not bounded by lockedFunds, and availableAmount can be 0 with no deposit, making the refund unbounded.
**Exploitation:** Malicious bidder opts in as provider, commits a bid equal to contract TVL with zero locked funds; openBid() refunds the full bid from other bidders' deposits, draining BidderRegistry.
**Insight:** When a contract refunds 'excess' input, check that the refunded amount is bounded by what the caller actually deposited; any refund path not tied to lockedFunds is a drain primitive.
