MultiSig Timelock

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

Proposal event omits calldata, enabling blind signing and spoofed reviews

Author Revealed upon completion

Scope
src/MultiSigTimelock.sol: TransactionProposed, _proposeTransaction

Root + Impact

Description

  • Normal behavior: Events should include calldata so off-chain reviewers can reconstruct intent.

  • Issue: TransactionProposed emits only to and value. Attackers can publish a “harmless” proposal summary off-chain while the on-chain calldata performs approve(spender, type(uint256).max) or upgradeTo(attacker), and observers cannot verify from logs alone.

event TransactionProposed(uint256 indexed transactionId, address indexed to, uint256 value); // data missing

Risk

Likelihood:

  • Reason 1 // Reviewers commonly rely on event streams, not direct storage reads

  • Reason 2 // Social-engineering around multisig approvals is common

Impact:

  • Impact 1 // Signers approve malicious calldata under false pretenses

  • Impact 2 // Incident response hampered; historical calldata unavailable from logs

Proof of Concept

Explanation: Propose data = abi.encodeWithSignature("approve(address,uint256)", attacker, type(uint256).max). Event consumers see only to/value, assume benign transfer, and confirmations proceed.

// Event inspection cannot reveal approve() payload

Recommended Mitigation

Explanation: Emit data (or a hash) in the proposal event and have UIs validate it against user-signed digests.

- event TransactionProposed(uint256 indexed transactionId, address indexed to, uint256 value);
+ event TransactionProposed(uint256 indexed transactionId, address indexed to, uint256 value, bytes data, bytes32 dataHash);

Status: Valid (Observability Gap)


Support

FAQs

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

Give us feedback!