User can bid after the auction ends which can happen if the auction ends within the same block and the user also bids within the same block, since the block shares the same timestamp. This way the calculated multiplier will not be affected after the bid.
Auction can be ended if the timestamps are equal.
https://github.com/Cyfrin/2024-08-fjord/blob/0312fa9dca29fa7ed9fc432fdcd05545b736575d/src/FjordAuction.sol#L182-#L184
Then we can go and bid within the same block that the auction has ended.
https://github.com/Cyfrin/2024-08-fjord/blob/0312fa9dca29fa7ed9fc432fdcd05545b736575d/src/FjordAuction.sol#L144-#L146
The user can use the multiplier in their favor.
The user can also claim their tokens and creating a DoS for the other users, since there won't be enough tokens at the end to be sent/claimed.
Example scenario:
TotalTokens: 100
.
Bob bids 10
.
Alice bids 10
.
Total bids: 20
.
Multiplier is: 100.mul(1e18).div(20)
= 5000000000000000000
So the tokens are calculated to be evenly
distributed among 2 users.
Exploiter also bids 10
after the auction ends.
Then the exploiter goes and claims his reward leaving 100 - 50 = 50 tokens
in the contract.
Bob claims his tokens ,leaving 50 - 50 = 0 tokens
in the contract.
Alice share is 50 tokens
, but there are 0 tokens
left in the contract. This results in a DoS and Alice can't claim her tokens.
Run the test forge test --mt testBidWhenAuctionEnd
Add the following test inside the test/unit/auction.t.sol
:
The malicious user can bid after the auction ends. This will create a DoS for the regular users that will try to claim their tokens.
This could happen intentionally and also unintentionally.
Manual Review
Foundry
Add ended
check for unbid and bid functions.
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.