In the mintProfile function, the profileToToken mapping defaults to 0 for unregistered users. If _nextTokenId starts at 0, the first minted profile will have a token ID of 0. This causes a conflict where the check profileToToken[msg.sender] == 0 incorrectly assumes that the user has not minted a profile, even if they have.
Steps to Reproduce:
Deploy the smart contract with _nextTokenId uninitialized (defaults to 0).
A user calls mintProfile() for the first time.
The contract assigns token ID 0 to the user and updates profileToToken[msg.sender] = 0.
If the user tries to mint another profile, the require(profileToToken[msg.sender] == 0, "Profile already exists"); check does not prevent them from doing so because profileToToken[msg.sender] == 0 is still true.
The user is able to mint multiple profiles because the check against profileToToken[msg.sender] == 0 is unreliable when 0 is a valid token ID.
manual review
Initialize _nextTokenId to 1 instead of 0, ensuring that no valid token ID is ever 0
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.