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

A user can call `Soulmate::getDivorced()` without having a soulmate

Summary

Any user that hasn't minted via Soulmate::mintSoulmateToken() or a user that is still awaiting a soulmate can call Soulmate::getDivorced() to set their divorce status to true.

Vulnerability Details

The Soulmate::getDivorced() function is meant to divorce msg.sender and their soulmate. However, if a user hasn't minted a soulmate, or they are awaiting a future soulmate soulmateOf[msg.sender] will return address(0) and assign that to the soulmate2 local variable.

function getDivorced() public {
@> address soulmate2 = soulmateOf[msg.sender];
divorced[msg.sender] = true;
divorced[soulmateOf[msg.sender]] = true;
emit CoupleHasDivorced(msg.sender, soulmate2);
}

This then results in divorce[msg.sender] to be set to true, and divorce[0x0000000000000000000000000000000000000000] to also be set to true.

When a user then mints a soulmate, this will result in soulmate1 to be divorced, and soulmate2 to not be divorced.

Impact

A user who divorces themselves without a soulmate will result in:

  • Incorrect divorce state for both soulmate1 (true) and soulmate2 (false).

  • soulmate1 not be eligible to claim lovetokens via Airdrop::claim() while soulmate2 will be able to.

  • Incorrect event emitted as the couple will be msg.sender and 0x0000000000000000000000000000000000000000.

POC

You can add the following POC test in foundry to test the incorrect state:

function test_UnauthorizedGetDivorced() public {
vm.prank(soulmate1);
soulmateContract.getDivorced();
_mintOneTokenForBothSoulmates();
vm.prank(soulmate1);
assertTrue(soulmateContract.isDivorced() == true);
vm.prank(soulmate2);
assertTrue(soulmateContract.isDivorced() == false);
}

Tools Used

VS Code, Foundry

Recommendations

Add a new error and check the soulmateOf mapping to ensure msg.sender has a soulmate before updating the divorced mapping:

+ error Soulmate__NoSoulmate();
function getDivorced() public {
+ if (soulmateOf(msg.sender) == address(0))
+ revert Soulmate__NoSoulmate();
address soulmate2 = soulmateOf[msg.sender];
divorced[msg.sender] = true;
divorced[soulmateOf[msg.sender]] = true;
emit CoupleHasDivorced(msg.sender, soulmate2);
}
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

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