Eggstravaganza

First Flight #37
Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: medium
Valid

Using `_mint` instead of `_safeMint` can lock NFTs

Summary

The mintEgg function in the EggstravaganzaNFT contract utilizes the _mint function for creating new NFTs. This function lacks a check to ensure the recipient address to can handle ERC721 tokens, potentially leading to NFTs being permanently locked if sent to incompatible smart contracts.

Vulnerability Details

The ERC721 standard specifies an optional onERC721Received interface check for safe transfers. While _mint successfully assigns the token ID to the to address, it bypasses this safety check. If the to address is a smart contract that has not implemented the IERC721Receiver interface, it will not be able to handle or transfer the received NFT, effectively locking it within the contract forever.

function mintEgg(address to, uint256 tokenId) external returns (bool) {
require(msg.sender == gameContract, "Unauthorized minter");
_mint(to, tokenId); // Lacks check for contract compatibility
totalSupply += 1;
return true;
}

Impact

NFTs minted via mintEgg to a contract address that does not support the ERC721 receiver interface will become permanently inaccessible and untransferable. This results in a loss of assets for the intended recipient. Although minting is restricted to the gameContract, errors or specific interactions could still lead to minting to an incompatible contract address.

Tools Used

Manual Review

Recommendations

Replace the use of _mint(to, tokenId) with _safeMint(to, tokenId) in the mintEgg function. The _safeMint function performs the necessary check to ensure that if to is a contract, it implements the IERC721Receiver interface. This prevents NFTs from being accidentally locked.

Additionally, since _safeMint does not return a boolean (it reverts on failure), the function signature should be updated to remove the returns (bool) part.

function mintEgg(address to, uint256 tokenId) external returns (bool) {
require(msg.sender == gameContract, "Unauthorized minter");
_safeMint(to, tokenId); // Use _safeMint for safety
totalSupply += 1;
return true;
}
Updates

Lead Judging Commences

m3dython Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Unsafe ERC721 Minting

Protocol doesn't check if recipient contracts can handle ERC721 tokens

Support

FAQs

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