Recent

↑ ↓ to move ↵ to open esc to close

Offline EVM Calldata, EIP-712 Safe Hash & EIP-7702 Risk Visualizer

Zero-network ABI selector decoder, deterministic Keccak-256 Safe multisig verifier, and Pectra SetCode delegation inspector.

OFFLINE SANDBOX (connect-src 'none') Zero network uploads | Client-side deterministic execution
Tool Verification Scope & Threat Model
The DT.gl Calldata and Signature Auditor decodes raw EVM hexadecimal payloads, EIP-712 typed structures, and EIP-7702 SetCode authorization tuples entirely inside a network-isolated browser tab. It computes deterministic Keccak-256 Safe multisig domain and transaction hashes locally while flagging proxy storage takeover vectors such as operation 1 DELEGATECALL before hardware confirmation.

Why Host-UI Blind Signing Caused the Largest Heists in Crypto History

Between July 2024 and February 2025, institutional multisig vaults suffered over $1.74 billion in cumulative losses without a single cryptographic flaw in secp256k1 elliptic-curve signatures or hardware Secure Element silicon. In the $230 million WazirX exploit (July 2024), the $50 million Radiant Capital compromise (October 2024), and the landmark $1.46 billion Bybit Safe multisig heist attributed by the FBI IC3 PSA Alert to DPRK TraderTraitor actors, every hardware signer functioned exactly as designed: it computed a valid ECDSA signature over the 32-byte digest delivered over USB or Bluetooth by a compromised host web browser.

The catastrophic failure occurred across the host-to-signer presentation gap. Modern smart-contract wallets, decentralized exchanges, and gasless token routers construct deeply nested ABI byte arrays or EIP-712 typed structures. When a browser extension, web frontend CDN bucket, or local macOS developer workstation is poisoned, the attacker renders a benign transaction summary in HTML ("Transfer 0 ETH or routine cold-to-warm rebalance") while mutating two critical fields inside the underlying signing buffer:

  1. Execution Context Escalation (operation: 0 -> 1): Changing a single byte in Safe.execTransaction or SafeTx from 0 (CALL) to 1 (DELEGATECALL) transforms an external message call into an unrestricted proxy code execution inside the vault's own EVM storage layout.
  2. Target Implementation Substitution (to & Storage slot 0): Pointing that DELEGATECALL at an unverified attacker contract whose bytecode executes SSTORE(0x00, attackerImplementation) overwrites the Safe singleton masterCopy pointer stored at storage slot 0x0, permanently handing vault control to a backdoored implementation contract.

Byte-Level Anatomy of EVM Calldata, EIP-712 & EIP-7702 Signing Envelopes

Auditing Ethereum Virtual Machine payloads without relying on cloud block explorers requires parsing three distinct binary serialization layers: Contract ABI Calldata, EIP-712 Structured Data Hashing, and RLP-Encoded EIP-7702 SetCode Tuples.

EVM PRE-SIGNING FORENSIC PIPELINE (ZERO-NETWORK DETERMINISTIC VERIFICATION)LAYER 1: ABI CALLDATA LAYOUT -- Safe.execTransaction (Selector 0x6a761202)0..3: 6a7612024..35: address to36..99: val + ptr100..131: op=1 DELEGATE132+: gas + data[]LAYER 2: EIP-712 SAFE DIGEST -- keccak256(0x1901 || domainSeparator || safeTxStructHash)Prefix 0x1901domainSeparator (chainId + Safe addr)safeTxStructHash (to, val, H(data), op, nonce)LAYER 3: PECTRA EIP-7702 SET_CODE -- keccak256(0x05 || RLP([chain_id, delegate, nonce]))If chain_id == 0, signature replays across ALL EVM chains, writing 0xef0100 || delegate into EOA code slot.

1. ABI Selector Dispatch and Spoofed Inner Selectors

When an externally owned account (EOA) or smart account calls a Solidity contract, the first 4 bytes (bytes[0..3]) of msg.data represent the function selector: the leading 32 bits of keccak256("functionName(type1,type2,...)") with canonical ABI type names and zero whitespace. Static 256-bit value types (address, uint256, uint8, bool, bytes32) occupy fixed 32-byte big-endian words starting at byte offset 4. Dynamic types (bytes, string, bytes[]) store a 32-byte relative byte offset in the head section pointing to a 32-byte length prefix followed by right-padded payload words in the tail section.

Sophisticated threat actors exploit naive 4-byte decoders using selector masquerading. In the February 2025 Bybit attack (preset: bybit-safe-2025), Lazarus Group deployed an unverified contract (0x96221423681A6d52E184D440a8eFCEbB105C7242) that exposed a function matching the standard ERC-20 transfer(address,uint256) selector (0xa9059cbb). Superficial UI parsers saw 0xa9059cbb inside the inner data buffer and labeled the payload a routine transfer. However, because the outer Safe.execTransaction set operation = 1 (DELEGATECALL), invoking 0xa9059cbb on that malicious target did not move ERC-20 tokens; instead, its assembly body wrote a new attacker implementation address directly into slot 0 of Bybit's cold Safe proxy! Our offline auditor inspects both the outer operation byte and the inner data call recursively to flag this exact deception pattern.

2. High-Risk EVM Selector & Authorization Signature Matrix

The table below catalogs the primary function selectors, off-chain typed-data digests, and Pectra transaction prefixes audited by calldata-auditor.ts, alongside their byte-level invariants and historical exploit vectors.

Selector / PrefixCanonical Signature / EnvelopeCritical Byte ConditionStorage / Asset Blast RadiusPrimary Incident Archetype
0x6a761202execTransaction(address,uint256,bytes,uint8,...)Word 3 (offset 100..131) equals 1 (DELEGATECALL)Total vault proxy takeover via slot 0 (singleton) or owner list overwriteBybit $1.46B (Feb 2025), WazirX $230M (Jul 2024)
0x05 + RLP (0x04 Tx)EIP-7702 AuthorizationTuple(chain_id, address, nonce)chain_id === 0 (0x80 in RLP)Installs 0xef0100 || delegate on EOA across all EVM chains at once2025-2026 Pectra EOA Sweeper Campaigns
0x2b67b570Permit2.permit(address,PermitSingle,bytes)amount >= 2^120 (uint160.max) & multi-year expirationGasless sweeping of all tokens previously approved to canonical Permit2Inferno, Pink, and Angel Drainer-as-a-Service kits
0xd505accfERC2612.permit(owner,spender,value,deadline,v,r,s)value == uint256.max (0xff..ff)Victim signs off-chain EIP-712 message; attacker pays gas to drain balancePhishing airdrop claim portals & Ledger Connect Kit
0x095ea7b3ERC20.approve(address spender, uint256 amount)amount >= 2^128 to unverified contract or EOAPersistent transferFrom pull authority until explicitly revoked to 0Malicious DEX router & infinite-approval exploits
0xa22cb465setApprovalForAll(address operator, bool approved)approved == true (0x01 in Word 1)Unconditional transfer rights over every ERC-721 / ERC-1155 item in collectionNFT marketplace & Blur/Seaport operator phishing
0x3659cfe6 / 0x4f1ef286upgradeTo(address) / upgradeToAndCall(address,bytes)Unverified newImplementation addressRewrites EIP-1967 slot 0x360894...bbc, replacing entire protocol logicCompromised admin multisig proxy upgrades
0x23b872ddtransferFrom(address from, address to, uint256 amount)amount == 0 or counterfeit token eventInjects GPU-mined vanity lookalike address into victim wallet transaction logZero-value ERC-20 address poisoning

Deterministic Offline Verification of Safe v1.3.0 / v1.4.1 Hashes

Hardware wallets that lack full ERC-7730 clear-signing descriptors for nested contracts still display two unforgeable 32-byte values on their physical Secure Element screen when signing an EIP-712 SafeTx: the Domain Hash (domainSeparator) and the Message Hash (safeTxStructHash) (or combined safeTxHash). Because the host computer cannot alter what the hardware wallet computes from the raw EIP-712 struct without changing the resulting ECDSA signature (which the on-chain Safe.checkNSignatures contract would then reject!), offline hash reconstruction mathematically defeats web UI spoofing.

In Safe v1.3.0 and v1.4.1, the domain separator omits name, version, and salt, binding strictly to the 256-bit chainId and the 20-byte verifyingContract (left-padded to 32 bytes):

DOMAIN_SEPARATOR_TYPEHASH = keccak256("EIP712Domain(uint256 chainId,address verifyingContract)")
                          = 0x47e79534a245952e8b16893a336b85a3d9ea9fa8c573f3d803afb92a79469218

domainSeparator = keccak256(
  DOMAIN_SEPARATOR_TYPEHASH || uint256(chainId) || address_word(safeProxyAddress)
)

Next, the transaction struct hash commits to all ten Safe execution fields, hashing the dynamic data byte array first via keccak256(data):

SAFE_TX_TYPEHASH = keccak256(
  "SafeTx(address to,uint256 value,bytes data,uint8 operation,uint256 safeTxGas,uint256 baseGas,uint256 gasPrice,address gasToken,address refundReceiver,uint256 nonce)"
) = 0xbb8310d486368db6bd6f849402fdd73ad53d316b5a4b2644ad6efe0f941286d8

safeTxStructHash = keccak256(
  SAFE_TX_TYPEHASH || word(to) || word(value) || keccak256(data) || word(operation) ||
  word(safeTxGas) || word(baseGas) || word(gasPrice) || word(gasToken) || word(refundReceiver) || word(nonce)
)

safeTxHash = keccak256(0x1901 || domainSeparator || safeTxStructHash)

Step-by-Step Multisig Signer Ceremony Protocol

  1. Never Trust the Same Machine Twice: Open this page (/tools/calldata-signature-auditor) on a secondary machine (such as an air-gapped Linux laptop or a hardened GrapheneOS tablet in airplane mode after loading) distinct from the workstation connected to the Safe web interface.
  2. Enter Your Known-Good Parameters: Switch to Tab 2 (Offline Safe domainSeparator & safeTxHash) and type the intended recipient to, value, operation = 0, nonce, and safeAddress from your independent treasury runbook -- do not blindly copy-paste raw JSON from the browser window you are auditing.
  3. Compare Every Nibble Against the Hardware Screen: Trigger the signing prompt on your hardware signer (Trezor Safe 7, Keystone 3 Pro, Lattice1, or Ledger). Compare all 64 hexadecimal characters of domainSeparator and safeTxStructHash / safeTxHash against the deterministic output above. If the Safe web UI was compromised to inject operation = 1 (DELEGATECALL) or alter to, the safeTxHash displayed on your hardware screen will diverge completely across ~50% of its bits (avalanche effect).

Auditing Pectra EIP-7702 (0x04 / 0x05) SetCode Delegations

Activated in Ethereum's May 2025 Pectra hard fork, EIP-7702 introduced transaction type 0x04 (SET_CODE_TX_TYPE), allowing a standard externally owned account (EOA) to sign an authorization tuple that writes a 23-byte delegation designator (0xef0100 || 20-byte contract_address) directly into the EOA's account code field. Once delegated, any call to the EOA executes the target smart contract's bytecode with full authority over the EOA's native ETH balance and storage.

Unlike an ERC-20 approve transaction (which must be mined by the victim or scoped to a single token contract), an EIP-7702 authorization signature is computed over a compact RLP-encoded tuple prefixed by magic byte 0x05:

authorization_digest = keccak256(0x05 || rlp([chain_id, delegate_address, nonce]))

Wallet drainers rapidly weaponized two subtle properties of EIP-7702 (documented in detail in our EIP-7702 Sweeper Delegations Post-Mortem):

  • Omnichain Wildcard Replay (chain_id === 0): Under EIP-7702's specification, setting chain_id = 0 intentionally enables cross-chain smart-account deployment. When a phishing kit tricks a user into signing a 0x05 digest with chain_id = 0 (encoded in RLP as 0x80 empty byte string) when the user's nonce is 0, a relayer bot can broadcast that single signature across Ethereum Mainnet, Arbitrum, Base, Optimism, BNB Chain, and Polygon simultaneously, installing an automated sweeper contract on every chain.
  • Relayer-Sponsored Execution: Because the authorization_list inside a Type-0x04 transaction can be submitted by any third-party transaction sender (msg.sender pays gas while the victim EOA only signs the 0x05 tuple off-chain), even an EOA holding 0 ETH for gas can be pre-compromised so that future incoming deposits are swept within the same block via mempool bots.

ERC-7730 Clear-Signing Descriptors vs Raw ABI Decoding

To permanently close the blind-signing gap at the industry level, hardware wallet engineers and smart-contract auditors introduced ERC-7730, a standardized JSON metadata schema mapping raw ABI contract parameters and nested EIP-712 fields into human-readable display intents (tokenTicker, decimals, spenderLabel, slippageBounds) signed and verified before rendering on a Secure Element screen. However, ERC-7730 coverage remains incomplete across newly deployed DeFi routers, cross-chain bridges, custom institutional Safe guard modules, and unverified proxy implementations.

Whenever an unindexed contract is invoked -- or whenever an attacker deliberately deploys a fresh unverified contract to evade registry-based clear signing (precisely as Lazarus Group deployed 0x96221423681A6d52E184D440a8eFCEbB105C7242 minutes before the Bybit heist) -- hardware signers fall back to raw digest display or refuse to sign unless the operator flips the dangerous Blind Signing toggle. Combining hardware-enforced ERC-7730 clear signing for routine DeFi operations with deterministic offline Keccak-256 domainSeparator + safeTxHash reconstruction (via this air-gapped auditor or local Foundry cast calldata-decode / safe-tx-hashes scripts) provides defense-in-depth across two independent software stacks. Even if a zero-day vulnerability compromises your primary browser, CDN provider, or cloud transaction simulator (Tenderly), an attacker cannot forge a 256-bit Keccak preimage collision matching both your benign treasury parameters and a malicious operation = 1 DELEGATECALL payload.

Verifying Zero-Telemetry Execution (CSP: connect-src 'none')

Security tools that transmit pasted calldata, unpublished multisig nonces, or internal treasury addresses to remote APIs create severe operational security leaks: mempool searchers and threat actors monitor public decoder APIs to front-run pending governance upgrades or map institutional signers by IP address.

To make zero-telemetry guarantees cryptographically verifiable rather than trust-based, /tools/calldata-signature-auditor is served with a locked HTTP response header (Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self'; connect-src 'none'; form-action 'none'). You can verify this in under ten seconds:

  1. Open your browser's Developer Tools (F12 or Cmd+Opt+I) and inspect the Network tab response headers on the document request to confirm connect-src 'none'.
  2. Click all four forensic presets and compute arbitrary Safe hashes; observe zero outbound requests.
  3. Inspect calldata-auditor.ts in the Sources panel: the entire 24-round Keccak-f[1600] sponge permutation, RLP parser, and ABI word decoder are implemented in self-contained TypeScript with zero third-party npm network dependencies. To audit wallet-level RPC IP leakage and UTXO clustering heuristics next, proceed to our Wallet RPC & UTXO Boltzmann Exposure Auditor and Major Crypto Incidents Ledger.

Frequently Verified Technical Questions

Why is operation equal to 1 inside a Safe multisig transaction considered critical danger?

In Safe smart accounts, operation 0 executes a standard external CALL where the target contract modifies only its own storage, whereas operation 1 executes a DELEGATECALL. Under DELEGATECALL, untrusted target bytecode runs inside the Safe proxy storage context and can overwrite slot 0 to hijack ownership.

Primary Reference: Safe Smart Account Contract Specification

What makes an EIP-7702 authorization tuple with chain_id equal to 0 uniquely hazardous?

Under Ethereum Pectra EIP-7702, signing a magic 0x05 authorization tuple writes a delegation designator into an externally owned account code slot. Setting chain_id to 0 acts as an omnichain wildcard, allowing an attacker to replay that single signature across Ethereum, Arbitrum, Base, Optimism, and Polygon simultaneously.

Primary Reference: Ethereum Improvement Proposal EIP-7702

How does Ethereum Keccak-256 differ from the standardized NIST FIPS 202 SHA3-256 hash?

Both algorithms execute the identical 24-round Keccak-f 1600-bit sponge permutation with a 1088-bit rate and 512-bit capacity, but they differ in domain separation padding. Ethereum Keccak-256 appends delimiter byte 0x01 prior to the final 0x80 bit, whereas NIST FIPS 202 SHA3-256 appends delimiter byte 0x06.

Primary Reference: NIST FIPS 202 SHA-3 Standard

Can this calldata auditor verify transactions without querying Etherscan or an RPC node?

Yes. This page enforces a strict HTTP Content-Security-Policy with connect-src set to none, blocking every fetch, XMLHttpRequest, and WebSocket connection at the browser engine boundary. All selector lookups, RLP decoding, and 24-round Keccak-256 hash derivations run deterministically in local memory.

Primary Reference: W3C Content Security Policy Level 3

Cryptographic & Editorial Revision Ledger

Published: | Last Verified:

  • 2026-11-11: Initial V1 zero-telemetry release featuring pure-TypeScript Keccak-256, Safe v1.3.0/v1.4.1 hash verification, Permit2 decoding, and EIP-7702 chain_id=0 detection.