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

Time Conflict Between Bidding and Auction End Functions

Summary

A medium severity vulnerability has been identified in the FjordAuction contract. There is a potential timing conflict between the bid/unbid functions and the auctionEnd function when block.timestamp is exactly equal to auctionEndTime. This could lead to unexpected behavior, potential unfairness in the auction process, and possible manipulation of the auction's final state.

Vulnerability Details

The vulnerability stems from the timing conditions in the bid, unbid, and auctionEnd functions:

  1. For bid and unbid:

if (block.timestamp > auctionEndTime) {
revert AuctionAlreadyEnded();
}
  1. For auctionEnd:

if (block.timestamp < auctionEndTime) {
revert AuctionNotYetEnded();
}

When block.timestamp == auctionEndTime, all three functions can be called within the same block. This creates a race condition where the order of transactions in the block becomes crucial:

  • If auctionEnd is called first, it will set ended = true, preventing any further bids or unbids.

  • If bid or unbid is called first, it will allow last-second changes to the auction state before it ends.

This inconsistency can lead to unfair advantages or disadvantages for participants depending on transaction ordering within the block.

Impact

The impact of this vulnerability includes:

  1. Potential for Unfair Advantage: Users who can manipulate transaction ordering might be able to place or withdraw bids after seeing the final state of the auction.

  2. Inconsistent Auction End State: The final state of the auction could vary depending on which function is executed first in the critical block.

  3. User Confusion and Dissatisfaction: Participants might expect to be able to bid until the last second, but find their transactions reverted if auctionEnd is called first.

  4. Possible Loss of Funds or Opportunities: Users attempting to place last-second bids might have their transactions fail unexpectedly, potentially leading to missed opportunities or gas costs without effect.

  5. Manipulation of Auction Outcome: In extreme cases, this could be exploited to manipulate the auction's outcome, especially if large bids or unbids are made in the final moments.

Tools Used

Manual

Recommendations

To address this vulnerability, we recommend modifying the auctionEnd function to make the auction end time exclusive. This ensures a clear and unambiguous end to the bidding period. Here's the suggested modification:

function auctionEnd() external {
if (block.timestamp <= auctionEndTime) {
revert AuctionNotYetEnded();
}
// ... rest of the function
}

This change accomplishes the following:

  1. It creates a clear distinction between the bidding period and the auction end.

  2. It allows bids and unbids to occur up to and including the auctionEndTime.

  3. The auction can only be ended after the auctionEndTime has passed.

Updates

Lead Judging Commences

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.

Appeal created

0xbrivan2 Judge
about 1 year ago
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.