The Soulmate::mintSoulmateToken
function mints an ERC721
token without the necessary checks to ensure that the receiver of a minted token can handle ERC721
tokens, which could lead to tokens being locked in the contract that do not support the ERC721
token interface.
The Soulmate
contract is an ERC721
token designed to represent soulmate pairings. The Soulmate::mintSoulmateToken
function mints a new token when two soulmates are reunited. The contract is intended to be soulbound, meaning that tokens cannot be transferred after minting. For a token minting the function uses ERC721::_mint
function.
The implementation of the _mint
function is the following:
We can see that the _mint
function doesn't perform a check if the account to mint the NFT
to is a smart contract that can handle ERC721
tokens. So tokens can be minted to non-ERC721
receivers.
The ERC721
standard includes an optional extension for safe transfers, which requires that the receiving contract implements the onERC721Received
function. This function must return a value to indicate that the contract can handle ERC721
tokens. If the receiving contract does not return this value, the transfer should be reverted.
The ERC721::_mint
function does not perform this check, which means that if a token is minted to a contract address that does not implement the onERC721Received
function, the token could become permanently locked within that contract.
The absence of the ERC721
receiver check poses a high risk of token loss if a token is minted to a contract that cannot handle ERC721
tokens.
The test function test_failIfCallerCanNotReceiveERC721Token
shows that the Soulmate::mintSoulmateToken
function doesn't revert when the contract address badReceiver
(the address can not receive ERC721 token) is calling the Soulmate::mintSoulmateToken
.
Manual Review
Use ERC721::_safeMint
function instead of ERC721::_mint
function. But add a nonReentrant
modifier and follow the checks-effects-interactions pattern in Soulmate::mintSoulmateToken
function, because the onERC721Received
callback in the _safeMint
function introduces a reentrancy vector.
Low severity, - If a user utilizes an EOA, the check is not required. - If a user utilizes a contract that they own to mint soulmate tokens, than check is required. However, this would rely on user error minting. Since there is no mention that ownership of token must be from EOAs, I believe low severity is appropriate.
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.