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

Reentrancy Vulnerability in claimTokens()

Summary

claimTokens updates the user's bid balance after transferring tokens. This exposes the contract to a reentrancy attack, allowing a user to claim more tokens than they are entitled

Vulnerability Details

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

The critical issue is that the function transfers tokens to the user before setting the user's bid balance to zero. If the transferred token’s contract (or another contract in the call chain) has a callback that can re-enter the claimTokens() function before the state is updated, the user can effectively call claimTokens() again with the same balance,

Impact

  • A malicious user could call the claimTokens() function and use a reentrancy attack to repeatedly call the function before the bids[msg.sender] balance is set to 0. This allows them to withdraw more tokens than they are entitled to, as the balance check is performed only after the transfer.

  • This attack can be executed if the auctionToken contract's transfer function calls back into the claimTokens() function, reentering the same logic and allowing the attacker to drain the contract of tokens.

Tools Used

vs code

Recommendations

The user’s bid balance is set to 0 before any external interaction occurs, ensuring that even if a reentrancy attack is attempted, the attacker cannot withdraw more tokens than they are supposed to.

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);
// Mitigation: Update the user's bid balance before transferring tokens
bids[msg.sender] = 0;
// Transfer tokens after the balance has been updated
auctionToken.transfer(msg.sender, claimable);
emit TokensClaimed(msg.sender, claimable);
}
Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Lack of quality

Support

FAQs

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