Missing token existence validation in tokenURI leads to EIP-721 standard violation and marketplace integration issues
tokenURI does not validate that the queried tokenId exists, returning default metadata instead of reverting as required by the EIP-721 standard, which can cause marketplace and wallet integration issues.
Description
The tokenURI function in both KnowledgeMarket.sol and KnowledgeMarketV2.sol does not validate that the requested tokenId exists before returning metadata, violating the EIP-721 standard. The function directly accesses storage mappings without checking token existence, causing it to return metadata with default/empty values for non-existent tokens instead of reverting as required by the standard.
function tokenURI(uint256 id) public view override returns (string memory) {Metadata memory data = nftData[id]; // No existence checkDeal memory deal = dealInfo[id];Settings memory set = accessControl[data.hash];// ... returns metadata for non-existent tokens}
EIP-721 Standard Requirement: The EIP-721 specification explicitly states that tokenURI should "Throws if _tokenId is not a valid NFT."
Vulnerable Scenario:
The following steps help reproduce the issue:
- An external application or user calls
tokenURI(999999)for a token ID that was never minted. - The function accesses
nftData[999999]which returns a default empty struct instead of reverting. - The function constructs and returns JSON metadata using these default values.
- The caller receives seemingly valid metadata for a non-existent token, creating a "ghost token" effect.
- NFT marketplaces and integrations may display this non-existent token as if it were real.
Impact
Direct violation of the EIP-721 standard leading to integration issues with NFT marketplaces and wallets. Applications may display non-existent tokens with default metadata, causing confusion for users and potentially breaking marketplace functionality that relies on standard-compliant behavior.
Recommendation
Add token existence validation at the beginning of the tokenURI function in both contracts:
require(_ownerOf(_tokenId) != address(0), "ERC721: invalid token ID");
Or use the OpenZeppelin _requireOwned(id) helper if available.
Resolution
Ipal Network: Confirmed. We agreed with the recommendation and have implemented a token existence check at the beginning of the tokenURI function.
Zealynx: Fixed. Added token existence validation with _requireOwned(id) at the beginning of the tokenURI function, ensuring EIP-721 compliance and proper error handling for non-existent tokens.

