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

The FjordAuction contract attempts to transfer auction tokens that it does not possess

Summary

The FjordAuction contract attempts to transfer auction tokens that it does not possess.

Vulnerability Details

In a case where there are no bids, and the owner or anyone else calls auctionEnd, the auctionToken.transfer(owner, totalTokens) line is executed.

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);
}

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

In the context of the transfer function, msg.sender is the FjordAuction contract address. Here's Solmate ERC20 transfer function:

function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
// Cannot overflow because the sum of all user
// balances can't exceed the max uint256 value.
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}

https://github.com/transmissions11/solmate/blob/97bdb2003b70382996a79a406813f76417b1cf90/src/tokens/ERC20.sol#L76C2-L88C6

Note that the transfer function in use is that of the Solmate library because the tokens are minted using the Solmate's library.

// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity =0.8.21;
import { ERC20 } from "solmate/tokens/ERC20.sol";
contract FjordToken is ERC20 {
constructor() ERC20("Fjord Foundry", "FJO", 18) {
_mint(msg.sender, 100_000_000 ether);
}
}

https://github.com/Cyfrin/2024-08-fjord/blob/0312fa9dca29fa7ed9fc432fdcd05545b736575d/src/FjordToken.sol#L1C1-L10C2

Openzeppelin's ERC20 interface was only used in the Fjordauction contract.

Now the transfer function attempts to deduct totalTokens from the balance of the FjordAuction contract.

balanceOf[msg.sender] -= amount;

Then it adds totalTokens to the owner's balance.

This is a bug and here's why:

  • The FjordAuction contract is attempting to transfer tokens that it doesn't own. No tokens were deposited into the contract initially.

  • Since the FjordAuction contract doesn't have any balance of auction tokens, the transfer will fail.

This same issue arise in the claimTokens function:

function claimTokens() external {
if (!ended) {
revert AuctionNotYetEnded();
}
uint256 userBids = bids[msg.sender];
if (userBids == 0) {
revert NoTokensToClaim();
}
uint256 claimable = userBids.mul(multiplier).div(PRECISION_18);
bids[msg.sender] = 0;
auctionToken.transfer(msg.sender, claimable);
emit TokensClaimed(msg.sender, claimable);
}

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

Here's the buggy line:

auctionToken.transfer(msg.sender, claimable);

Where there were bids and end auction function called successfully, when it's time for users to claim tokens and claimTokens() is called, the function would revert. This is because the Fjordauction contract has no token balance.

Impact

The transfer would fail making it impossible to end the auction.

It would be impossible for users to claim their tokens.

Tools Used

Manual review

Recommendations

The auction contract should be designed to hold the auction tokens from the start.

Updates

Lead Judging Commences

inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

sabit Submitter
10 months ago
inallhonesty Lead Judge
10 months ago
inallhonesty Lead Judge 10 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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