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

```Soulmate::getDivorced``` soulmates can continue to ```Airdrop::claim``` the ```LoveToken``` even if divorced

Summary

Soulmate::getDivorced soulmates can continue to Airdrop::claim claim the LoveToken even if divorced. This is possible because theSoulmate::isDivorced function returns the msg.sender status.

Vulnerability Details

Soulmate::getDivorced soulmates can continue to Airdrop::claim the LoveToken even if divorced. This is possible because theSoulmate::isDivorced function returns the msg.sender status and not the status of a specific address passed as input.

When a user calls the Airdrop::claim function, the function checks if the user is divorced (calling soulmateContract.isDivorced() and reverting if the status is true). The isDivorced()function, as is written, returns the status of the msg.sender . In this case, the msg.sender is the Airdrop smart contract address (status = false) and not the user. The returned status is always false, the function doesn't revert and the divorced user can continue to claim their LoveToken.

Soulmate.sol
function isDivorced() public view returns (bool) {
@> return divorced[msg.sender];
}
Airdrop.sol
function claim() public {
@> if (soulmateContract.isDivorced()) revert Airdrop__CoupleIsDivorced();
....

Impact

//solmate1 and solmate2 can claim the LoveToken even if divorced
function testCanClaimEvenIfDivorced() public isACouple {
//The soulmate1 get divorced from soulmate2
vm.startPrank(soulmate1);
assertEq(loveToken.balanceOf(soulmate1), 0);
soulmateContract.getDivorced();
assertTrue(soulmateContract.isDivorced());
vm.stopPrank();
//The soulmate2 is divorced
vm.startPrank(soulmate2);
assertEq(loveToken.balanceOf(soulmate2), 0);
assertTrue(soulmateContract.isDivorced());
vm.stopPrank();
//The soulmate1 can claim the LoveToken even if divorced
vm.warp(block.timestamp + 200 days + 1 seconds);
vm.startPrank(soulmate1);
airdropContract.claim();
assertTrue(loveToken.balanceOf(soulmate1) == 200 ether);
vm.stopPrank();
//The soulmate2 can claim the LoveToken even if divorced
vm.startPrank(soulmate2);
airdropContract.claim();
assertTrue(loveToken.balanceOf(soulmate2) == 200 ether);
vm.stopPrank();
}
Running 1 test for test/unit/SoulmateTest.t.sol:SoulmateTest
[PASS] testCanClaimEvenIfDivorced() (gas: 395363)
Test result: ok. 1 passed; 0 failed; 0 skipped; finished in 7.81ms

Tools Used

Manual review.

Recommendations

Pass the user address as an in input in the function.

ISolamate.sol
- function isDivorced() external view returns (bool);
+ function isDivorced(address user) external view returns (bool);
Soulmate.sol
- function isDivorced() public view returns (bool) {
+ function isDivorced(address user) public view returns (bool) {
- return divorced[msg.sender];
+ return divorced[user];
}
Airdrop.sol
function claim() public {
- if (soulmateContract.isDivorced()) revert Airdrop__CoupleIsDivorced();
+ if (soulmateContract.isDivorced(msg.sender)) revert Airdrop__CoupleIsDivorced();
....

Now if you run the test again, it correctly fails. The uses is divorced and can't claim the LoveToken.

function testCanClaimEvenIfDivorced() public isACouple {
//The soulmate1 get divorced from soulmate2
vm.startPrank(soulmate1);
assertEq(loveToken.balanceOf(soulmate1), 0);
soulmateContract.getDivorced();
assertTrue(soulmateContract.isDivorced(soulmate1));
vm.stopPrank();
//The soulmate2 is divorced
vm.startPrank(soulmate2);
assertEq(loveToken.balanceOf(soulmate2), 0);
assertTrue(soulmateContract.isDivorced(soulmate2));
vm.stopPrank();
//The soulmate1 can claim the LoveToken even if divorced
vm.warp(block.timestamp + 200 days + 1 seconds);
vm.startPrank(soulmate1);
airdropContract.claim();
assertTrue(loveToken.balanceOf(soulmate1) == 200 ether);
vm.stopPrank();
//The soulmate2 can claim the LoveToken even if divorced
vm.startPrank(soulmate2);
airdropContract.claim();
assertTrue(loveToken.balanceOf(soulmate2) == 200 ether);
vm.stopPrank();
}
Failing tests:
Encountered 1 failing test in test/unit/SoulmateTest.t.sol:SoulmateTest
[FAIL. Reason: Airdrop__CoupleIsDivorced()] testCanClaimEvenIfDivorced() (gas: 277782)
Updates

Lead Judging Commences

0xnevi Lead Judge over 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

finding-isDivorced-wrong-check

Support

FAQs

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