Files
mev-beta/TESTING.md
Administrator 65c1005d91 feat(testing): add Anvil fork local testing infrastructure
Complete local testing setup with Anvil fork of Arbitrum mainnet:

Infrastructure:
- Docker Compose orchestration (Anvil, MEV Bot, Prometheus, Grafana)
- Anvil fork configuration with 1-second blocks
- Multi-stage Dockerfile for optimized builds
- Health checks and auto-restart policies

Configuration:
- Comprehensive .env.example with all parameters
- Prometheus metrics collection setup
- Grafana datasource provisioning
- .gitignore to prevent committing secrets

Testing Scripts:
- setup-local-fork.sh: Initialize fork and fund test wallet
- create-test-swap.sh: Generate test swaps for bot detection
- Both scripts include validation and helpful output

Integration Components:
- pkg/sequencer/reader.go: WebSocket reader for pending transactions
  - Worker pool pattern (10 workers)
  - <50ms processing target
  - Front-running capability
  - Auto-reconnection with exponential backoff

- pkg/pools/discovery.go: Pool discovery service
  - UniswapV2-style pools (SushiSwap, Camelot)
  - UniswapV3 pools (multiple fee tiers)
  - Factory contract queries
  - Liquidity filtering

Documentation:
- TESTING.md: Complete testing guide
  - Quick start instructions
  - Testing scenarios
  - Monitoring and debugging
  - Performance benchmarks
  - Troubleshooting guide

This enables safe local testing without deploying to public testnet,
using real Arbitrum mainnet state forked locally with Anvil.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 18:52:56 +01:00

447 lines
10 KiB
Markdown

# 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 <YOUR_ADDRESS> --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 <ADDRESS>
```
### Manipulate State
```bash
# Set arbitrary balances
docker-compose exec anvil cast rpc anvil_setBalance <ADDRESS> <AMOUNT>
# Mine blocks
docker-compose exec anvil cast rpc anvil_mine 100
# Set next block timestamp
docker-compose exec anvil cast rpc evm_setNextBlockTimestamp <TIMESTAMP>
```
### 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`