256 lines
13 KiB
Bash
Executable File
256 lines
13 KiB
Bash
Executable File
#!/bin/bash
|
|
# Live MEV Bot Activity Monitor
|
|
# Shows real-time opportunities and execution attempts
|
|
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo "🤖 MEV Bot Live Activity Monitor"
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo "Monitoring: logs/mev_bot.log"
|
|
echo "Bot Wallet: 0x40091653f652a259747D86d7Cbe3e2848082a051"
|
|
echo "Network: Arbitrum One"
|
|
echo ""
|
|
echo "Watching for:"
|
|
echo " 🎯 Opportunities detected"
|
|
echo " ✅ Executable opportunities (isExecutable:true)"
|
|
echo " ⚡ Execution attempts"
|
|
echo " 💰 Successful trades"
|
|
echo " ❌ Errors (parsing, RPC, zero address)"
|
|
echo ""
|
|
echo "Press Ctrl+C to stop"
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
|
|
# Color codes
|
|
GREEN='\033[0;32m'
|
|
RED='\033[0;31m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
CYAN='\033[0;36m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Track stats
|
|
OPPORTUNITIES=0
|
|
EXECUTABLE=0
|
|
EXECUTIONS=0
|
|
ERRORS=0
|
|
PARSING_ERRORS=0
|
|
RPC_ERRORS=0
|
|
ZERO_ADDRESS_ERRORS=0
|
|
LAST_STATS_DISPLAY=0 # Track last opportunity count when stats were displayed
|
|
|
|
# CRITICAL FIX: Use correct log file name (mev_bot.log with underscore, not mev-bot.log with hyphen)
|
|
tail -f logs/mev_bot.log | while read line; do
|
|
# Detect opportunities (NEW: Updated to match current log format)
|
|
if echo "$line" | grep -q "⚡ Starting arbitrage analysis\|ARBITRAGE OPPORTUNITY DETECTED\|\[OPPORTUNITY\]"; then
|
|
OPPORTUNITIES=$((OPPORTUNITIES + 1))
|
|
|
|
# Extract basic info
|
|
TIMESTAMP=$(echo "$line" | awk '{print $1, $2}')
|
|
|
|
# Check if executable
|
|
if echo "$line" | grep -q "isExecutable:true"; then
|
|
EXECUTABLE=$((EXECUTABLE + 1))
|
|
echo -e "${GREEN}[$TIMESTAMP] ✅ EXECUTABLE OPPORTUNITY #$EXECUTABLE${NC}"
|
|
|
|
# Extract token pair (executable)
|
|
if echo "$line" | grep -oP 'tokenIn:[^ ]+' &>/dev/null; then
|
|
TOKEN_IN=$(echo "$line" | grep -oP 'tokenIn:[^ \]]+' | cut -d: -f2)
|
|
TOKEN_OUT=$(echo "$line" | grep -oP 'tokenOut:[^ \]]+' | cut -d: -f2)
|
|
echo -e "${CYAN} 🔄 Pair: ${TOKEN_IN} → ${TOKEN_OUT}${NC}"
|
|
fi
|
|
|
|
# Extract amounts
|
|
AMOUNT_IN=$(echo "$line" | grep -oP 'Amount In: [0-9.]+' | grep -oP '[0-9.]+')
|
|
AMOUNT_OUT=$(echo "$line" | grep -oP 'Amount Out: [0-9.]+' | grep -oP '[0-9.]+')
|
|
if [[ -n "$AMOUNT_IN" ]] && [[ -n "$AMOUNT_OUT" ]]; then
|
|
echo -e "${CYAN} 📊 Amounts: ${AMOUNT_IN} → ${AMOUNT_OUT}${NC}"
|
|
fi
|
|
|
|
# Extract financial metrics
|
|
ESTIMATED_PROFIT=$(echo "$line" | grep -oP 'estimatedProfitETH:[0-9.]+' | cut -d: -f2)
|
|
GAS_COST=$(echo "$line" | grep -oP 'gasCostETH:[0-9.eE+-]+' | cut -d: -f2)
|
|
NET_PROFIT=$(echo "$line" | grep -oP 'netProfitETH:[0-9.eE+-]+' | cut -d: -f2)
|
|
|
|
if [[ -n "$NET_PROFIT" ]]; then
|
|
echo -e "${GREEN} 💰 Net Profit: ${NET_PROFIT} ETH${NC}"
|
|
fi
|
|
if [[ -n "$GAS_COST" ]]; then
|
|
echo -e "${YELLOW} ⛽ Gas Cost: ${GAS_COST} ETH${NC}"
|
|
fi
|
|
|
|
# Extract profit margin
|
|
PROFIT_MARGIN=$(echo "$line" | grep -oP 'profitMargin:[0-9.eE+-]+' | cut -d: -f2)
|
|
if [[ -n "$PROFIT_MARGIN" ]]; then
|
|
PROFIT_MARGIN_PCT=$(echo "$PROFIT_MARGIN * 100" | bc -l 2>/dev/null || echo "$PROFIT_MARGIN")
|
|
echo -e "${GREEN} 📊 Profit Margin: $(printf "%.4f" $PROFIT_MARGIN_PCT 2>/dev/null || echo "$PROFIT_MARGIN")%${NC}"
|
|
fi
|
|
|
|
# Extract price impact
|
|
PRICE_IMPACT=$(echo "$line" | grep -oP 'priceImpact:[0-9.eE+-]+' | cut -d: -f2)
|
|
if [[ -n "$PRICE_IMPACT" ]]; then
|
|
PRICE_IMPACT_PCT=$(echo "$PRICE_IMPACT * 100" | bc -l 2>/dev/null || echo "$PRICE_IMPACT")
|
|
echo -e "${GREEN} 📊 Price Impact: $(printf "%.6f" $PRICE_IMPACT_PCT 2>/dev/null || echo "$PRICE_IMPACT")%${NC}"
|
|
fi
|
|
|
|
# Extract confidence
|
|
CONFIDENCE=$(echo "$line" | grep -oP 'confidence:[0-9.]+' | cut -d: -f2)
|
|
if [[ -n "$CONFIDENCE" ]]; then
|
|
CONFIDENCE_PCT=$(echo "$CONFIDENCE * 100" | bc -l 2>/dev/null || echo "$CONFIDENCE")
|
|
echo -e "${GREEN} 🎯 Confidence: $(printf "%.1f" $CONFIDENCE_PCT 2>/dev/null || echo "$CONFIDENCE")%${NC}"
|
|
fi
|
|
else
|
|
# Non-executable - Show detailed metrics
|
|
echo -e "${YELLOW}[$TIMESTAMP] 🎯 Opportunity #$OPPORTUNITIES (not executable)${NC}"
|
|
|
|
# Extract token pair (non-executable)
|
|
if echo "$line" | grep -oP 'tokenIn:[^ ]+' &>/dev/null; then
|
|
TOKEN_IN=$(echo "$line" | grep -oP 'tokenIn:[^ \]]+' | cut -d: -f2)
|
|
TOKEN_OUT=$(echo "$line" | grep -oP 'tokenOut:[^ \]]+' | cut -d: -f2)
|
|
echo -e "${CYAN} 🔄 Pair: ${TOKEN_IN} → ${TOKEN_OUT}${NC}"
|
|
fi
|
|
|
|
# Extract amounts
|
|
AMOUNT_IN=$(echo "$line" | grep -oP 'Amount In: [0-9.]+' | grep -oP '[0-9.]+')
|
|
AMOUNT_OUT=$(echo "$line" | grep -oP 'Amount Out: [0-9.]+' | grep -oP '[0-9.]+')
|
|
if [[ -n "$AMOUNT_IN" ]] && [[ -n "$AMOUNT_OUT" ]]; then
|
|
echo -e "${CYAN} 📊 Amounts: ${AMOUNT_IN} → ${AMOUNT_OUT}${NC}"
|
|
fi
|
|
|
|
# Extract financial metrics
|
|
ESTIMATED_PROFIT=$(echo "$line" | grep -oP 'estimatedProfitETH:[0-9.]+' | cut -d: -f2)
|
|
GAS_COST=$(echo "$line" | grep -oP 'gasCostETH:[0-9.eE+-]+' | cut -d: -f2)
|
|
NET_PROFIT=$(echo "$line" | grep -oP 'netProfitETH:-?[0-9.eE+-]+' | cut -d: -f2)
|
|
|
|
if [[ -n "$ESTIMATED_PROFIT" ]] && [[ -n "$GAS_COST" ]] && [[ -n "$NET_PROFIT" ]]; then
|
|
# Convert scientific notation to readable format
|
|
GAS_COST_GWEI=$(echo "$GAS_COST * 1000000000" | bc -l 2>/dev/null || echo "$GAS_COST")
|
|
echo -e "${YELLOW} 💰 Estimated Profit: ${ESTIMATED_PROFIT} ETH${NC}"
|
|
echo -e "${RED} ⛽ Gas Cost: ${GAS_COST} ETH ($(printf "%.4f" $GAS_COST_GWEI 2>/dev/null || echo "?") Gwei)${NC}"
|
|
echo -e "${RED} 📉 Net After Gas: ${NET_PROFIT} ETH${NC}"
|
|
fi
|
|
|
|
# Extract slippage/price impact
|
|
PRICE_IMPACT=$(echo "$line" | grep -oP 'priceImpact:[0-9.eE+-]+' | cut -d: -f2)
|
|
if [[ -n "$PRICE_IMPACT" ]]; then
|
|
# Convert to percentage (multiply by 100)
|
|
PRICE_IMPACT_PCT=$(echo "$PRICE_IMPACT * 100" | bc -l 2>/dev/null || echo "$PRICE_IMPACT")
|
|
echo -e "${YELLOW} 📊 Price Impact: $(printf "%.6f" $PRICE_IMPACT_PCT 2>/dev/null || echo "$PRICE_IMPACT")%${NC}"
|
|
fi
|
|
|
|
# Extract profit margin
|
|
PROFIT_MARGIN=$(echo "$line" | grep -oP 'profitMargin:-?[0-9.eE+-]+' | cut -d: -f2)
|
|
if [[ -n "$PROFIT_MARGIN" ]]; then
|
|
PROFIT_MARGIN_PCT=$(echo "$PROFIT_MARGIN * 100" | bc -l 2>/dev/null || echo "$PROFIT_MARGIN")
|
|
echo -e "${RED} 📊 Profit Margin: $(printf "%.6f" $PROFIT_MARGIN_PCT 2>/dev/null || echo "$PROFIT_MARGIN")%${NC}"
|
|
fi
|
|
|
|
# Extract confidence score
|
|
CONFIDENCE=$(echo "$line" | grep -oP 'confidence:[0-9.]+' | cut -d: -f2)
|
|
if [[ -n "$CONFIDENCE" ]]; then
|
|
CONFIDENCE_PCT=$(echo "$CONFIDENCE * 100" | bc -l 2>/dev/null || echo "$CONFIDENCE")
|
|
echo -e "${YELLOW} 🎯 Confidence: $(printf "%.1f" $CONFIDENCE_PCT 2>/dev/null || echo "$CONFIDENCE")%${NC}"
|
|
fi
|
|
|
|
# Extract reject reason (at the end for context)
|
|
if echo "$line" | grep -oP 'rejectReason:[^]]+' &>/dev/null; then
|
|
REASON=$(echo "$line" | grep -oP 'rejectReason:\K[^}]+' | head -c 200)
|
|
# Trim to just the meaningful part (remove trailing field names)
|
|
REASON=$(echo "$REASON" | sed 's/ token[0-9].*$//' | sed 's/ protocol.*$//' | sed 's/ poolAddress.*$//')
|
|
echo -e "${RED} ❌ Reason: $REASON${NC}"
|
|
fi
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# Detect execution attempts (NEW: Updated to match current log format)
|
|
if echo "$line" | grep -q "Executing arbitrage\|Transaction submitted\|Flash loan initiated\|🚀 EXECUTING ARBITRAGE\|Flash loan executed"; then
|
|
EXECUTIONS=$((EXECUTIONS + 1))
|
|
TIMESTAMP=$(echo "$line" | awk '{print $1, $2}')
|
|
|
|
if echo "$line" | grep -q "Flash loan\|⚡"; then
|
|
echo -e "${BLUE}[$TIMESTAMP] ⚡ FLASH LOAN/EXECUTION INITIATED #$EXECUTIONS${NC}"
|
|
elif echo "$line" | grep -q "Transaction submitted\|🚀"; then
|
|
TXHASH=$(echo "$line" | grep -oP '0x[a-fA-F0-9]{64}' | head -1)
|
|
echo -e "${GREEN}[$TIMESTAMP] 🚀 TRANSACTION SUBMITTED${NC}"
|
|
if [[ -n "$TXHASH" ]]; then
|
|
echo -e "${GREEN} 📝 TxHash: $TXHASH${NC}"
|
|
echo -e "${GREEN} 🔗 Arbiscan: https://arbiscan.io/tx/$TXHASH${NC}"
|
|
fi
|
|
else
|
|
echo -e "${BLUE}[$TIMESTAMP] ⚡ EXECUTING ARBITRAGE #$EXECUTIONS${NC}"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# Detect confirmations (NEW: Updated to match current log format)
|
|
if echo "$line" | grep -q "Trade confirmed\|execution successful\|✅ Trade executed\|Successfully executed"; then
|
|
TIMESTAMP=$(echo "$line" | awk '{print $1, $2}')
|
|
echo -e "${GREEN}[$TIMESTAMP] ✅ TRADE CONFIRMED!${NC}"
|
|
|
|
# Extract profit if available
|
|
if echo "$line" | grep -oP 'Profit:.*ETH' &>/dev/null; then
|
|
PROFIT=$(echo "$line" | grep -oP 'Profit:.*ETH')
|
|
echo -e "${GREEN} 💰 $PROFIT${NC}"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# Detect CRITICAL errors only (skip rate limits and batch fetch failures)
|
|
if echo "$line" | grep -qi "ERROR\|WARN" && ! echo "$line" | grep -qi "429 Too Many\|batch fetch.*failed\|Failed to fetch batch"; then
|
|
ERRORS=$((ERRORS + 1))
|
|
TIMESTAMP=$(echo "$line" | awk '{print $1, $2}')
|
|
|
|
# Categorize error type and show descriptive label
|
|
if echo "$line" | grep -qi "parsing.*failed\|PARSING FAILED"; then
|
|
PARSING_ERRORS=$((PARSING_ERRORS + 1))
|
|
echo -e "${RED}[$TIMESTAMP] ❌ PARSING ERROR #$PARSING_ERRORS${NC}"
|
|
elif echo "$line" | grep -qi "panic\|fatal\|crash"; then
|
|
echo -e "${RED}[$TIMESTAMP] 🔥 CRITICAL ERROR #$ERRORS${NC}"
|
|
elif echo "$line" | grep -qi "DNS\|name resolution\|lookup.*failed"; then
|
|
RPC_ERRORS=$((RPC_ERRORS + 1))
|
|
echo -e "${RED}[$TIMESTAMP] ❌ DNS/NETWORK ERROR #$RPC_ERRORS${NC}"
|
|
elif echo "$line" | grep -qi "connection.*closed\|connection refused\|dial tcp"; then
|
|
RPC_ERRORS=$((RPC_ERRORS + 1))
|
|
echo -e "${RED}[$TIMESTAMP] ❌ CONNECTION ERROR #$RPC_ERRORS${NC}"
|
|
elif echo "$line" | grep -qi "0x0000000000000000000000000000000000000000"; then
|
|
ZERO_ADDRESS_ERRORS=$((ZERO_ADDRESS_ERRORS + 1))
|
|
echo -e "${RED}[$TIMESTAMP] ❌ ZERO ADDRESS ERROR #$ZERO_ADDRESS_ERRORS${NC}"
|
|
else
|
|
echo -e "${RED}[$TIMESTAMP] ❌ ERROR #$ERRORS${NC}"
|
|
fi
|
|
|
|
# IMPROVED: Extract error message using multiple patterns (CRITICAL FIX: removed truncation)
|
|
# Try pattern 1: "error:" or "error="
|
|
ERROR_MSG=$(echo "$line" | grep -oP 'error[=:]\s*\K[^|]*' | head -c 300)
|
|
|
|
# Try pattern 2: Extract message after [ERROR] or [WARN] tag (CRITICAL FIX: increased limit to 300)
|
|
if [[ -z "$ERROR_MSG" ]]; then
|
|
ERROR_MSG=$(echo "$line" | sed -n 's/.*\[ERROR\]\s*//p' | sed -n 's/.*\[WARN\]\s*//p' | head -c 300)
|
|
fi
|
|
|
|
# Try pattern 3: Extract everything after timestamp and log level (CRITICAL FIX: increased limit to 300)
|
|
if [[ -z "$ERROR_MSG" ]]; then
|
|
# Format: "2025/11/02 20:19:03 [ERROR] message"
|
|
ERROR_MSG=$(echo "$line" | sed -E 's/^[0-9]{4}\/[0-9]{2}\/[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} \[(ERROR|WARN)\] //' | head -c 300)
|
|
fi
|
|
|
|
# Display error message if extracted
|
|
if [[ -n "$ERROR_MSG" ]]; then
|
|
echo -e "${RED} ⚠️ $ERROR_MSG${NC}"
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
# Show periodic stats every 20 opportunities (only when count changes)
|
|
if [ $((OPPORTUNITIES % 20)) -eq 0 ] && [ $OPPORTUNITIES -gt 0 ] && [ $OPPORTUNITIES -ne $LAST_STATS_DISPLAY ]; then
|
|
echo -e "${CYAN}────────────────────────────────────────────────────────────${NC}"
|
|
echo -e "${CYAN}📊 Stats:${NC}"
|
|
echo -e "${CYAN} Opportunities: $OPPORTUNITIES | Executable: $EXECUTABLE | Executions: $EXECUTIONS${NC}"
|
|
echo -e "${CYAN} Errors: $ERRORS (Parsing: $PARSING_ERRORS | RPC: $RPC_ERRORS | Zero Addr: $ZERO_ADDRESS_ERRORS)${NC}"
|
|
echo -e "${CYAN}────────────────────────────────────────────────────────────${NC}"
|
|
echo ""
|
|
LAST_STATS_DISPLAY=$OPPORTUNITIES # Update last display count
|
|
fi
|
|
done
|