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

Low severity issues

L-1: Auction tokens can be stuck in the FjordAuction contract

Summary

Users can bid an unrestricted amount of Fjord Points to participate in an auction. If a situation arises where high bidders submit a large number of Fjord Points, the auction contract may fail to distribute auction tokens to users with lower bid amounts.

Vulnerability Details

The multiplier(ratio between fjord points and auction token) is calculated based on the total auction tokens and the total bids received:

if (totalBids == 0) {
auctionToken.transfer(owner, totalTokens);
return;
}
multiplier = totalTokens.mul(PRECISION_18).div(totalBids);

If totalBids is large (due to high bids by some users), the multiplier becomes small, affecting the claimable amount for users with lower bids.

Each user's claimable amount is calculated using their bids and the multiplier:

uint256 claimable = userBids.mul(multiplier).div(PRECISION_18);
bids[msg.sender] = 0;
auctionToken.transfer(msg.sender, claimable);

Here, if a user has a low amount of userBids and the multiplier is very small, the calculated claimable tokens may end up being zero, making it impossible for low-bid users to receive their share of auction tokens.

Following test can be added to auction.t.sol and run forge test -vv --mt testLowAmountBid

function testLowAmountBid() public {
address bidderBig = address(0x2);
uint256 bidAmountBig = 1_000_000 ether;
address bidderLow = address(0x3);
uint256 bidAmountLow = 1000;
deal(address(fjordPoints), bidderBig, bidAmountBig);
deal(address(fjordPoints), bidderLow, bidAmountLow);
vm.startPrank(bidderBig);
fjordPoints.approve(address(auction), bidAmountBig);
auction.bid(bidAmountBig);
vm.stopPrank();
vm.startPrank(bidderLow);
fjordPoints.approve(address(auction), bidAmountLow);
auction.bid(bidAmountLow);
vm.stopPrank();
skip(biddingTime);
auction.auctionEnd();
vm.prank(bidderBig);
auction.claimTokens();
vm.prank(bidderLow);
auction.claimTokens();
console.log(auction.auctionToken().balanceOf(bidderBig));
console.log(auction.auctionToken().balanceOf(bidderLow));
}
Logs:
999999999999999000000
0

Impact

Auction token being stuck in the contract.

Tools Used

Manual review, Foundry.

Recommendations

To address this issue, consider adding a withdrawal function that allows the protocol to recover unclaimable Fjord Points. Alternatively, increase the precision in calculations to reduce the chances of this issue occurring.

L-2: Possible overflow in FjordAuction contract

Summary

totalPoints is set in the contract constructor and does not have any restrictions. Huge values can cause overflow issues in auctionEnd().

Vulnerability Details

constructor(
address _fjordPoints,
address _auctionToken,
uint256 _biddingTime,
uint256 _totalTokens
) {
if (_fjordPoints == address(0)) {
revert InvalidFjordPointsAddress();
}
if (_auctionToken == address(0)) {
revert InvalidAuctionTokenAddress();
}
fjordPoints = ERC20Burnable(_fjordPoints);
auctionToken = IERC20(_auctionToken);
owner = msg.sender;
auctionEndTime = block.timestamp.add(_biddingTime);
totalTokens = _totalTokens;
}
function auctionEnd() external {
if (block.timestamp < auctionEndTime) {
revert AuctionNotYetEnded();
}
if (ended) {
revert AuctionEndAlreadyCalled();
}
ended = true;
emit AuctionEnded(totalBids, totalTokens);
if (totalBids == 0) {
auctionToken.transfer(owner, totalTokens);
return;
}
multiplier = totalTokens.mul(PRECISION_18).div(totalBids);
// Burn the FjordPoints held by the contract
uint256 pointsToBurn = fjordPoints.balanceOf(address(this));
fjordPoints.burn(pointsToBurn);
}

Huge totalTokens value would cause the totalTokens.mul(PRECISION_18).div(totalBids) to overflow leading to being unable to end the auction.

Impact

Locked fjord points

Tools Used

Manual review

Recommendations

Consider adding a restriction on the totalTokens values.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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