Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

nonReentrant guard not working

Summary

The nonReentrant modifier is ineffective due to an incorrect implementation using assembly. The intended reentrancy protection mechanism can be bypassed, making the contract vulnerable to reentrancy attacks.

Vulnerability Details

  • The modifier uses storage slot 0 to store the reentrancy lock, but it loads from slot 1, creating an inconsistency.

  • The check if tload(1) { revert(0, 0) } is ineffective because it never reads the correct storage location.

  • This means an attacker can call the function recursively without triggering the expected revert condition, allowing reentrancy exploits.

Problematic Code

modifier nonReentrant() { assembly { if tload(1) { revert(0, 0) } // ❌ Loads from slot 1 (incorrect) tstore(0, 1) // ❌ Stores lock in slot 0 (inconsistent) } _; assembly { tstore(0, 0) // ❌ Unlocks slot 0, but it was never checked properly } }

The first assembly block checks slot 1, but the lock is set in slot 0, making the check ineffective.

  • As a result, the function can be reentered because the revert(0, 0) statement never executes under normal conditions

Impact

Complete bypass of reentrancy protection, making functions vulnerable to reentrancy attacks where an attacker can drain funds or manipulate contract state.

  • High risk in financial applications, especially if the function deals with ETH transfers, token approvals, or state changes that assume a single execution flow.

  • Potential contract compromise if attackers exploit reentrancy to drain assets or disrupt operations.

Tools Used

Manual Review

Recommendations

✅ Fix Storage Slot Inconsistency

Modify the modifier to use the same slot for both reading and writing:

solidity

CopyEdit

modifier nonReentrant() { assembly { if tload(0) { revert(0, 0) } // ✅ Correctly loads from slot 0 tstore(0, 1) // ✅ Sets lock in the same slot } _; assembly { tstore(0, 0) // ✅ Unlocks correctly } }

🔹 Alternative: Use OpenZeppelin’s ReentrancyGuard

If possible, use OpenZeppelin’s ReentrancyGuard, which is a battle-tested approach:

solidity

CopyEdit

import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract MyContract is ReentrancyGuard { function myFunction() external nonReentrant { // Safe from reentrancy } }

Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Wrong value in nonReentrant modifier

Support

FAQs

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