The EIP-721 Metadata extension says tokenURI "Throws if _tokenId is not a valid NFT". The OpenZeppelin 5.0.0 base implementation starts with _requireOwned(tokenId). SantasList advertises IERC721Metadata through supportsInterface(0x5b5e139f).
SantasList overrides tokenURI as pure, comments out tokenId and returns the constant TOKEN_URI. A pure function cannot read ownership state, so the existence check is gone. tokenURI returns full metadata for ids that were never minted, while ownerOf correctly reverts for the same ids.
Likelihood:
It occurs whenever a wallet, marketplace or indexer calls tokenURI for an id that has not been minted yet or for a guessed id.
Harm requires an off-chain consumer that treats a tokenURI revert as its signal that a token does not exist. Most consumers rely on ownerOf or Transfer events instead, and those still behave correctly, so likelihood is Low.
Impact:
The contract breaks the ERC-721 Metadata standard it advertises. In the PoC, three calls each return the same 51,373-byte metadata as a real token: tokenURI(0) before any mint, tokenURI(1_000_000), and tokenURI(type(uint256).max).
Off-chain consumers that rely on the revert can show nonexistent ids as genuine Santa NFTs. No on-chain funds or state are affected.
test_baseline_StockOZTokenURIRevertsForNonexistentId: an unmodified OpenZeppelin 5.0.0 ERC721, defined inside the PoC, reverts tokenURI(1_000_000) with ERC721NonexistentToken. This is the behaviour the override removes.
test_SantasListTokenURIReturnsMetadataForNonexistentIds: SantasList reports IERC721Metadata support. Before any mint, ownerOf(0) reverts but tokenURI(0) returns TOKEN_URI. After one real mint, ownerOf(1_000_000) reverts, but tokenURI(1_000_000) and tokenURI(type(uint256).max) return the same metadata as token 0.
File test/PoC_SL-09.t.sol:
Run from the repository root:
Result:
Restore the existence check. The function must become view so that it can read ownership.
The contest is live. Earn rewards by submitting a finding.
Submissions are being reviewed by our AI judge. Results will be available in a few minutes.
View all submissionsThe contest is complete and the rewards are being distributed.