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

Incorrect Transient Storage Slot Usage in Reentrancy Protection

Summary

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.

Vulnerability Details

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.

Technical Impact

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.

Vulnerable 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)

Attack Vector

An attacker could exploit this vulnerability by:

  1. Creating a malicious contract with a fallback function that calls back into vulnerable functions

  2. Calling a protected function like sendETH

  3. During the ETH transfer, the attacker's fallback function would execute

  4. The fallback function could call back into the same or another protected function

  5. The reentrancy check would pass because it checks slot 1, which remains at 0

  6. This could lead to multiple withdrawals before state updates are completed

Code Context

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.

Tools Used

manual review

Recommendations

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 } }`

Updates

Lead Judging Commences

0xtimefliez Lead Judge 5 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Wrong value in nonReentrant modifier

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.