An attacker can steal the auctionTokens from other eligible bidders of an auction by making a bid after the auction has ended.
The FjordAuction contract is used to allow the Fjord community members to redeem thier FjordPoints for auctionTokens via a bidding process. The FjordAuction.bid function is used to make a bid and the FjordAuction.auctionEnd function is used to end the auction once the auction has expired and the FjordAuction.claimTokens is used to claim the auctionTokens corresponding to the respective bid amount of the bidder (msg.sender).
But the issue here is that the contract allows to end the auction and make a bid simultaneously at block.timestamp == auctionEndTime as shown in the following code snippets:
This vulnerability allows an Attacker to call FjordAuction.auctionEnd (In which the multiplier is calculated) and end the auction and then in the same transaction to call the FjordAuction.bid and increase attacker's bid amount. Then in the same transaction the attacker can call FjordAuction.claimTokens and claim the auctionTokens corresponding to the attacker's inflated bid amount. Since the multiplier does not account for the bid amount made after the auction end, this will allow the attacker to steal funds (auction tokens) from the other bidders. Other bidders will not be able to claim thier eligible auctionTokens since the contract does not have enough balance as the attacker has stolen the funds from the contract.
Please add the following testcase to the test/unit/auction.t.sol file and execute the following command.
forge test --match-test testClaimTokensAttackBid
https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L181-L184
https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L143-L146
https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L197
https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L207-L222
Manual Review, Foundry and VSCode
Hence it is recommended to change the auctionEndTime timestamp conditional check in the FjordAuction.auctionEnd() function to block.timestamp <= auctionEndTime as shown below:
The above change will ensure that auctions can not be ended when the block.timestamp == auctionEndTime which means an attacker can not make a bid after the auction has ended, since there is no overlap of the timestamps during which the bid and auctionEnd transaction can be called.
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.