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