Status: ✅ Phase 1 Live - Core fork infrastructure and simulation features are implemented and functional. Phase 2+ (persistent sessions, Tevm Black) are planned.
For Phase 2+ specifications, see Fork Mode Engineering Spec.
Fork Mode transforms tevm.app from a read-only blockchain explorer into an interactive simulation environment. Users can fork from any historical block to create a local EVM sandbox, resimulate transactions with modified parameters, and preview transaction effects before execution.
Key Capability: "What-if" analysis for any transaction or contract interaction.
- Fork from any block via block page "Fork" button
- Fork session metadata persisted client-side (localStorage)
- Automatic fork initialization on first resimulation
- Fork configuration (modal):
- Fork point: end-of-block or pre-state (block - 1)
- Optional session label
- Chain + block are derived from the current page context
- Page:
/simulate- Single transaction simulation UI - Results Page:
/simulate/results/[encoded]- Shareable simulation results - Multiple input formats:
- Transaction hash (resimulate historical tx)
- Contract address + function call
- Raw transaction data
- Parameter modification before simulation:
- Caller address
- Transaction value (ETH)
- Gas limit
- Function arguments
- Safety verdicts:
- 🟢 Safe - No warnings detected
- 🟡 Review Needed - Approval changes or moderate warnings
- 🔴 High Risk - Unlimited approvals, unverified contracts
- Balance Diffs: Before/after comparison for all affected addresses
- Approval Changes: Token approval modifications (ERC20, ERC721)
- Event Logs: Raw emitted logs (topics + data)
- Gas Metrics: Gas used (and simulated vs actual on resimulations)
- Warnings Panel: Risk indicators with severity levels
- Client-side fork state persistence (localStorage)
- Fork session tracking:
- Session ID
- Chain ID
- Fork block number + block hash
- Optional label + acting-as address
- Simulation count
- State serialization/deserialization for persistence
- Fork reset capability
- State cache thresholds exist (warn at 50MB, max 100MB), but current UI reports 0 until backend stats are wired.
- ForkStatusPill - Header indicator showing active fork state
- ForkButton - Entry point for fork creation
- ForkModal - Fork configuration dialog
- ForkDrawer - Fork management panel (session info, reset)
- SimulationTab - Main simulation interface (20KB component)
- SimulationPreview - Results preview card
- SimulationResults - Detailed results display
- SimulationSummary - Quick summary view
- VerdictBanner - Safety verdict display
- BalanceDiffTable - Balance comparison table
- WarningsPanel - Risk warnings list
- SimulationQueuePanel - Batch simulation queue (implemented, not wired in UI yet)
- SimulationParamsEditor - Parameter editor (implemented, not wired in UI yet)
- Encode simulation parameters into a URL-safe string
- Results are re-simulated on load using the encoded spec
- URL formats:
/simulate/results/[base64-encoded-spec]and/s/[encoded]
- Queue utilities and panel exist in code
- Not currently surfaced in the
/simulateUI
apps/explorer-astro/src/
├── pages/
│ └── simulate/
│ ├── index.astro # Simulation entry page
│ └── results/[encoded].astro # SimLink results page
├── components/
│ ├── fork/
│ │ └── ForkStatusPill.astro # Static fork indicator
│ └── islands/
│ ├── ForkStatusPillIsland.tsx # Interactive fork status
│ ├── ForkButton.tsx # Fork creation trigger
│ ├── ForkModal.tsx # Fork config dialog (18KB)
│ ├── ForkDrawerIsland.tsx # Fork management panel
│ ├── SimulationTab.tsx # Main simulation UI (20KB)
│ ├── SimulationPreview.tsx # Preview card (19KB)
│ ├── SimulationResults.tsx # Detailed results (14KB)
│ ├── SimulationSummary.tsx # Summary display (11KB)
│ ├── SimulationQueuePanel.tsx # Batch queue (20KB)
│ ├── SimulationParamsEditor.tsx # Params editor (20KB)
│ ├── BalanceDiffTable.tsx # Balance comparison
│ ├── VerdictBanner.tsx # Safety verdict
│ └── WarningsPanel.tsx # Risk warnings
├── lib/fork/
│ ├── fork-store.ts # Fork state management
│ ├── fork-session.ts # Session tracking
│ ├── fork-worker-client.ts # Worker communication
│ └── fork-serialization.ts # State persistence
└── workers/
└── simulator.worker.ts # Simulation execution worker
/simulate (standalone simulation)
User Input → SimulatorIsland → useSimulator → simulator.worker.ts (RPC eth_call)
→ Effects extraction → SimulationResults
Resimulation (Fork Mode)
ResimulateButton → fork-worker-client.ts → /api/fork/* → EXPLORER_DO
→ SimResult → SimulationTab / VerdictBanner
Note: The client-side
simulator.worker.tsuses RPC-basedeth_callfor lightweight simulation. For full guillotine-mini-powered fork sessions with persistent state, the externalexplorer-doDurable Object service uses the guillotine runtime. See Fork Mode Resimulation for architecture details.
Fork Store (lib/fork/fork-store.ts):
interface ForkSession {
id: string
chainId: number
forkBlock: bigint
simulations: SimulationRun[]
stateSize: number // Memory usage tracking
createdAt: number
}
interface SimulationRun {
id: string
input: SimSpec
result: SimResult | null
timestamp: number
status: 'pending' | 'success' | 'error'
}Client-Side Simulation Worker (simulator.worker.ts):
- Uses RPC-based
eth_callfor lightweight simulation (not full guillotine runtime) - Executes simulations via RPC to fork source
- Extracts effects (balance changes, approvals, logs)
- Calculates safety verdict
- Returns structured results to main thread
Server-Side Fork Sessions (apps/explorer-do):
- Uses guillotine-mini runtime for full EVM simulation
- Runs in Cloudflare Durable Objects for persistence
- Supports RPC endpoint for external tools (Phase 2+)
- See Fork Mode Resimulation for details
-
Navigate to Simulation Page
- Click "Simulate" in header
- Or use
/simulateURL
-
Input Transaction
- Paste transaction hash for resimulation
- Or enter contract address + function name
- Or paste raw transaction data
-
Modify Parameters (Optional)
- Change caller address
- Adjust transaction value
- Modify function arguments
- Set gas limit
-
Run Simulation
- Click "Simulate" button
- Fork auto-creates if needed
- Transaction executes in sandbox
-
Review Results
- Check safety verdict (Safe / Review / Risk)
- Review balance diffs
- Inspect approval changes
- Read warnings panel
- View event logs
-
Share Results
- Copy SimLink URL
- Share with others for review
-
Navigate to Any Transaction
- Example:
/tx/0xabc...
- Example:
-
Click "Resimulate" Button
- Opens simulation modal with prefilled data
-
Modify Parameters
- Change caller to test different senders
- Adjust value to test edge cases
- Modify args to test different scenarios
-
Run & Compare
- Original transaction effects vs modified simulation
- Identify impact of parameter changes
-
Navigate to Any Block
- Example:
/block/12345
- Example:
-
Click "Fork" Button
- Fork modal appears with block prefilled
-
Configure Fork
- Confirm chain (Base Mainnet / Sepolia)
- Confirm block number
- Create fork
-
Fork Indicator Appears
- ForkStatusPill shows in header
- All simulations use this fork state
-
Reset Fork
- Click fork pill → "Reset Fork" button
- Clears all simulation state
- No warnings detected
- No approval changes
- Known contract patterns
- All state changes expected
- Has approval changes (limited amounts)
- Moderate warnings present
- Unverified contract interactions
- Unusual state changes
- Unlimited approval (
type(uint256).max) - Unverified contract with state changes
- Suspicious patterns detected
- Multiple high-severity warnings
-
Approval Warnings
- Unlimited ERC20 approval
- ERC721 setApprovalForAll
- Approval to unverified contract
-
Value Warnings
- Large ETH transfer
- Transfer to unverified contract
- Unusual value for function type
-
State Warnings
- Ownership transfer
- Proxy upgrade
- Critical storage modifications
-
Contract Warnings
- Unverified contract interaction
- Proxy contract detected
- Selfdestruct operation
- Runtime: guillotine-mini (WASM EVM)
- Fork Source: Base RPC (Mainnet or Sepolia)
- State Isolation: Each simulation runs in isolated fork
- Persistence: localStorage (client-side, per-browser)
- Fork Creation: ~1-2s (downloads block state)
- Simulation Execution: ~100-500ms typical
- Memory Usage: ~5-50MB per fork (depends on state size)
- Storage Limits:
- Warn at 50MB
- Hard limit at 100MB
- Auto-cleanup on limit exceeded
Balance Diffs:
- Pre-flight balance query for all affected addresses
- Post-simulation balance query
- Diff calculation with percentage changes
Approval Changes:
- Parse
ApprovalandApprovalForAllevents - Extract spender, amount, token type
- Flag unlimited approvals
Event Logs:
- ABI decoding via WhatsABI
- Topic extraction and indexing
- Parameter formatting
State Changes:
- Storage slot diffs
- Account nonce changes
- Code deployments
- ❌ Fork state is client-side only (localStorage)
- ❌ Fork resets on browser close/clear data
- ❌ No cross-device sync
- ❌ Limited to ~5MB localStorage quota
- ❌ Cannot share live fork sessions (SimLinks are read-only)
- ❌ No persistent fork URLs
- ❌ Single fork per browser (no multiple concurrent forks)
- ❌ Fork state not visible in global explorer navigation
- ❌ Simulated transactions don't appear in feeds/search
- ❌ No RPC endpoint for external tools
- ❌ No time travel (block forwarding/rewinding)
- ❌ No account impersonation (fixed test account)
- ❌ No batch simulation UI for complex flows
- ❌ No simulation history persistence
See FORK_MODE_ENGINEERING.md for full Phase 2+ specifications.
- Cloudflare Durable Objects backend
- Persistent fork URLs:
/fork/<account>/<fork>/... - Cross-device sync
- RPC endpoint for external tools (
/fork/<account>/<fork>/rpc) - Multiple concurrent forks per account
- Fork session management dashboard
- Simulated transactions appear in all feeds
- Search integration (find simulated txs)
- Global fork indicator across all pages
- Fork-aware data fetching everywhere
- Time travel (forward/backward block navigation)
- Account impersonation (simulate as any address)
- Complex simulation flows (multi-tx scenarios)
- Simulation history with replay
- Collaboration (multiplayer forks)
- Fork Mode PRD - Product requirements
- Fork Mode Design - UI/UX specifications
- Fork Mode Engineering - Full technical spec
- Simulation Spec - Simulation patterns
- Transaction Simulation Feature - Single-tx simulation
- Playground Feature - Solidity playground integration
- Pages:
apps/explorer-astro/src/pages/simulate/ - Components:
apps/explorer-astro/src/components/fork/,components/islands/ - State Management:
apps/explorer-astro/src/lib/fork/ - Workers:
apps/explorer-astro/src/workers/simulator.worker.ts
- Fork state serialization/deserialization
- Safety verdict calculation
- Balance diff computation
- Approval detection logic
- Create fork from block page
- Resimulate transaction with modified params
- SimLink encoding/decoding
- Fork reset functionality
- Multi-transaction queue
{
"tevm": "latest",
"lz-string": "^1.5.0"
}Q: Does my fork state persist across browser sessions? A: In Phase 1, fork state is stored in localStorage and persists across tabs but is lost if you clear browser data. Phase 2 (Tevm Black) will introduce persistent cloud-backed forks.
Q: Can I share my fork session with others? A: In Phase 1, you can only share read-only SimLinks (simulation results). Phase 2 will enable shareable live fork sessions via persistent URLs.
Q: Can I use my fork as an RPC endpoint for MetaMask/Foundry? A: Not in Phase 1. Phase 2 (Tevm Black) will expose fork sessions as JSON-RPC endpoints.
Q: How many simulations can I run? A: Unlimited simulations in Phase 1, but fork state is limited to ~100MB. Phase 2 removes limits for Tevm Black subscribers.
Q: Can I fork from any chain? A: Currently Base Mainnet (8453) and Base Sepolia (84532) only. Other chains may be added in the future.
Q: What happens if my fork exceeds the memory limit? A: You'll see a warning at 50MB and the fork will reset at 100MB to prevent browser performance issues.