DeFiFoundry
20,000 USDC
View results
Submission Details
Severity: high
Invalid

Price manipulation vulnerability in auction mechanism due to unrestricted unbidding

Summary

The FjordAuction contract allows users to withdraw their bids (unbid) until the exact moment the auction ends. This feature can be exploited by a large bidder to manipulate the token price and claim an unfair proportion of auction tokens.

Vulnerability Details

At the end of the auction, the system calculates a multiplier using the formula totalTokens / totalBids, which is then stored as a state variable. This multiplier determines how many tokens each bidder receives based on their bids.

function auctionEnd() external {
if (block.timestamp < auctionEndTime) {
revert AuctionNotYetEnded();
}
if (ended) {
revert AuctionEndAlreadyCalled();
}
ended = true;
...
}

https://github.com/Cyfrin/2024-08-fjord/blob/14cab810598ddda6008d9523d0ed4a428b1b1153/src/FjordAuction.sol#L181-L202

However, the unbid function allows withdrawals up to auctionEndTime:

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

https://github.com/Cyfrin/2024-08-fjord/blob/14cab810598ddda6008d9523d0ed4a428b1b1153/src/FjordAuction.sol#L159-L176

This creates an opportunity for a malicious whale to:

  • Place a large bid early in the auction, discouraging other participants.

  • Wait until block.timestamp == auctionEndTime.

  • Withdraw almost all of their bid, drastically reducing totalBids.

  • Immediately call auctionEnd, resulting in an inflated multiplier.

Exploit Scenario:

  • Alice (the whale) bids 1,000,000 fjordPoints for 100 auction tokens.

  • This large bid discourages others from participating due to the perceived high price.

  • At auctionEndTime, Alice withdraws 999,999 fjordPoints, leaving only 1 fjordPoint bid.

  • Alice calls auctionEnd, resulting in a multiplier of 100 * 1e18 / 1 = 100e18.

  • Alice can now claim all 100 tokens by burning just 1 fjordPoint.

Impact

This vulnerability allows a malicious actor to manipulate the auction outcome, potentially claiming all tokens for a minimal cost.

Tools Used

Manual

Recommendations

  • Implement a time-lock for unbidding.

function unbid(uint256 amount) external {
- if (block.timestamp > auctionEndTime) {
+ if (block.timestamp > auctionEndTime - 1 days) {
revert UnbiddingLocked();
}
// ... rest of the function
}
  • Or charge a percentage fee for withdrawing bids, increasing as the auction nears its end.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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