Christmas Dinner

First Flight #31
Beginner FriendlyFoundrySolidity
100 EXP
View results
Submission Details
Severity: high
Invalid

Reentrancy Vulnerability in `_refundERC20` Function

Summary

The _refundERC20 function in the ChristmasDinner contract transfers ERC20 tokens to the user before updating their balance to zero. This introduces a reentrancy vulnerability because the external call to safeTransfer allows the recipient to re-enter the contract before the balance is reset. If exploited, this can drain the entire contract balance.

function _refundERC20(address _to) internal {
i_WETH.safeTransfer(_to, balances[_to][address(i_WETH)]);
i_WBTC.safeTransfer(_to, balances[_to][address(i_WBTC)]);
i_USDC.safeTransfer(_to, balances[_to][address(i_USDC)]);
balances[_to][address(i_USDC)] = 0;
balances[_to][address(i_WBTC)] = 0;
balances[_to][address(i_WETH)] = 0;
}

Vulnerability Details

The _refundERC20 function in the ChristmasDinner contract allows the recipient to re-enter the contract during the token transfer process. The balance is updated after the safeTransfer calls, leaving the contract vulnerable to reentrancy attacks. An attacker can exploit this by repeatedly calling the refund() function, draining ERC20 tokens from the contract before the balances are reset. This results in the potential loss of all funds stored in the contract.

Impact

  • Attackers can repeatedly call the refund() function through a fallback or receive function.

  • This could result in the attacker draining all ERC20 tokens from the contract.

  • The contract’s funds can be entirely compromised, causing a significant financial loss.

Tools Used

Foundry

Recommendations

function _refundERC20(address _to) internal {
uint256 wethAmount = balances[_to][address(i_WETH)];
uint256 wbtcAmount = balances[_to][address(i_WBTC)];
uint256 usdcAmount = balances[_to][address(i_USDC)];
balances[_to][address(i_USDC)] = 0;
balances[_to][address(i_WBTC)] = 0;
balances[_to][address(i_WETH)] = 0;
i_WETH.safeTransfer(_to, wethAmount);
i_WBTC.safeTransfer(_to, wbtcAmount);
i_USDC.safeTransfer(_to, usdcAmount);
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 11 months ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Appeal created

shrxyeh Submitter
11 months ago
0xtimefliez Lead Judge
11 months ago
shrxyeh Submitter
11 months ago
0xtimefliez Lead Judge
10 months ago
shrxyeh Submitter
10 months ago
0xtimefliez Lead Judge
10 months ago
0xtimefliez 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.