Christmas Dinner

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

Incomplete Reentrancy Guard

Location

modifier nonReentrant() {
require(!locked, "No re-entrancy");
_;
locked = false;
}

Issue
The nonReentrant modifier currently never sets locked = true before executing the function body. As a result, require(!locked, "No re-entrancy") will always pass, and locked will be set to false again after the function body. This leaves the contract effectively unguarded against reentrancy.

Root Cause
A typical “check-effect-interaction” or mutex pattern for a non-reentrant modifier in Solidity should be:

modifier nonReentrant() {
require(!locked, "No re-entrancy");
locked = true;
_;
locked = false;
}

By not setting locked = true before _;, the contract’s state does not prevent calls into refund() (or other functions using this modifier) from re-entering.

Potential Impact

  • Attackers could call refund() recursively (by re-entering during an external call, e.g., if there were a token with a malicious transfer/fallback), draining user balances or performing unexpected logic flows multiple times.

Recommendation

  • Fix the nonReentrant modifier to set locked = true before executing the function body. For example:

    modifier nonReentrant() {
    require(!locked, "No re-entrancy");
    locked = true;
    _;
    locked = false;
    }
  • Review all functions that may need reentrancy protection, especially those making external calls (e.g., token transfers). Ensure they use the corrected nonReentrant modifier if appropriate.

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!