Verifying Multisig Transactions
The security of a multisig wallet relies on each signer independently verifying what they are signing. A compromised web interface could present a legitimate-looking transaction while tricking a hardware wallet into signing a malicious one.
The verification process is divided into two distinct phases: signing the off-chain message and executing the on-chain transaction.
Phase 1: Signing the Off-Chain Message
When you are the first signer or are adding your signature to a transaction that has not yet met its threshold, you are not sending an on-chain transaction. Instead, you are signing a structured, off-chain message that conforms to the EIP-712 standard.
Goal: To confirm that the cryptographic hash displayed on your hardware wallet exactly matches the hash of the transaction you intend to approve.
Process
- Initiate Signing: Start the signing process in the multisig wallet's web interface.
- Verify on Hardware Wallet: Your hardware wallet will display an EIP-712 hash for you to sign.
- Independently Compute Hash: Use an independent, local tool like safe-hash to re-calculate the expected hash. The tool will ask for the transaction's parameters (nonce,
to
,value
,data
, etc.) to generate the hash locally on your machine.For less technical users, a web-based tool like Safe Utils can perform this calculation, but a local command-line tool offers superior security against browser-based attacks.
- Compare Hashes: Compare the
SafeTxHash
generated by the local tool with the hash displayed on your hardware wallet's screen. They must match perfectly. - Sign: If the hashes match, you can confidently sign the message on your hardware wallet. This confirms you are approving the correct transaction, even if the web UI has been compromised.
Phase 2: Executing the On-Chain Transaction
Once a transaction has the required M-of-N signatures, it can be executed. This involves submitting a final on-chain transaction that calls the execTransaction
function on the multisig contract, passing in all the previously signed data.
Goal: To confirm that the on-chain transaction being sent correctly encapsulates the multisig transaction you and other signers approved.
Process
- Initiate Execution: In the multisig interface, start the execution of the fully signed transaction.
- Verify Calldata: Your hardware wallet will prompt you to sign a new on-chain transaction. It will display the raw transaction data (calldata), which should show a call to the
execTransaction
function. - Decode and Compare: Use a calldata decoder (e.g.,calldata.swiss-knife.xyz) to parse the data shown on your hardware wallet.
- Confirm Parameters: Carefully check the decoded parameters within the
execTransaction
call, especially the internal destination address (to
),value
, anddata
payload. Ensure they match the original, intended transaction. - Sign and Broadcast: If the calldata is correct, sign the transaction on your hardware wallet to broadcast it to the network.
Operational Best Practices
⚠️ Beware of
DELEGATECALL
: In a smart contract multisig transaction, anoperation: 1 (DELEGATECALL)
is dangerous if the target contract is not explicitly known and trusted. This opcode gives another contract full control over your wallet's context and storage.
- Transaction Simulation: Before signing, use a simulator like Tenderly or Alchemy to preview the transaction's outcome. This helps confirm that it will not revert and will result in the expected state changes.
- Hardware Wallet Standard: All multisig signers should use hardware wallets to protect their keys from online threats. Data shown in a browser extension wallet should be treated with the same skepticism as data in the web UI.
- Alternative Frontends: To further reduce reliance on a single public UI, consider using an alternative or self-hosted multisig interface.