Description
For genereting or minting the NFT for the profile to register for profile in `SoulboundProfileNFT.sol` user pass data into `mintProfile` function, which mint their appropriate NFT. But diffrent user can also mint same NFT by passing same data into `mintProfile` function. As there is no checks for `ipfs` hash. Lead to mint same NFT to multiple user.
Impact
Multiple users can mint same NFT with diffrent NFT id which is not fair for users.
Proof of Concept
suppose there are two users for now.
1. mint their profile by same input.
2. same nft with diffrent id will be minted to them.
Add this into `testSoulboundProfileNFT.t.sol` file.
Proof Of Code:
```javascript
function testSameNftWithdiffrentIdCanMinteToDiffrentUser() public {
vm.prank(user); // Simulates user calling the function
soulboundNFT.mintProfile("Alice", 25, "ipfs://profileImage");
uint256 tokenId = soulboundNFT.profileToToken(user);
assertEq(tokenId, 1, "Token ID should be 1");
string memory uri = soulboundNFT.tokenURI(tokenId);
assertTrue(bytes(uri).length > 0, "Token URI should be set user1");
vm.prank(user2);
soulboundNFT.mintProfile("Alice", 25, "ipfs://profileImage");
uint256 tokenId2 = soulboundNFT.profileToToken(user2);
assertEq(tokenId2, 2, "Token Id should be 2");
string memory uri2 = soulboundNFT.tokenURI(tokenId2);
assertTrue(bytes(uri2).length > 0, "Token URI should be set for user2");
assertEq(bytes(uri), bytes(uri2));
}
```
Recommended Mitigation
As the `name` and `age` can be same for diffrent users, we have to make sure that they use diffrent `profileImage` to identified diffrent from each other.
We have to add checks for `ipfs` as all the `ipfs` has are diffrent for all the diffrent file.
Add the following checks in `minfProfile` function.
```diff
function mintProfile(string memory name, uint8 age, string memory profileImage) external {
require(profileToToken[msg.sender] == 0, "Profile already exists");
+ require(profileImageHash[profileImage] == false, "Use diffrent profile image as the image is used");
uint256 tokenId = ++_nextTokenId;
_safeMint(msg.sender, tokenId);
+ profileImageHash[profileImage] = true;
// Store metadata on-chain
_profiles[tokenId] = Profile(name, age, profileImage);
profileToToken[msg.sender] = tokenId;
emit ProfileMinted(msg.sender, tokenId, name, age, profileImage);
}
```
And also same required addons in `burn` and `block` functions.
Also add the `mapping` in the contract.
```diff
+ mapping(string => bool) public profileImageHash;
```