The nonReentrant
modifier, designed to prevent reentrancy attacks, contains a critical flaw due to inconsistent use of transient storage slots. The modifier checks tload(1)
but sets tstore(0, 1)
, resulting in an ineffective lock.
Vulnerable Code :
Exploitation Scenario :
An attacker can bypass the reentrancy check by reentering the contract during a call to a vulnerable function (e.g., sendETH
, sendERC20
, or contractInteractions
). Since the lock is set in slot 0
but checked in slot 1
, the modifier fails to detect reentrant calls, allowing:
Fund Drain : Repeated withdrawals of ETH or ERC20 tokens.
Malicious Contract Calls : Exploiting contractInteractions
to manipulate external protocols.
Critical Fund Loss : Reentrancy attacks can drain all contract-held assets.
Broken Security Guarantees : Functions marked as nonReentrant
are not protected, undermining trust in the contract.
Fix Transient Storage Mismatch :
Use consistent transient storage slots for both the check and lock:
OR Adopt OpenZeppelin’s ReentrancyGuard
:
Replace the custom implementation with a battle-tested library:
This ensures compatibility with Solidity’s transient storage and mitigates edge cases.
The following functions are vulnerable to reentrancy due to the flawed modifier:
sendETH
sendERC20
contractInteractions
Conclusion :
The broken reentrancy guard poses an existential risk to the contract. Immediate patching is required to prevent catastrophic fund loss. Always prioritize well-audited security libraries over custom implementations for critical safeguards.
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.