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
Looking at this helper function and the natspec comments
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.
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
Day 0: Contract deployed with deadline = block.timestamp + 90 days.
Day 45: Owner calls removeBeneficiary (but deadline remains Day 0 + 90 days).
Day 67: Owner calls removeBeneficiary to remove another beneficiary (but deadline remains Day 0 + 90 days).
Day 82: Owner calls removeBeneficiary third time removing the last beneficiary (but deadline remains Day 0 + 90 days).
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
Day 91: if there remains only one beneficiary left , Beneficiary calls inherit() which would be executed despite owner's partial involvement
manual review
Add _setDeadline() to the removeBeneficiary function
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.