MultiSig Timelock

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

Confirmation Replay Due to Missing Transaction-Scoped Approval Tracking

Author Revealed upon completion

Root + Impact

Description

  • Each signer’s confirmation must be strictly bound to a single transaction, preventing reuse across proposals.

  • The multisig logic lacks a transaction-scoped confirmation mapping, allowing confirmations or signatures to be reused or replayed for different transactions. This breaks signer intent guarantees and enables unauthorized execution.

// @> Missing mapping: transactionId => signer => confirmed
mapping(address => bool) public isSigner;

Risk

Likelihood:

  • Multiple transactions exist concurrently.

Signers reuse interfaces or off-chain signing flows.

Impact:

  • Transactions execute without proper quorum.

Unauthorized state changes or fund transfers occur.

Proof of Concept

  • Without transaction-scoped confirmation tracking, signer approvals lose isolation, violating multisig safety assumptions.

// Signer confirms txA
confirmTransaction(txA);
// Attacker submits txB with same structure
// Confirmation reused implicitly
executeTransaction(txB); // Executes without fresh approvals

Recommended Mitigation

- remove this code
+ add this code
+ mapping(uint256 => mapping(address => bool)) public confirmed;
+ function confirmTransaction(uint256 txId) external {
+ require(!confirmed[txId][msg.sender], "Already confirmed");
+ confirmed[txId][msg.sender] = true;
+ }

Support

FAQs

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

Give us feedback!