The SoulboundProfileNFT::mintProfile
function is vulnerable to a reentrancy attack, which could allow a malicious actor to create multiple profiles by reentering the function before profileToToken[msg.sender] is updated.
The contract doesn't follow CEI(checks, effects, interactions). The function checks whether profileToToken[msg.sender] == 0 before proceeding. _safeMint(msg.sender, tokenId); is called before updating profileToToken[msg.sender].
If the _safeMint function triggers an external call, an attacker could reenter the mintProfile function before profileToToken[msg.sender] is updated.
Since profileToToken[msg.sender] remains 0 during reentrancy, the attacker can call mintProfile multiple times, creating multiple profiles.
Here is what a malicious actor would do:
After we run this code, this is the output:
Which means malicious actor has succesfully created more than 1 profile
An attacker could bypass the one-profile-per-address restriction.
This could lead to an attacker unfairly obtaining multiple identities in a system designed to restrict each user to a single profile.
The exploit could be used for Sybil attacks, spam, or other manipulations in applications relying on unique profiles.
Manual review
Foundry
Use the Checks-Effects-Interactions Pattern: Move profileToToken[msg.sender] = tokenId; before _safeMint to prevent reentrancy.
Use Reentrancy Guards: Add nonReentrant from OpenZeppelin's ReentrancyGuard to prevent multiple executions.
Likelihood: High, anyone can do it. Impact: Low, several profile will be minted, which is not allowed by the protocol, but only the last one will be stored in profileToToken and won't affect `likeUser` or `matchRewards`.
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.