Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

`require` statements after executing code.

Summary

The ERC721.sol::_safeMint functions the protocol uses, have their require statements after the executing code.

Vulnerability Details

In the ERC721.sol contract, the _safeMint functions have their require statements placed after the execution of the _mint function. This means that the minting operation occurs before checking whether the recipient address is a smart contract or not. As a result, tokens can be minted to contracts (when to.code.length > 0), potentially leading to unexpected behavior or security vulnerabilities.

Impact

This coding pattern could result in tokens being mistakenly transferred to contracts that are not intended to receive ERC721 tokens. If the recipient contract does not handle ERC721 tokens correctly, it could result in loss of tokens or unexpected behavior.

Proof of Concept

contract MaliciousContract {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns(bytes4) {
// Malicious behavior here
return bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"));
}
}

Tools Used

manual review

Recommendations

The require statements should be placed before executing the _mint function to ensure that tokens are only minted to addresses that are not smart contracts or that properly handle ERC721 tokens. Here's the corrected version of the _safeMint function. Please follow this pattern for both _safeMint functions.

function _safeMint(address to, uint256 id) internal virtual {
require(
to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector,
"UNSAFE_RECIPIENT"
);
_mint(to, id);
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.