DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: medium
Valid

Unbid is callable after auction ends, resulting in auctionTokens getting permanently locked

Summary

In the fjordAuction contract,
Unbid can be called after auction ends when block.timestamp == auctionEndTime
resulting in auctionTokens being permanently locked in contract.

Links to affected code

https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L159-L161

https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L181-L184

Vulnerability Details

As per the Auction contracts' intended design,
`Unbid` function should not be callable after the end of auction.

Note that, Ethereum currently produces a new block every 12 seconds.
So there is a 1/12 probability for the block.timestamp
to coincide with the auctionEndTime

In an edge case where block.timestamp coincides with the auctionEndTime
Unbid function can be called in the same block after the auctionEndis called
either accidently or intentionally.

In this case,
the multiplier is calculated in the auctionEnd before unbid is called.
Which results in a certain propotion of auctionTokens remaining unclaimable.

Even if there is no incentive for an user to perform this action,
It is still possible for an innocent user to call unbidin the same block after someone else calls auctionEnd.
This leads to auctionTokens getting permanently locked in the contract
with no way to recover.

Impact

AuctionTokens could be permanently locked in contract
when an user accidently calls Unbid function when
block.timestamp == auctionEndTime

Tools Used

Manual Review

Recommendations

This can be fixed by changing the condition in unbid
to revert when block.timestamp > = auctionEndTime

function unbid(uint256 amount) external {
if (block.timestamp > = auctionEndTime) {
revert AuctionAlreadyEnded();
}
Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Users can bid in the same block when the actionEnd could be called (`block.timestamp==actionEndTime`), depending on the order of txs in block they could lose funds

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.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.