Summary
The owner
is able to influence the future allocation of funds between beneficiaries, contradicting the core assumption:
"3. After the 90 days only the beneficiaries get access to the funds, entirely equally divided"
This is possible as the owner
is able to add duplicates of beneficiary addresses to InheritanceManager::beneficiaries[]
.
Vulnerability Details
This is possible as the owner
is able to add duplicates of the same beneficiary
address to the InheritanceManager::beneficiaries[]
array using InheritanceManager::addBeneficiary()
(lines 153-156):
function addBeneficiery(address _beneficiary) external onlyOwner {
beneficiaries.push(_beneficiary);
_setDeadline();
}
Impact
Although no assets are lost, the expected behaviour as described is incorrect.
Proof Of Concept
function test_influencedShare() public {
vm.startPrank(owner);
im.addBeneficiery(user1);
im.addBeneficiery(user1);
im.addBeneficiery(user2);
im.addBeneficiery(user2);
im.addBeneficiery(user3);
vm.stopPrank();
vm.deal(address(im), 10e10);
vm.warp(1 + 90 days);
console.log("Total inheritance:\t\t%s", address(im).balance);
vm.startPrank(user1);
im.inherit();
im.withdrawInheritedFunds(address(0));
vm.stopPrank();
console.log("user1 balance:\t\t%s", address(user1).balance);
console.log("user2 balance:\t\t%s", address(user2).balance);
console.log("user3 balance:\t\t%s", address(user3).balance);
}
Ran 1 test for test/InheritanceManagerTest.t.sol:InheritanceManagerTest
[PASS] test_influencedShare() (gas: 338770)
Logs:
Total inheritance: 100000000000
user1 balance: 40000000000
user2 balance: 40000000000
user3 balance: 20000000000
Tools Used
Foundry Forge:
forge test --mt test_influencedShare -vv
Recommendations
Check the beneficiary
index for the address to be added, if the index exists, beneficiary
has already been added and the call reverts with an InheritanceManager::InvalidBeneficiaries()
error:
function addBeneficiery(address _beneficiary) external onlyOwner {
@> if(_getBeneficiaryIndex(_beneficiary) != 0) {
@> revert InvalidBeneficiaries();
@> }
beneficiaries.push(_beneficiary);
_setDeadline();
}