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

Missing Inactivity Timer Reset in removeBeneficiary Function

Summary

The _setDeadline() function is designed to reset the deadline state variable whenever the owner performs an action, ensuring the "inactivity timer" (TIMELOCK) is extended

The removeBeneficiary function is owner-controlled but does not call _setDeadline(), meaning the inactivity timer does not reset when this function is used.

This allows the deadline to expire even if the owner is actively managing the contract via removeBeneficiary

Vulnerability Details

Looking at this helper function and the natspec comments

/**
* @dev internal helper function to be called at contract creation and every owner controlled event/function call
* to resett the timer off inactivity.
*/
function _setDeadline() internal {
deadline = block.timestamp + TIMELOCK;
}

The internal helper _setDeadline() is intended to reset this timer whenever the owner interacts with every owner controlled function. However, the removeBeneficiary function, which is owner-controlled, fails to call _setDeadline(). This omission breaks the intended security model, allowing the inactivity timer to expire even if the owner is actively managing the contract via this function.

function removeBeneficiary(address _beneficiary) external onlyOwner {
uint256 indexToRemove = _getBeneficiaryIndex(_beneficiary);
delete beneficiaries[indexToRemove];
}

Impact

The deadline is a critical security feature meant to track owner activity. By not resetting it in removeBeneficiary, the contract creates a loophole:

  • Owner Activity Misrepresentation: The owner could be actively using removeBeneficiary (proving they are alive/active), but the timer does not update.

  • Premature Deadline Expiry: The deadline remains tied to older interactions, allowing it to expire even if the owner is partially active.

Proof of Concept

  1. Day 0: Contract deployed with deadline = block.timestamp + 90 days.

  2. Day 45: Owner calls removeBeneficiary (but deadline remains Day 0 + 90 days).

  3. Day 67: Owner calls removeBeneficiary to remove another beneficiary (but deadline remains Day 0 + 90 days).

  4. Day 82: Owner calls removeBeneficiary third time removing the last beneficiary (but deadline remains Day 0 + 90 days).

  5. Day 90: deadline expires. Since there is no beneficiary again because he removed all of them. His funds become lost forever and no way to recover assets based on the timelock

  6. Day 91: if there remains only one beneficiary left , Beneficiary calls inherit() which would be executed despite owner's partial involvement

Tools Used

manual review

Recommendations

Add _setDeadline() to the removeBeneficiary function

function removeBeneficiary(address _beneficiary) external onlyOwner {
uint256 indexToRemove = _getBeneficiaryIndex(_beneficiary);
delete beneficiaries[indexToRemove];
_setDeadline(); // Ensure the inactivity timer is reset
}
Updates

Lead Judging Commences

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

functions do not reset the deadline

Support

FAQs

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