Summary
When a couple decides to divorce and Soulmate::getDivorced is called, it's not resetting the ownerToId mapping, which may cause future exploits, if any changes to the protocol are made related to it.
Vulnerability Details
Add the following in the SoulmateTest.t.sol file:
function testIdDoesNotReset() public {
_mintOneTokenForBothSoulmates();
address soulmate3 = makeAddr("soulmate3");
address soulmate4 = makeAddr("soulmate4");
vm.startPrank(soulmate3);
soulmateContract.mintSoulmateToken();
vm.stopPrank();
vm.startPrank(soulmate4);
soulmateContract.mintSoulmateToken();
vm.stopPrank();
vm.startPrank(soulmate3);
soulmateContract.getDivorced();
assert(soulmateContract.isDivorced());
vm.stopPrank();
vm.prank(soulmate4);
assert(soulmateContract.isDivorced());
assert(soulmateContract.ownerToId(soulmate1) == 0);
assert(soulmateContract.ownerToId(soulmate2) == 0);
assert(soulmateContract.ownerToId(soulmate3) == 1);
assert(soulmateContract.ownerToId(soulmate4) == 1);
}
Impact
Can lead to future vulnerabilities if changes are made to the code.
Tools Used
Manual Review, Foundry
Recommendations
Reset the ownerToId mapping for both owners, when getDivorced function is called:
function getDivorced() public {
address soulmate2 = soulmateOf[msg.sender];
divorced[msg.sender] = true;
divorced[soulmateOf[msg.sender]] = true;
+ ownerToId[msg.sender] = 0;
+ ownerToId[soulmateOf[msg.sender]] = 0;
emit CoupleHasDivorced(msg.sender, soulmate2);
}