The InheritanceManager contract is designed to facilitate asset inheritance by enabling ownership transfers or asset claims after a specified period of owner inactivity. However, a critical vulnerability in the inherit function undermines this functionality. Specifically, when there is a single beneficiary, the function lacks proper access control and validation, allowing any external caller to assume ownership of the contract after the inactivity deadline, regardless of whether they are the designated beneficiary. This flaw exposes the contract to unauthorized ownership transfers, risking the loss of assets and control to malicious actors.
Lack of Caller Validation for Single Beneficiary
When the number of beneficiaries is exactly one (beneficiaries.length == 1), the function assigns owner = msg.sender without verifying that msg.sender matches the address stored in the beneficiaries array.
This omission allows any external address to call inherit() after the deadline and claim ownership, circumventing the intended inheritance process.
Unrestricted External Access
The function is marked external, making it callable by any address.
Once the inactivity deadline (getDeadline()) is reached, any caller can invoke inherit(), and in the single-beneficiary case, they will automatically become the new owner.
No Ownership Transfer Safeguards
In the single-beneficiary scenario, the function directly reassigns ownership to msg.sender without additional checks or confirmation mechanisms.
This design contradicts the contract’s purpose of securely transferring ownership to a pre-designated beneficiary.
The inherit function is implemented as follows in the InheritanceManager contract:
Consider the following sequence of events:
Deployment: The contract is deployed with an owner who designates Alice as the sole beneficiary.
Inactivity: The owner remains inactive, and the deadline is surpassed (i.e., block.timestamp >= getDeadline()).
Exploitation: A malicious actor, Bob, calls inherit().
Result: Since beneficiaries.length == 1, the contract assigns owner = Bob, granting him full control over the contract and its assets, despite Alice being the intended beneficiary.
This scenario demonstrates how the flaw enables unauthorized parties to hijack the contract, rendering the inheritance mechanism ineffective.
Below is a Foundry test demonstrating the vulnerability:
Below is a Foundry test demonstrating the vulnerability:
The absence of proper validation and access control in the inherit function introduces significant risks:
Unauthorized Ownership Transfer
Any external actor can call inherit() after the deadline and assume ownership if there is only one beneficiary, effectively taking control of the contract.
Asset Loss
The new, unauthorized owner gains the ability to manage or withdraw the contract’s assets, potentially leading to theft or misappropriation.
Violation of Inheritance Intent
The contract fails to enforce the owner’s intent to transfer ownership to a specific beneficiary, eroding trust in the inheritance system.
Potential for Disruption
Even non-malicious callers could inadvertently trigger inherit(), disrupting the intended inheritance process and causing disputes among legitimate beneficiaries.
Manual Review
To mitigate this vulnerability and align the contract with its intended purpose, the following remediation steps are proposed:
Implement Caller Validation for Single Beneficiary
Update the inherit function to verify that msg.sender is the designated beneficiary before transferring ownership in the single-beneficiary case.
Updated Code:
Restrict Access for Multiple Beneficiaries
When there are multiple beneficiaries (beneficiaries.length > 1), ensure that only a listed beneficiary can trigger the inheritance process.
Updated Code:
Helper Function:
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.