Files
mev-beta/scripts/auto_test_swaps.sh
Administrator 047f2d2389 test(swap-detection): add automated swap detection and analysis tools
- Add auto_test_swaps.sh for monitoring live Arbitrum mainnet
- Add fetch_swaps.sh for capturing recent swap transactions
- Add analyze_detected_swaps.py for parsing and analyzing swap data
- Add comprehensive test results documentation

Test Results:
- Successfully detected 91 swaps from live mainnet
- Identified 33 unique liquidity pools
- Validated UniswapV2 and UniswapV3 event detection
- Confirmed transaction data capture accuracy

Key Features:
- Real-time monitoring with 3-second polling
- UniswapV2/V3 swap event signature filtering
- Transaction impersonation for Anvil replay (blocked by archive RPC)
- Comprehensive analytics and reporting

Known Limitations:
- Anvil replay requires archive RPC access
- WebSocket connection to Anvil not functional
- Recommendation: Deploy to testnet for full E2E testing

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 21:37:51 +01:00

174 lines
6.3 KiB
Bash
Executable File

#!/bin/bash
# Automated script to:
# 1. Monitor live Arbitrum mainnet for swaps
# 2. Replay those swaps on Anvil fork
# 3. Let MEV Bot detect arbitrage opportunities
set -e
CAST="/home/administrator/.foundry/bin/cast"
ARBITRUM_MAINNET_RPC="https://arb1.arbitrum.io/rpc"
ANVIL_RPC="http://localhost:8545"
TEST_ACCOUNT="0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"
TEST_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"
SWAPS_LOG="detected_swaps.jsonl"
REPLAY_LOG="replayed_swaps.log"
# Known swap event signatures
UNISWAP_V2_SWAP="0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822"
UNISWAP_V3_SWAP="0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67"
echo "========================================="
echo " MEV Bot V2 - Automatic Swap Tester"
echo "========================================="
echo ""
echo "Monitoring: Arbitrum Mainnet"
echo "Testing on: Anvil Fork (localhost:8545)"
echo "Bot Wallet: $TEST_ACCOUNT"
echo ""
echo "This script will:"
echo "1. Monitor recent Arbitrum mainnet blocks"
echo "2. Detect swap transactions"
echo "3. Replay them on Anvil fork"
echo "4. Let MEV Bot detect arbitrage"
echo ""
echo "Press Ctrl+C to stop"
echo ""
echo "========================================="
# Initialize logs
> "$SWAPS_LOG"
> "$REPLAY_LOG"
SWAPS_PROCESSED=0
BLOCKS_SCANNED=0
while true; do
# Get latest mainnet block
MAINNET_BLOCK=$($CAST block-number --rpc-url "$ARBITRUM_MAINNET_RPC" 2>/dev/null || echo "0")
if [ "$MAINNET_BLOCK" == "0" ]; then
echo "[ERROR] Failed to get mainnet block number, retrying..."
sleep 5
continue
fi
# Get current Anvil block
ANVIL_BLOCK=$($CAST block-number --rpc-url "$ANVIL_RPC" 2>/dev/null || echo "0")
echo "[$(date +%H:%M:%S)] Mainnet: $MAINNET_BLOCK | Anvil: $ANVIL_BLOCK | Processed: $SWAPS_PROCESSED swaps"
# Scan blocks (start from 5 blocks back to ensure finality)
SCAN_BLOCK=$((MAINNET_BLOCK - 5))
BLOCK_DATA=$($CAST block $SCAN_BLOCK --json --rpc-url "$ARBITRUM_MAINNET_RPC" 2>/dev/null || echo "{}")
# Extract transaction hashes
TX_HASHES=$(echo "$BLOCK_DATA" | jq -r '.transactions[]?' 2>/dev/null || echo "")
for TX_HASH in $TX_HASHES; do
if [ -z "$TX_HASH" ]; then
continue
fi
# Check if already processed
if grep -q "$TX_HASH" "$SWAPS_LOG" 2>/dev/null; then
continue
fi
# Get transaction receipt
RECEIPT=$($CAST receipt "$TX_HASH" --json --rpc-url "$ARBITRUM_MAINNET_RPC" 2>/dev/null || echo "{}")
# Check if this transaction has swap events
SWAP_LOGS=$(echo "$RECEIPT" | jq -r ".logs[]? | select(.topics[0]? == \"$UNISWAP_V2_SWAP\" or .topics[0]? == \"$UNISWAP_V3_SWAP\")" 2>/dev/null || echo "")
if [ ! -z "$SWAP_LOGS" ]; then
# Get pool address
POOL_ADDRESS=$(echo "$SWAP_LOGS" | jq -r '.address' | head -1)
# Get full transaction
TX_DATA=$($CAST tx "$TX_HASH" --json --rpc-url "$ARBITRUM_MAINNET_RPC" 2>/dev/null || echo "{}")
TO=$(echo "$TX_DATA" | jq -r '.to // empty')
FROM=$(echo "$TX_DATA" | jq -r '.from // empty')
VALUE_HEX=$(echo "$TX_DATA" | jq -r '.value // "0x0"')
INPUT=$(echo "$TX_DATA" | jq -r '.input // "0x"')
GAS_PRICE=$(echo "$TX_DATA" | jq -r '.gasPrice // "0x0"')
# Convert VALUE from hex to decimal for Cast (handles 0x0, null, empty)
if [ "$VALUE_HEX" == "null" ] || [ -z "$VALUE_HEX" ] || [ "$VALUE_HEX" == "0x0" ] || [ "$VALUE_HEX" == "0x00" ]; then
VALUE="0"
else
# Convert hex to decimal using Cast
VALUE=$($CAST --to-base "$VALUE_HEX" 10 2>/dev/null || echo "0")
fi
if [ -z "$TO" ] || [ "$TO" == "null" ]; then
continue # Skip contract creation
fi
echo "[SWAP DETECTED] Block: $SCAN_BLOCK | TX: ${TX_HASH:0:10}... | Pool: ${POOL_ADDRESS:0:10}..."
# Log the swap
jq -n \
--arg tx "$TX_HASH" \
--arg block "$SCAN_BLOCK" \
--arg pool "$POOL_ADDRESS" \
--arg to "$TO" \
--arg from "$FROM" \
--arg value "$VALUE_HEX" \
--arg input "$INPUT" \
'{tx: $tx, block: $block, pool: $pool, to: $to, from: $from, value: $value, input: $input}' \
>> "$SWAPS_LOG"
# Replay on Anvil fork
echo "[REPLAYING] Sending swap to Anvil..."
# Impersonate the original sender
$CAST rpc anvil_impersonateAccount "$FROM" --rpc-url "$ANVIL_RPC" 2>/dev/null || true
# Set balance for gas
$CAST rpc anvil_setBalance "$FROM" "0x56BC75E2D63100000" --rpc-url "$ANVIL_RPC" 2>/dev/null || true # 100 ETH
# Send the transaction
REPLAY_TX=$($CAST send "$TO" \
--from "$FROM" \
--value "$VALUE" \
--gas-limit 500000 \
--rpc-url "$ANVIL_RPC" \
"$INPUT" 2>&1 || echo "FAILED")
if echo "$REPLAY_TX" | grep -q "blockHash"; then
REPLAY_TX_HASH=$(echo "$REPLAY_TX" | jq -r '.transactionHash // empty' 2>/dev/null || echo "unknown")
echo "[SUCCESS] Replayed as: ${REPLAY_TX_HASH:0:10}..."
echo "[$(date)] $TX_HASH -> $REPLAY_TX_HASH" >> "$REPLAY_LOG"
# Stop impersonating
$CAST rpc anvil_stopImpersonatingAccount "$FROM" --rpc-url "$ANVIL_RPC" 2>/dev/null || true
SWAPS_PROCESSED=$((SWAPS_PROCESSED + 1))
echo ""
echo "=== Swap #$SWAPS_PROCESSED Replayed ==="
echo "Original TX: $TX_HASH"
echo "Pool: $POOL_ADDRESS"
echo "Replayed TX: $REPLAY_TX_HASH"
echo "===================================="
echo ""
# Pause to let the bot process
sleep 2
else
echo "[FAILED] Could not replay: $REPLAY_TX"
$CAST rpc anvil_stopImpersonatingAccount "$FROM" --rpc-url "$ANVIL_RPC" 2>/dev/null || true
fi
fi
done
BLOCKS_SCANNED=$((BLOCKS_SCANNED + 1))
# Check every 3 seconds
sleep 3
done