# REVM Transaction Simulator and Analyzer A Rust library that combines powerful transaction simulation with comprehensive analysis capabilities for EVM-based blockchains. Built on [REVM](https://github.com/bluealloy/revm), this tool enables you to: - **Simulate** complex transactions and their interactions before actual execution - **Analyze** potential outcomes, asset transfers, and state changes - **Detect** possible errors and their root causes - **Preview** all transaction effects in a safe, isolated environment Perfect for: - DeFi developers testing complex interactions - Wallet developers validating transaction safety - Protocol teams analyzing contract behaviors - Security researchers investigating transaction patterns ## Key Features - **Flexible Inspector System** - Built on REVM's inspector framework - Custom `TxInspector` for transaction analysis - Support for custom inspector implementations - Comprehensive asset transfer tracking - **Complete Call Hierarchy Analysis** - Full depth call stack tracking - Detailed call context information - Internal transaction tracing - Precise error location in call stack - Step-by-step execution tracing - **Enhanced Error Handling** - Detailed error messages and traces - Error location in call stack - Revert reason decoding - Custom error parsing - Contract-specific error context - **Batch Transaction Processing** - Process multiple transactions - Stateful/stateless execution modes - Automatic state management - Detailed execution results - **Asset Analysis** - Native token transfers - ERC20 token transfers - Transfer event parsing - Balance change tracking - Complete transaction logs ## Features - `async` - Enable async support - `ws` - WebSocket provider support - `http` - HTTP provider support (default) ### TLS Implementation Options By default, this library uses the system's native TLS implementation (typically OpenSSL). However, you can switch to a pure Rust TLS implementation: - **rustls-tls**: Uses rustls instead of native-tls (OpenSSL) ```toml # In your Cargo.toml [dependencies] revm-trace = { version = "2.0.5", default-features = false, features = ["rustls-tls"] } ``` To run examples with rustls-tls: ```bash cargo run --example test_rustls --no-default-features --features rustls-tls ``` This is particularly useful for: - Cross-compilation scenarios - Environments where OpenSSL is not available - Alpine Linux-based Docker containers - WASM targets ## Installation Add this to your `Cargo.toml`: ```toml revm-trace = "2.0.5" ``` ## Quick Start ```rust use revm_trace::{ TransactionProcessor, evm::create_evm_with_inspector, types::{BlockEnv, SimulationTx, SimulationBatch}, inspectors::TxInspector, }; use alloy::primitives::{address, U256, TxKind}; #[tokio::main] async fn main() -> anyhow::Result<()> { // Initialize EVM with transaction inspector let mut evm = create_evm_with_inspector( "https://eth-mainnet.g.alchemy.com/v2/your-api-key", TxInspector::new(), ).await?; // Create simulation transaction let tx = SimulationTx { caller: address!("C255fC198eEdAC7AF8aF0f6e0ca781794B094A61"), transact_to: TxKind::Call(address!("d878229c9c3575F224784DE610911B5607a3ad15")), value: U256::from(120000000000000000u64), // 0.12 ETH data: vec![].into(), }; // Create batch with single transaction let batch = SimulationBatch { block_env: BlockEnv { number: 21784863, timestamp: 1700000000, }, transactions: vec![tx], is_stateful: false, }; // Execute transaction batch let results = evm.process_transactions(batch) .into_iter() .map(|v| v.unwrap()) .collect::<Vec<_>>(); // Process results for (execution_result, inspector_output) in results { match execution_result.is_success() { true => { println!("Transaction succeeded!"); for transfer in inspector_output.asset_transfers { println!( "Transfer: {} from {} to {}", transfer.value, transfer.from, transfer.to.unwrap() ); } } false => { println!("Transaction failed!"); if let Some(error_trace) = inspector_output.error_trace_address { println!("Error occurred at call depth: {}", error_trace.len()); } } } } Ok(()) } ``` ## More Examples For more detailed examples and use cases, please check: - [Example Directory](./examples/): Contains standalone examples demonstrating specific features - DeFi interaction simulations - Token transfer analysis - Complex contract interactions - Proxy contract handling - [Integration Tests](./tests/trace_tests.rs): Comprehensive test cases showing various usage scenarios - Transaction batching - Error handling - State tracking - Event analysis These examples cover common use cases and demonstrate best practices for using the library. For a quick overview, here are some key examples: 1. [Simulating DeFi Swaps](./examples/defi_swap.rs) 2. [Analyzing Token Transfers](./examples/token_transfer.rs) 3. [Handling Complex Contract Interactions](./examples/contract_interaction.rs) 4. [Working with Proxy Contracts](./examples/proxy_contracts.rs) ## Important Notes ### Safe Simulation Environment All simulations run in an isolated environment: - No actual blockchain state is modified - No real transactions are submitted - No gas fees are spent - Perfect for testing and validation ### Thread Safety and Concurrency The EVM instance is not thread-safe and cannot be shared between threads. Here's how to handle concurrent operations: ##### ⌠What NOT to do ```rust // DON'T share a single EVM instance across threads let mut evm = create_evm_with_inspector("https://rpc...", TxInspector::new()).await?; let results: Vec<_> = transactions .par_iter() // ⌠This will fail - EVM instance is not thread-safe .map(|tx| { evm.process_transactions(SimulationBatch { block_env: block_env.clone(), transactions: vec![tx.clone()], is_stateful: true, }) // Sharing EVM across threads }) .collect(); ``` ##### ✅ Correct Usage 1. **Sequential Processing** ```rust // Process transactions sequentially with a single EVM instance let mut evm = create_evm_with_inspector("https://rpc...", TxInspector::new()).await?; let results: Vec<_> = transactions .iter() .map(|tx| { evm.process_transactions(SimulationBatch { block_env: block_env.clone(), transactions: vec![tx.clone()], is_stateful: true, }) }) .collect(); ``` 2. **Parallel Processing with Multiple Instances** ```rust use rayon::prelude::*; // Create new EVM instance for each thread let results: Vec<Result<_, _>> = transactions .par_iter() .map(|tx| async { // Each thread gets its own EVM instance let mut evm = create_evm_with_inspector("https://rpc...", TxInspector::new()).await?; evm.process_transactions(SimulationBatch { block_env: block_env.clone(), transactions: vec![tx.clone()], is_stateful: true, }) }) .collect(); ``` #### Performance Considerations - **RPC Limitations**: - Each EVM instance maintains its own RPC connection - Consider your RPC provider's connection and rate limits - Too many parallel instances might exceed provider limits - **Resource Usage**: - Each EVM instance requires its own memory - Balance parallelism with resource constraints - Monitor system memory usage when scaling - **Optimal Approach**: - For small batches: Use sequential processing - For large batches: Use parallel processing with connection pooling - Consider implementing a worker pool pattern for better resource management ### Working with Proxy Contracts The library automatically handles proxy contracts by resolving their implementations: - EIP-1967 proxies - EIP-1967 beacon proxies - OpenZeppelin transparent proxies - EIP-1822 (UUPS) proxies ## Features in Detail ### Asset Transfer Tracking - Native token transfers (including internal transfers) - ERC20 token transfers - Transaction logs and events - Chronological ordering of transfers - Complete token information collection ### Transaction Simulation - Full EVM context simulation - Custom environment configuration - Detailed execution results - Error handling and revert messages ## Historical State Access Simulations can be run against different historical states: - Recent blocks: Available on all nodes - Historical blocks: Requires archive node access - Future blocks: Uses latest state as base ## Contributing Contributions are welcome! Please feel free to submit a Pull Request. ## License This project is licensed under either of * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) * MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) at your option. ## Acknowledgments Built with [REVM](https://github.com/bluealloy/revm) and [Alloy](https://github.com/alloy-rs/alloy)