SignLens

Warnings › Multisig approvals you cannot see

Multisig approvals: when the bytes do not say what you approve

Published

A Squads multisig runs a transaction once enough members approve it. The member who proposes it signs the whole transaction into the proposal; the members who approve later sign only a reference to a proposal stored on chain. Their wallets cannot show what they approve from the bytes they sign.

The Security Alliance's guide to verifying Squads transactions puts it plainly: "Limited tooling is available for Solana verification compared to EVM."

What SignLens shows

When the proposal is created in the transaction you sign, SignLens decodes its transaction step by step, as if you were signing it (see a proposal of a token transfer).

When you only approve, what you sign names the proposal and nothing more. SignLens then reads the proposal and the transaction it stores from your RPC, checks that they are the accounts the approval names and decode as Squads writes them, and shows the steps as your RPC's word. The high finding stays: the steps come from your RPC, not from what you sign. A member's approval of a 3,000 USDT transfer, with the two accounts as an RPC returned them:

Warning

Approve proposal #69 (Transfer 3,000 USDT from DykM…LxRp to 6PgM…LYdc, per your RPC)

What SignLens found

What this does

Full text, as the engine prints it
Approve proposal #69 (Transfer 3,000 USDT from DykM…LxRp to 6PgM…LYdc, per your RPC)
WARNING: review the findings before approving

Findings:
  [HIGH] This would approve a multisig proposal whose content is on chain, not in the signed bytes; its steps are shown from the transaction account as your RPC returned it, which the signed bytes cannot confirm (instruction 3)

== Approve proposal | Squads multisig v4
  Multisig: 85yqfP7w9PoEuwgUrjp4yQovLmfS6g6C7LZs2MPpiXJn
  Proposal: 94JcnrNxmorKtquUUh8hvEPPMrBC1X8FUen5zSA6XuEV
  Content: transaction #69 of this multisig, from its account as your RPC returned it at slot 461298601; the signed bytes do not hold it (claimed, unverified)
  Vault: Vault 0 of multisig 85yq…iXJn (4D2x…cCJs)
  Member: Your wallet (3xvJ…L5Zf)
  Steps: 1

==== Step 1: Transfer tokens | Token program
  Amount: 3,000 USDT
  From: Vault 0 of multisig 85yq…iXJn's USDT account (DykM…LxRp)
  To: 6PgMZUFGmEFxAqccaHaL94aVV4JDnShKE44E2DaLLYdc
  Authorized by: Vault 0 of multisig 85yq…iXJn (4D2x…cCJs)
  Mint: USDT mint (Es9v…wNYB)

== Also [collapsed]
  Compute unit limit: 100001
  Compute unit price: 182,710 micro-lamports per compute unit

== Signers
  Fee payer: Your wallet (3xvJ…L5Zf)

== Fee
  Total: 0.000023272 SOL
  Base: 0.000005 SOL
  Priority: 0.000018272 SOL
  Priority basis: 182,710 micro-lamports per compute unit × 100,001 compute units requested

== Validity
  Expires: in about a minute (recent blockhash)

Effects:
  - Once approved, Vault 0 of multisig 85yq…iXJn (4D2x…cCJs) would: Transfer 3,000 USDT from Vault 0 of multisig 85yq…iXJn's USDT account (DykM…LxRp) to 6PgMZUFGmEFxAqccaHaL94aVV4JDnShKE44E2DaLLYdc
  - You pay a fee of 0.000023272 SOL
  - Valid for about a minute (recent blockhash)

Raw: solana v0 (234 bytes)
  digest: 1a6535608c36e5befb87e314cd8508237f32a8a6de2d8bba3cc183d5f79ed683
Mainnet transaction 3sxH…dB2K, slot 461,268,978. Explained for 3xvJ…L5Zf as the signer, by the SignLens engine 0.3.0, on 2026-11-01, with the 2 accounts the explanation asked for, as an RPC returned them on 2026-10-25. How to read this.

When the RPC has nothing to give, because the proposal has been closed or does not exist yet, SignLens says it cannot show what you approve. Three approvals whose proposals have since been closed:

Warning

3 actions

  1. Approve proposal AZEy…gXM7
  2. Approve proposal 6yju…U9d9
  3. Approve proposal Gyks…hWap

What SignLens found

What this does

Full text, as the engine prints it
3 actions: Approve proposal AZEy…gXM7; Approve proposal 6yju…U9d9; Approve proposal Gyks…hWap
WARNING: review the findings before approving

Findings:
  [HIGH] This would approve a multisig proposal whose content is on chain, not in the signed bytes; SignLens cannot show what it does (instruction 3)
  [HIGH] This would approve a multisig proposal whose content is on chain, not in the signed bytes; SignLens cannot show what it does (instruction 4)
  [HIGH] This would approve a multisig proposal whose content is on chain, not in the signed bytes; SignLens cannot show what it does (instruction 5)

== Approve proposal | Squads multisig v4
  Multisig: 2ZDFsDzcztw6fRgpvRECytSDTnWtJbUDiVqck7CJS1oi
  Proposal: AZEy1xu8MxB8BwbSYTfEmDmTuTKTc9DFQnFwdyFXgXM7
  Content: on chain, not in these bytes
  Member: Your wallet (By8Z…h5wY)

== Approve proposal | Squads multisig v4
  Multisig: 2ZDFsDzcztw6fRgpvRECytSDTnWtJbUDiVqck7CJS1oi
  Proposal: 6yjuCo1HuS8Zv9m253XXnmm2k7rM464P4R8PtGg5U9d9
  Content: on chain, not in these bytes
  Member: Your wallet (By8Z…h5wY)

== Approve proposal | Squads multisig v4
  Multisig: 2ZDFsDzcztw6fRgpvRECytSDTnWtJbUDiVqck7CJS1oi
  Proposal: Gyksz4KLTiG2E1UPDd7QEdsA16eBc2w64MFhDfyvhWap
  Content: on chain, not in these bytes
  Member: Your wallet (By8Z…h5wY)

== Also [collapsed]
  Compute unit price: 100,000 micro-lamports per compute unit
  Compute unit limit: 70000

== Signers
  Fee payer: Your wallet (By8Z…h5wY)

== Fee
  Total: 0.000012 SOL
  Base: 0.000005 SOL
  Priority: 0.000007 SOL
  Priority basis: 100,000 micro-lamports per compute unit × 70,000 compute units requested

== Validity
  Expires: in about a minute (recent blockhash)

Effects:
  - You pay a fee of 0.000012 SOL
  - Valid for about a minute (recent blockhash)

Would read, to explain more:
  - AZEy1xu8MxB8BwbSYTfEmDmTuTKTc9DFQnFwdyFXgXM7: the proposal: its index names the transaction it runs
  - 6yjuCo1HuS8Zv9m253XXnmm2k7rM464P4R8PtGg5U9d9: the proposal: its index names the transaction it runs
  - Gyksz4KLTiG2E1UPDd7QEdsA16eBc2w64MFhDfyvhWap: the proposal: its index names the transaction it runs

Raw: solana legacy (326 bytes)
  digest: 3b6740be3740ec2b03ef6d6463058ebcf11855ad0b55da435ba5f194c5c3e711
Mainnet transaction owEA…wsfK, slot 453,905,368. Explained for By8Z…h5wY as the signer, by the SignLens engine 0.3.0, on 2026-11-01. How to read this.

Both kinds of signature handed Drift's admin to an attacker in April 2026. The second member approved a proposal that did not exist yet when they signed, so nothing could have read it for them: the two signatures, read by SignLens.

What to do

Read the steps before approving, and remember where they come from: a dishonest RPC could show a harmless transaction. For a large transfer, check them against the proposer's signature or the proposal account on an explorer you trust, not against the interface that asks you to approve.

Other warnings: accounts given away, spending rights, signatures that never expire, lookalike addresses, programs it does not know, a swap paying someone else.

Try it: install SignLens for Chrome or Firefox.

Sources