The ChristmasDinner contract has a reentrancy vulnerability in the refund() function. This vulnerability arises because the contract transfers Ether to the user before applying the reentrancy lock, which can lead to a recursive call of the refund() function. This can result in an attacker draining the contract's funds by repeatedly calling the refund() function via their receive() function.
The refund() function in the contract calls two functions to refund the user: _refundERC20() and _refundETH(). The nonReentrant modifier is applied to refund(), but the issue lies in how the Ether refund is executed
The vulnerability occurs in the _refundETH() function, where Ether is sent to the user before the reentrancy lock is applied. This enables the attacker to call refund() again via their receive() function and re-enter the contract, bypassing the reentrancy guard.
The nonReentrant modifier is intended to prevent reentrancy attacks by ensuring that no other external function can be called before the current function finishes executing. However, in the refund() function, the state is updated (such as sending Ether or ERC20 tokens to the user) before the modifier fully locks the contract.
Here is the problematic code in the _refundETH() function:
The reentrancy vulnerability allows an attacker to repeatedly call the refund() function, draining the contract of its funds.
Manual
The modifier should immediately lock the contract before any other logic is executed. Update the nonReentrant modifier as follows:
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.