DatingDapp

First Flight #33
Beginner FriendlyFoundrySolidityNFT
100 EXP
View results
Submission Details
Severity: medium
Valid

Reentrancy Risk in mintProfile Due to External Call Before State Update

Description: The mintProfile function in the SoulboundProfileNFT contract calls _safeMint(msg.sender, tokenId) before updating critical state variables such as _profiles[tokenId] and profileToToken[msg.sender]. Since _safeMint invokes IERC721Receiver(to).onERC721Received, if msg.sender is a contract, it can execute arbitrary code before the function completes. This allows potential reentrant calls that could manipulate state inconsistencies or execute unintended logic.

Impact:

  1. If a malicious contract is used as msg.sender, it can re-enter the mintProfile function via onERC721Received.

  2. This could lead to double minting or inconsistent state, where profiles and profileToToken are not correctly updated.

  3. The vulnerability could potentially allow an attacker to mint multiple NFTs or bypass profile uniqueness constraints.

Proof of Concept:

/// @notice Mint a soulbound NFT representing the user's profile.
function mintProfile(string memory name, uint8 age, string memory profileImage) external {
require(profileToToken[msg.sender] == 0, "Profile already exists");
uint256 tokenId = ++_nextTokenId;
// Store metadata first (before external calls)
+ _profiles[tokenId] = Profile(name, age, profileImage);
+ profileToToken[msg.sender] = tokenId;
+ emit ProfileMinted(msg.sender, tokenId, name, age, profileImage);
// External call happens after state update
_safeMint(msg.sender, tokenId);
// Store metadata on-chain
- _profiles[tokenId] = Profile(name, age, profileImage);
- profileToToken[msg.sender] = tokenId;
- emit ProfileMinted(msg.sender, tokenId, name, age, profileImage);
}

Recommended Mitigation:

  1. Follow the Checks-Effects-Interactions - (CEI) pattern to ensure state updates occur before external calls.

  2. Move _safeMint after all state changes to prevent reentrancy risks.

  3. By consider using OpenZeppelin’s ReentrancyGuard to prevent reentrant calls ("")

Updates

Appeal created

n0kto Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_mintProfile_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`.

vkgoud Submitter
7 months ago
n0kto Lead Judge
7 months ago
n0kto Lead Judge 7 months ago
Submission Judgement Published
Validated
Assigned finding tags:

finding_mintProfile_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`.

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.