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

Denial of service possible in `withdrawInheritedFunds`.

Summary

IMPACT : HIGH
Likelyhood : medium

The withdrawInheritedFunds() function distributes ETH to all beneficiaries in a single transaction . If one beneficiary cannot receive ETH , the entire function reverts , preventing all other beneficiaries from receiving their share. A malicious beneficiary can exploit this by forcing their ETH transfer to fail , blocking inheritance payouts for everyone .

Attack Scenario

  1. The InheritanceManager owner adds only beneficiaries that can receive ETH (contracts with a receive() function).

  2. A malicious beneficiary initially deploys a proxy contract that allows ETH deposits.

  3. After the owner verifies and adds the beneficiary , they upgrade their proxy contract to remove the receive() function , making ETH transfers to their address fail.

  4. When withdrawInheritedFunds() executes, it attempts to send ETH to all beneficiaries in a loop .

  5. Because one transfer fails, the entire function reverts, locking all ETH inside the contract .

Impact

All beneficiaries are blocked from receiving their Eth and the malicious beneficiary could demand a bribe in order for the other beneficiaries to recieve their eth.
This is especially dangerous in inheritance disputes, where family members may have conflicts.

Recommendation

if transfer fails, user can claim their eth afterwards.

+ mapping(address => uint256) public claimAfterFailedToSendEth;
...
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
}("");
- require(success, "something went wrong");
+ if (!success) {
+ claimAfterFailedToSendEth[beneficiary] = amountPerBeneficiary;
}
}
....
}
+ function ClaimFunds() public {
+ if (claimAfterFailedToSendEth[msg.sender] ==0 ){
+ Revert InheritanceManager__NoFundsToClaim();
+ }
+ uint256 fundsAmount =claimAfterFailedToSendEth[msg.sender] ;
+ (bool success, ) = payable(msg.sender).call{value : fundsAmount}("");
+ require(success, " transfer failed");
+}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 3 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.