In the InheritanceManager.sol
contract the inherit()
and withdrawInheritedFunds
are only supposed to be called by beneficiaries but currently anyone can call them, even when they are not beneficiaries and start the inheritance process.
The InheritanceManager.sol
has the beneficiary function inherit
, which is used to change the state of the contract to inheritable which opens up access to any funds and assets. The beneficiary function withdrawInheritedFunds
calculates how much each beneficiary will get and sends the funds/assets. Currently, both beneficiary functions do not have any checks to make sure they can only be called by beneficiaries.
The error InvalidBeneficiaries
and modifier onlyBeneficiaryWithIsInherited
exist but are not implemented within the above functions logic.
The
inherit()
missing modifier to check only beneficiaries can call
The
withdrawInheritedFunds
missing modifieronlyBeneficiaryWithIsInherited
As the @dev information provides, these functions are only supposed to be callable by only beneficiaries. While, no one can steal the inheritance funds/assets via this method resulting in the impact being low, this still breaks the protocols functionality as the code logic is not working as supposed to.
The impact is low as anyone can change the contract state once the 90 days has passed to inheritable and initiate the inheritance transfers which is against the protocols functionality and no funds are at risk. Furthermore, there is no profit for the attacker
Manual Review
Foundry for Testing
I have included a test function that can be run using: `forge test --mt testAnyoneCanCallInherit -vvv`.
The function:
Deposits 10 ether as the owner
Adds 2 beneficiaries
Fast forwards past the 90 day deadline
Calls inherit
as a random user to change the contract state to inheritable
Calls withdrawInheritedFunds
as a random user to initiate the inheritance transfers
Displays logs showing wallet balance before and after along with the beneficiaries balances
The recommended mitigation for this is
Implement a modifier that checks if the caller to inherit
is part of the is part of the beneficiaries list before executing. An example of this is:
The modifier onlyBeneficiaryWithIsInherited
exists but is not suitable for the inherit
function as the modifier requires the current state to be isInherited = true
. If its used, the contracts state will never be updated thus locking all funds forever and breaking contract logic.
The modifier onlyBeneficiaryWithIsInherited
should be implemented on the withdrawInheritedFunds
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.