If a bid is placed post-auction due to timing issues, the FjordPoints remain stuck, and the bidder can claim tokens despite their bid not factoring into calculations, preventing earlier bidders from reclaiming their tokens and causing potential fund losses.
In bid function, users can place bids if the current block timestamp is not greater than the auctionEndTime:
The auctionEnd function can be called when the block timestamp is greater than or equal to auctionEndTime to conclude the auction and calculate the multiplier which then determines each users' propotion of token claim.
The issue arises because both the bid and auctionEnd functions can be executed when the block timestamp matches auctionEndTime. If a user submits a bid in the same block where auctionEndTime occurs and the auctionEnd function executes first, the bid will be processed after the auction officially concludes, with claimable tokens for each bidder already determined.
Same thing can happen with unbid.
If a bid is placed after the auction ends due to the scenario described, the FjordPoints sent with that bid won't be burned as they should when auctionEnd is called, leaving them indefinitely stuck in the contract. Additionally, the bidder can claim tokens, but since their bid wasn't included in the multiplier calculation, the last user(s) to claim may be unable to retrieve their tokens post-auction.
Bidders can still place bids even after the auction has ended (ended = true). Consequently, early bidders may be unable to claim the auctionToken tokens allocated to them and cannot reclaim their FjordPoints tokens since attempting to call FjordAuction::unbid will trigger an AuctionAlreadyEnded error, resulting in a loss of funds for the bidders.
Manual Review
Check ended state in bid function:
The protocol doesn't properly treat the `block.timestamp == auctionEndTime` case. Impact: High - There are at least two possible impacts here: 1. By chance, user bids could land in a block after the `auctionEnd()` is called, not including them in the multiplier calculation, leading to a situation where there are insufficient funds to pay everyone's claim; 2. By malice, where someone can use a script to call `auctionEnd()` + `bid(totalBids)` + `claimTokens()`, effectively depriving all good faith bidders from tokens. Likelihood: Low – The chances of getting a `block.timestamp == auctionEndTime` are pretty slim, but it’s definitely possible.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.