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

Incorrect auction end time check in `FjordAuction::bid` and `FjordAuction::unbid` functions

Summary

The FjordAuction.solauction contract provided includes time-bound checks in the bid and unbid functions to ensure that bids can only be placed or withdrawn before the auction ends. However, the current implementation uses if (block.timestamp > auctionEndTime) for this validation, which may lead to edge cases where bids or withdrawals are allowed precisely at the end of the auction. To enforce the intended behavior strictly, the check should be updated to if (block.timestamp >= auctionEndTime) to prevent any interaction after the auction end time.

Vulnerability Details

In the bid and unbid functions, the contract currently uses the following checks:

if (block.timestamp > auctionEndTime) {
revert AuctionAlreadyEnded();
}

https://github.com/Cyfrin/2024-08-fjord/blob/0312fa9dca29fa7ed9fc432fdcd05545b736575d/src/FjordAuction.sol#L144-L145

https://github.com/Cyfrin/2024-08-fjord/blob/0312fa9dca29fa7ed9fc432fdcd05545b736575d/src/FjordAuction.sol#L160C8-L161

This check allows bids and withdrawals to be executed up until the exact moment when block.timestamp equals auctionEndTime. However, this is not the intended behavior. The auction should strictly end at auctionEndTime, and no further bids or withdrawals should be permitted once the auction has concluded.

Impact

Allowing bids or withdrawals at the exact end time of the auction can undermine the integrity of the auction process. articipants with precise timing capabilities (e.g., automated bots) may exploit this behavior to place last-second bids or withdrawals, gaining an unfair advantage over other participants.

Tools Used

Manual review.

Recommendations

Replace the current check with a stricter validation that prevents any transactions once block.timestamp equals or exceeds auctionEndTime:

function bid(uint256 amount) external {
if (block.timestamp >= auctionEndTime) {
revert AuctionAlreadyEnded();
}
// Rest of the function logic...
}
function unbid(uint256 amount) external {
if (block.timestamp >= auctionEndTime) {
revert AuctionAlreadyEnded();
}
// Rest of the function logic...
}
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year 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.