The mintProfile function mints a soulbound NFT for the caller, ensuring that each address can only have one profile. However, this function does not follow the checks-effects-interactions pattern, making it vulnerable to reentrancy if the _safeMint() function calls an external contract (such as a malicious ERC721 receiver).
If an attacker deploys a malicious contract implementing onERC721Received, they can reenter mintProfile before profileToToken[msg.sender] is updated, allowing them to mint multiple NFTs for the same address. While only the last minted profile remains usable, this still violates the intended logic of the contract, which is to strictly enforce one profile per user, undermining the integrity of the system.
Bypassing the one-profile-per-user rule, an attacker can mint multiple soulbound NFTs, breaking the intended logic.
Slither
Manual
First we create a contract to attack:
If we put this code in the testSoulboundProfileNTF.t.sol
Follow the Checks-Effects-Interactions Pattern:
Move _profiles[tokenId] and profileToToken[msg.sender] updates before _safeMint() to prevent reentrancy.
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.