Summary
IMPACT : HIGH
Likelihood : Medium
The InheritanceManager contract is designed to transfer wallet custody to the sole beneficiary after 90 days of inactivity. However, the current implementation allows anyone to call the inherit function and take ownership of the contract when there is only one beneficiary, bypassing the intended inheritance logic.
function inherit() external {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
--> if (beneficiaries.length == 1) {
--> owner = msg.sender;
_setDeadline();
} else if (beneficiaries.length > 1) {
isInherited = true;
} else {
revert InvalidBeneficiaries();
}
}
Impact
anyone can inherit this wallet when there is only one beneficiary. Putting the entire inheritance at risk
Proof Of Concept
function testAnyOneCanInherit() public {
address non_beneficiary = makeAddr("non_beneficiary");
vm.prank(owner);
im.addBeneficiery(user1);
vm.warp(1 + 90 days);
vm.prank(non_beneficiary);
im.inherit();
assertEq(non_beneficiary, im.getOwner());
}
Recommendation
function inherit() external {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
- if (beneficiaries.length == 1) {
+ if (beneficiaries.length == 1 && msg.sender == beneficiaries[0]) {
owner = msg.sender;
_setDeadline();
} else if (beneficiaries.length > 1) {
isInherited = true;
} else {
revert InvalidBeneficiaries();
}
}