DoubPresaleVesting: setClaimsEnabled is bidirectional, owner can disable claims mid-vesting and freeze beneficiary DOUB #130
Labels
No labels
agent:fix_bugfix
agent:fix_conflicts
agent:fix_security
agent:gap_analysis
agent:implement
agent:open_issues
agents
agent:security_audit
agent:verify
area
timecurve
arena
arena-v2
audit
block:feature_review
block:security
bug
contracts
design
devops
docs
documentation
enhancement
epic
feature
frontend
indexer
low priority
megaeth
operations
ops
performance
QA
qa checklist
referrals
removal
security
smart-contracts
tech-debt
testing
time-arena
timecurve
visual-qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
code/yieldomega#130
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
found during the post-audit security review pass (followup to #126).
Summary
setClaimsEnabled(bool enabled)(line 130) is bidirectional — owner can flip claims on AND off at any time, including AFTER vesting has started and beneficiaries are mid-claim. Disabling claims mid-vesting freezes beneficiaries' allocations until owner re-enables.Same shape as #127 (FeeRouter governor DoS via setDistributableToken): privileged toggle that can brick legitimate user flows.
Code
DoubPresaleVesting.sol:130-133:DoubPresaleVesting.sol:191-192(claim gate):Attack / footgun paths
setClaimsEnabled(false)mid-vesting, all beneficiaries' active claims revert. recovery requires owner key recovery + re-enable tx. value frozen during gap.DOUB stays in the contract during the freeze, but vesting clock keeps ticking.
vestedAtcontinues accruing. When claims re-enable, beneficiaries get larger lump-sum claims (no actual loss) but the freeze is still a real DoS for everyone counting on cashflow timing.Severity
Medium. privileged DoS, no fund extraction (DOUB stays in contract). audit H-01 covers privileged upgrade/role centralization generically; this is the specific concrete consequence on the user-facing claim path.
Mitigations
One-way ratchet — once
claimsEnabledis set true, it stays true. setter reverts onfalseafter first true.Remove the disable path entirely — split into separate
enableClaims()anddisableClaims()and remove the latter post-deploy.Add a permanent "frozen" lock —
finalizeClaimsEnabled()admin call that locks the current state. operationally awkward but preserves emergency-pause flexibility until lock.option 1 is cleanest — minimal surface change, preserves the existing setter shape, eliminates the DoS vector.
Pre-deploy relevance
DoubPresaleVesting is in v1 deployment scope (the
/vestingroute + presale +15% CHARM tie-in is live in the new code dev pushed today). worth a fix or explicit operational policy (governor key cold-stored, only thawed via emergency rotation procedure) before mainnet.cc @PlasticDigits
mentioned in issue #131
Acceptable governance risk, closing