P13: Layer 2 Optimistic Rollup (Simplified)

P13: Layer 2 Optimistic Rollup (Simplified)

Project Overview

Attribute Value
Main Language Rust + Solidity
Alternative Languages Go + Solidity
Difficulty Master
Coolness Level Level 5: Pure Magic (Super Cool)
Business Potential Industry Disruptor (L2 Infrastructure)
Knowledge Area Scaling / Layer 2
Main Book โ€œMastering Ethereumโ€ by Andreas M. Antonopoulos & Gavin Wood

Learning Objectives

By completing this project, you will:

  1. Master the fundamental Layer 2 tradeoff understanding how rollups achieve 10-100x throughput improvement while inheriting Layer 1 security through cryptographic proofs and economic incentives
  2. Implement off-chain execution with on-chain data availability learning why posting transaction data to L1 is essential for trustless fraud proofs even when computation happens elsewhere
  3. Build a fraud proof mechanism understanding the game theory of challenge periods, sequencer bonds, and the 1-of-N honest verifier assumption
  4. Design cross-layer bridges implementing secure deposit/withdrawal flows between L1 and L2 with proper finality guarantees
  5. Understand sequencer architecture including transaction ordering, batching strategies, state commitment, and the tradeoffs between centralization and performance
  6. Implement state root commitment schemes using Merkle trees to cryptographically commit to L2 state while enabling efficient proofs
  7. Apply economic security models designing incentive-compatible systems where honest behavior is economically rational

The Core Question Youโ€™re Answering

โ€œHow can we scale blockchain throughput 10-100x while still inheriting Layer 1 security guarantees?โ€

This question is at the heart of blockchainโ€™s scaling trilemma (security, decentralization, scalability). Optimistic rollups solve it by:

  • Moving computation off-chain (scalability)
  • Keeping data on-chain (decentralization through data availability)
  • Using fraud proofs (security through economic incentives)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     THE LAYER 2 SCALING PARADIGM                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   Layer 1 (Ethereum)              Layer 2 (Rollup)                          โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”‚
โ”‚   โ”‚                     โ”‚        โ”‚                     โ”‚                    โ”‚
โ”‚   โ”‚   โ€ข Final authority โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค โ€ข Fast execution    โ”‚                    โ”‚
โ”‚   โ”‚   โ€ข Data storage    โ”‚  Data  โ”‚ โ€ข Cheap transactionsโ”‚                    โ”‚
โ”‚   โ”‚   โ€ข Fraud proofs    โ”‚  +     โ”‚ โ€ข Batched commits   โ”‚                    โ”‚
โ”‚   โ”‚   โ€ข Settlement      โ”‚  Roots โ”‚ โ€ข State management  โ”‚                    โ”‚
โ”‚   โ”‚                     โ”‚        โ”‚                     โ”‚                    โ”‚
โ”‚   โ”‚   15-30 TPS         โ”‚        โ”‚   230-4000+ TPS     โ”‚                    โ”‚
โ”‚   โ”‚   $5-50 per tx      โ”‚        โ”‚   $0.01-0.10 per tx โ”‚                    โ”‚
โ”‚   โ”‚                     โ”‚        โ”‚                     โ”‚                    โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ”‚
โ”‚              โ–ฒ                              โ”‚                                โ”‚
โ”‚              โ”‚         Challenge Period    โ”‚                                โ”‚
โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                โ”‚
โ”‚                        (7 days)                                              โ”‚
โ”‚                                                                              โ”‚
โ”‚   Security Model:                                                            โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ "Optimistic": Assume all state roots are valid UNLESS proven false  โ”‚   โ”‚
โ”‚   โ”‚ "Fraud Proof": Anyone can challenge invalid state with on-chain tx  โ”‚   โ”‚
โ”‚   โ”‚ "1-of-N": Only ONE honest verifier needed for security guarantee    โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Before building, deeply understand: Why do we need a 7-day challenge period? What happens if we make it shorter? Why canโ€™t we just trust the sequencer? How does posting transaction data to L1 enable trustless fraud proofs? These arenโ€™t implementation detailsโ€“theyโ€™re the core security model.


Deep Theoretical Foundation

Why Layer 2?

Ethereum mainnet has fundamental constraints:

  • Block gas limit: ~30 million gas per block
  • Block time: 12 seconds
  • Result: ~15-30 transactions per second globally

For context, Visa processes ~24,000 TPS at peak. Ethereum canโ€™t scale by simply increasing block size (centralization risk). Layer 2 solutions process transactions off the main chain while inheriting its security.

The Rollup Taxonomy

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                         LAYER 2 SCALING SOLUTIONS                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                        ROLLUPS (This Project)                        โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Execute off-chain, post data on-chain                            โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Inherit L1 security                                               โ”‚    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚   OPTIMISTIC ROLLUPS    โ”‚  โ”‚     ZK-ROLLUPS          โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚                         โ”‚  โ”‚                          โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข Fraud proofs         โ”‚  โ”‚  โ€ข Validity proofs       โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข 7-day challenge      โ”‚  โ”‚  โ€ข Instant finality      โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข Simpler tech         โ”‚  โ”‚  โ€ข Complex cryptography  โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข EVM compatible       โ”‚  โ”‚  โ€ข Harder EVM compat     โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚                         โ”‚  โ”‚                          โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  Examples:              โ”‚  โ”‚  Examples:               โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข Arbitrum             โ”‚  โ”‚  โ€ข zkSync Era            โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข Optimism             โ”‚  โ”‚  โ€ข Scroll                โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ”‚  โ€ข Base                 โ”‚  โ”‚  โ€ข Starknet              โ”‚           โ”‚    โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                        OTHER L2 APPROACHES                           โ”‚    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ”‚  SIDECHAINS             PLASMA                STATE CHANNELS          โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Separate security    โ€ข Exit games          โ€ข Two-party direct     โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Own consensus        โ€ข Data on-chain       โ€ข Instant finality     โ”‚    โ”‚
โ”‚  โ”‚  โ€ข Not true L2          โ€ข Complex exits       โ€ข Limited use cases    โ”‚    โ”‚
โ”‚  โ”‚  (Polygon PoS)          (Deprecated)          (Lightning Network)    โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Optimistic Rollups: How They Work

The core idea is brilliantly simple:

  1. Execute transactions off-chain on the L2 sequencer
  2. Post transaction data to L1 for data availability
  3. Post state root to L1 as a commitment to the new state
  4. Assume valid unless someone proves otherwise (optimistic)
  5. Challenge window allows fraud proof submission (7 days)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    OPTIMISTIC ROLLUP ARCHITECTURE                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  LAYER 1 (ETHEREUM MAINNET)                                                  โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                                                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                        ROLLUP BRIDGE CONTRACT                        โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚   deposits[]          stateRoots[]         withdrawals[]             โ”‚   โ”‚
โ”‚   โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”              โ”‚   โ”‚
โ”‚   โ”‚   โ”‚ user     โ”‚        โ”‚ batch 1  โ”‚         โ”‚ pending  โ”‚              โ”‚   โ”‚
โ”‚   โ”‚   โ”‚ amount   โ”‚        โ”‚ root     โ”‚         โ”‚ proofs   โ”‚              โ”‚   โ”‚
โ”‚   โ”‚   โ”‚ block    โ”‚        โ”‚ timestampโ”‚         โ”‚ finality โ”‚              โ”‚   โ”‚
โ”‚   โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚ challengedโ”‚        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜              โ”‚   โ”‚
โ”‚   โ”‚                       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                                    โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚   Functions:                                                          โ”‚   โ”‚
โ”‚   โ”‚   โ€ข deposit()         โ†’ Emit DepositEvent for L2                     โ”‚   โ”‚
โ”‚   โ”‚   โ€ข submitBatch()     โ†’ Store state root, start challenge period     โ”‚   โ”‚
โ”‚   โ”‚   โ€ข challengeBatch()  โ†’ Verify fraud proof, slash sequencer          โ”‚   โ”‚
โ”‚   โ”‚   โ€ข finalizeWithdraw()โ†’ Transfer after challenge period              โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                              โ–ฒ                                               โ”‚
โ”‚                              โ”‚ Batch Submissions                             โ”‚
โ”‚                              โ”‚ (state root + calldata)                       โ”‚
โ”‚   โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ”‚โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•   โ”‚
โ”‚                              โ”‚                                               โ”‚
โ”‚  LAYER 2 (OFF-CHAIN)         โ”‚                                               โ”‚
โ”‚                              โ”‚                                               โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                   SEQUENCER NODE                                     โ”‚   โ”‚
โ”‚   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚   MEMPOOL     โ”‚โ”€โ”€โ”€โ–บโ”‚   EXECUTOR    โ”‚โ”€โ”€โ”€โ–บโ”‚  STATE TREE   โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚               โ”‚    โ”‚               โ”‚    โ”‚               โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  pending txs  โ”‚    โ”‚  apply txs    โ”‚    โ”‚  Merkle trie  โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  ordering     โ”‚    โ”‚  compute new  โ”‚    โ”‚  state root   โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  validation   โ”‚    โ”‚  state        โ”‚    โ”‚  proofs       โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚   โ”‚
โ”‚   โ”‚          โ–ฒ                                          โ”‚                โ”‚   โ”‚
โ”‚   โ”‚          โ”‚                                          โ–ผ                โ”‚   โ”‚
โ”‚   โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  L1 WATCHER   โ”‚    โ”‚   BATCHER     โ”‚    โ”‚   RPC API     โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚               โ”‚    โ”‚               โ”‚    โ”‚               โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  deposits     โ”‚    โ”‚  batch txs    โ”‚    โ”‚  eth_* calls  โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  L1 finality  โ”‚    โ”‚  compress     โ”‚    โ”‚  l2 queries   โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ”‚  reorgs       โ”‚    โ”‚  submit to L1 โ”‚    โ”‚  user access  โ”‚       โ”‚   โ”‚
โ”‚   โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                    VERIFIER / CHALLENGER                             โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚   โ€ข Independently executes all L2 transactions                       โ”‚   โ”‚
โ”‚   โ”‚   โ€ข Compares computed state root to posted state root                โ”‚   โ”‚
โ”‚   โ”‚   โ€ข If mismatch detected โ†’ submits fraud proof to L1                 โ”‚   โ”‚
โ”‚   โ”‚   โ€ข Receives reward if fraud proven, sequencer slashed               โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Data Availability: The Critical Insight

Why must transaction data be posted to L1, even though execution happens on L2?

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     THE DATA AVAILABILITY PROBLEM                            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  SCENARIO: Malicious sequencer posts INVALID state root                     โ”‚
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ”‚  State Before: Alice=100 ETH, Bob=50 ETH                             โ”‚    โ”‚
โ”‚  โ”‚  Transaction: Alice sends 10 ETH to Bob                               โ”‚    โ”‚
โ”‚  โ”‚  Correct State: Alice=90 ETH, Bob=60 ETH, Root=0xAAA                  โ”‚    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ”‚  FRAUD: Sequencer posts Root=0xBBB where Bob=1000 ETH                โ”‚    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ”‚  CASE 1: Transaction data ON L1 (Rollup)                                    โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                    โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  Challenger can:                                                       โ”‚    โ”‚
โ”‚  โ”‚  1. Read transaction data from L1 calldata                            โ”‚    โ”‚
โ”‚  โ”‚  2. Re-execute: "Alice sends 10 to Bob"                               โ”‚    โ”‚
โ”‚  โ”‚  3. Compute correct root: 0xAAA                                       โ”‚    โ”‚
โ”‚  โ”‚  4. Prove 0xAAA != 0xBBB โ†’ FRAUD PROVEN                              โ”‚    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ”‚  Result: Sequencer SLASHED, state REVERTED                           โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ”‚  CASE 2: Transaction data OFF L1 (Validium/External DA)                     โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                   โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”‚
โ”‚  โ”‚  If sequencer withholds data:                                         โ”‚    โ”‚
โ”‚  โ”‚  1. Challenger cannot access transaction data                         โ”‚    โ”‚
โ”‚  โ”‚  2. Cannot re-execute transactions                                    โ”‚    โ”‚
โ”‚  โ”‚  3. Cannot prove fraud even if fraud exists                          โ”‚    โ”‚
โ”‚  โ”‚                                                                       โ”‚    โ”‚
โ”‚  โ”‚  Result: FRAUD SUCCEEDS, users lose funds                            โ”‚    โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ”‚
โ”‚                                                                              โ”‚
โ”‚  CONCLUSION: Data availability on L1 is NON-NEGOTIABLE for security         โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Fraud Proof Mechanics

Fraud proofs are the security backbone of optimistic rollups. There are two main approaches:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        FRAUD PROOF APPROACHES                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  NON-INTERACTIVE (Single-Round) โ”‚  โ”‚  INTERACTIVE (Multi-Round)      โ”‚   โ”‚
โ”‚  โ”‚  (Optimism style)               โ”‚  โ”‚  (Arbitrum style)               โ”‚   โ”‚
โ”‚  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค  โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค   โ”‚
โ”‚  โ”‚                                  โ”‚  โ”‚                                  โ”‚   โ”‚
โ”‚  โ”‚  Re-execute entire batch         โ”‚  โ”‚  Binary search for bad step     โ”‚   โ”‚
โ”‚  โ”‚  on L1 in ONE transaction        โ”‚  โ”‚  through challenge game         โ”‚   โ”‚
โ”‚  โ”‚                                  โ”‚  โ”‚                                  โ”‚   โ”‚
โ”‚  โ”‚  Pros:                           โ”‚  โ”‚  Pros:                          โ”‚   โ”‚
โ”‚  โ”‚  โ€ข Simple implementation         โ”‚  โ”‚  โ€ข Gas efficient                โ”‚   โ”‚
โ”‚  โ”‚  โ€ข Fast dispute resolution       โ”‚  โ”‚  โ€ข Can handle large batches     โ”‚   โ”‚
โ”‚  โ”‚                                  โ”‚  โ”‚  โ€ข More flexible                โ”‚   โ”‚
โ”‚  โ”‚  Cons:                           โ”‚  โ”‚                                  โ”‚   โ”‚
โ”‚  โ”‚  โ€ข Gas limited by L1 block       โ”‚  โ”‚  Cons:                          โ”‚   โ”‚
โ”‚  โ”‚  โ€ข Limits batch size             โ”‚  โ”‚  โ€ข Complex implementation       โ”‚   โ”‚
โ”‚  โ”‚  โ€ข More expensive                โ”‚  โ”‚  โ€ข Longer dispute time          โ”‚   โ”‚
โ”‚  โ”‚                                  โ”‚  โ”‚  โ€ข Multiple rounds needed       โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ”‚  This project: We implement SIMPLIFIED non-interactive fraud proofs         โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Interactive Fraud Proof (Arbitrum-style) Flow:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              INTERACTIVE FRAUD PROOF BINARY SEARCH                           โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   Batch: 1000 transactions                                                   โ”‚
โ”‚   Sequencer claims: Stateโ‚€ โ†’ Stateโ‚โ‚€โ‚€โ‚€                                       โ”‚
โ”‚   Challenger says: Stateโ‚โ‚€โ‚€โ‚€ is wrong!                                       โ”‚
โ”‚                                                                              โ”‚
โ”‚   Round 1: Where did state diverge?                                          โ”‚
โ”‚   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚   Sequencer:  Stateโ‚…โ‚€โ‚€ = 0xABC                                               โ”‚
โ”‚   Challenger: I agree Stateโ‚…โ‚€โ‚€ = 0xABC โœ“                                     โ”‚
โ”‚   โ†’ Fraud is in txs 501-1000                                                 โ”‚
โ”‚                                                                              โ”‚
โ”‚   Round 2:                                                                   โ”‚
โ”‚   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚   Sequencer:  Stateโ‚‡โ‚…โ‚€ = 0xDEF                                               โ”‚
โ”‚   Challenger: I disagree! Stateโ‚‡โ‚…โ‚€ = 0xGHI โœ—                                 โ”‚
โ”‚   โ†’ Fraud is in txs 501-750                                                  โ”‚
โ”‚                                                                              โ”‚
โ”‚   ... continue binary search ...                                             โ”‚
โ”‚                                                                              โ”‚
โ”‚   Final Round: Single instruction dispute                                    โ”‚
โ”‚   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚   Isolated: tx 623 execution                                                 โ”‚
โ”‚   Re-execute ON L1: just this one instruction                                โ”‚
โ”‚   Compute correct state                                                      โ”‚
โ”‚   Compare with sequencer's claim                                             โ”‚
โ”‚   โ†’ FRAUD PROVEN at tx 623                                                   โ”‚
โ”‚                                                                              โ”‚
โ”‚   Gas cost: O(log n) instead of O(n)                                         โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Challenge Period: Game Theory

Why 7 days? This is a carefully chosen duration:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    CHALLENGE PERIOD GAME THEORY                              โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   7 DAYS BALANCES:                                                           โ”‚
โ”‚                                                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”               โ”‚
โ”‚   โ”‚   TOO SHORT (1 hour)    โ”‚     โ”‚   TOO LONG (30 days)    โ”‚               โ”‚
โ”‚   โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค     โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค               โ”‚
โ”‚   โ”‚                          โ”‚     โ”‚                          โ”‚               โ”‚
โ”‚   โ”‚ โ€ข Verifiers may miss    โ”‚     โ”‚ โ€ข Terrible UX            โ”‚               โ”‚
โ”‚   โ”‚   fraud during outage   โ”‚     โ”‚ โ€ข Capital locked too     โ”‚               โ”‚
โ”‚   โ”‚ โ€ข Network attacks can   โ”‚     โ”‚   long                   โ”‚               โ”‚
โ”‚   โ”‚   delay challenges      โ”‚     โ”‚ โ€ข Users won't use L2     โ”‚               โ”‚
โ”‚   โ”‚ โ€ข Insufficient review   โ”‚     โ”‚ โ€ข Economic inefficiency  โ”‚               โ”‚
โ”‚   โ”‚   time                  โ”‚     โ”‚                          โ”‚               โ”‚
โ”‚   โ”‚                          โ”‚     โ”‚                          โ”‚               โ”‚
โ”‚   โ”‚ RISK: Fraud succeeds   โ”‚     โ”‚ RISK: User abandonment  โ”‚               โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜               โ”‚
โ”‚                                                                              โ”‚
โ”‚   7 DAYS PROVIDES:                                                           โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ โ€ข Enough time for verifiers to detect fraud (even with downtime)    โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Weekend coverage (fraud detected regardless of day submitted)     โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Time to coordinate response to attacks                            โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Acceptable UX tradeoff for security                               โ”‚   โ”‚
โ”‚   โ”‚ โ€ข Matches typical audit/review cycles                                โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ”‚   FAST WITHDRAWALS (Workaround):                                             โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚ Third-party liquidity providers offer instant withdrawals           โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚ User: "I want my 10 ETH now, not in 7 days"                          โ”‚   โ”‚
โ”‚   โ”‚ LP: "I'll give you 9.95 ETH now, claim your 10 ETH in 7 days"        โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚ LP takes risk of fraud (unlikely) for 0.5% fee                       โ”‚   โ”‚
โ”‚   โ”‚ User gets instant liquidity                                          โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The 1-of-N Security Model

Optimistic rollups have a powerful security property:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        1-OF-N HONEST VERIFIER                                โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                              โ”‚
โ”‚   Traditional systems: Need majority honest (N/2 of N)                       โ”‚
โ”‚   Optimistic rollups:  Need ONLY ONE honest verifier (1 of N)                โ”‚
โ”‚                                                                              โ”‚
โ”‚   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ”‚   Verifiers: โ•ณ โ•ณ โ•ณ โ•ณ โ•ณ โ•ณ โ•ณ โ•ณ โ•ณ โœ“ โ•ณ โ•ณ โ•ณ โ•ณ โ•ณ                          โ”‚   โ”‚
โ”‚   โ”‚                                 โ–ฒ                                     โ”‚   โ”‚
โ”‚   โ”‚                                 โ”‚                                     โ”‚   โ”‚
โ”‚   โ”‚                          ONE honest verifier                          โ”‚   โ”‚
โ”‚   โ”‚                          is sufficient!                               โ”‚   โ”‚
โ”‚   โ”‚                                                                       โ”‚   โ”‚
โ”‚   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                              โ”‚
โ”‚   WHY THIS WORKS:                                                            โ”‚
โ”‚   1. Fraud proof is publicly verifiable on L1                               โ”‚
โ”‚   2. Anyone can submit it (permissionless)                                   โ”‚
โ”‚   3. If fraud exists, ONE honest party can prove it                         โ”‚
โ”‚   4. L1 contract executes regardless of who submitted                       โ”‚
โ”‚                                                                              โ”‚
โ”‚   WHO RUNS VERIFIERS?                                                        โ”‚
โ”‚   โ€ข Rollup team (self-preservation)                                          โ”‚
โ”‚   โ€ข Major L2 users (protecting their funds)                                 โ”‚
โ”‚   โ€ข MEV searchers (profitable fraud detection)                               โ”‚
โ”‚   โ€ข Altruistic community members                                             โ”‚
โ”‚   โ€ข Cross-chain bridges (protecting locked assets)                          โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Concepts You Must Understand First

Stop and research these before coding:

1. Data Availability vs. Execution

  • Whatโ€™s the difference between โ€œwhere data is storedโ€ and โ€œwhere computation happensโ€?
  • Why must transaction data be posted to L1, even though execution is on L2?
  • What is the โ€œdata availability problemโ€ and how do rollups solve it?
DATA AVAILABILITY LAYER          EXECUTION LAYER
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                       โ”‚       โ”‚                       โ”‚
โ”‚  WHERE: Ethereum L1   โ”‚       โ”‚  WHERE: L2 Sequencer  โ”‚
โ”‚                       โ”‚       โ”‚                       โ”‚
โ”‚  WHAT: Raw tx data    โ”‚       โ”‚  WHAT: State machine  โ”‚
โ”‚        (calldata)     โ”‚       โ”‚        (EVM/custom)   โ”‚
โ”‚                       โ”‚       โ”‚                       โ”‚
โ”‚  WHY: Anyone can      โ”‚       โ”‚  WHY: Fast, cheap     โ”‚
โ”‚       re-execute      โ”‚       โ”‚       computation     โ”‚
โ”‚       and verify      โ”‚       โ”‚                       โ”‚
โ”‚                       โ”‚       โ”‚                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜       โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โ”‚                               โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                        โ”‚
                   BOTH NEEDED
                   FOR SECURITY

Book Reference: โ€œMastering Ethereumโ€ Ch. 13 - Antonopoulos & Wood Web Reference: Optimistic Rollups on ethereum.org

2. State Roots and Merkle Proofs

  • How does a state root cryptographically commit to all account balances?
  • How can you prove an accountโ€™s balance without revealing all accounts?
  • Why is the state root the โ€œsource of truthโ€ for L2 state?
                        STATE ROOT
                       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
                       โ”‚ 0xABC   โ”‚
                       โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
                            โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ”‚                           โ”‚
         โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”                 โ”Œโ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”
         โ”‚ 0xDEF   โ”‚                 โ”‚ 0xGHI   โ”‚
         โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜                 โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
              โ”‚                           โ”‚
       โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”             โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”
       โ”‚             โ”‚             โ”‚             โ”‚
   โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”
   โ”‚Alice: โ”‚     โ”‚ Bob:  โ”‚     โ”‚Carol: โ”‚     โ”‚ Dave: โ”‚
   โ”‚100 ETHโ”‚     โ”‚50 ETH โ”‚     โ”‚75 ETH โ”‚     โ”‚25 ETH โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

   MERKLE PROOF for Bob's balance (50 ETH):
   [0xDEF, 0xGHI, Hash(Alice)] โ†’ verifies against root 0xABC

Book Reference: โ€œMastering Bitcoinโ€ Ch. 9 (Merkle Trees) - Antonopoulos Project Reference: You should have built Project 3 (Merkle Tree Library)

3. Fraud Proofs vs. Validity Proofs

  • Whatโ€™s the difference between โ€œoptimisticโ€ (fraud proofs) and โ€œzero-knowledgeโ€ (validity proofs)?
  • Why is it called โ€œoptimisticโ€? (Hint: assume valid unless proven otherwise)
  • How does a fraud proof work without re-executing all transactions?
OPTIMISTIC ROLLUP                    ZK-ROLLUP
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                        โ”‚          โ”‚                        โ”‚
โ”‚  1. Execute on L2      โ”‚          โ”‚  1. Execute on L2      โ”‚
โ”‚  2. Post state root    โ”‚          โ”‚  2. Generate ZK proof  โ”‚
โ”‚  3. Wait 7 days        โ”‚          โ”‚  3. Post root + proof  โ”‚
โ”‚  4. If no challenge    โ”‚          โ”‚  4. L1 verifies proof  โ”‚
โ”‚     โ†’ finalized        โ”‚          โ”‚     โ†’ instant finality โ”‚
โ”‚                        โ”‚          โ”‚                        โ”‚
โ”‚  Security: Game theory โ”‚          โ”‚  Security: Math        โ”‚
โ”‚  Assumption: 1 honest  โ”‚          โ”‚  Assumption: None      โ”‚
โ”‚                        โ”‚          โ”‚                        โ”‚
โ”‚  Cost: Cheaper compute โ”‚          โ”‚  Cost: Expensive proof โ”‚
โ”‚  Time: 7 day withdraw  โ”‚          โ”‚  Time: Instant withdrawโ”‚
โ”‚                        โ”‚          โ”‚                        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜          โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Web Reference: Arbitrum vs Optimism fraud proofs

4. Challenge Period Game Theory

  • Why 7 days? Why not 7 minutes or 7 months?
  • What economic incentives keep sequencers honest?
  • What happens if no one monitors for fraud?
  • How much should the sequencer bond be?
SEQUENCER INCENTIVES:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                                              โ”‚
โ”‚  Honest Behavior:                                                            โ”‚
โ”‚  โ€ข Earn transaction fees: $100,000/day                                       โ”‚
โ”‚  โ€ข Keep reputation                                                           โ”‚
โ”‚  โ€ข Keep bond: 1000 ETH                                                       โ”‚
โ”‚  โ€ข Sustainable business                                                      โ”‚
โ”‚                                                                              โ”‚
โ”‚  Fraudulent Behavior:                                                        โ”‚
โ”‚  โ€ข Potential theft: $1,000,000                                               โ”‚
โ”‚  โ€ข MINUS probability of detection: ~99.99% (1 honest verifier)               โ”‚
โ”‚  โ€ข MINUS bond slashing: 1000 ETH ($3,000,000)                               โ”‚
โ”‚  โ€ข MINUS legal consequences                                                  โ”‚
โ”‚  โ€ข MINUS reputation destruction                                              โ”‚
โ”‚                                                                              โ”‚
โ”‚  Expected Value of Fraud = $1M ร— 0.01% - $3M = -$2,999,900                  โ”‚
โ”‚  โ†’ FRAUD IS ECONOMICALLY IRRATIONAL                                         โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Book Reference: โ€œDesigning Data-Intensive Applicationsโ€ Ch. 9 (Consistency) - Kleppmann

5. Sequencer Centralization Tradeoff

  • Why do most rollups use a single sequencer?
  • What are the risks of a centralized sequencer?
  • How can you make sequencer selection decentralized?
CENTRALIZATION SPECTRUM:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                                              โ”‚
โ”‚  FULLY CENTRALIZED          HYBRID                    FULLY DECENTRALIZED   โ”‚
โ”‚  (Single Sequencer)         (Rotating)                (Shared Sequencing)   โ”‚
โ”‚        โ”‚                       โ”‚                              โ”‚              โ”‚
โ”‚        โ–ผ                       โ–ผ                              โ–ผ              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”           โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                 โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”        โ”‚
โ”‚  โ”‚โ€ข Fast     โ”‚           โ”‚โ€ข Moderate โ”‚                 โ”‚โ€ข Slow     โ”‚        โ”‚
โ”‚  โ”‚โ€ข Cheap    โ”‚           โ”‚โ€ข Resilientโ”‚                 โ”‚โ€ข Expensiveโ”‚        โ”‚
โ”‚  โ”‚โ€ข Censorable           โ”‚โ€ข Partiallyโ”‚                 โ”‚โ€ข Censorshipโ”‚       โ”‚
โ”‚  โ”‚โ€ข Single    โ”‚          โ”‚  censorship                โ”‚  resistant โ”‚        โ”‚
โ”‚  โ”‚  point of  โ”‚          โ”‚  resistantโ”‚                 โ”‚โ€ข Complex  โ”‚        โ”‚
โ”‚  โ”‚  failure   โ”‚          โ”‚           โ”‚                 โ”‚           โ”‚        โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                 โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜        โ”‚
โ”‚                                                                              โ”‚
โ”‚  Current state: Most L2s use centralized sequencer with "training wheels"   โ”‚
โ”‚  Roadmap: All major L2s plan decentralized sequencing                       โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Web Reference: L2Beat Risks Dashboard

6. Cross-Layer Messaging (L1 <-> L2)

  • How do deposits from L1 reach L2?
  • How do withdrawals from L2 reach L1?
  • Why can deposits be fast but withdrawals must wait 7 days?
DEPOSIT FLOW (L1 โ†’ L2): FAST
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                                              โ”‚
โ”‚   User                 L1 Bridge              Sequencer            L2       โ”‚
โ”‚    โ”‚                      โ”‚                      โ”‚                  โ”‚       โ”‚
โ”‚    โ”‚โ”€โ”€โ”€ deposit() โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚                      โ”‚                  โ”‚       โ”‚
โ”‚    โ”‚                      โ”‚โ”€โ”€โ”€ DepositEvent โ”€โ”€โ”€โ”€โ–บโ”‚                  โ”‚       โ”‚
โ”‚    โ”‚                      โ”‚                      โ”‚โ”€โ”€โ”€ credit() โ”€โ”€โ”€โ”€โ–บโ”‚       โ”‚
โ”‚    โ”‚                      โ”‚                      โ”‚                  โ”‚       โ”‚
โ”‚    โ”‚                      โ”‚    (10 L1 blocks)    โ”‚                  โ”‚       โ”‚
โ”‚    โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€ L2 funds โ”€โ”€โ”€โ”€โ”‚       โ”‚
โ”‚                                                                              โ”‚
โ”‚   Time: ~2-12 minutes (wait for L1 finality)                                 โ”‚
โ”‚   Why fast: L1 deposit is final, L2 just mirrors it                         โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

WITHDRAWAL FLOW (L2 โ†’ L1): SLOW
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                                              โ”‚
โ”‚   User      L2 Bridge     Sequencer       L1 Bridge      Challenger         โ”‚
โ”‚    โ”‚            โ”‚             โ”‚               โ”‚               โ”‚             โ”‚
โ”‚    โ”‚โ”€withdraw()โ”€โ–บโ”‚             โ”‚               โ”‚               โ”‚             โ”‚
โ”‚    โ”‚            โ”‚โ”€โ”€โ”€ burn โ”€โ”€โ”€โ”€โ–บโ”‚               โ”‚               โ”‚             โ”‚
โ”‚    โ”‚            โ”‚             โ”‚โ”€โ”€โ”€ batch โ”€โ”€โ”€โ”€โ”€โ–บโ”‚               โ”‚             โ”‚
โ”‚    โ”‚            โ”‚             โ”‚               โ”‚               โ”‚             โ”‚
โ”‚    โ”‚            โ”‚             โ”‚     7 DAYS CHALLENGE PERIOD   โ”‚             โ”‚
โ”‚    โ”‚            โ”‚             โ”‚               โ”‚โ—„โ”€โ”€ verify โ”€โ”€โ”€โ”€โ”‚             โ”‚
โ”‚    โ”‚            โ”‚             โ”‚               โ”‚ (no challenge) โ”‚             โ”‚
โ”‚    โ”‚            โ”‚             โ”‚               โ”‚               โ”‚             โ”‚
โ”‚    โ”‚โ”€finalize()โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–บโ”‚               โ”‚             โ”‚
โ”‚    โ”‚โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€ L1 funds โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”‚               โ”‚             โ”‚
โ”‚                                                                              โ”‚
โ”‚   Time: 7 days + finality time                                               โ”‚
โ”‚   Why slow: Must wait to ensure no fraud in the batch                        โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Web Reference: Optimism Bridge Architecture

7. EIP-4844 and Blob Transactions

  • What are โ€œblobsโ€ and why do they reduce rollup costs?
  • How did EIP-4844 (March 2024) change rollup economics?
  • Whatโ€™s the difference between calldata and blob data?
BEFORE EIP-4844:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Transaction data stored in CALLDATA                                        โ”‚
โ”‚   โ€ข 16 gas per non-zero byte                                                 โ”‚
โ”‚   โ€ข Data stored FOREVER on chain                                             โ”‚
โ”‚   โ€ข Cost: $0.05-0.50 per L2 tx                                               โ”‚
โ”‚   โ€ข Expensive! Data storage is biggest L2 cost                               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

AFTER EIP-4844:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   Transaction data stored in BLOBS                                           โ”‚
โ”‚   โ€ข ~1 gas per byte (16x cheaper!)                                           โ”‚
โ”‚   โ€ข Data pruned after ~18 days                                               โ”‚
โ”‚   โ€ข Cost: $0.001-0.01 per L2 tx                                              โ”‚
โ”‚   โ€ข 90% cost reduction for rollups                                           โ”‚
โ”‚                                                                              โ”‚
โ”‚   Why 18 days is enough:                                                     โ”‚
โ”‚   โ€ข Challenge period is 7 days                                               โ”‚
โ”‚   โ€ข Fraud proofs only need data during challenge                             โ”‚
โ”‚   โ€ข After finalization, state root is canonical                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Web Reference: EIP-4844: Shard Blob Transactions


Questions to Guide Your Design

Before implementing, think through these:

1. L1 Contract Architecture

  • What functions does the L1 bridge contract need? (deposit, submitBatch, challengeBatch, finalizeWithdrawal)
  • How do you store pending state roots and their challenge status?
  • What data must be included in each batch submission?
  • How do you prevent replay attacks on deposits/withdrawals?
// Minimal L1 Contract Interface
interface IRollupBridge {
    // User deposits ETH/tokens to L2
    function deposit() external payable;

    // Sequencer submits batch with state root
    function submitBatch(
        bytes32 stateRoot,
        bytes calldata txData,
        bytes32 prevStateRoot
    ) external;

    // Anyone can challenge invalid state
    function challengeBatch(
        uint256 batchId,
        bytes calldata fraudProof
    ) external;

    // User finalizes withdrawal after challenge period
    function finalizeWithdrawal(
        bytes32[] calldata merkleProof,
        uint256 amount
    ) external;
}

2. L2 Sequencer Design

  • How does the sequencer maintain L2 state (accounts, balances)?
  • How do you decide when to batch transactions? (time-based, size-based, or both?)
  • How do you compress transaction data before posting to L1?
  • What happens if the sequencer crashes mid-batch?

3. State Transition Function

  • How do you execute L2 transactions? (EVM? Custom VM?)
  • How do you compute the new state root after a batch?
  • What validation rules must all transactions pass?
  • How do you handle transaction failures on L2?

4. Fraud Proof Construction

  • What data is needed to prove a state transition is invalid?
  • How can you prove fraud in a single L1 transaction (gas limits)?
  • Interactive vs. non-interactive fraud proofsโ€“which to implement?
  • How do you slash the malicious sequencerโ€™s bond?

5. Withdrawal Security

  • How do you prove a withdrawal occurred on L2?
  • What prevents users from withdrawing more than they have?
  • Why must withdrawals wait for the challenge period?
  • How do you handle withdrawals during a fraud proof dispute?

Thinking Exercise

Trace a Transaction Through the Rollup

Before coding, trace this scenario on paper:

1. Alice has 10 ETH on L1
2. Alice deposits 5 ETH to L2
3. On L2, Alice sends 1 ETH to Bob
4. Bob sends 0.5 ETH to Charlie
5. Sequencer batches these L2 transactions
6. Sequencer submits batch to L1
7. Eve (malicious) tries to challenge with false fraud proof
8. Alice initiates withdrawal of 3 ETH
9. After 7 days, Alice finalizes withdrawal

Questions while tracing:

  • Draw the state roots at each step (what changes?)
  • What data is posted to L1 in step 6? (full transaction data)
  • How does Eveโ€™s challenge fail in step 7? (her recomputed state root matches)
  • Why must Alice wait in step 9? (challenge period for batch containing her withdrawal)
  • What are the gas costs at each L1 interaction?

State Root Progression:

Step 1: L1 State
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  L1: Alice = 10 ETH                                                          โ”‚
โ”‚  L2: [empty]                                                                 โ”‚
โ”‚  L2 State Root: 0x0000 (genesis)                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 2: After Deposit
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  L1: Alice = 5 ETH (5 locked in bridge)                                      โ”‚
โ”‚  L2: Alice = 5 ETH                                                           โ”‚
โ”‚  L2 State Root: 0xAAA1                                                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 3-4: After L2 Transfers
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  L1: Alice = 5 ETH (5 locked in bridge)                                      โ”‚
โ”‚  L2: Alice = 4 ETH, Bob = 0.5 ETH, Charlie = 0.5 ETH                         โ”‚
โ”‚  L2 State Root: 0xAAA3                                                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 5-6: Batch Submitted
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  L1 Bridge Contract:                                                         โ”‚
โ”‚    batches[1] = {                                                            โ”‚
โ”‚      stateRoot: 0xAAA3,                                                      โ”‚
โ”‚      timestamp: now,                                                         โ”‚
โ”‚      challenged: false,                                                      โ”‚
โ”‚      txData: [compressed L2 txs]                                             โ”‚
โ”‚    }                                                                         โ”‚
โ”‚  Challenge period: blocks 100 - 604900                                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 8: Withdrawal Initiated
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  L2: Alice = 1 ETH, Bob = 0.5 ETH, Charlie = 0.5 ETH                         โ”‚
โ”‚       + pending_withdrawal: {Alice, 3 ETH, batchId: 2}                       โ”‚
โ”‚  L2 State Root: 0xAAA4                                                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Step 9: After 7 Days
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  L1: Alice = 8 ETH (5 original + 3 withdrawn)                                โ”‚
โ”‚  L1 Bridge: 2 ETH remaining locked                                           โ”‚
โ”‚  L2: Alice = 1 ETH, Bob = 0.5 ETH, Charlie = 0.5 ETH                         โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Design a Fraud Proof

Given:

  • L2 state root before: 0xAAA...
  • L2 transaction: โ€œAlice sends 100 ETH to Bobโ€ (but Alice only has 50 ETH)
  • Sequencer posted state root after: 0xBBB... (claiming transaction succeeded)

How do you prove fraud on L1?

  1. What data do you need from L2? (Aliceโ€™s balance proof, transaction, state root)
  2. How do you re-execute the transaction on L1? (in a single tx? off-chain then verify?)
  3. What should the correct state root be? (transaction should revert, state unchanged)
  4. How do you convince L1 the sequencer lied? (show mismatch)
FRAUD PROOF STRUCTURE:
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                                                              โ”‚
โ”‚  FraudProof {                                                                โ”‚
โ”‚    batchId: 5,                                                               โ”‚
โ”‚    preStateRoot: 0xAAA,     // Agreed starting state                         โ”‚
โ”‚    postStateRoot: 0xBBB,    // Claimed by sequencer (WRONG)                  โ”‚
โ”‚    transaction: {                                                            โ”‚
โ”‚      from: Alice,                                                            โ”‚
โ”‚      to: Bob,                                                                โ”‚
โ”‚      amount: 100 ETH                                                         โ”‚
โ”‚    },                                                                        โ”‚
โ”‚    accountProof: [           // Merkle proof of Alice's balance              โ”‚
โ”‚      0x..., 0x..., 0x...                                                     โ”‚
โ”‚    ],                                                                        โ”‚
โ”‚    aliceBalance: 50 ETH      // Alice's actual balance (not 100)             โ”‚
โ”‚  }                                                                           โ”‚
โ”‚                                                                              โ”‚
โ”‚  VERIFICATION ON L1:                                                         โ”‚
โ”‚  1. Verify accountProof against preStateRoot                                 โ”‚
โ”‚  2. Check: aliceBalance < transaction.amount (50 < 100)                      โ”‚
โ”‚  3. Therefore: transaction should FAIL                                       โ”‚
โ”‚  4. postStateRoot should equal preStateRoot                                  โ”‚
โ”‚  5. But sequencer claimed 0xBBB != 0xAAA                                     โ”‚
โ”‚  6. FRAUD PROVEN!                                                            โ”‚
โ”‚                                                                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The Interview Questions Theyโ€™ll Ask

Prepare to answer these:

Fundamental Understanding

  1. โ€œExplain optimistic rollups to me like Iโ€™m five.โ€
    • Expected: โ€œRollups do math homework off-chain, show their work on-chain, and if someone catches a mistake within 7 days, they get rewarded and the wrong answer is erased.โ€
  2. โ€œWhy is the challenge period 7 days? Isnโ€™t that too long for users waiting to withdraw?โ€
    • Expected: Discuss honest challenger liveness assumptions, coordination time, and tradeoff with security. Mention fast withdrawal services as workaround.
  3. โ€œWhatโ€™s the difference between Arbitrum and Optimism?โ€
    • Expected: Multi-round vs. single-round fraud proofs, EVM equivalence differences, governance models. Arbitrum uses interactive bisection; Optimism re-executes entire batch.
  4. โ€œWhat happens if no one runs a verifier to check for fraud?โ€
    • Expected: Security depends on at least one honest verifier (1-of-N trust model). Incentives via MEV and altruism. Rollup teams always run verifiers for self-preservation.
  5. โ€œHow do optimistic rollups compare to ZK-rollups?โ€
    • Expected: Optimistic = fraud proofs, 7-day withdrawals, simpler tech, EVM compatible. ZK = validity proofs, instant withdrawals, complex cryptography, harder EVM compat.
  6. โ€œCan you explain the data availability problem?โ€
    • Expected: If transaction data isnโ€™t public, challengers canโ€™t compute fraud proofs. Thatโ€™s why calldata/blobs must be on L1. Without DA, sequencer could commit fraud and withhold evidence.
  7. โ€œWhatโ€™s the worst-case scenario for an optimistic rollup?โ€
    • Expected: Sequencer is malicious AND no honest challenger exists AND users trust the bad state root. Also: sequencer censorship, prolonged downtime.
  8. โ€œWhy not just use a sidechain instead of a rollup?โ€
    • Expected: Sidechains have separate security (can be attacked independently). Rollups inherit L1 security via fraud proofs. Sidechains require trusting their validators; rollups only need 1 honest verifier.

Technical Deep Dives

  1. โ€œHow does transaction compression work in rollups?โ€
    • Expected: Remove signatures (replace with aggregate), use shorter addresses, encode amounts efficiently, batch headers. Can achieve 10-100x compression.
  2. โ€œWhat is MEV in the context of L2?โ€
    • Expected: Sequencer can reorder transactions for profit. Discuss sequencer auction, fair ordering, encryption schemes (threshold encryption, time-lock).
  3. โ€œHow do you handle L1 reorganizations on L2?โ€
    • Expected: L2 must wait for L1 finality before crediting deposits. If L1 reorgs, L2 must also reorg. Discuss safe confirmation depths.
  4. โ€œWhat is the escape hatch mechanism?โ€
    • Expected: If sequencer censors, users can force-include transactions via L1 or exit directly to L1. Essential for censorship resistance.
  5. โ€œHow do smart contracts work across L1 and L2?โ€
    • Expected: Same address can have different contracts on L1/L2. Cross-layer calls use message passing with async callbacks. Not atomic across layers.
  6. โ€œWhat happens during a dispute/challenge?โ€
    • Expected: Challenger posts bond, dispute enters resolution phase, losing party loses bond. During dispute, affected batch is pending (canโ€™t finalize withdrawals).
  7. โ€œHow would you design a decentralized sequencer?โ€
    • Expected: Options include rotating sequencer (based on stake/auction), shared sequencing (multiple rollups), PBS-style separation. Discuss tradeoffs of each.

System Design

  1. โ€œDesign a rollup that handles 10,000 TPS.โ€
    • Expected: Discuss parallel execution, state sharding, batch sizing, DA layer choice (blobs vs. external DA), hardware requirements.
  2. โ€œHow would you implement atomic cross-rollup transactions?โ€
    • Expected: Shared sequencer, fast messaging with bridges, escrow patterns. Discuss latency and security tradeoffs.
  3. โ€œWhat monitoring and alerting would you set up for a production rollup?โ€
    • Expected: State root verification, batch submission monitoring, challenge detection, sequencer health, gas price tracking, bridge balance monitoring.
  4. โ€œHow do rollups handle contract upgrades?โ€
    • Expected: Proxy patterns, timelock delays, governance votes. Security considerations around upgrade authority.
  5. โ€œExplain the economics of running a rollup.โ€
    • Expected: Revenue (tx fees, MEV), costs (L1 data posting, compute), margins. How EIP-4844 changed the economics dramatically.

Real World Outcome

When your simplified optimistic rollup is complete, youโ€™ll have a working Layer 2 system that demonstrates Ethereum scaling in action. Hereโ€™s exactly what youโ€™ll see:

# Terminal 1 - Start L1 (local Ethereum node)
$ anvil --chain-id 1
[Anvil] Listening on http://127.0.0.1:8545
[Anvil] Block time: 12 seconds

# Terminal 2 - Deploy L1 Bridge Contract
$ forge create RollupBridge --rpc-url http://127.0.0.1:8545
Deployed RollupBridge at: 0x5FbDB2315678afecb367f032d93F642f64180aa3

# Terminal 3 - Start L2 Sequencer
$ ./rollup-sequencer --l1-rpc http://127.0.0.1:8545 --bridge 0x5FbDB...
[Sequencer] Connected to L1 at block 100
[Sequencer] L2 chain initialized with genesis state
[Sequencer] Listening for L2 transactions on http://127.0.0.1:8546
[Sequencer] Batch interval: 10 L2 blocks or 60 seconds
[Sequencer] Challenge period: 7 days (604800 blocks on L1)

# Terminal 4 - User deposits ETH from L1 to L2
$ cast send 0x5FbDB... "deposit()" --value 1ether --rpc-url http://127.0.0.1:8545
Transaction: 0xabc123...
[L1] DepositEvent emitted: user=0xf39Fd..., amount=1000000000000000000

# Watch L2 Sequencer process the deposit
[Sequencer] L1 deposit detected at block 101
[Sequencer] Crediting 1 ETH to 0xf39Fd... on L2
[L2 State] 0xf39Fd... balance: 0 -> 1000000000000000000

# Terminal 5 - Send fast L2 transactions
$ cast send 0xRecipient --value 0.1ether --rpc-url http://127.0.0.1:8546
[L2] Transaction confirmed in 0.2 seconds
[L2] Gas cost: $0.0001 (vs $5 on L1)

$ cast send 0xRecipient2 --value 0.2ether --rpc-url http://127.0.0.1:8546
[L2] Transaction confirmed in 0.2 seconds

# Watch sequencer batch and submit to L1
[Sequencer] Batch ready: 47 transactions
[Sequencer] Computing new state root: 0x7f3a2b...
[Sequencer] Compressing transaction data (47 txs -> 3.2 KB)
[Sequencer] Submitting batch to L1...
[L1] Transaction cost: 0.002 ETH (split across 47 users = $0.15 each)
[L1] StateRootSubmitted: batchId=1, stateRoot=0x7f3a2b..., blockNumber=102
[Sequencer] Challenge period starts: block 102 -> block 604902

# Terminal 6 - Honest challenger verifies (all is good)
$ ./rollup-verifier --l1-rpc http://127.0.0.1:8545 --l2-rpc http://127.0.0.1:8546
[Verifier] Checking batch 1...
[Verifier] Re-executing 47 transactions...
[Verifier] Computed state root: 0x7f3a2b...
[Verifier] State root matches! No fraud detected.

# Simulate malicious sequencer (optional test)
[Sequencer] TESTING: Submitting INVALID state root 0xBADBEEF...
[L1] StateRootSubmitted: batchId=2, stateRoot=0xBADBEEF..., blockNumber=103

[Verifier] Checking batch 2...
[Verifier] Re-executing 23 transactions...
[Verifier] Computed state root: 0x9a4c1d... (expected)
[Verifier] Posted state root:   0xBADBEEF... (actual)
[Verifier] FRAUD DETECTED! Submitting fraud proof...

[L1] Challenge submitted by 0xChallenger...
[L1] Fraud proof verified
[L1] Batch 2 REVERTED
[L1] Sequencer slashed: 100 ETH burned
[L1] Challenger rewarded: 10 ETH

# Terminal 7 - User withdraws from L2 to L1 (7-day delay)
$ cast send --rpc-url http://127.0.0.1:8546 $BRIDGE "initiateWithdrawal(uint256)" 0.5ether
[L2] Withdrawal initiated: 0.5 ETH
[L2] Withdrawal included in batch 3
[Sequencer] Batch 3 submitted to L1 at block 110
[L1] Challenge period: blocks 110-604910 (7 days)

# Wait 7 days... (in test mode, fast-forward)
$ cast rpc anvil_mine 604800

# Finalize withdrawal
$ cast send $BRIDGE "finalizeWithdrawal(bytes32)" $WITHDRAWAL_PROOF --rpc-url http://127.0.0.1:8545
[L1] Withdrawal proof verified
[L1] 0.5 ETH transferred to user
[L1] User balance: 10 ETH -> 10.5 ETH

# Performance comparison dashboard
$ ./rollup-stats
+================================================+
|         L2 Rollup Statistics                   |
+================================================+
| Total L2 transactions:        1,247            |
| Total L1 batches:             27               |
| Average batch size:           46 txs           |
| L2 block time:                0.2s             |
| L1 block time:                12s              |
|                                                |
| Cost Savings:                                  |
|   L2 tx cost:                 $0.0001          |
|   L1 tx cost:                 $5.00            |
|   Savings per tx:             99.998%          |
|                                                |
| Throughput:                                    |
|   L2 TPS:                     ~230 tps         |
|   L1 TPS (if no rollup):      ~15 tps          |
|   Scalability factor:         15x              |
|                                                |
| Security:                                      |
|   Fraud proofs submitted:     1                |
|   Invalid batches reverted:   1                |
|   Uptime:                     99.97%           |
+================================================+

Youโ€™re witnessing Ethereum scaling through computation off-chain, security on-chain. Your L2 processes thousands of transactions for pennies, while maintaining Ethereumโ€™s security guarantees through fraud proofs.


Complete Project Specification

Functional Requirements

  1. L1 Bridge Contract
    • Accept ETH deposits and emit events for L2 pickup
    • Store sequencer-submitted state roots with timestamps
    • Process fraud proof challenges and slash malicious sequencers
    • Handle withdrawal finalization after challenge period
  2. L2 Sequencer
    • Maintain L2 state (balances, nonces) in Merkle tree
    • Execute L2 transactions and update state
    • Watch L1 for deposit events and credit L2 accounts
    • Batch transactions and submit to L1
  3. State Management
    • Merkle tree for efficient state root computation
    • Proof generation for individual account states
    • State rollback capability for fraud proof testing
  4. Fraud Proof System
    • Verifier that re-executes all batches
    • Fraud proof generation when mismatch detected
    • L1 verification of fraud proofs
  5. Withdrawal Bridge
    • L2 withdrawal initiation with state commitment
    • Merkle proof generation for withdrawals
    • L1 finalization after challenge period

Command-Line Interface

# Initialize and deploy
$ rollup init --l1-rpc http://localhost:8545
$ rollup deploy-bridge

# Start sequencer
$ rollup sequencer start --port 8546

# Start verifier
$ rollup verifier start

# User operations
$ rollup deposit --amount 1.0 --l1-key $PRIVATE_KEY
$ rollup transfer --to 0x... --amount 0.5 --l2-key $PRIVATE_KEY
$ rollup withdraw --amount 0.3 --l2-key $PRIVATE_KEY
$ rollup finalize-withdrawal --proof $PROOF

# Admin operations
$ rollup status
$ rollup batches list
$ rollup verify-batch --id 5

Solution Architecture

Module Structure

rollup/
+-- Cargo.toml
+-- contracts/                    # Solidity L1 contracts
|   +-- RollupBridge.sol
|   +-- FraudProver.sol
|   +-- test/
|       +-- RollupBridge.t.sol
+-- src/
|   +-- main.rs                   # CLI entry point
|   +-- lib.rs                    # Library exports
|   +-- sequencer/
|   |   +-- mod.rs                # Sequencer coordinator
|   |   +-- executor.rs           # Transaction execution
|   |   +-- batcher.rs            # Batch creation and submission
|   |   +-- l1_watcher.rs         # L1 event monitoring
|   +-- state/
|   |   +-- mod.rs                # State management
|   |   +-- merkle.rs             # Merkle tree implementation
|   |   +-- account.rs            # Account data structures
|   |   +-- storage.rs            # Persistent storage (RocksDB)
|   +-- verifier/
|   |   +-- mod.rs                # Verifier coordinator
|   |   +-- executor.rs           # Re-execution engine
|   |   +-- fraud_proof.rs        # Fraud proof generation
|   +-- bridge/
|   |   +-- mod.rs                # Bridge coordination
|   |   +-- deposit.rs            # Deposit handling
|   |   +-- withdrawal.rs         # Withdrawal handling
|   +-- types/
|   |   +-- mod.rs                # Common types
|   |   +-- transaction.rs        # L2 transaction
|   |   +-- batch.rs              # Batch structure
|   |   +-- proof.rs              # Proof structures
|   +-- rpc/
|       +-- mod.rs                # JSON-RPC server
|       +-- handlers.rs           # RPC method handlers
+-- tests/
    +-- integration/
        +-- deposit_flow.rs
        +-- withdrawal_flow.rs
        +-- fraud_proof.rs

Core Data Structures

use primitive_types::{H256, U256};
use std::collections::HashMap;

/// L2 Account state
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Account {
    pub balance: U256,
    pub nonce: u64,
}

/// L2 Transaction
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Transaction {
    pub from: Address,
    pub to: Address,
    pub value: U256,
    pub nonce: u64,
    pub signature: Signature,
}

/// L2 State (Merkle tree of accounts)
pub struct L2State {
    accounts: HashMap<Address, Account>,
    merkle_tree: MerkleTree,
}

impl L2State {
    pub fn new() -> Self {
        Self {
            accounts: HashMap::new(),
            merkle_tree: MerkleTree::new(),
        }
    }

    pub fn apply_transaction(&mut self, tx: &Transaction) -> Result<(), Error> {
        // 1. Verify signature
        let recovered = tx.recover_signer()?;
        if recovered != tx.from {
            return Err(Error::InvalidSignature);
        }

        // 2. Check nonce
        let account = self.accounts.entry(tx.from).or_default();
        if account.nonce != tx.nonce {
            return Err(Error::InvalidNonce);
        }

        // 3. Check balance
        if account.balance < tx.value {
            return Err(Error::InsufficientBalance);
        }

        // 4. Execute transfer
        account.balance -= tx.value;
        account.nonce += 1;

        let recipient = self.accounts.entry(tx.to).or_default();
        recipient.balance += tx.value;

        // 5. Update Merkle tree
        self.merkle_tree.update(tx.from, account.hash());
        self.merkle_tree.update(tx.to, recipient.hash());

        Ok(())
    }

    pub fn state_root(&self) -> H256 {
        self.merkle_tree.root()
    }

    pub fn get_proof(&self, address: Address) -> MerkleProof {
        self.merkle_tree.get_proof(address)
    }
}

/// Batch submitted to L1
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Batch {
    pub id: u64,
    pub prev_state_root: H256,
    pub post_state_root: H256,
    pub transactions: Vec<Transaction>,
    pub timestamp: u64,
}

/// State commitment stored on L1
#[derive(Clone, Debug)]
pub struct StateCommitment {
    pub state_root: H256,
    pub timestamp: u64,
    pub challenged: bool,
    pub finalized: bool,
}

/// Fraud proof structure
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct FraudProof {
    pub batch_id: u64,
    pub pre_state_root: H256,
    pub post_state_root: H256,  // What sequencer claimed
    pub correct_state_root: H256,  // What it should be
    pub transaction_index: usize,  // Which tx was invalid
    pub account_proof: MerkleProof,  // Proof of account state
    pub transaction: Transaction,  // The invalid transaction
}

Key Algorithms

Transaction Execution

impl Sequencer {
    pub async fn execute_transaction(&mut self, tx: Transaction) -> Result<TxReceipt> {
        // 1. Validate transaction
        self.validate_transaction(&tx)?;

        // 2. Apply to state
        self.state.apply_transaction(&tx)?;

        // 3. Add to pending batch
        self.pending_batch.push(tx.clone());

        // 4. Check if batch should be submitted
        if self.should_submit_batch() {
            self.submit_batch().await?;
        }

        Ok(TxReceipt {
            tx_hash: tx.hash(),
            status: true,
            state_root: self.state.state_root(),
        })
    }

    fn should_submit_batch(&self) -> bool {
        self.pending_batch.len() >= MAX_BATCH_SIZE
            || self.time_since_last_batch() > MAX_BATCH_TIME
    }

    async fn submit_batch(&mut self) -> Result<()> {
        let batch = Batch {
            id: self.next_batch_id,
            prev_state_root: self.last_submitted_root,
            post_state_root: self.state.state_root(),
            transactions: std::mem::take(&mut self.pending_batch),
            timestamp: current_timestamp(),
        };

        // Compress transaction data
        let compressed = self.compress_transactions(&batch.transactions);

        // Submit to L1
        let tx = self.l1_contract
            .submit_batch(batch.post_state_root, compressed)
            .send()
            .await?;

        self.last_submitted_root = batch.post_state_root;
        self.next_batch_id += 1;

        Ok(())
    }
}

Fraud Proof Verification

impl Verifier {
    pub async fn verify_batch(&self, batch_id: u64) -> Result<bool> {
        // 1. Get batch data from L1
        let batch_data = self.l1_contract.get_batch(batch_id).await?;
        let transactions = self.decompress_transactions(&batch_data.tx_data);

        // 2. Get pre-state root
        let pre_state = if batch_id == 0 {
            H256::zero()
        } else {
            self.l1_contract.get_batch(batch_id - 1).await?.state_root
        };

        // 3. Re-execute all transactions
        let mut state = self.state_at_root(pre_state)?;
        for tx in &transactions {
            if let Err(e) = state.apply_transaction(tx) {
                // Transaction should have failed but didn't
                // This could be fraud if sequencer claimed success
            }
        }

        // 4. Compare state roots
        let computed_root = state.state_root();
        let claimed_root = batch_data.state_root;

        if computed_root != claimed_root {
            // FRAUD DETECTED!
            let fraud_proof = self.generate_fraud_proof(
                batch_id,
                pre_state,
                computed_root,
                claimed_root,
                &transactions,
            )?;

            self.submit_fraud_proof(fraud_proof).await?;
            return Ok(false);
        }

        Ok(true)
    }

    fn generate_fraud_proof(
        &self,
        batch_id: u64,
        pre_state: H256,
        correct_root: H256,
        claimed_root: H256,
        transactions: &[Transaction],
    ) -> Result<FraudProof> {
        // Find the first transaction that causes divergence
        let mut state = self.state_at_root(pre_state)?;

        for (i, tx) in transactions.iter().enumerate() {
            let pre_tx_root = state.state_root();
            state.apply_transaction(tx)?;
            let post_tx_root = state.state_root();

            // Check if this tx causes the divergence
            // (simplified - real impl would compare intermediate roots)
        }

        // Generate proof
        Ok(FraudProof {
            batch_id,
            pre_state_root: pre_state,
            post_state_root: claimed_root,
            correct_state_root: correct_root,
            transaction_index: 0,  // Would be computed
            account_proof: state.get_proof(Address::zero()),
            transaction: transactions[0].clone(),
        })
    }
}

Phased Implementation Guide

Phase 1: L2 State Management (Days 1-5)

Goal: Implement the core L2 state with Merkle tree.

Tasks:

  1. Implement Account struct with balance and nonce
  2. Build Merkle tree for state root computation
  3. Implement state transitions (credit, debit, transfer)
  4. Add Merkle proof generation and verification

Validation:

#[test]
fn test_state_transitions() {
    let mut state = L2State::new();

    // Credit Alice
    state.credit(alice, U256::from(100));
    assert_eq!(state.balance(alice), U256::from(100));

    // Transfer to Bob
    state.transfer(alice, bob, U256::from(30)).unwrap();
    assert_eq!(state.balance(alice), U256::from(70));
    assert_eq!(state.balance(bob), U256::from(30));

    // State root changes
    let root1 = state.state_root();
    state.transfer(alice, bob, U256::from(10)).unwrap();
    let root2 = state.state_root();
    assert_ne!(root1, root2);
}

#[test]
fn test_merkle_proofs() {
    let mut state = L2State::new();
    state.credit(alice, U256::from(100));

    let proof = state.get_proof(alice);
    let root = state.state_root();

    assert!(verify_proof(proof, root, alice, U256::from(100)));
}

Phase 2: L1 Bridge Contract (Days 6-12)

Goal: Deploy and test the L1 Solidity contract.

Tasks:

  1. Implement deposit() with event emission
  2. Implement submitBatch() with state root storage
  3. Implement challengeBatch() with fraud proof verification
  4. Implement finalizeWithdrawal() with proof verification
  5. Add sequencer bond and slashing

Validation:

function test_deposit() public {
    vm.deal(alice, 10 ether);
    vm.prank(alice);
    bridge.deposit{value: 1 ether}();

    // Check event emitted
    assertEq(address(bridge).balance, 1 ether);
}

function test_submit_batch() public {
    vm.prank(sequencer);
    bridge.submitBatch(
        bytes32(uint256(1)),  // state root
        hex"00"  // tx data
    );

    (bytes32 root, uint256 timestamp, bool challenged) = bridge.batches(0);
    assertEq(root, bytes32(uint256(1)));
    assertFalse(challenged);
}

function test_challenge_period() public {
    // Submit batch
    vm.prank(sequencer);
    bridge.submitBatch(bytes32(uint256(1)), hex"00");

    // Try to finalize immediately - should fail
    vm.expectRevert("Challenge period not over");
    bridge.finalizeWithdrawal(proof);

    // Wait 7 days
    vm.warp(block.timestamp + 7 days);

    // Now should succeed
    bridge.finalizeWithdrawal(proof);
}

Phase 3: Sequencer Node (Days 13-20)

Goal: Build the L2 sequencer that processes transactions.

Tasks:

  1. Implement L1 event watcher for deposits
  2. Build transaction mempool and ordering
  3. Implement transaction execution engine
  4. Create batch assembler and submitter
  5. Add JSON-RPC API for users

Validation:

#[tokio::test]
async fn test_sequencer_deposit_flow() {
    let sequencer = TestSequencer::new().await;

    // Simulate L1 deposit
    sequencer.l1.deposit(alice, U256::from(100)).await;

    // Wait for sequencer to process
    tokio::time::sleep(Duration::from_secs(5)).await;

    // Check L2 balance
    let balance = sequencer.get_balance(alice).await;
    assert_eq!(balance, U256::from(100));
}

#[tokio::test]
async fn test_batch_submission() {
    let sequencer = TestSequencer::new().await;

    // Add transactions
    for i in 0..50 {
        sequencer.submit_tx(test_tx(i)).await.unwrap();
    }

    // Force batch submission
    sequencer.force_batch().await;

    // Check L1 has the batch
    let batch = sequencer.l1.get_batch(0).await;
    assert!(batch.is_some());
}

Phase 4: Verifier and Fraud Proofs (Days 21-30)

Goal: Implement the fraud detection and proof system.

Tasks:

  1. Build verifier that re-executes all batches
  2. Implement state divergence detection
  3. Create fraud proof generator
  4. Test fraud proof submission to L1
  5. Implement sequencer slashing

Validation:

#[tokio::test]
async fn test_fraud_detection() {
    let mut test_env = TestEnv::new().await;

    // Submit valid batch
    test_env.sequencer.submit_batch(valid_batch).await;
    assert!(test_env.verifier.verify_batch(0).await.is_ok());

    // Submit invalid batch (manually craft bad state root)
    test_env.sequencer.submit_invalid_batch().await;

    // Verifier should detect fraud
    let result = test_env.verifier.verify_batch(1).await;
    assert!(result.is_err());

    // Check fraud proof was submitted
    let batch = test_env.l1.get_batch(1).await;
    assert!(batch.challenged);
}

#[tokio::test]
async fn test_slashing() {
    let mut test_env = TestEnv::new().await;

    let initial_bond = test_env.l1.sequencer_bond().await;

    // Submit fraud and prove it
    test_env.sequencer.submit_invalid_batch().await;
    test_env.verifier.verify_batch(0).await.unwrap_err();

    // Sequencer should be slashed
    let final_bond = test_env.l1.sequencer_bond().await;
    assert!(final_bond < initial_bond);
}

Phase 5: Withdrawal Bridge (Days 31-38)

Goal: Complete the withdrawal flow.

Tasks:

  1. Implement L2 withdrawal initiation
  2. Build withdrawal Merkle proof generation
  3. Implement L1 withdrawal finalization
  4. Add challenge period enforcement
  5. Test full deposit->withdraw cycle

Validation:

#[tokio::test]
async fn test_full_cycle() {
    let mut test_env = TestEnv::new().await;

    // 1. Deposit
    test_env.l1.deposit(alice, U256::from(100)).await;
    test_env.wait_for_l2_sync().await;
    assert_eq!(test_env.l2_balance(alice).await, U256::from(100));

    // 2. L2 transfers
    test_env.l2_transfer(alice, bob, U256::from(30)).await;
    assert_eq!(test_env.l2_balance(alice).await, U256::from(70));

    // 3. Initiate withdrawal
    test_env.initiate_withdrawal(alice, U256::from(50)).await;

    // 4. Wait for batch submission
    test_env.force_batch().await;

    // 5. Wait for challenge period (in test, fast-forward)
    test_env.fast_forward(7 * 24 * 60 * 60).await;

    // 6. Finalize withdrawal
    let proof = test_env.get_withdrawal_proof(alice).await;
    test_env.l1.finalize_withdrawal(proof).await;

    // 7. Check final balances
    assert_eq!(test_env.l1_balance(alice).await, U256::from(50));
    assert_eq!(test_env.l2_balance(alice).await, U256::from(20));
}

Phase 6: Production Hardening (Days 39-45)

Goal: Make the system robust for real use.

Tasks:

  1. Add comprehensive error handling
  2. Implement state persistence (RocksDB)
  3. Add monitoring and metrics
  4. Implement graceful shutdown and recovery
  5. Add configuration management
  6. Write documentation

Hints in Layers

Hint 1: Start with a Simple L1 Contract

Your L1 bridge contract needs these minimal functions:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract RollupBridge {
    struct StateCommitment {
        bytes32 stateRoot;
        uint256 timestamp;
        bool challenged;
    }

    mapping(uint256 => StateCommitment) public batches;
    uint256 public nextBatchId;
    address public sequencer;
    uint256 public constant CHALLENGE_PERIOD = 7 days;

    event Deposit(address indexed user, uint256 amount);
    event BatchSubmitted(uint256 indexed batchId, bytes32 stateRoot);
    event BatchChallenged(uint256 indexed batchId, address challenger);
    event WithdrawalFinalized(address indexed user, uint256 amount);

    function deposit() external payable {
        emit Deposit(msg.sender, msg.value);
    }

    function submitBatch(bytes32 stateRoot, bytes calldata txData) external {
        require(msg.sender == sequencer, "Only sequencer");

        batches[nextBatchId] = StateCommitment({
            stateRoot: stateRoot,
            timestamp: block.timestamp,
            challenged: false
        });

        emit BatchSubmitted(nextBatchId, stateRoot);
        nextBatchId++;
    }

    function challengeBatch(uint256 batchId, bytes calldata fraudProof) external {
        StateCommitment storage batch = batches[batchId];
        require(!batch.challenged, "Already challenged");
        require(block.timestamp < batch.timestamp + CHALLENGE_PERIOD, "Too late");

        // Verify fraud proof (simplified)
        require(verifyFraudProof(batchId, fraudProof), "Invalid proof");

        batch.challenged = true;
        emit BatchChallenged(batchId, msg.sender);

        // Slash sequencer, reward challenger
    }

    function finalizeWithdrawal(bytes32[] calldata proof) external {
        // Verify withdrawal was included in finalized batch
        // Transfer funds to user
    }

    function verifyFraudProof(uint256 batchId, bytes calldata proof) internal returns (bool) {
        // Re-execute and compare state roots
        return true;
    }
}

Hint 2: L2 State as a Simple Mapping

Donโ€™t overcomplicate L2 state initially:

pub struct L2State {
    balances: HashMap<Address, U256>,
    nonces: HashMap<Address, u64>,
    // Use a simple Patricia-Merkle trie for state root
    state_trie: PatriciaTrie,
}

impl L2State {
    pub fn apply_transaction(&mut self, tx: &Transaction) -> Result<(), Error> {
        // 1. Check nonce
        let current_nonce = self.nonces.get(&tx.from).copied().unwrap_or(0);
        if tx.nonce != current_nonce {
            return Err(Error::InvalidNonce);
        }

        // 2. Check balance
        let balance = self.balances.get(&tx.from).copied().unwrap_or(U256::zero());
        if balance < tx.value {
            return Err(Error::InsufficientBalance);
        }

        // 3. Update state
        *self.balances.entry(tx.from).or_default() -= tx.value;
        *self.balances.entry(tx.to).or_default() += tx.value;
        *self.nonces.entry(tx.from).or_default() += 1;

        // 4. Update trie
        self.update_trie(&tx.from);
        self.update_trie(&tx.to);

        Ok(())
    }

    pub fn state_root(&self) -> H256 {
        self.state_trie.root()
    }
}

Hint 3: Batching Strategy

Batch when either condition is met:

const MAX_BATCH_SIZE: usize = 100;
const MAX_BATCH_TIME: Duration = Duration::from_secs(60);

impl Sequencer {
    fn should_submit_batch(&self) -> bool {
        self.pending_transactions.len() >= MAX_BATCH_SIZE
            || self.time_since_last_batch() > MAX_BATCH_TIME
    }

    async fn batch_loop(&mut self) {
        loop {
            if self.should_submit_batch() && !self.pending_transactions.is_empty() {
                if let Err(e) = self.submit_batch().await {
                    log::error!("Failed to submit batch: {}", e);
                }
            }
            tokio::time::sleep(Duration::from_secs(1)).await;
        }
    }
}

Hint 4: Simplified Fraud Proof

For a minimal version, fraud proofs can be simple:

function challengeBatch(
    uint256 batchId,
    bytes calldata txData,
    bytes32 claimedStateRoot,
    bytes32 correctStateRoot,
    bytes calldata accountProofs
) external {
    StateCommitment storage batch = batches[batchId];
    require(batch.stateRoot == claimedStateRoot, "Wrong batch");

    // Re-execute transactions on L1
    // This is gas-intensive but simple
    bytes32 computed = reExecuteTransactions(txData, accountProofs);
    require(computed != claimedStateRoot, "No fraud");

    // Fraud proven!
    batch.challenged = true;

    // Slash sequencer, reward challenger
    slashSequencer();
    payable(msg.sender).transfer(CHALLENGER_REWARD);
}

function reExecuteTransactions(bytes calldata txData, bytes calldata proofs)
    internal
    returns (bytes32)
{
    // Decode and execute each transaction
    // Return final state root
}

Hint 5: Testing Fraud Detection

Create a test where the sequencer is malicious:

#[test]
fn test_fraud_proof() {
    // Honest execution
    let mut state = L2State::new();
    state.credit(alice, U256::from(100));
    state.apply_transaction(&Transfer {
        from: alice,
        to: bob,
        amount: U256::from(50)
    }).unwrap();
    let honest_root = state.state_root();

    // Malicious execution (ignore balance check)
    let mut evil_state = L2State::new();
    evil_state.credit(alice, U256::from(100));
    evil_state.force_credit(bob, U256::from(1_000_000)); // FRAUD!
    let evil_root = evil_state.state_root();

    // Roots should differ
    assert_ne!(honest_root, evil_root);

    // Submit evil root to L1
    l1_bridge.submit_batch(evil_root, tx_data);

    // Challenger proves fraud
    let fraud_proof = generate_fraud_proof(
        honest_root,
        evil_root,
        &state,
    );
    l1_bridge.challenge_batch(batch_id, fraud_proof);

    // Batch should be challenged
    assert!(l1_bridge.batches(batch_id).challenged);
}

Hint 6: Use Existing Tools

Donโ€™t build everything from scratch:

  • Use ethers-rs for L1 interaction
  • Use serde for transaction serialization
  • Use RocksDB or sled for L2 state storage
  • Use your Merkle tree from Project 3 for state roots
  • Use Foundry for Solidity testing
  • Use alloy for modern Ethereum types

Common Pitfalls & Debugging

Pitfall 1: State Root Mismatch After Deposit

Problem: L2 state root doesnโ€™t match after processing deposit.

Symptom: Fraud proofs fail even for honest batches.

Solution:

// Ensure deposits are processed deterministically
impl L2State {
    fn process_deposit(&mut self, deposit: &Deposit) {
        // Always process in same order (by L1 block, then log index)
        let key = (deposit.l1_block, deposit.log_index);
        if self.processed_deposits.contains(&key) {
            return; // Already processed
        }

        self.credit(deposit.user, deposit.amount);
        self.processed_deposits.insert(key);
    }
}

Pitfall 2: Nonce Gaps

Problem: Transactions fail due to nonce gaps.

Symptom: Valid transactions rejected with โ€œinvalid nonceโ€.

Solution:

// Handle nonces carefully
impl Sequencer {
    fn validate_transaction(&self, tx: &Transaction) -> Result<()> {
        let expected_nonce = self.state.nonce(tx.from);

        if tx.nonce < expected_nonce {
            return Err(Error::NonceTooLow);
        }

        if tx.nonce > expected_nonce {
            // Could queue for later, or reject
            return Err(Error::NonceTooHigh);
        }

        Ok(())
    }
}

Pitfall 3: L1 Reorg Handling

Problem: L1 reorganization causes L2 inconsistency.

Symptom: Deposits credited twice or missed after L1 reorg.

Solution:

impl L1Watcher {
    async fn handle_reorg(&mut self, new_head: BlockNumber) {
        // Identify reorged blocks
        let reorged_deposits = self.deposits_after(new_head);

        // Rollback L2 state
        for deposit in reorged_deposits.rev() {
            self.l2_state.debit(deposit.user, deposit.amount);
        }

        // Re-sync from new head
        self.sync_from(new_head).await;
    }

    async fn watch_l1(&mut self) {
        loop {
            let new_head = self.l1.block_number().await?;

            if new_head < self.last_processed {
                // Reorg detected!
                self.handle_reorg(new_head).await;
            } else {
                self.process_new_blocks(self.last_processed, new_head).await;
            }

            self.last_processed = new_head;
            tokio::time::sleep(POLL_INTERVAL).await;
        }
    }
}

Pitfall 4: Gas Limit in Fraud Proofs

Problem: Fraud proof transaction runs out of gas.

Symptom: Challenge transaction reverts with โ€œout of gasโ€.

Solution:

// Limit batch size or use interactive proofs
function challengeBatch(
    uint256 batchId,
    uint256 txIndex,  // Challenge specific transaction
    bytes calldata proof
) external {
    // Only re-execute ONE transaction, not entire batch
    // This bounds gas usage

    bytes32 preState = getStateBeforeTx(batchId, txIndex, proof);
    bytes32 postState = executeOneTx(batchId, txIndex, proof);
    bytes32 claimed = getClaimedPostState(batchId, txIndex);

    require(postState != claimed, "No fraud");
    // ...
}

Pitfall 5: Withdrawal Proof Verification

Problem: Valid withdrawals rejected.

Symptom: Users canโ€™t finalize withdrawals.

Solution:

// Ensure proof matches exactly what L1 expects
impl WithdrawalProof {
    fn generate(
        state: &L2State,
        batch_id: u64,
        withdrawal: &Withdrawal,
    ) -> Self {
        // The leaf must match exactly what L1 hashes
        let leaf = keccak256(abi.encode(
            withdrawal.user,
            withdrawal.amount,
            withdrawal.nonce,
            batch_id,
        ));

        let proof = state.merkle_tree.get_proof(leaf);

        Self {
            user: withdrawal.user,
            amount: withdrawal.amount,
            nonce: withdrawal.nonce,
            batch_id,
            merkle_proof: proof,
        }
    }
}

Extensions and Challenges

Challenge 1: EVM Execution

Replace the simple transfer model with full EVM execution:

  • Integrate revm for EVM execution
  • Support smart contract deployment on L2
  • Handle CREATE/CREATE2 addresses
  • Implement EVM-compatible fraud proofs

Challenge 2: Decentralized Sequencer

Implement a rotating sequencer system:

  • Sequencer auction (highest bidder wins next slot)
  • Proof-of-stake based selection
  • Fallback to forced transaction inclusion via L1

Challenge 3: Fast Withdrawals

Build a liquidity provider network for instant withdrawals:

  • LP stakes capital on L1
  • User requests fast withdrawal, LP provides liquidity
  • LP claims userโ€™s withdrawal after challenge period
  • Fee based on risk and capital lock-up

Challenge 4: Cross-Rollup Communication

Implement messaging between two L2s:

  • Shared sequencer approach
  • Message passing via L1
  • Atomic cross-rollup swaps

Challenge 5: Data Compression

Optimize data posted to L1:

  • Signature aggregation (BLS signatures)
  • State diff compression
  • Custom encoding for common patterns
  • Blob transactions (EIP-4844)

Books That Will Help

Topic Book Chapter
Optimistic rollups overview โ€œMastering Ethereumโ€ by Antonopoulos & Wood Ch. 13: EVM & Ch. 14: Consensus
Merkle trees and proofs โ€œMastering Bitcoinโ€ by Antonopoulos Ch. 9: The Blockchain
State management โ€œDesigning Data-Intensive Applicationsโ€ by Kleppmann Ch. 3: Storage Engines & Ch. 9: Consistency
Fraud proof game theory โ€œGame Theoryโ€ by Osborne Ch. 1-3: Strategic Games
P2P networking โ€œComputer Networksโ€ by Tanenbaum Ch. 2: The Application Layer
Distributed consensus โ€œDesigning Data-Intensive Applicationsโ€ by Kleppmann Ch. 9: Consistency and Consensus
EVM execution โ€œMastering Ethereumโ€ by Antonopoulos & Wood Ch. 13: The Ethereum Virtual Machine
Cryptographic commitments โ€œSerious Cryptographyโ€ by Aumasson Ch. 6: Hash Functions
Smart contract security โ€œMastering Ethereumโ€ by Antonopoulos & Wood Ch. 9: Smart Contract Security

Additional Resources

Official Documentation

Research & Analysis

Code References

Videos & Talks


Self-Assessment Checklist

Before moving to the next project, verify:

Conceptual Understanding

  • I can explain why rollups need to post data to L1 for security
  • I understand the difference between optimistic and ZK rollups
  • I can describe the fraud proof mechanism and its game theory
  • I understand why the challenge period is 7 days
  • I can explain the 1-of-N honest verifier security model
  • I understand how EIP-4844 reduces rollup costs

Implementation Verification

  • Deposits from L1 are correctly credited on L2
  • L2 transactions correctly update state and nonces
  • State roots are correctly computed via Merkle tree
  • Batches are correctly submitted to L1 with calldata
  • Fraud proofs can detect invalid state transitions
  • Challenge mechanism correctly slashes malicious sequencer
  • Withdrawals work after challenge period

Security

  • No double-deposit vulnerability
  • No withdrawal amount manipulation
  • Challenge period correctly enforced
  • Sequencer bond correctly slashed on fraud
  • L1 reorgs handled correctly

Production Readiness

  • State persists across restarts
  • Graceful shutdown preserves pending transactions
  • Monitoring metrics exposed
  • Error handling is comprehensive
  • Documentation is complete

Whatโ€™s Next?

With a working optimistic rollup, you understand how Ethereum scales. In Project 14: Smart Contract Security Scanner, youโ€™ll apply your deep knowledge of EVM execution and smart contract patterns to build a static analysis tool that detects vulnerabilities before theyโ€™re exploited.

Your rollup implementation demonstrates:

  • Layer 2 scaling architecture
  • Fraud proof security models
  • Cross-layer bridge design
  • State commitment schemes

This knowledge is directly applicable to:

  • L2 protocol development (Arbitrum, Optimism, Base)
  • Bridge security auditing
  • MEV and sequencer design
  • ZK-rollup architecture (next evolution)

The future of Ethereum is Layer 2. Now you understand why and how.