Snowman Merkle Airdrop

AI First Flight #10
Beginner FriendlyFoundrySolidityNFT
EXP
View results
Submission Details
Impact: medium
Likelihood: low
Invalid

Centralization Risk: Missing SVG URI Update Function in Snowman Contract

Description

Normal Behavior

The Snowman contract should allow the owner to update metadata if needed, providing flexibility for maintenance and recovery from hosting failures.

Issue Description

The contract inherits from Ownable but lacks a function to update the s_SnowmanSvgUri after deployment, creating a false sense of centralization while preventing necessary maintenance.

Root + Impact

Description

The contract implements ownership control but lacks practical tools to manage the SVG URI, leaving owners unable to fix metadata issues despite having administrative privileges.

Root Cause

// @> Contract inherits Ownable but lacks URI update functionality
contract Snowman is ERC721, Ownable {
string private s_SnowmanSvgUri; // @> Set once in constructor, never updatable
constructor(string memory _SnowmanSvgUri) ERC721("Snowman Airdrop", "SNOWMAN") Ownable(msg.sender) {
s_TokenCounter = 0;
s_SnowmanSvgUri = _SnowmanSvgUri; // @> One-time setup only
}
// @> Missing: updateSnowmanSvgUri() function
}

The SVG URI is used in metadata generation but cannot be updated 2 .

Risk

Likelihood:

  • Reason 1: URI hosting failures are rare but possible with IPFS or external services

  • Reason 2: The issue only manifests if the initial URI becomes invalid or needs updates

Impact:

  • Impact 1: If IPFS/hosting fails, NFTs display broken images with no recovery mechanism

  • Impact 2: Owners cannot fix metadata issues despite having Ownable privileges, creating a false sense of control

Proof of Concept

function testMissingUpdateFunction() public {
// Deploy contract with initial URI
string memory initialUri = "data:image/svg+xml;base64,invalid_data";
Snowman nft = new Snowman(initialUri);
// Owner tries to update broken URI - function doesn't exist
vm.prank(nft.owner());
// nft.updateSnowmanSvgUri("new_valid_uri"); // This function doesn't exist
// All NFTs permanently show broken metadata
nft.mintSnowman(alice, 1);
string memory uri = nft.tokenURI(0);
// URI contains invalid data with no way to fix
assertTrue(bytes(uri).length > 0);
}

Recommended Mitigation

contract Snowman is ERC721, Ownable {
string private s_SnowmanSvgUri;
constructor(string memory _SnowmanSvgUri) ERC721("Snowman Airdrop", "SNOWMAN") Ownable(msg.sender) {
s_TokenCounter = 0;
s_SnowmanSvgUri = _SnowmanSvgUri;
}
+ function updateSnowmanSvgUri(string memory newUri) external onlyOwner {
+ s_SnowmanSvgUri = newUri;
+ }
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 3 hours ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!