DatingDapp

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

Low: Unbounded User Metadata Can Cause Excessive Permanent Storage Growth

Low: Unbounded User Metadata Can Cause Excessive Permanent Storage Growth

Description

  • The protocol allows arbitrary-length name and profileImage strings during profile creation.

  • No upper bounds are enforced on user-controlled metadata fields.

  • Malicious users can submit extremely large strings, causing unnecessary permanent storage growth and increased gas costs.

  • Although the attacker pays deployment gas, the bloated storage remains permanently on-chain.

// Root cause in the codebase with @> marks to highlight the relevant section
struct Profile {
string name;
uint8 age;
// @> No length restrictions enforced
string profileImage;
}
function mintProfile(
string memory name,
uint8 age,
string memory profileImage
) external {
// @> User-controlled strings stored without validation
_profiles[tokenId] = Profile(name, age, profileImage);
}

Risk

Likelihood:

  • Any user can provide arbitrarily large string inputs.

  • Permanent on-chain storage is written for every profile mint.

Impact:

  • Excessive and unnecessary state growth increases long-term protocol costs.

  • Large metadata values may negatively affect indexers and frontends.

  • User transactions become unnecessarily gas-expensive.

Proof of Concept

The following test demonstrates that extremely large metadata strings can be stored successfully.

function testLargeMetadataStorage() public {
string memory hugeString =
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
vm.prank(user);
soulboundNFT.mintProfile(
hugeString,
25,
hugeString
);
uint256 tokenId = soulboundNFT.profileToToken(user);
assertEq(tokenId, 1);
}

Recommended Mitigation

Restrict metadata lengths during minting.

function mintProfile(
string memory name,
uint8 age,
string memory profileImage
) external {
+ require(bytes(name).length <= 64, "Name too long");
+ require(bytes(profileImage).length <= 256, "Image URI too long");
_profiles[tokenId] = Profile(name, age, profileImage);
}
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge 1 day 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!