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

Unrestricted ownership transfer in `inherit` function allows theft of assets

Summary

The inherit function in the InheritanceManager contract is not access restricted and any external address can inherit the contract when there is one beneficiary after the 90 day inactivity period has elapsed. This vulnerability allows an attacker to gain full control of the contract drain its assets and disinherit the intended beneficiary.

The problem is because there is no validation for the fact that msg.sender is the intended recipient which makes this a pretty straightforward vulnerability to exploit

Vulnerability Details

The vulerability can be located here: https://github.com/CodeHawks-Contests/2025-03-inheritable-smart-contract-wallet/blob/main/src/InheritanceManager.sol#L217-L229

The inherit function serves to control the passing of control upon the owner's 90 day inactivity period as monitored by the deadline variable. It sets owner = msg.sender when beneficiaries.length == 1 and it also resets the deadline passing full ownership over to the caller. It doesn't verify if msg.sender is equal to the one beneficiary in the beneficiaries array. Because the function is public and can be called by any address it is probable that any address can call once block.timestamp < getDeadline() allowing an attacker to steal the ownership.

Impact

The impact of this vulnerability is critical, as an attacker can gain full control over the contract, which leads to all the funds lost. On top of that, this vulnerability is quite easy to exploit.

Recommendations

In order to stop this vulnerability from happening I would add an access control check to allow only the preset beneficiary to claim ownership for the single beneficiary case.

Following is the fixed code:

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

Lead Judging Commences

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

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

0xtimefliez Lead Judge 4 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.