The InheritanceManager
contract's sendETH
function is restricted to the contract owner. However, despite this restriction, the nonReentrant modifier fails to work correctly due to an incorrect transient storage slot usage. This flaw allows a reentrancy attack, enabling the owner (or a compromised owner account) to repeatedly call sendETH
within a single transaction, effectively draining the entire ETH balance of the contract.
An attacker who gains control over the contract owner (through phishing, private key compromise, or social engineering) can fully drain the ETH balance by exploiting this bug. Even though the function is onlyOwner, the incorrect nonReentrant modifier does not prevent reentrancy as intended.
Impact: High (Complete loss of funds)
Likelihood: Medium (Requires owner compromise)
Affected Function: sendETH
nonReentrant
ModifierThe nonReentrant
modifier aims to prevent reentrancy using transient storage (tstore
and tload
), but it contains an implementation mistake:
The modifier checks for a lock in slot 1
(tload(1)
).
The modifier sets the lock in slot 0
(tstore(0, 1)
).
Since slot 1
is never written to, the reentrancy check always passes, allowing the function to be recursively called.
onlyOwner
Is Not EnoughEven though sendETH
is protected by onlyOwner
, this does not prevent reentrancy. A malicious or compromised owner can still reenter the function before the lock is applied, draining all ETH.
A malicious owner can deploy a helper contract (MaliciousOwner
) to exploit the sendETH
function.
The owner deploys MaliciousOwner
, funding InheritanceManager
with 100 ETH.
The owner calls sendETH(1 ether, address(attacker))
, receiving 1 ETH.
In the receive()
function, the owner reenters sendETH
before the function completes.
This process repeats until all ETH is drained from the contract.
Modify the nonReentrant
modifier to read and write to the same transient storage slot (0
or 1
consistently).
This vulnerability allows a full reentrancy attack due to incorrect transient storage slot usage in the nonReentrant
modifier. Despite being an onlyOwner
function, the broken modifier enables the contract's funds to be drained by a compromised or malicious owner. The recommended fix ensures that the lock is properly enforced, preventing unauthorized recursive calls. Given the severity and ease of exploitation, this issue should be addressed immediately.
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.