Beginner FriendlySolidity
100 EXP
View results
Submission Details
Severity: high
Valid

Unauthorized Takeover in `inherit()` due to lack of beneficiary verification

Summary

The inherit() function in contract InheritanceManager allows anyone to claim ownership of the contract if beneficiaries.length == 1, without verifying that msg.sender is actually the sole beneficiary. This means that after 90 days of inactivity, an attacker can call inherit() and become the contract owner, completely bypassing the inheritance mechanism.

Vulnerability Details

Root Cause:
The contract fails to check whether msg.sender is the actual beneficiary when executing inherit(). The flawed logic:

function inherit() external {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
if (beneficiaries.length == 1) {
@> owner = msg.sender; // ❌ No check if msg.sender is the legitimate beneficiary
_setDeadline();
} else if (beneficiaries.length > 1) {
isInherited = true;
} else {
revert InvalidBeneficiaries();
}
}

Steps to Exploit:

  1. The contract owner adds a single beneficiary using addBeneficiery().

  2. The owner remains inactive for 90+ days, triggering the inheritance condition.

  3. Any external address (attacker) calls inherit().

  4. Since beneficiaries.length == 1, the contract assigns ownership to the attacker.

  5. The attacker takes full control of the contract and its assets.

Impact

  • Complete contract takeover by an unauthorized entity.

  • Loss of all assets stored in the contract.

  • Beneficiaries may never receive their rightful inheritance.

Tools Used

  • Foundry (Solidity smart contract testing framework)

  • Manual review

Recommendations

To prevent unauthorized contract takeover, modify the inherit function to ensure that only the legitimate beneficiary can claim ownership. Specifically, add a check to verify that msg.sender is the sole beneficiary before assigning ownership.

The inherit function can be modified as given below:

function inherit() external {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
if (beneficiaries.length == 1) {
// ✅ Ensure only the legitimate beneficiary can inherit
if (msg.sender != beneficiaries[0]) {
revert NotOwner(msg.sender);
}
owner = msg.sender;
_setDeadline();
} else if (beneficiaries.length > 1) {
isInherited = true;
} else {
revert InvalidBeneficiaries();
}
}
Updates

Lead Judging Commences

0xtimefliez Lead Judge 3 months ago
Submission Judgement Published
Validated
Assigned finding tags:

Inherit depends on msg.sender so anyone can claim the contract

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.