The mintProfile function calls _safeMint(msg.sender, tokenId); before updating the contract's state. Since _safeMint is an ERC721 function, it invokes the onERC721Received function if msg.sender is a smart contract. A malicious contract could exploit this by reentering mintProfile and minting multiple profiles before the first transaction completes.
Deploy the smart contract.
A malicious contract calls mintProfile(), which triggers _safeMint().
_safeMint() checks if the recipient is a smart contract and calls onERC721Received.
The attacker's contract executes a reentrant call to mintProfile().
Since profileToToken[msg.sender] has not been updated yet, the attacker bypasses the duplicate profile check and mints multiple profiles.
_safeMint() is called before updating state, allowing a reentrant call to mint multiple profiles.
manual review
Reorder state updates before _safeMint()
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.