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.