MultiSig Timelock

First Flight #55
Beginner FriendlyWallet
100 EXP
View results
Submission Details
Impact: high
Likelihood: high
Invalid

Daily outflow guard reset enables midnight drain scheduling

Scope
src/MultiSigTimelock.sol: _executeTransaction, s_outflowPerDay

Root + Impact

Description

  • Normal behavior: s_outflowPerDay should slow cumulative withdrawals.

  • Issue: The guard resets at UTC day boundaries. An attacker can queue multiple 99 ETH transfers, wait past midnight, and execute them back-to-back with only the per-tx delay enforced, bypassing aggregate throttling.

uint256 dayIndex = block.timestamp / 1 days;
uint256 aggregateOutflow = s_outflowPerDay[dayIndex] + txn.value; // resets each day

Risk

Likelihood:

  • Reason 1 // Attackers can coordinate execution timing around day rollover

  • Reason 2 // Operational teams rarely monitor exact day boundaries

Impact:

  • Impact 1 // Drains large balances over consecutive day edges with minimal warning

  • Impact 2 // Defeats perceived “daily cap” protection promised by aggregate tracking

Proof of Concept

Explanation: Propose two 99 ETH withdrawals. Execute one at 23:59:59 and the other at 00:00:01; both see low aggregateOutflow and use only the base per-tx delay.

// dayIndex changes; second tx ignores first day’s outflow

Recommended Mitigation

Explanation: Use a sliding window or rolling sum (e.g., TWAP-style) instead of calendar days, or carry forward the previous day’s outflow until a decay period elapses.

+ mapping(uint256 window => uint256 value) private s_outflowRolling;
+ // compute rolling 24h sum using ring buffer

Status: Valid (Design Flaw)


Updates

Lead Judging Commences

kelechikizito Lead Judge 4 days ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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

Give us feedback!