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

Gas Griefing Vulnerability in Asset Distribution Allows Single Beneficiary to Block Entire Withdrawal

Summary

The withdrawInheritedFunds function is vulnerable to gas griefing attacks, where a single beneficiary can intentionally cause the entire ETH distribution process to fail, blocking all other beneficiaries from receiving funds.

Vulnerability Details

The withdrawInheritedFunds function contains a critical gas-related vulnerability in its ETH distribution logic:

for (uint256 i = 0; i < divisor; i++) {
(bool success,) = beneficiary.call{value: amountPerBeneficiary}("");
require(success, "something went wrong"); // ❌ Atomic revert
}
POC
Attack Scenario:
Malicious beneficiary deploys contract with:
solidity
Copy
receive() external payable {
while(true) {} // Infinite loop
// OR
revert("Blocking receive");
}
Regular user calls withdrawInheritedFunds()
Transaction reaches malicious beneficiary:
Gas limit exceeded (infinite loop)
OR Explicit revert triggered
Entire transaction reverts - no beneficiaries receive funds

Key Issues:

  1. Atomic Transaction Failure: A single failed ETH transfer reverts the entire transaction

  2. Gas Limit Exploitation: Malicious beneficiaries can:

    • Deploy contracts with expensive fallback functions

    • Consume all gas allocated for transfers

    • Force transaction failures through revert-on-receive logic

  3. Denial-of-Service: One bad actor can block all beneficiaries from receiving funds

Impact

  • Complete Withdrawal Blockade: Single malicious beneficiary can freeze all ETH distributions

  • Funds Locked Indefinitely: Assets remain trapped in contract until vulnerability is exploited

  • Protocol Paralysis: Critical inheritance functionality becomes unusable for ETH transfers

Tools Used

Manual Review

Recommendations

Solution 1: Isolate Transfers with Individual Send Attempts

for (uint i; i < divisor; i++) {
(bool success,) = beneficiaries[i].call{
value: amountPerBeneficiary,
gas: 2300 // Forward minimal gas
}("");
// Continue regardless of success
}

Solution 2: Track Successful Transfers

uint256 remainingAmount = ethAmountAvailable;
for (uint i; i < divisor; i++) {
uint256 amount = remainingAmount / (divisor - i);
(bool success,) = beneficiaries[i].call{value: amount}("");
if (success) remainingAmount -= amount;
}
Updates

Lead Judging Commences

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