# Highest bid in first auction can get irretrievably stuck in the protocol

Pausing and unpausing the first auction with tokenId 0 resets highestBid and mints token #1, stranding the top bidder's ETH and NFT #0 forever.

- Payout: Contest reward
- Severity: medium
- Program: Nouns Builder
- Credited: PwnPatrol
- Disclosed: 2022-11-03
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-09-nouns-builder-findings/issues/376
- Library page: https://bugbountylibrary.com/r/c4%3A2022-09-nouns-builder%3AM-02
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** Auction.sol unpause()/_createAuction()
**Root cause:** unpause() calls _createAuction() when auction.tokenId == 0, which is also true for a live first auction on token #0, so it mints token #1 and overwrites highestBid/highestBidder without settling.
**Steps:**
1. Deploy with founder ownership percentage 0 so first auctioned tokenId is #0.
2. Unpause; bidder1 calls `auction.createBid{value: 1 ether}(0)`.
3. Treasury calls `auction.pause()` then `auction.unpause()`.
4. unpause() sees tokenId==0, calls _createAuction(), minting token #1 and resetting highestBid/highestBidder.
5. Bidder2 bids on token #1; bidder1's 1 ETH and NFT #0 remain stuck, first auction never settled.
**How found:** Code reading of unpause()'s `if (auction.tokenId == 0)` branch, noticing tokenId 0 is a valid live auction id when founders are empty, then confirming with a Foundry test.
**Exploitation:** Requires treasury pause/unpause during the first auction after a bid; the bidder's ETH is trapped in the contract and NFT #0 is never transferred, with no settle path for the original auction.
**Insight:** Sentinel checks like `tokenId == 0` are unsafe when 0 is a legitimate id; verify state-machine guards against the first-item case, especially in pause/unpause or re-init flows.
