GivingThanks

First Flight #28
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Invalid

Bug Report: Unsafe NFT Minting Using _mint() Instead of _safeMint() in GivingThanks.sol

Summary:
The GivingThanks contract utilizes the _mint() function to mint NFTs directly to the user. This approach does not verify whether the recipient can receive ERC721 tokens, which can lead to NFTs being sent to addresses that do not support ERC721. To avoid this issue, it is recommended to use _safeMint() instead, which ensures the recipient address can properly handle ERC721 tokens.

Vulnerability Details:
The donate function currently uses _mint():

function donate(address charity) public payable {
require(registry.isVerified(charity), "Charity not verified");
(bool sent, ) = charity.call{value: msg.value}("");
require(sent, "Failed to send Ether");
_mint(msg.sender, tokenCounter);
// Create metadata for the tokenURI
string memory uri = _createTokenURI(
msg.sender,
block.timestamp,
msg.value
);
_setTokenURI(tokenCounter, uri);
tokenCounter += 1;
}

Problem: The _mint() function directly assigns the NFT to the specified address without checking if the recipient can accept ERC721 tokens. If the recipient is a smart contract that does not implement the IERC721Receiver interface, the NFT will be permanently locked in that contract, making it irretrievable.

Impact:

  • Permanent Loss of NFTs: NFTs sent to non-compliant smart contracts may be permanently lost and irretrievable, causing asset loss for users.

  • User Frustration and Financial Loss: Users could lose valuable NFTs if the recipient address is not compatible with ERC721 tokens.

  • Potential Exploitation: Malicious actors could exploit this by intentionally providing addresses of contracts that do not support ERC721 tokens to lock up NFTs.

Proof of Concept:
The following scenario illustrates the issue:

  1. A user donates, and the donate() function is called with _mint().

  2. The NFT is minted to a contract address that does not implement IERC721Receiver.

  3. The NFT is permanently locked in the recipient contract and cannot be transferred or recovered.

Tools Used

  • Manual Code Review

Recommendations:
Replace all instances of _mint() with _safeMint() in GivingThanks.sol to ensure that the recipient address can handle ERC721 tokens properly.

function donate(address charity) public payable {
require(registry.isVerified(charity), "Charity not verified");
(bool sent, ) = charity.call{value: msg.value}("");
require(sent, "Failed to send Ether");
_safeMint(msg.sender, tokenCounter); // Using _safeMint instead of _mint
// Create metadata for the tokenURI
string memory uri = _createTokenURI(
msg.sender,
block.timestamp,
msg.value
);
_setTokenURI(tokenCounter, uri);
tokenCounter += 1;
}
Updates

Lead Judging Commences

n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Appeal created

koinerdegen Submitter
9 months ago
n0kto Lead Judge
9 months ago
n0kto Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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