MultiSig Timelock

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

Timelock defeated by transaction splitting

Author Revealed upon completion

Root + Impact

Description

  • Normal behavior: Larger ETH amounts incur longer delays.

  • Issue: An attacker or rushed operator can split a single large transfer into many small transfers (<1 ETH), each executing immediately to drain funds quickly.

// @> Timelock scales per transaction, not per time window
// Multiple proposals with value < 1 ether -> NO_TIME_DELAY for each

Risk

Likelihood:

  • Reason 1 // Common operational pattern to bypass per-tx throttles

  • Reason 2 // No global rate limit or windowed aggregation

Impact:

  • Impact 1 // Rapid depletion of funds without intended delay

  • Impact 2 // Governance control ineffective against rushed outflows

Proof of Concept

Explanation: The test testH3_AggregateOutflowIncreasesDelay demonstrates that multiple small transactions can be executed sequentially without delay. The mitigation introduces daily aggregate tracking.

for (uint256 i; i < 100; i++) {
vm.prank(OWNER);
uint256 id = multiSigTimelock.proposeTransaction(beneficiary, 0.9 ether, hex"");
// collect confirmations
vm.prank(SIGNER_THREE);
multiSigTimelock.executeTransaction(id); // immediate
}

Recommended Mitigation

Explanation: Track daily outflow in a mapping s_outflowPerDay. In _executeTransaction, add the current transaction value to the daily total and calculate the delay based on the aggregate amount.

+ // Add windowed outflow caps (e.g., per 24h) and aggregate values
+ // Enforce minimum delay for cumulative daily outflow exceeding thresholds

Status: Valid (Mitigated in src/MultiSigTimelock.sol)


Support

FAQs

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

Give us feedback!