InheritanceManager
contract tries to prevent reentrancy attacks by using Solidity's new transient storage (tstore
/tload
). However, it makes a mistake when choosing and using storage keys, which could allow attackers to bypass this protection. This issue puts the contract's funds at serious risk.The contract uses a nonReentrant
modifier to prevent functions from being called in a reentrant way ( called again before the first call finishes). But here’s what’s wrong:
Mismatch in keys:
The contract checks if a lock is active using tload(1)
but stores the lock value in tstore(0, 1)
.
Since it stores and checks different keys (0
and 1
), the lock doesn’t work — making the protection useless.
Unsafe hardcoded key:
Using a low-value key like 0
is unsafe because other parts of the contract (or future updates) might use it too, leading to accidental overwriting of the lock and possible reentrancy vulnerabilities.
Shared storage across contract:
Transient storage is shared in the contract. If other functions or parts of the contract use the same key (0
), they can interfere with the reentrancy lock.
Manual code review and analysis of how tstore
and tload
are used.
Reference to Solidity's official documentation on transient storage.
Knowledge of smart contract security best practices.
Manual code review
Reference to Solidity's official documentation on transient storage.
Fix the key mismatch: Make sure that both tstore
and tload
use the same key.
Use a unique key instead of a hardcoded number like 0
.
For example
uint256 constant NON_REENTRANT_KEY = uint256(keccak256("InheritanceManager.reentrancy.lock"));modifier nonReentrant() {assembly {if tload(NON_REENTRANT_KEY) { revert(0, 0) }tstore(NON_REENTRANT_KEY, 1)}_;assembly {tstore(NON_REENTRANT_KEY, 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.