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

first soulmates looking for another soulmate are not minted their NFT, preventing them from claiming their airdrop

Summary

A soulmate entering the queue first to look for another soulmate is not minted their NFT, unlike their soulmate which joins in second. Assuming the airdrop was correctly implemented, it would check if the claimer has their NFT minted. This prevents the first soulmate to claim their airdrops.

Vulnerability Details

In the Soulmate::mintSoulmateToken function, the following code part mints the NFT token:

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++);
}

The _mint function is only called, if a second soulmate joins the first soulmate waiting in the queue for their soulmate. which then mints the NFT to the second soulmate. Nevertheless, the first soulmate never receives their NFT token.

Add the following PoC to the BaseTest.t.sol to test for the issue:

function testOnlySecondSoulmateMintsNFT() external {
// become soulmates
vm.prank(soulmate1);
uint256 ownerId1 = soulmateContract.mintSoulmateToken();
vm.prank(soulmate2);
uint256 ownerId2 = soulmateContract.mintSoulmateToken();
console.log(ownerId1);
console.log(ownerId2);
assertEq(ownerId1, ownerId2);
// check NFTs
console.log("soulmate 1: ", soulmateContract.balanceOf(soulmate1));
console.log("soulmate 2: ", soulmateContract.balanceOf(soulmate2));
assertEq(soulmateContract.balanceOf(soulmate1), soulmateContract.balanceOf(soulmate2));
}

Impact

The Airdrop::claim function supposedly only sends rewards to those, who are in possession of a soulmate NFT token. Since soulmate1 did not get their NFT minted, they will never receive their airdrops.

Tools Used

Foundry

Recommendations

Upon successfully matching two soulmates, mint the NFT to both:

+ _mint(soulmate1, nextID++);
+ _mint(soulmate2, nextID++);
- _mint(msg.sender, nextID++);
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.