The bid
function in the FjordAuction
contract allows users to place bids as long as the current block timestamp is not greater than the auctionEndTime
, as shown below:
The auctionEnd
function can be called when the block timestamp is greater than or equal to auctionEndTime
to conclude the auction and calculate the claimable tokens for each bidder based on their bid proportion.
The problem is because both the bid
function and auctionEnd
can be called when the block timestamp is exactly equal to auctionEndTime
. If a user places a bid in the same block when auctionEndTime
is reached and the auctionEnd
function is executed first in that block, the bid will be placed after the auction has technically ended, and the claimable tokens for each bidder will have already been calculated.
If a bid is placed after the auction has ended through the scenario described above, the FjordPoints sent to the contract as part of that bid will not be burned as they should be when auctionEnd
is called, causing them to remain stuck in the contract indefinitely.
Additionally, the user who placed the bid will be able to claim tokens for their bid, but since their bid was not considered during the multiplier calculation, the last user(s) to claim will not be able to claim their tokens after the auction has ended.
Manual analysis
To prevent this issue, modify the auctionEnd
function to revert if block.timestamp
is less than or equal to auctionEndTime
. This change ensures that users will not be able to place bids after the auction has ended.
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.