A malicious user can call the FjordAuction::bid
function after the FjordAuction::auctionEnd
function has been executed. This issue arises because both the FjordAuction::bid
and FjordAuction::auctionEnd
functions check block.timestamp
against FjordAuction::auctionEndTime
but do not account for the scenario where block.timestamp
equals FjordAuction::auctionEndTime
. Details are provided in the 'Proof of Concept' section.
A malicious user can bid after the auction has ended to receive more tokens than expected. As a result, some bidders are unable to claim auction tokens and lose their FjordPoints
tokens.
First, the malicious user creates an attacker contract to call the FjordAuction::auctionEnd
function and the FjordAuction::bid
function within a single transaction. Then, they wait until the block.timestamp
equals FjordAuction::auctionEndTime
to send the transaction and execute the attack.
Add the code for the Attacker
contract to the test/unit/auction.t.sol
file:
Add the test case and run the command forge test --mt testBidAfterAuctionEnd
:
Update function FjordAuction::auctionEnd
:
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.