OpenZeppelin's ERC721.sol includes callback functions to manage NFTs and prevent them from getting stuck in contracts. For NFT contracts, there exist some implicit external function calls that could be neglected by developers. They include onERC721Received function. The onERC721Received function was designed to check whether the receiver contract can handle NFTs. This function is invoked in the safeTransferFrom() of the OwnershipNFTs contract. Due to this external function call, the reentrancy could happen without being noticed by contract developer.
According to what I said above, the malicious person can abuse the same things and write in the onERC721Received function of his contract to call the safeTransferFrom() function many times in a loop in one transaction.
In the safeTransferFrom() function of the OwnershipNFTs.sol contract, the _onTransferReceived() function is called.
function _onTransferReceived(
address _sender,
address _from,
address _to,
uint256 _tokenId
) internal {
// only call the callback if the receiver is a contract
if (_to.code.length == 0) return;
bytes4 data = IERC721TokenReceiver(_to).onERC721Received(
_sender,
_from,
_tokenId,
// this is empty byte data that can be optionally passed to
// the contract we're confirming is able to receive NFTs
""
);
require(
data != IERC721TokenReceiver.onERC721Received.selector,
"bad nft transfer received data"
);
}
POC :
Attacker calls the safeTransferFrom() function.
Due to the lack of Reentrancy Guard adherence, the attacker re-enters the safeTransferFrom() function in onERC721Received before the initial call completes.
This process can be repeated, allowing the attacker to transfer token/NFT more than their allowed.
Impact Details
An attacker can transfer a large amount of tokens/NFTs using reentrancy.
Lines of code
https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/sol/OwnershipNFTs.sol#L145 https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/sol/OwnershipNFTs.sol#L156
Vulnerability details
Impact
Vulnerability Details
OpenZeppelin's ERC721.sol includes callback functions to manage NFTs and prevent them from getting stuck in contracts. For NFT contracts, there exist some implicit external function calls that could be neglected by developers. They include onERC721Received function. The onERC721Received function was designed to check whether the receiver contract can handle NFTs. This function is invoked in the
safeTransferFrom()
of theOwnershipNFTs
contract. Due to this external function call, the reentrancy could happen without being noticed by contract developer.According to what I said above, the malicious person can abuse the same things and write in the
onERC721Received
function of his contract to call thesafeTransferFrom()
function many times in a loop in one transaction.In the
safeTransferFrom()
function of theOwnershipNFTs.sol
contract, the_onTransferReceived()
function is called.https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/sol/OwnershipNFTs.sol#L145
https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/sol/OwnershipNFTs.sol#L156
https://github.com/code-423n4/2024-08-superposition/blob/main/pkg/sol/OwnershipNFTs.sol#L82
POC :
Attacker calls the
safeTransferFrom()
function.Due to the lack of Reentrancy Guard adherence, the attacker re-enters the
safeTransferFrom()
function inonERC721Received
before the initial call completes.This process can be repeated, allowing the attacker to transfer token/NFT more than their allowed.
Impact Details
An attacker can transfer a large amount of tokens/NFTs using reentrancy.
References
https://samczsun.com/the-dangers-of-surprising-code/
https://blog.openzeppelin.com/reentrancy-after-istanbul
https://eips.ethereum.org/EIPS/eip-721
https://medium.com/amber-group/position-exchanges-re-entrancy-loophole-explained-ef176a0fd987
https://solodit.xyz/issues/re-entrancy-issue-for-erc1155-fixed-consensys-bridge-mutual-markdown
https://solodit.xyz/issues/h-03-an-attacker-can-hijack-any-erc1155-token-he-rents-due-to-a-design-issue-in-renft-via-reentrancy-exploitation-code4rena-renft-renft-git
https://www.rareskills.io/post/where-to-find-solidity-reentrancy-attacks
https://blocksecteam.medium.com/revest-finance-vulnerabilities-more-than-re-entrancy-1609957b742f
Proof of Concept
Provide direct links to all referenced code in GitHub. Add screenshots, logs, or any other relevant proof that illustrates the concept.
Tools Used
Manual Analysis
Recommended Mitigation Steps
Add a reentrancy guard (
nonReentrant()
)Assessed type
Reentrancy