The SmartVaultManagerV5.sol contract is vulnerable to reentrancy attacks in the _afterTokenTransfer function, which is a hook provided by the ERC721Upgradeable contract from the OpenZeppelin library. The vulnerability arises from calling external functions after state changes, allowing potential reentrancy exploits.
Cross-Function Reentrancy :
Cross-Function Reentrancy occurs when an external function is called after state changes within a contract, and this external function may invoke the calling contract's functions again, leading to reentrancy attacks.
In the context of the SmartVaultManagerV5.sol contract, the _afterTokenTransfer function is a hook that gets called when a token transfer occurs. This function performs state changes by updating the smartVaultIndex mapping and potentially invoking external functions. If an attacker can control the destination of a token transfer, they could repeatedly invoke the _afterTokenTransfer function, leading to reentrancy and potential exploits.
In the _afterTokenTransfer function, external functions such as smartVaultIndex.transferTokenId and ISmartVault(smartVaultIndex.getVaultAddress(_tokenId)).setOwner(_to) are called after modifying the state by updating the smartVaultIndex mapping and the owner of a specific SmartVault. This pattern can introduce a reentrancy vulnerability, as an external contract or attacker could potentially execute malicious code during the state transition.
Vulnerable Code Snippet :
// In ISmartVault.sol
interface ISmartVault {
function setOwner(address _newOwner) external;
}
// In SmartVaultManagerV5.sol
function _afterTokenTransfer(address _from, address _to, uint256 _tokenId, uint256) internal override {
smartVaultIndex.transferTokenId(_from, _to, _tokenId);
// WARNING: If setOwner allows external calls, this can be a vulnerability
ISmartVault(smartVaultIndex.getVaultAddress(_tokenId)).setOwner(_to);
emit VaultTransferred(_tokenId, _from, _to);
}
Exploitation:
An attacker creates a malicious contract that exploits the reentrancy vulnerability:
// MaliciousContract.sol
contract MaliciousContract {
function attack(uint256 _tokenId) external {
// Calling the vulnerable _afterTokenTransfer
SmartVaultManagerV5 smartVaultManager = SmartVaultManagerV5(yourSmartVaultManagerAddress);
smartVaultManager._afterTokenTransfer(msg.sender, address(this), _tokenId,
// Malicious logic to be executed during reentrancy
// ...
}
}
The reentrancy vulnerability could allow an attacker to repeatedly invoke the _afterTokenTransfer function, leading to unexpected behavior, potential unauthorized fund transfers, and a reentrancy attack.
The analysis is performed manually without specific tools.
To mitigate this vulnerability, consider using the checks-effects-interactions pattern and ensure that external calls are the last operations in functions.
Implement reentrancy protection mechanisms, such as the reentrancyGuard pattern or using the reentrancyGuard modifier provided by the OpenZeppelin library.
Additionally, carefully review and audit all interactions with external contracts to minimize the risk of reentrancy attacks.
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.