DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: low
Invalid

Missing Input Validation in Profile Creation in SoulboundProfileNFT contract

Description

The SoulboundProfileNFT contract lacks input validation in the mintProfile function, allowing users to create profiles with empty or invalid data. For a dating app, this is particularly problematic because:

  • Users can create profiles with empty names

  • Age can be set to 0 or unrealistic values

  • Profile images can be empty strings

  • No validation of string lengths or content

  • Users below the age of 18 can register.

Impact:

  • Reduces platform credibility with empty/invalid profiles

  • Makes user discovery and matching ineffective

  • Poor user experience when viewing empty profiles

Lines of code

(https://github.com/CodeHawks-Contests/2025-02-datingdapp/blob/878bd34ef6607afe01f280cd5aedf3184fc4ca7b/src/SoulboundProfileNFT.sol#L30)

Proof of Concept

function testEmptyProfileCreation() public {
vm.startPrank(user3);
// Can create profile with empty data
soulboundNFT.mintProfile("", 0, "");
vm.stopPrank();
uint256 tokenId = soulboundNFT.profileToToken(address(user3));
// TokenURI returns invalid/empty profile data
string memory uri = soulboundNFT.tokenURI(tokenId);
console.log(uri, "uri");
//using https://www.base64decode.org/ to decode the URI:
//URI contains: {"name":"", "description":"A soulbound dating profile NFT.", "attributes": [{"trait_type": "Age", "value": 0}], "image":""}
// Can also create profile with unrealistic age
vm.prank(user2);
soulboundNFT.mintProfile("Alice", 255, ""); // Age of 255 accepted
vm.prank(user);
soulboundNFT.mintProfile("", 0, ""); //empty data
vm.stopPrank();
}

Recommended Mitigation Steps

contract SoulboundProfileNFT is ERC721, Ownable {
//other codes
error EmptyNameNotAllowed();
error InvalidAgeRange();
error EmptyProfileImageNotAllowed();
error InvalidNameLength();
uint8 public constant MIN_AGE = 18;
uint8 public constant MAX_AGE = 100;
uint256 public constant MAX_NAME_LENGTH = 50;
function mintProfile(string memory name, uint8 age, string memory profileImage) external {
// Check for empty name
if (bytes(name).length == 0) revert EmptyNameNotAllowed();
// Check name length
if (bytes(name).length > MAX_NAME_LENGTH) revert InvalidNameLength();
// Validate age range
if (age < MIN_AGE || age > MAX_AGE) revert InvalidAgeRange();
// Check for empty profile image
if (bytes(profileImage).length == 0) revert EmptyProfileImageNotAllowed();
// Existing checks
require(profileToToken[msg.sender] == 0, "Profile already exists");
uint256 tokenId = ++_nextTokenId;
_safeMint(msg.sender, tokenId);
_profiles[tokenId] = Profile(name, age, profileImage);
profileToToken[msg.sender] = tokenId;
emit ProfileMinted(msg.sender, tokenId, name, age, profileImage);
}
}

These validations ensure profile quality and improve the dating app experience by:

  • Improving matchmaking quality

  • Ensuring all profiles are meaningful and complete

Tools Used

Manual Review + Foundry Testing Framework

Updates

Appeal created

n0kto Lead Judge 6 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity
Assigned finding tags:

invalid_URI_injection_scam_underaged_bad_name_photo_etc

Scamming/phishing is not the protocol problem, that's a user mistake. NFT are unique, even if someone does a copy of your profile (which is also possible in web2), I consider it informational. Injection is a problem for the web2 part of the protocol, not a bug here. For the age, it depends on the countries law and future medicine. Anyways, that's more an ethical/political problem, not a bug.

Users mistake, only impacting themselves.

Please read the CodeHawks documentation to know which submissions are valid. If you disagree, provide a coded PoC and explain the real likelihood and the detailed impact on the mainnet without any supposition (if, it could, etc) to prove your point.

Support

FAQs

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