DatingDapp

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

[L-02] No input validation on profile data allows age=0, empty names, and unbounded strings

Description

mintProfile() accepts arbitrary values for name, age, and profileImage with no validation. Users can mint profiles with age 0, empty strings, or megabytes of on-chain data.

Vulnerability Details

// src/SoulboundProfileNFT.sol, line 30-41
function mintProfile(string memory name, uint8 age, string memory profileImage) external {
require(profileToToken[msg.sender] == 0, "Profile already exists");
// @> no validation on name, age, or profileImage
uint256 tokenId = ++_nextTokenId;
_safeMint(msg.sender, tokenId);
_profiles[tokenId] = Profile(name, age, profileImage); // @> stored directly
profileToToken[msg.sender] = tokenId;
}

All three parameters are stored directly without any bounds checking. age = 0 creates a profile for a zero-year-old. Empty name and profileImage strings create a faceless, nameless profile. Arbitrarily long strings are stored on-chain, and tokenURI() encodes all stored data in Base64, so excessively long strings inflate gas costs for anyone reading the token metadata.

Risk

Likelihood:

  • Any user can submit invalid profile data. Bots or griefers can submit empty or absurdly long strings. There is no cost barrier beyond the gas fee.

Impact:

  • Profiles with age 0 or empty names degrade the dating platform's data quality. A profile with no name and no image is useless but costs the same to process. Very long strings stored on-chain waste permanent storage and inflate tokenURI() gas costs for all consumers.

PoC

The test mints a profile with empty name, age 0, and no image — all accepted. It also shows that very long strings (192+ characters) are stored successfully, wasting on-chain storage.

function testNoInputValidation() public {
// age = 0, empty name, empty image — all accepted
vm.prank(alice);
profileNFT.mintProfile("", 0, "");
assertEq(profileNFT.profileToToken(alice), 1); // minted successfully
// Very long string — also accepted, stored on-chain
string memory longName = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
vm.prank(bob);
profileNFT.mintProfile(longName, 255, "ipfs://something");
assertEq(profileNFT.profileToToken(bob), 2);
}

Recommendations

Add basic input validation to enforce reasonable bounds. Setting minimum age to 18 aligns with the dating app context, capping name length prevents storage abuse, and requiring a profile image ensures profiles are meaningful.

function mintProfile(string memory name, uint8 age, string memory profileImage) external {
require(profileToToken[msg.sender] == 0, "Profile already exists");
+ require(bytes(name).length > 0 && bytes(name).length <= 64, "Invalid name");
+ require(age >= 18 && age <= 120, "Invalid age");
+ require(bytes(profileImage).length > 0, "Image required");
Updates

Lead Judging Commences

ai-first-flight-judge Lead Judge about 16 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!