Beginner FriendlyFoundryNFT
100 EXP
View results
Submission Details
Severity: high
Invalid

Two addresses can't own the same NFT - there can only be one address that owns a given tokenID

Summary

The mintSoulmateToken() function anticipates that the paired users will share one tokenID for their NFT. But the ERC721.sol standard that Soulmate.sol inherits from allows only one owner per tokenID. Each user should get an NFT but it can't be with the same tokenID (it is called nextID in the function, but it is the tokenID for ERC721 purposes).

Vulnerability Details

function mintSoulmateToken() public returns (uint256) {
// Check if people already have a soulmate, which means already have a token
address soulmate = soulmateOf[msg.sender];
if (soulmate != address(0))
revert Soulmate__alreadyHaveASoulmate(soulmate);
address soulmate1 = idToOwners[nextID][0];
address soulmate2 = idToOwners[nextID][1];
if (soulmate1 == address(0)) {
idToOwners[nextID][0] = msg.sender;
ownerToId[msg.sender] = nextID;
emit SoulmateIsWaiting(msg.sender);
} else if (soulmate2 == address(0)) {
idToOwners[nextID][1] = msg.sender;
// Once 2 soulmates are reunited, the token is minted
ownerToId[msg.sender] = nextID;
soulmateOf[msg.sender] = soulmate1;
soulmateOf[soulmate1] = msg.sender;
idToCreationTimestamp[nextID] = block.timestamp;
emit SoulmateAreReunited(soulmate1, soulmate2, nextID);
_mint(msg.sender, nextID++);
}

Impact

If the function was otherwise set up properly, it would revert every time soulmate2 called it (because it would have already minted an NFT at nextID and wouldn't mint a second one). The reason this doesn't happen is because the function fails to mint an NFT at nextID to soulmate1 (but it should in fact do this) and also because the call to _mint() for soulmate2 incorrectly iterates to nextID++ (even though the state variables like idToOwners[nextID][1] would say that soulmate2 owns the NFT of nextID, not nextID++).

Tools Used

Manual review

Recommendations

Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Other

Support

FAQs

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