The InheritanceManager.sol::inherit()
function contains a critical vulnerability that allows anyone to claim ownership of the contract after deadline has passed. When there is only one beneficiary (owner has backup wallet as described in docs), and the owner has been inactive beyond the deadline
, an attacker can frontrun the legitimate beneficiary and take control of the contract. This allows unauthorized access to all stored funds and assets.
Affected code:
The InheritanceManager.sol::inherit()
function allows inheritance only after deadline
has passed. If only one beneficiary exists, the contract assigns ownership without verifying the caller. This means anyone can call inherit()
and take over the contract if they frontrun the legitimate beneficiary.
Consider the following attack path which is possible when the owner of the contract has 2 wallets, one primary as the owner wallet and one secondary one as a backup as stated in Examples sections of the project's docs:
The owner becomes inactive (lost keys, etc.), and the deadline
passes.
The contract has only one beneficiary (owner's backup wallet) (beneficiaries.length == 1
).
The legitimate beneficiary attempts to call inherit()
.
An attacker sees the tx in mempool, frontruns and calls inherit()
first.
The contract assigns ownership to msg.sender
, but since there is no validation, the attacker now controls the contract.
The attacker can now withdraw all assets, remove the beneficiary, and lock out the rightful inheritor.
Add the following test to InheritanceManagerTest.t.sol
contract.
The test passed meaning the attack was successful and the attacker stole all funds.
An attacker can take ownership of the contract and steal all stored funds and assets.
The rightful beneficiary is permanently locked out.
Once the attacker takes ownership, they can remove all beneficiaries, making recovery impossible.
The likelihood is medium, but the impact is critical thus the high severity of this issue.
Manual review
Foundry
A simple and clean fix would be to just set the ownership to beneficiaries[0]
instead of msg.sender
.
Run the previous test again but now with mitigation implemented. The test now fails meaning the attacker was not able to claim ownership and steal all funds.
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.