The contract accepts a single collectionImage string in the constructor, stores it, and returns it from _baseURI(). In the current implementation, there is no override of tokenURI(), so the inherited OpenZeppelin ERC721 metadata logic is used for every token.
OpenZeppelin’s ERC721 implementation computes tokenURI(tokenId) as string.concat(_baseURI(), tokenId.toString()) whenever the base URI is non-empty. Since this contract’s _baseURI() returns the single image URL stored in collectionImage, every minted token ends up with a URI like collectionImage + "1", collectionImage + "2", etc., instead of a valid per-token metadata URI or the original image URL itself.
As a result, if collectionImage is intended to be a direct image URL - as shown by the test suite’s BASE_IMAGE value using a fixed Unsplash image URL - then tokenURI(1) becomes something like https://images.unsplash.com/photo-...1, which is not the original configured asset and is not a proper ERC721 metadata JSON endpoint either. This makes token metadata resolution incorrect for every NFT.
Additionally, the contract declares bool public metadataFrozen;, but there is no logic that sets it, checks it, or uses it to control metadata mutability. So the contract both fails to implement correct token metadata and includes a dead metadata-freezing variable that does nothing.
Likelihood: Low
This occurs for every minted token, because every tokenURI(tokenId) call uses the inherited ERC721 concatenation logic and _baseURI() always returns the same collectionImage string. [contracts | Txt], [github.com]
This occurs during normal metadata reads by wallets, marketplaces, and indexers, because ERC721 consumers resolve token metadata through tokenURI(tokenId), not through the custom baseURI() helper alone.
Impact: Low
All NFTs expose an incorrect token URI, so wallets and marketplaces may fail to load the intended metadata/image or may request a malformed/unintended URL.
The declared metadataFrozen variable gives a false impression of metadata immutability controls, even though there is no implemented freezing mechanism.
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.
The contest is complete and the rewards are being distributed.