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

Zero Beneficiaries Creates Permanent Lock

Summary

If no beneficiaries are added to the contract and the deadline passes, the contract enters a permanently locked state where no one can access the funds - not even the original owner.

Vulnerability Details

function inherit() external {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
if (beneficiaries.length == 1) {
owner = msg.sender;
_setDeadline();
} else if (beneficiaries.length > 1) {
isInherited = true;
} else {
revert InvalidBeneficiaries(); // Reverts if beneficiaries.length == 0
}
}

Critical issues:

  1. Deadlock Scenario

    • Owner doesn't add beneficiaries

    • 90 days pass

    • Deadline expires

    • Owner can't access funds (no deadline reset)

    • No one can inherit (reverts on zero beneficiaries)

    • Funds permanently locked

  2. No Recovery Path

    • Owner operations need active deadline

    • inherit() reverts on zero beneficiaries

    • No mechanism to reset deadline

    • No emergency recovery function

    • No way to add beneficiaries after lock

  3. Affected Assets

    • All ETH in contract

    • All ERC20 tokens

    • All NFTs

    • All contract state

Impact

CRITICAL - The vulnerability enables:

  1. Permanent Fund Lock

    • All assets inaccessible

    • No recovery mechanism

    • Affects all contract value

    • Complete loss of funds

  2. Contract Deadlock

    • No state changes possible

    • Can't add beneficiaries

    • Can't reset deadline

    • Can't access funds

Proof of Concept

contract LockTest {
InheritanceManager target;
function demonstrateLock() external {
// 1. Deploy contract
// 2. Don't add any beneficiaries
// 3. Wait 90 days
// Now:
target.inherit(); // Reverts: "InvalidBeneficiaries"
// Owner tries to send ETH:
target.sendETH(); // Reverts: deadline passed
// Owner tries to add beneficiary:
target.addBeneficiary(); // Reverts: deadline passed
// Result: All funds permanently locked
}
}

Recommendations

  1. Add Zero Beneficiary Protection:

function inherit() external {
if (block.timestamp < getDeadline()) {
revert InactivityPeriodNotLongEnough();
}
// Allow owner recovery if no beneficiaries
if (beneficiaries.length == 0) {
require(msg.sender == owner, "Only owner");
_setDeadline();
return;
}
// Normal inheritance logic
if (beneficiaries.length == 1) {
owner = msg.sender;
_setDeadline();
} else {
isInherited = true;
}
}
  1. Add Emergency Recovery:

function emergencyRecover() external {
require(msg.sender == owner, "Only owner");
require(beneficiaries.length == 0, "Has beneficiaries");
_setDeadline();
emit EmergencyRecovery(owner);
}
  1. Enforce Beneficiary Requirements:

constructor() {
owner = msg.sender;
_setDeadline();
require(_addInitialBeneficiary(), "Must add beneficiary");
}
function _addInitialBeneficiary() internal returns (bool) {
// Logic to ensure at least one beneficiary
}
  1. Add Safety Features:

    • Minimum beneficiary requirement

    • Emergency recovery mechanism

    • Clear state transitions

    • Proper event logging

Updates

Lead Judging Commences

0xtimefliez Lead Judge 9 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

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

Give us feedback!