When the owner adds themselves as the sole beneficiary and triggers inheritance, they cannot withdraw funds through withdrawInheritedFunds() because the isInherited flag is never set to true for a single beneficiary. Instead, when there's only one beneficiary, the contract transfers ownership but doesn't set the inheritance flag, blocking access to the withdrawal functionality.
The vulnerability stems from the logic in the inherit() function, which handles single beneficiaries differently than multiple beneficiaries:
When there's only one beneficiary, the contract transfers ownership to the caller but doesn't set isInherited = true. This prevents the withdrawInheritedFunds() function from being used, as it has the following check:
This creates a situation where an owner who sets themselves as the sole beneficiary cannot access the withdrawal mechanism after inheritance. While they regain ownership and can use owner-level functions like sendETH and sendERC20, they must manually extract each asset type rather than using the streamlined withdrawal function.
This vulnerability has significant impact:
Locked Functionality: The single-beneficiary inheritance path prevents access to the dedicated withdrawal function, creating inconsistent behavior
Self-Recovery Limitation: An owner trying to recover their own wallet through inheritance will gain ownership but lack the intended withdrawal mechanism
UX Inconsistency: Different number of beneficiaries leads to drastically different inheritance behavior with no clear documentation
Redundant Gas Costs: An owner seeking to recover funds must extract each asset type individually rather than using the batch distribution function
In case owner decides to add another beneficiare and then removes it to bypass the if (beneficiaries.length == 1 then due the suboptiomal design - deleting array value the beneficiaries array will get an empty value for the removed beneficiaroes but the amounts will be split /beneficiaries.length, inlcuding the 0 address and the owner might not even realized he will get just a portion of the funds, rest going to the 0-th address.
Manual code review
Foundry testing framework
PoC
this reverts but is supposed to not.
In the above case the owner seeking workaround might artificially add and remove beneficiary to bypass a check but then ends up splitting the assets with address 0
add a flag update:
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.