Description:
The nonReentrant modifier is implemented incorrectly by checking slot 1 instead of slot 0 in transient storage. This allows reentrancy attacks since the storage slot used for locking is not the expected one.
Although the impact is mitigated in the current implementation by always combining nonReentrant with onlyOwner, this introduces a major security risk if the modifier is later applied to functions that do not require ownership.
Impact:
Medium Severity
Likelihood: High – If this modifier is applied to any function that lacks onlyOwner, reentrancy attacks become possible.
Potential Consequences: Attacker-controlled contracts could exploit functions using this incorrect nonReentrant implementation, leading to loss of funds or unintended behavior.
Proof of Concept:
The attacker can re-enter the function before it finishes execution, manipulating contract state.
We can see we ae reentering the Fn thanks to the vulnerability in nonReentrant modifier but we revert because of onlyOwner.
Logs: [29144] InheritanceManagerTest::test_audit_ReentrancyBySendingEth()
InheritanceManager::sendETH(1000000000000000000 [1e18], Malicious1: [0xF62849F9A0B5Bf2913b396098F7c7019b51A820a])
[4640] Malicious1::receive{value: 1000000000000000000}()
[1310] InheritanceManager::sendETH(9000000000000000000 [9e18], Malicious1: [0xF62849F9A0B5Bf2913b396098F7c7019b51A820a])
[Revert] NotOwner(0xF62849F9A0B5Bf2913b396098F7c7019b51A820a)
Recommended Mitigation:
To properly implement reentrancy protection, the modifier must use the correct transient storage slot (0):
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.