wardcrest

How to verify a Safe transaction before you sign it

The Bybit theft showed that signers approve what their screen shows. Here is how to check what a pending Safe transaction really does, and why the hash matters.

Updated 14 Sept 2026 · Advanced · 3 min read

In short

  • A Safe transaction is authorised by signatures over a hash of its exact contents: target, value, calldata, operation and nonce.
  • If the interface lies, signers can approve something other than what they see. Check the contents and the hash independently.
  • Be most careful with delegatecall, with owner, threshold, module and guard changes, and with anything that touches the Safe itself.

What you are actually signing

A Safe (formerly Gnosis Safe) is a multisig smart-contract wallet: a transaction executes only when enough owners have signed it. Each signature covers the safeTxHash, an EIP-712 hash of the transaction’s fields: the destination, the value, the calldata, the operation type (call or delegatecall), the gas parameters, the gas token and refund receiver, and the Safe’s nonce.

Change any field and the hash changes. That is the protection, and the weak point. Signers rarely read raw calldata, so they rely on an interface to tell them what a transaction does. A compromised interface can show one thing and ask for a signature over another.

What happened at Bybit

In February 2025 the exchange Bybit lost about $1.5 billion in ether from a Safe-based cold wallet; the FBI attributed the theft to North Korean hackers. According to the post-incident investigations, the attackers had compromised the Safe web interface the signers used. It showed a routine transfer while the transaction actually being signed was a delegatecall that replaced the Safe’s implementation with the attackers’ code. Once enough signatures were collected, the attackers controlled the wallet.

The checks that matter

  1. Operation type. A delegatecall runs another contract’s code with the Safe’s own storage and authority. Apart from Safe’s official MultiSend and SignMessage libraries, it should almost never appear.
  2. Target and value. Is the destination the contract or person you expect? Is the amount what was agreed?
  3. Decoded calldata. Which function is called, with which arguments? Watch for approvals, ownership transfers, upgrades and calls to the Safe itself: owner, threshold, module, guard and fallback-handler changes.
  4. Gas token and refund receiver. Non-zero values can pay a third party out of the Safe; for ordinary transactions they are zero.
  5. Nonce. Transactions execute in nonce order. Two proposals with the same nonce means only one can ever run. Find out why there are two.
  6. The hash. Recompute the safeTxHash yourself from the fields and compare it with what your hardware wallet shows.

Checking the hash independently

Our Safe transaction checker reads pending transactions from the Safe Transaction Service, decodes them, flags risky operations and recomputes each safeTxHash locally, so you can see whether the hash matches the contents. If your hardware wallet displays the EIP-712 domain and message hashes when you sign, compare them with independently computed values before approving.

Beyond the single transaction

  • Set a threshold that no single person, device or office can meet alone.
  • Watch the Safe continuously: Wardcrest monitoring warns you about risky proposals before they execute, and about any change to owners, threshold, modules or guard.
  • Put upgrades and large movements behind a timelock where you can, so there is time to react.
  • Rehearse: agree in advance who verifies what, and what signers do when something does not match.

Put it into practice