The mintProfile function in the SoulboundProfileNFT contract is vulnerable to a reentrancy attack due to the use of _safeMint before updating the contract's state. Specifically, the profileToToken mapping. This allows an attacker to mint multiple NFTs in a single transaction by exploiting the onERC721Received callback.
The function calls _safeMint before updating the profileToToken mapping. _safeMint internally calls onERC721Received on the recipient contract (if the recipient is a contract), allowing an attacker to reenter mintProfile.
An attacker can deploy a malicious contract that implements onERC721Received to reenter mintProfile before profileToToken[msg.sender] is updated. This allows bypassing the require(profileToToken[msg.sender] == 0) check and minting multiple NFTs.
This allows a user to create multiple fake profiles on the protocol, enabling catfishing and potentially making other users pay 1 ETH to like a fake profile.
Manual Review
Foundry
We create a MaliciousMinter contract that exploits the vulnerability to mint multiple NFTs. This proof-of-concept mints one extra token, but the logic can be modified to mint an unlimited number.
Deploy MaliciousMinter with the NFT contract address, then add the following test:
This test passes, confirming that an attacker can mint more than one NFT.
Modify mintProfile to update state variables before calling _safeMint:
Add OpenZeppelin's ReentrancyGuard to prevent reentrancy attacks:
More details: OpenZeppelin ReentrancyGuard
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.