โ†
Previous Module
Security Best Practices Game

๐Ÿ”Ž Trace Execution: Step-by-Step Analysis

Master transaction tracing with Tenderly and Etherscan

Debug failed transactions and trace execution

๐Ÿ”ฌ Transaction Execution Trace

Traces reveal the complete execution path. A single transaction can trigger dozens of internal callsโ€”contract A calls contract B, which calls C, which emits events and updates state. When debugging, you need to see this entire call tree: which contracts were invoked, in what order, with what parameters, and where it failed. Etherscan shows internal transactions, but only high-level. Tenderly provides interactive traces with step-by-step debugger, state diffs, and gas profiling. Hardhat console.log lets you inject debug output into local traces. This section teaches you to read traces, identify the failing call in a chain, and understand cross-contract interactions.

๐ŸŽฎ Interactive: Execution Trace Walkthrough

Step through a Uniswap swap transaction. See each internal call, gas usage, parameters, and state changes.

Step 1 of 6

External Call

โœ“ Success

User calls swap function on Uniswap Router

Function
swap(tokenIn, tokenOut, amountIn)
Contract
UniswapRouter (0x7a25...)
Gas Used5,432
๐Ÿ“Š Details

Router receives 1000 DAI, prepares to swap for USDC via liquidity pool

๐Ÿ”ข Stack / Parameters
msg.sender: 0xUser
tokenIn: DAI
tokenOut: USDC
amountIn: 1000
1 / 6

๐Ÿ› ๏ธ Tracing Tools

Etherscan Internal Txs

Free, public, shows all contract calls in tree view

  • โ€ข View call hierarchy
  • โ€ข See value transfers
  • โ€ข Identify failing contract
  • โ€ข Limited detail (no opcodes)
Tenderly Debugger

Visual debugger with step-through, state diffs, gas profiling

  • โ€ข Step through opcodes
  • โ€ข See state changes
  • โ€ข Gas breakdown per line
  • โ€ข Requires account (free tier)
Hardhat console.log

Local debugging with Solidity console output

  • โ€ข Add console.log() in contracts
  • โ€ข Run tests locally
  • โ€ข See custom debug output
  • โ€ข Requires local setup
debug_traceTransaction

RPC method for full opcode-level trace

  • โ€ข Complete EVM trace
  • โ€ข Requires archive node
  • โ€ข Large data output
  • โ€ข For advanced debugging

๐Ÿ” Reading a Trace

1. Start at External Call

User calls contract A. This is the entry point. Check function signature, parameters, msg.sender.

2. Follow Internal Calls

Contract A calls B, B calls C. Each call has depth (indent level). Failed call shows red marker + revert reason.

3. Check State Changes

Look for storage writes, balance updates, event emissions. These show what changed before failure.

4. Identify Failure Point

Find deepest call that failed. Read revert reason. Trace back to understand why inputs were invalid.

๐Ÿ’ก Common Trace Patterns

  • โ€ข
    Reentrancy: See same contract called multiple times in trace (A โ†’ B โ†’ A). Check for state updates between calls.
  • โ€ข
    Out of Gas in Deep Call: Early calls succeed, deep call fails OOG. Indicates insufficient gas limit for complex operation.
  • โ€ข
    Failed transferFrom: Router calls token.transferFrom() โ†’ fails. Check allowance and balance before transferFrom.
  • โ€ข
    Uniswap K Check: Swap calls pair.swap() โ†’ K invariant check fails. Means insufficient liquidity or price manipulation.