The tokenURI function constructs NFT metadata JSON on-chain. This JSON includes an image field, whose value is sourced from s_weatherToTokenURI. This mapping is populated in the constructor using weatherURIs provided by the contract deployer (owner). There are no checks on the length of these URIs.
If the contract owner, during deployment, provides excessively long strings for weatherURIs, the image string in the generated JSON can become extremely large. The subsequent Base64.encode(jsonData) operation scales in gas cost with the size of jsonData. Returning the final, very long metadata string also incurs gas costs proportional to its length.
This means that if an image URI is excessively long, any attempt to call tokenURI for an NFT currently displaying that image could consume a large amount of gas. This might lead to transactions running out of gas or becoming prohibitively expensive, effectively making the NFT's metadata inaccessible on-chain for wallets, marketplaces, or other dApps.
Likelihood: Low
This vulnerability depends on the contract owner deploying with extremely long image URIs. Typically, owners want metadata to be accessible. It might occur due to error, misunderstanding gas implications, or in a test/malicious scenario by the owner (though self-sabotaging).
Impact: Low
Metadata Inaccessibility: Calls to tokenURI for affected NFTs might fail due to out-of-gas errors or become too expensive for practical use by dApps like marketplaces or wallets.
Reduced NFT Interoperability: If metadata cannot be reliably retrieved, the NFTs might not display or function correctly on third-party platforms.
The contract owner deploys WeatherNft. During deployment, for one of the weather states (e.g., Weather.SUNNY), they provide an extremely long string as its URI in the weatherURIs array (e.g., 50,000 characters, perhaps a data URI with embedded content).
A user mints an NFT, and its current weather state is Weather.SUNNY.
A marketplace attempts to display this NFT by calling tokenURI(tokenId).
Inside tokenURI:
image becomes the 50,000-character string.
jsonData becomes a string of slightly more than 50,000 bytes.
Base64.encode(jsonData) operates on this large byte array. This operation's gas cost is proportional to the input size. For very large inputs, this can be substantial.
Returning the resulting base64 string (approx. 66,500 characters) also consumes considerable gas.
The tokenURI call might hit the block gas limit or the gas limit provided by the caller, causing the transaction to revert and the metadata to be unretrievable.
The primary mitigation is for the contract deployer to be aware of these gas implications and use reasonably sized URIs.
Documentation: Clearly document for the deployer the potential gas issues with very long image URIs and recommend keeping them concise (e.g., pointing to off-chain resources like IPFS/Arweave if the image data itself is large, rather than embedding large data URIs directly).
Deployment Scripts: If providing deployment scripts, add comments or console warnings about URI length.
A strict on-chain code change to limit URI length in the constructor is possible but might be overly restrictive for legitimate use cases of moderately long URIs. This is often a policy decision for the project.
If an on-chain length restriction is desired as a hard safeguard:
This mitigation focuses on preventing the storage of overly long URIs at deployment time. The choice of MAX_IMAGE_URI_LENGTH would be crucial and depends on expected URI types (URLs vs. small data URIs).
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.