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

Multiplier in auction can be equal to zero

Summary

The multiplier can be zero, which will result in no one being able to withdraw the auction token.

Vulnerability Details

If tokens with low decimals, such as USDC/USDT (6 decimals) or Gemini USD (https://etherscan.io/token/0x056Fd409E1d7A124BD7017459dFEa2F387b6d5Cd, which has 2 decimals, are used in the auction, it is possible for the multiplier to be zero. It's important to note that these tokens are fully compatible with ERC20 and are popular in use. On line https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L197, the code multiplier = totalTokens.mul(PRECISION_18).div(totalBids); is found.

Let's say the auction token is GeminiUSD, and the totalBids (representing the number of points users used in the auction) is greater than the token amount by 10**2 + 1 wei, then the multiplier will be equal to zero. This situation is quite possible because the supply of points is large and can be increased by the owner. If the multiplier is zero, then on line https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L217, claimable will always be zero.

Below is a test confirming the calculations. Add it to the units folder if you want to run it.

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity =0.8.21;
import "forge-std/Test.sol";
import "src/FjordAuction.sol";
import { SafeMath } from "lib/openzeppelin-contracts/contracts/utils/math/SafeMath.sol";
contract TestAuctionExploit is Test {
using SafeMath for uint256;
uint256 public constant PRECISION_18 = 1e18;
function setUp() public { }
function test_exploit_multiplier_equals_zero() public view {
uint256 geminiDecimals = 2;
uint256 totalTokens = 10_000 * 10 ** geminiDecimals; // 10k USD
uint256 totalBids = 1_000_001 ether; // 1mln+1 fjordPoints
uint256 multiplier = totalTokens.mul(PRECISION_18).div(totalBids);
assertEq(multiplier, 0);
// any value of the userBids will give zero
uint256 userBids = 1000 ether;
uint256 claimable = userBids.mul(multiplier).div(PRECISION_18);
assertEq(claimable, 0);
}
}

Impact

Auction tokens are locked forever. FjordPoints lost.

Tools Used

Manual review.

Recommendations

Remove the multiplier from the FjordAuction contract and calculate claimable on line https://github.com/Cyfrin/2024-08-fjord/blob/main/src/FjordAuction.sol#L217 using the formula:

uint256 claimable = userBids.mul(totalTokens).div(totalBids);
Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue
Assigned finding tags:

Low decimal tokens or super small bids can lead to 0 claims

Support

FAQs

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