Summary
The getDivorced function in the Soulmate contract correctly updates the divorced status for both parties involved in a soulmate pair. However, it fails to clear the soulmateOf
mappings, leading to an inconsistent state.
Vulnerability Details
Upon invoking getDivorced, the contract marks both soulmates as divorced in the divorced mapping but neglects to remove the associations in the soulmateOf mapping. This oversight allows for potential misuse of the contract's functions that rely on this mapping to determine current soulmate relationships.
function getDivorced() public {
address soulmate2 = soulmateOf[msg.sender];
divorced[msg.sender] = true;
divorced[soulmateOf[msg.sender]] = true;
emit CoupleHasDivorced(msg.sender, soulmate2);
}
function testDivorceLogic() public {
address alice = address(0x1);
address bob = address(0x2);
vm.startPrank(alice);
soulmateContract.mintSoulmateToken();
vm.stopPrank();
vm.startPrank(bob);
soulmateContract.mintSoulmateToken();
vm.stopPrank();
assertEq(soulmateContract.soulmateOf(alice), bob, "Alice should be paired with Bob.");
assertEq(soulmateContract.soulmateOf(bob), alice, "Bob should be paired with Alice.");
console.log("Before divorce:");
console.log("Alice's soulmate:", soulmateContract.soulmateOf(alice));
console.log("Bob's soulmate:", soulmateContract.soulmateOf(bob));
vm.startPrank(alice);
soulmateContract.getDivorced();
bool isDivorced = soulmateContract.isDivorced();
console.log("Soulmate1 divorce status:", isDivorced);
vm.stopPrank();
console.log("After divorce:");
console.log("Alice's soulmate:", soulmateContract.soulmateOf(alice));
console.log("Bob's soulmate:", soulmateContract.soulmateOf(bob));
assertEq(soulmateContract.soulmateOf(alice), address(0), "Alice's soulmate mapping should be cleared.");
assertEq(soulmateContract.soulmateOf(bob), address(0), "Bob's soulmate mapping should be cleared.");
}
Impact
The inconsistency in the contract's state post-divorce can have several adverse effects:
Divorced users may be able to participate in activities intended only for active soulmate pairs.
The contract may incorrectly recognize divorced users as still being in a soulmate relationship, affecting the integrity of the minting process for new tokens.
Tools Used
Manual Review
Recommendations
Modify the getDivorced function to include deletion of the associated entries in the soulmateOf mapping for both soulmates.
function getDivorced() public {
address soulmate2 = soulmateOf[msg.sender];
divorced[msg.sender] = true;
divorced[soulmate2] = true;
delete soulmateOf[msg.sender];
delete soulmateOf[soulmate2];
emit CoupleHasDivorced(msg.sender, soulmate2);
}