The withdrawInheritedFunds
function uses the full array length to calculate shares, including deleted (address(0)) beneficiaries. This leads to incorrect fund distribution, violating the core invariant of equal distribution among active beneficiaries.
The current implementation:
The issue:
divisor = beneficiaries.length
includes deleted beneficiaries (address(0))
amountPerBeneficiary
is calculated using this incorrect divisor
Transfers to address(0) will revert
The reverted amounts are never redistributed to active beneficiaries
This violates the core invariant from README: "After the 90 days only the beneficiaries get access to the funds, entirely equally divided"
HIGH
Direct loss of funds that should go to beneficiaries
Violates core invariant of equal fund distribution
Portion of inheritance becomes permanently locked
Affects both ETH and token distributions
Likelihood: High
Occurs whenever there are deleted beneficiaries
Part of normal contract operation
No special conditions needed
Affects core functionality
Contract has 100 ETH to distribute
Initially 4 beneficiaries: Alice, Bob, Charlie, and Dave
Owner removes Bob and Dave using removeBeneficiary
Array becomes: [Alice, address(0), Charlie, address(0)]
When withdrawInheritedFunds
is called:
Result:
Alice receives 25 ETH
Second transfer reverts (address(0))
Charlie receives 25 ETH
Fourth transfer reverts (address(0))
50 ETH remains locked in contract
Correct distribution should have been:
Alice: 50 ETH
Charlie: 50 ETH
Manual review
Code inspection
Foundry tests
Maintain a separate counter for active beneficiaries:
These changes would:
Ensure correct fund distribution
Maintain equal shares among active beneficiaries
Prevent funds from being locked
Uphold the contract's core invariants
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.