Christmas Dinner

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

Reentrancy Risk in refund() Function

Vulnerability Details

The refund() function uses a nonReentrant modifier to prevent reentrancy. However, the modifier resets locked = false after the function execution. If an attacker finds a way to bypass the nonReentrant lock (e.g., via a malicious contract or external calls), they could repeatedly call the function and drain funds.

Impact

An attacker could repeatedly trigger the refund() function, draining assets or causing unexpected state changes.

Poc

  1. Deploy a malicious contract that interacts with refund():

contract Malicious {
ChristmasDinner target;
constructor(address _target) {
target = ChristmasDinner(_target);
}
receive() external payable {
// Re-enter refund
target.refund();
}
function attack() external {
target.refund();
}
}
  1. Call the attack() function from the malicious contract.

  2. Observe that the funds are drained because reentrancy prevention is not robust.


Recommendation
  • Use OpenZeppelin's ReentrancyGuard directly for better security practices.

  • Ensure that external calls (_refundETH or _refundERC20) are made after state updates.

  • Follow the Checks-Effects-Interactions (CEI) pattern strictly.

Updates

Lead Judging Commences

0xtimefliez Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

mutex lock incomplete

Support

FAQs

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

Give us feedback!