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.