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>
This commit is contained in:
105
scripts/create-test-swap.sh
Executable file
105
scripts/create-test-swap.sh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/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"
|
||||
Reference in New Issue
Block a user