Snowman Merkle Airdrop

First Flight #42
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Impact: low
Likelihood: low
Invalid

Redundant and Ineffective Token Existence Check in tokenURI() Function

Root + Impact

Description

  • The tokenURI() function normally returns the metadata URI for a given token ID, assuming the token exists. The standard OpenZeppelin ERC721 contract’s ownerOf(tokenId) reverts automatically when called with a non-existent token ID.

  • The problem is that the code redundantly checks if ownerOf(tokenId) == address(0) to detect non-existent tokens. However, ownerOf() already reverts for invalid tokens, so this check is unreachable and unnecessary, adding complexity without benefit.

function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
@> if (ownerOf(tokenId) == address(0)) {
@> revert ERC721Metadata__URI_QueryFor_NonExistentToken();
@> }
string memory imageURI = s_SnowmanSvgUri;
...
}

Risk

Likelihood:

  • This redundant check will never evaluate to true because ownerOf(tokenId) reverts first on non-existent tokens.

  • The function may be slightly less clear or efficient due to unreachable code.

Impact:

  • Minor gas cost increase due to unnecessary conditional check.

  • Possible confusion for developers reading the code, potentially leading to misunderstandings of how ownerOf behaves.

Proof of Concept

Calling tokenURI with a non-existent tokenId will revert from ownerOf call, never reaching the custom revert in the code.

snowmanContract.tokenURI(9999999); // reverts with "ERC721: owner query for nonexistent token"

Recommended Mitigation

Replace the unnecessary ownerOf(tokenId) == address(0) check with an explicit call to the _exists(tokenId) function. This function returns true if the token has been minted and exists, otherwise false. This makes the intent clearer and prevents relying on ownerOf’s internal revert behavior. It also allows you to control the revert error message precisely.

- if (ownerOf(tokenId) == address(0)) {
- revert ERC721Metadata__URI_QueryFor_NonExistentToken();
- }
+ if (!_exists(tokenId)) {
+ revert ERC721Metadata__URI_QueryFor_NonExistentToken();
+ }
Updates

Lead Judging Commences

yeahchibyke Lead Judge 3 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.