The nonReentrant
modifier contains a critical vulnerability due to inconsistent transient storage slot usage. The modifier checks slot 1 (tload(1)
) to determine if a reentrant call is occurring, but sets its lock flag in slot 0 (tstore(0, 1)
). This implementation error completely negates the reentrancy protection, as the slot being checked never contains the lock flag. Consequently, all functions using this modifier, including sendERC20
, sendETH
, and contractInteractions
, remain vulnerable to reentrancy attacks despite appearing protected. This vulnerability could allow attackers to drain funds through reentrant calls to these critical functions.
The smart contract implements a reentrancy guard using transient storage via Solidity's tload
and tstore
assembly instructions. However, there is a critical implementation error where the code checks and updates different storage slots, creating an ineffective reentrancy protection mechanism.
The reentrancy check examines slot 1 with tload(1)
, but sets the lock flag in slot 0 with tstore(0, 1)
. When a function protected by this modifier is called and a reentrant call occurs, the check will always pass because slot 1 remains at its default value of 0, regardless of how many nested calls exist.
This implementation error essentially renders the reentrancy protection completely ineffective, allowing malicious contracts to perform reentrant calls on protected functions.
The following functions are affected as they rely on this defective modifier:
sendERC20(address _tokenAddress, uint256 _amount, address _to)
sendETH(uint256 _amount, address _to)
contractInteractions(address _target, bytes calldata _payload, uint256 _value, bool _storeTarget)
An attacker could exploit this vulnerability by:
Creating a malicious contract with a fallback function that calls back into vulnerable functions
Calling a protected function like sendETH
During the ETH transfer, the attacker's fallback function would execute
The fallback function could call back into the same or another protected function
The reentrancy check would pass because it checks slot 1, which remains at 0
This could lead to multiple withdrawals before state updates are completed
The contract handles valuable assets including ETH, ERC20 tokens, and NFTs representing real estate. The reentrancy vulnerability puts all these assets at risk of unauthorized manipulation or theft.
manual review
Correct the mismatch by using the same slot for both checking and setting the lock flag:
`modifier nonReentrant() { assembly { if tload(1) { revert(0, 0) } tstore(1, 1) // Use the same slot as in the check } _; assembly { tstore(1, 0) // Clear the same slot as set above } }`
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.