BaseToolbox LogoBaseToolbox
Blog

© 2025 BaseToolbox. All rights reserved.

Privacy PolicyAboutContact Us

How to Decode EVM Calldata and Spot Token Approvals

Published on August 12, 2026

EVM calldata is the byte sequence supplied as transaction input. Its first four bytes usually identify a function signature; the remaining bytes encode arguments according to the Ethereum ABI. Decoding those bytes can reveal a spender, recipient, amount, approval flag, or nested tuple before a transaction is submitted.

Paste the input into the EVM Calldata and ABI Decoder with an ABI or known function signature. The tool runs locally, keeps unknown selectors unknown, and does not query a remote selector directory or RPC endpoint.

What the first four bytes mean

The Solidity ABI specification defines a function selector as the first four bytes of the Keccak-256 hash of the canonical function signature. For example, transfer(address,uint256) produces 0xa9059cbb.

Canonical signatures use the function name and parameter types without parameter names, spaces, data locations, or return types. A selector is only four bytes, so treat it as an identifier candidate rather than collision-proof evidence. The destination contract's actual code and proxy state determine what executes.

Starting at byte five, ABI arguments are encoded in 32-byte-aligned structures. Static values appear directly in the head. Dynamic strings, byte arrays, arrays, and some tuples use offsets to data stored later. A maintained ABI parser is safer than manually slicing hex because nested dynamic values are easy to misread.

Choose the correct decoding mode

Use a pasted ABI JSON when you have a trusted contract artifact or verified interface. The ABI provides function overloads, tuple components, and parameter names.

Use a function signature when you know the exact prototype but do not need a full ABI. The selector in the calldata must match that signature. If neither an ABI nor signature is available, record the selector and stop: the bytes are not self-describing.

Use raw ABI mode only for data that intentionally omits a function selector, such as separately encoded return values or tuple payloads. You must supply the Solidity types in the correct order.

Read ERC-20 approve precisely

The ERC-20 standard defines approve(address spender,uint256 value). When decoded calldata matches approve(address,uint256), inspect both arguments:

  • spender is the address receiving allowance.
  • The integer amount is the allowance value in the token's smallest unit.

If amount equals 2^256 - 1, the decoder can state that it is the maximum uint256 value. Many interfaces describe this as an unlimited approval, but actual behavior still belongs to the token contract. Convert raw units with the Ethereum Unit Converter only after independently confirming the token decimals.

An amount below the maximum can still be large. Compare the exact decimal value with your intended operation rather than relying on a label.

Understand setApprovalForAll

ERC-721 defines setApprovalForAll(address operator,bool approved). A decoded true means the call asks the token contract to enable that operator for all assets owned by the caller within that contract. It is not a single-token approval.

Check the operator address using the Crypto Address Validator for syntax and checksum state. A valid address form does not establish ownership or trust. A decoded false requests that the approval be disabled, subject to actual contract execution.

Distinguish Permit2 calls

Uniswap Permit2 has reviewed interfaces for expiring allowances and signature-based transfers. Locally recognizing a Permit2 selector is useful context, but a four-byte match does not prove the destination is the canonical deployment or that a call will succeed.

Permit2 calldata may contain nested token, spender, amount, expiration, nonce, transfer-detail, owner, and signature values. Expand every tuple and array. If the flow also includes EIP-712 JSON, inspect it separately with the EIP-712 Inspector; the signed message and submitted calldata are different artifacts.

Do not overlook addresses and transaction value

A zero address in a recipient or spender field is a deterministic fact worth highlighting. Its effect varies by contract: it may revert, burn, clear a value, or have application-specific meaning.

Also check the transaction's native-currency value. Non-zero value means the call is accompanied by Wei in addition to calldata. The ABI arguments alone do not include that transaction field.

Decoding is not simulation

A successful parse proves only that the bytes fit the supplied ABI or signature. It does not verify the destination bytecode, resolve a proxy implementation, inspect balances or allowances, predict reverts, model internal calls, or show the final state.

Before acting, compare the decoded recipient, spender, amounts, flags, and transaction value with your intended action. Then verify the destination contract and chain through an independent official source. Keep unknown context explicitly unknown.

Primary references

  • Solidity contract ABI specification
  • ERC-20 token standard
  • ERC-721 non-fungible token standard
  • Uniswap Permit2 repository and interfaces

Ready to try it yourself?

Put what you have learned into practice with our free online tool.

Decode EVM Calldata Locally