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>
106 lines
3.0 KiB
Bash
Executable File
106 lines
3.0 KiB
Bash
Executable File
#!/bin/bash
|
|
set -e
|
|
|
|
# MEV Bot V2 - Create Test Swap Script
|
|
# This script creates a test swap on the Anvil fork for the bot to detect
|
|
|
|
# Colors for output
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
NC='\033[0m' # No Color
|
|
|
|
echo "🔄 Creating test swap on Anvil fork..."
|
|
|
|
# Load environment variables
|
|
if [ ! -f .env ]; then
|
|
echo -e "${RED}❌ Error: .env file not found${NC}"
|
|
exit 1
|
|
fi
|
|
source .env
|
|
|
|
# Token addresses on Arbitrum
|
|
WETH="0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
|
|
USDC="0xFF970a61A04b1cA14834A43f5dE4533eBDDB5CC8"
|
|
|
|
# SushiSwap Router on Arbitrum
|
|
SUSHISWAP_ROUTER="0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506"
|
|
|
|
# Amount to swap (0.1 ETH)
|
|
AMOUNT="100000000000000000"
|
|
|
|
echo -e "${YELLOW}Token In: WETH ($WETH)${NC}"
|
|
echo -e "${YELLOW}Token Out: USDC ($USDC)${NC}"
|
|
echo -e "${YELLOW}Amount: 0.1 ETH${NC}"
|
|
|
|
# Step 1: Wrap ETH to WETH
|
|
echo ""
|
|
echo "📦 Step 1: Wrapping ETH to WETH..."
|
|
docker-compose exec -T anvil cast send $WETH \
|
|
"deposit()" \
|
|
--value 0.1ether \
|
|
--private-key $PRIVATE_KEY \
|
|
--rpc-url http://localhost:8545
|
|
|
|
WETH_BALANCE=$(docker-compose exec -T anvil cast call $WETH \
|
|
"balanceOf(address)(uint256)" \
|
|
$(docker-compose exec -T anvil cast wallet address $PRIVATE_KEY) \
|
|
--rpc-url http://localhost:8545)
|
|
echo -e "${GREEN}✅ WETH Balance: $WETH_BALANCE${NC}"
|
|
|
|
# Step 2: Approve router to spend WETH
|
|
echo ""
|
|
echo "✅ Step 2: Approving SushiSwap router..."
|
|
docker-compose exec -T anvil cast send $WETH \
|
|
"approve(address,uint256)" \
|
|
$SUSHISWAP_ROUTER \
|
|
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" \
|
|
--private-key $PRIVATE_KEY \
|
|
--rpc-url http://localhost:8545
|
|
|
|
echo -e "${GREEN}✅ Approval confirmed${NC}"
|
|
|
|
# Step 3: Execute swap
|
|
echo ""
|
|
echo "🔄 Step 3: Executing swap on SushiSwap..."
|
|
echo -e "${YELLOW}This swap should be detected by the MEV bot!${NC}"
|
|
|
|
# Build swap calldata
|
|
# swapExactTokensForTokens(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline)
|
|
DEADLINE=$(($(date +%s) + 3600))
|
|
TO=$(docker-compose exec -T anvil cast wallet address $PRIVATE_KEY)
|
|
|
|
docker-compose exec -T anvil cast send $SUSHISWAP_ROUTER \
|
|
"swapExactTokensForTokens(uint256,uint256,address[],address,uint256)" \
|
|
$AMOUNT \
|
|
"0" \
|
|
"[$WETH,$USDC]" \
|
|
$TO \
|
|
$DEADLINE \
|
|
--private-key $PRIVATE_KEY \
|
|
--rpc-url http://localhost:8545
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✅ Test swap executed!${NC}"
|
|
|
|
# Check balances
|
|
echo ""
|
|
echo "📊 Final balances:"
|
|
WETH_BALANCE=$(docker-compose exec -T anvil cast call $WETH \
|
|
"balanceOf(address)(uint256)" \
|
|
$TO \
|
|
--rpc-url http://localhost:8545)
|
|
echo -e " WETH: $WETH_BALANCE"
|
|
|
|
USDC_BALANCE=$(docker-compose exec -T anvil cast call $USDC \
|
|
"balanceOf(address)(uint256)" \
|
|
$TO \
|
|
--rpc-url http://localhost:8545)
|
|
echo -e " USDC: $USDC_BALANCE"
|
|
|
|
echo ""
|
|
echo -e "${GREEN}✨ Test swap complete!${NC}"
|
|
echo ""
|
|
echo "Check the MEV bot logs to see if it detected the opportunity:"
|
|
echo " docker-compose logs -f mev-bot"
|