# MEV Bot V2 - Local Fork Testing Guide This guide explains how to test the MEV Bot V2 using a local Arbitrum fork with Anvil. ## Overview Instead of deploying to a public testnet, we use Foundry's Anvil to create a local fork of Arbitrum mainnet. This allows us to: - ✅ Test with real mainnet state (pools, liquidity, etc.) - ✅ Execute transactions instantly (no waiting for block confirmations) - ✅ Use unlimited test funds - ✅ Reset and replay scenarios easily - ✅ Debug without spending real gas - ✅ Test front-running scenarios safely ## Prerequisites 1. **Docker & Docker Compose** installed 2. **Foundry** (for cast commands) - `curl -L https://foundry.paradigm.xyz | bash && foundryup` 3. **Test wallet with private key** (NEVER use real funds) ## Quick Start ### 1. Initial Setup ```bash # Copy environment file cp .env.example .env # Edit .env and set your test private key nano .env # Set PRIVATE_KEY to a test wallet key # Set up the local fork ./scripts/setup-local-fork.sh ``` This script will: - Start Anvil fork of Arbitrum - Fund your test wallet with 100 ETH - Verify connection and balances ### 2. Start the Full Stack ```bash # Start all services (Anvil, MEV Bot, Prometheus, Grafana) docker-compose up -d # View MEV bot logs docker-compose logs -f mev-bot # View Anvil logs docker-compose logs -f anvil ``` ### 3. Create Test Swaps ```bash # Create a test swap for the bot to detect ./scripts/create-test-swap.sh ``` This will: - Wrap ETH to WETH - Approve SushiSwap router - Execute a 0.1 ETH → USDC swap - The MEV bot should detect this as a potential front-run opportunity ### 4. Monitor Activity **View Metrics:** ```bash # Prometheus metrics open http://localhost:9090 # Query example: mev_bot_opportunities_found ``` **View Grafana Dashboard:** ```bash # Grafana UI open http://localhost:3000 # Login: admin / admin ``` **View Bot Logs:** ```bash docker-compose logs -f mev-bot | grep -i "opportunity\|profit\|execution" ``` ## Architecture ``` ┌─────────────────┐ │ Anvil Fork │ ← Forked Arbitrum mainnet state │ (Port 8545) │ └────────┬────────┘ │ ├─────────► Pool Discovery (queries real pools) │ ├─────────► Sequencer Reader (monitors pending txs) │ └─────────► Executor (sends front-run txs) │ ▼ ┌──────────────────┐ │ MEV Bot V2 │ └──────────────────┘ │ ▼ ┌──────────────────┐ │ Prometheus │ ← Metrics │ (Port 9090) │ └──────────────────┘ │ ▼ ┌──────────────────┐ │ Grafana │ ← Visualization │ (Port 3000) │ └──────────────────┘ ``` ## Configuration ### Environment Variables Edit `.env` to configure the bot: **Critical Settings:** ```bash # Your test wallet private key PRIVATE_KEY=your_test_key_here # Minimum profit to execute (0.01 ETH) MIN_PROFIT=10000000000000000 # Enable front-running ENABLE_FRONT_RUNNING=true # Enable simulation before execution ENABLE_SIMULATION=true ``` **Risk Parameters:** ```bash # Maximum position size (10 ETH) MAX_POSITION_SIZE=10000000000000000000 # Maximum daily volume (100 ETH) MAX_DAILY_VOLUME=100000000000000000000 ``` **Performance Tuning:** ```bash # Worker threads WORKER_COUNT=10 # Buffer size BUFFER_SIZE=1000 # Log level LOG_LEVEL=debug ``` ### Anvil Configuration You can customize the fork in `docker-compose.yml`: ```yaml anvil: command: > anvil --fork-url ${ARBITRUM_RPC_URL} --fork-block-number ${FORK_BLOCK_NUMBER:-latest} # Specific block or latest --chain-id 42161 --accounts 10 # Test accounts --balance 10000 # ETH per account --block-time 1 # 1 second blocks ``` ## Testing Scenarios ### Scenario 1: Simple Arbitrage Detection ```bash # 1. Start the bot docker-compose up -d mev-bot # 2. Create imbalance by swapping on one DEX ./scripts/create-test-swap.sh # 3. Check if bot detected opportunity docker-compose logs mev-bot | grep "opportunity" ``` ### Scenario 2: Front-Running Test ```bash # 1. Enable front-running in .env ENABLE_FRONT_RUNNING=true # 2. Restart bot docker-compose restart mev-bot # 3. Create a large swap ./scripts/create-test-swap.sh # 4. Check if bot front-ran the transaction docker-compose logs mev-bot | grep "front-running" ``` ### Scenario 3: Multi-Hop Arbitrage ```bash # Create price imbalance across multiple pools # Swap WETH → USDC on SushiSwap # Swap USDC → WBTC on Uniswap V3 # Swap WBTC → WETH on Camelot # Bot should detect triangular arbitrage opportunity docker-compose logs mev-bot | grep "triangular" ``` ### Scenario 4: Stress Test ```bash # Generate many swaps quickly for i in {1..100}; do ./scripts/create-test-swap.sh & done # Monitor processing latency docker-compose logs mev-bot | grep "latency" ``` ## Monitoring & Debugging ### Check Pool Discovery ```bash # View discovered pools docker-compose logs mev-bot | grep "discovered pool" # Check total pools cached docker-compose logs mev-bot | grep "pools_cached" ``` ### Check Sequencer Connection ```bash # Verify WebSocket connection docker-compose logs mev-bot | grep "connected to sequencer" # Check transaction processing docker-compose logs mev-bot | grep "tx_processed" ``` ### Check Opportunity Detection ```bash # View detected opportunities docker-compose logs mev-bot | grep "opportunities_found" # View execution attempts docker-compose logs mev-bot | grep "executions_attempted" ``` ### Check Performance Metrics ```bash # Prometheus queries curl http://localhost:9090/api/v1/query?query=mev_bot_parse_latency_seconds curl http://localhost:9090/api/v1/query?query=mev_bot_detect_latency_seconds curl http://localhost:9090/api/v1/query?query=mev_bot_execute_latency_seconds ``` ### Debug Mode ```bash # Enable debug logging echo "LOG_LEVEL=debug" >> .env # Restart with debug logs docker-compose restart mev-bot # View detailed logs docker-compose logs -f mev-bot ``` ## Common Issues ### Issue: Anvil not starting ```bash # Check if port 8545 is already in use lsof -i :8545 # Kill existing process or change port in docker-compose.yml ``` ### Issue: Bot not discovering pools ```bash # Check RPC connectivity docker-compose exec anvil cast block-number --rpc-url http://localhost:8545 # Check pool discovery logs docker-compose logs mev-bot | grep "pool discovery" # Verify token addresses are correct for Arbitrum ``` ### Issue: No opportunities detected ```bash # 1. Verify pools were discovered docker-compose logs mev-bot | grep "pools_cached" # 2. Check minimum thresholds # Lower MIN_PROFIT in .env for testing # 3. Create larger price imbalances # Increase swap amounts in create-test-swap.sh ``` ### Issue: Transactions reverting ```bash # Enable simulation to catch errors before execution ENABLE_SIMULATION=true # Check revert reasons docker-compose logs mev-bot | grep "revert" # Verify wallet has sufficient balance docker-compose exec anvil cast balance --rpc-url http://localhost:8545 ``` ## Advanced Testing ### Forking from Specific Block ```bash # Set specific block in .env FORK_BLOCK_NUMBER=180000000 # Restart Anvil docker-compose restart anvil ``` ### Impersonate Accounts ```bash # Use Anvil's account impersonation to test edge cases docker-compose exec anvil cast rpc anvil_impersonateAccount
``` ### Manipulate State ```bash # Set arbitrary balances docker-compose exec anvil cast rpc anvil_setBalance
# Mine blocks docker-compose exec anvil cast rpc anvil_mine 100 # Set next block timestamp docker-compose exec anvil cast rpc evm_setNextBlockTimestamp ``` ### Reset Fork ```bash # Reset to original fork state docker-compose exec anvil cast rpc anvil_reset # Re-run pool discovery docker-compose restart mev-bot ``` ## Performance Benchmarks Target metrics for production readiness: - ✅ **Parse Latency:** < 5ms per transaction - ✅ **Detect Latency:** < 10ms per opportunity scan - ✅ **Execute Latency:** < 30ms decision time - ✅ **Total Latency:** < 50ms end-to-end - ✅ **Throughput:** > 100 tx/second processing - ✅ **Memory:** < 500MB steady state - ✅ **CPU:** < 50% on 4 cores ### Benchmarking Commands ```bash # Measure parse latency docker-compose logs mev-bot | grep "avg_parse_latency" # Measure detection latency docker-compose logs mev-bot | grep "avg_detect_latency" # Measure execution latency docker-compose logs mev-bot | grep "avg_execute_latency" # Check memory usage docker stats mev-bot-v2 # Load test with many concurrent swaps ./scripts/load-test.sh ``` ## Cleanup ```bash # Stop all services docker-compose down # Remove volumes (clears metrics data) docker-compose down -v # Clean up logs rm -rf logs/* ``` ## Next Steps Once local testing is successful: 1. **Optimize Parameters:** Tune MIN_PROFIT, MAX_SLIPPAGE, etc. 2. **Deploy Flashloan Contract:** Deploy executor contract to Arbitrum testnet 3. **Testnet Testing:** Test on Arbitrum Goerli with real test ETH 4. **Mainnet Deployment:** Deploy with conservative parameters and monitoring ## Resources - **Anvil Docs:** https://book.getfoundry.sh/anvil/ - **Arbitrum Docs:** https://docs.arbitrum.io/ - **Prometheus Docs:** https://prometheus.io/docs/ - **Grafana Docs:** https://grafana.com/docs/ ## Support For issues or questions: 1. Check logs: `docker-compose logs mev-bot` 2. Review configuration: `.env` 3. Check Anvil status: `docker-compose logs anvil` 4. Verify metrics: `http://localhost:9090`