Eggstravaganza

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

Unsafe NFT minting in EggstravaganzaNFT could lead to permanently locked tokens

Summary

The mintEgg function in the EggstravaganzaNFT contract uses _mint instead of _safeMint when creating new NFTs. This implementation fails to verify whether the recipient address (to) is capable of handling ERC721 tokens if it's a contract. If NFTs are minted to contracts that don't support the ERC721 standard or don't have retrieval mechanisms, tokens can become permanently locked and inaccessible.

Vulnerability Details

Standard ERC721 provides the following minting functions:

  1. _mint - Basic minting that transfers tokens without checking recipient capability

  2. _safeMint - Validated minting that verifies contract recipients can handle ERC721 tokens

The current implementation uses _mint, which lacks proper validation. When minting to contract addresses, it doesn't verify if the contract:

  • Implements the ERC721Receiver interface

  • Can interact with NFTs properly

  • Has any mechanism to extract the NFTs later

Unlike _safeMint, which would check if a recipient contract implements onERC721Received() and revert if not, _mint will complete successfully even when sending to incompatible contracts.

Impact

  • Permanent token lockup: NFTs sent to incompatible contracts become permanently inaccessible

  • Loss of assets: Valuable NFTs could be irretrievably lost

  • Inaccurate accounting: The totalSupply would increase, but the effective circulating supply would be lower due to locked tokens

This issue has a medium severity because:

  1. It requires specific circumstances (minting to incompatible contracts)

  2. The problem is not exploitable by malicious actors for direct gain

  3. It represents a functional error rather than an exploitable security vulnerability

Tools Used

Foundry

Recommendations

Replace _mint with _safeMint to ensure recipient contracts can handle ERC721 tokens. If there are gas optimization concerns with _safeMint, consider adding a parameter to toggle between safe and regular minting, with safe being the default:

function mintEgg(address to, uint256 tokenId, bool unsafe) external returns (bool) {
require(msg.sender == gameContract, "Unauthorized minter");
totalSupply += 1;
if (unsafe) {
_mint(to, tokenId);
} else {
_safeMint(to, tokenId);
}
return true;
}
Updates

Lead Judging Commences

m3dython Lead Judge 8 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.

Give us feedback!