Files
mev-beta/orig/scripts/watch-live-enhanced.sh
Administrator c54c569f30 refactor: move all remaining files to orig/ directory
Completed clean root directory structure:
- Root now contains only: .git, .env, docs/, orig/
- Moved all remaining files and directories to orig/:
  - Config files (.claude, .dockerignore, .drone.yml, etc.)
  - All .env variants (except active .env)
  - Git config (.gitconfig, .github, .gitignore, etc.)
  - Tool configs (.golangci.yml, .revive.toml, etc.)
  - Documentation (*.md files, @prompts)
  - Build files (Dockerfiles, Makefile, go.mod, go.sum)
  - Docker compose files
  - All source directories (scripts, tests, tools, etc.)
  - Runtime directories (logs, monitoring, reports)
  - Dependency files (node_modules, lib, cache)
  - Special files (--delete)

- Removed empty runtime directories (bin/, data/)

V2 structure is now clean:
- docs/planning/ - V2 planning documents
- orig/ - Complete V1 codebase preserved
- .env - Active environment config (not in git)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-10 10:53:05 +01:00

397 lines
18 KiB
Bash
Executable File

#!/bin/bash
# Enhanced Live MEV Bot Activity Monitor
# Comprehensive monitoring with error tracking, health metrics, and statistics
# Color codes
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
PURPLE='\033[0;35m'
BOLD='\033[1m'
NC='\033[0m'
# Configuration
LOG_FILE="${1:-logs/mev_bot.log}"
UPDATE_INTERVAL=10 # Stats update interval in opportunities
ALERT_ERROR_THRESHOLD=50 # Alert when errors exceed this
# Check if log file exists
if [[ ! -f "$LOG_FILE" ]]; then
echo -e "${RED}Error: Log file not found: $LOG_FILE${NC}"
echo "Usage: $0 [log-file]"
echo "Example: $0 logs/mev_bot.log"
exit 1
fi
# Initialize counters
declare -A STATS=(
# Opportunities
["opportunities_total"]=0
["opportunities_executable"]=0
["opportunities_rejected"]=0
# Executions
["executions_attempted"]=0
["executions_successful"]=0
["executions_failed"]=0
["flash_loans_initiated"]=0
["transactions_submitted"]=0
# Errors
["errors_total"]=0
["errors_parsing"]=0
["errors_rpc"]=0
["errors_validation"]=0
["errors_zero_address"]=0
["errors_timeout"]=0
["errors_connection"]=0
["errors_rate_limit"]=0
# Processing
["blocks_processed"]=0
["transactions_analyzed"]=0
["swap_events_detected"]=0
["dex_transactions"]=0
# Performance
["gas_estimations"]=0
["pool_queries"]=0
["price_checks"]=0
)
# Track recent activity for rate calculations
declare -a RECENT_OPPORTUNITIES=()
declare -a RECENT_ERRORS=()
START_TIME=$(date +%s)
LAST_ACTIVITY=$(date +%s)
# Function to calculate rates
calculate_rate() {
local count=$1
local elapsed=$(($(date +%s) - START_TIME))
if [[ $elapsed -gt 0 ]]; then
echo "scale=2; $count / $elapsed * 60" | bc -l
else
echo "0"
fi
}
# Function to calculate percentage
calculate_percentage() {
local part=$1
local total=$2
if [[ $total -gt 0 ]]; then
echo "scale=1; $part * 100 / $total" | bc -l
else
echo "0"
fi
}
# Function to get health status
get_health_status() {
local error_rate=$(calculate_percentage ${STATS["errors_total"]} $((${STATS["opportunities_total"]} + ${STATS["errors_total"]})))
local error_rate_int=${error_rate%.*}
if [[ $error_rate_int -lt 5 ]]; then
echo -e "${GREEN}EXCELLENT${NC}"
elif [[ $error_rate_int -lt 15 ]]; then
echo -e "${YELLOW}GOOD${NC}"
elif [[ $error_rate_int -lt 30 ]]; then
echo -e "${YELLOW}DEGRADED${NC}"
else
echo -e "${RED}CRITICAL${NC}"
fi
}
# Function to display header
display_header() {
clear
echo -e "${BOLD}${PURPLE}════════════════════════════════════════════════════════════════════════${NC}"
echo -e "${BOLD}${PURPLE} 🤖 MEV Bot Enhanced Live Activity Monitor${NC}"
echo -e "${BOLD}${PURPLE}════════════════════════════════════════════════════════════════════════${NC}"
echo ""
echo -e "${CYAN}📊 Log File:${NC} $LOG_FILE"
echo -e "${CYAN}💼 Bot Wallet:${NC} 0x40091653f652a259747D86d7Cbe3e2848082a051"
echo -e "${CYAN}🌐 Network:${NC} Arbitrum One"
echo -e "${CYAN}⏱️ Started:${NC} $(date)"
echo ""
echo -e "${BOLD}Monitoring:${NC}"
echo -e " ${GREEN}${NC} Opportunities (executable & rejected)"
echo -e " ${BLUE}${NC} Executions (flash loans, transactions, confirmations)"
echo -e " ${RED}${NC} Errors (parsing, RPC, validation, timeouts)"
echo -e " ${CYAN}📈${NC} Performance (blocks, transactions, events)"
echo -e " ${PURPLE}💊${NC} Health (success rate, error rate, uptime)"
echo ""
echo -e "${YELLOW}Press Ctrl+C to stop${NC}"
echo -e "${PURPLE}════════════════════════════════════════════════════════════════════════${NC}"
echo ""
}
# Function to display comprehensive stats
display_stats() {
local elapsed=$(($(date +%s) - START_TIME))
local hours=$((elapsed / 3600))
local minutes=$(((elapsed % 3600) / 60))
local seconds=$((elapsed % 60))
local opp_rate=$(calculate_rate ${STATS["opportunities_total"]})
local exec_rate=$(calculate_rate ${STATS["executions_attempted"]})
local error_rate_pct=$(calculate_percentage ${STATS["errors_total"]} $((${STATS["opportunities_total"]} + ${STATS["errors_total"]})))
local executable_pct=$(calculate_percentage ${STATS["opportunities_executable"]} ${STATS["opportunities_total"]})
local success_pct=$(calculate_percentage ${STATS["executions_successful"]} ${STATS["executions_attempted"]})
echo -e "${BOLD}${CYAN}╔════════════════════════════════════════════════════════════════════════╗${NC}"
echo -e "${BOLD}${CYAN}║ 📊 LIVE STATISTICS ║${NC}"
echo -e "${BOLD}${CYAN}╠════════════════════════════════════════════════════════════════════════╣${NC}"
# Opportunities section
echo -e "${CYAN}${NC} ${BOLD}🎯 OPPORTUNITIES${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Total: ${GREEN}${STATS["opportunities_total"]}${NC} (${opp_rate}/min) ${CYAN}${NC}"
echo -e "${CYAN}${NC} Executable: ${GREEN}${STATS["opportunities_executable"]}${NC} (${executable_pct}%) ${CYAN}${NC}"
echo -e "${CYAN}${NC} Rejected: ${YELLOW}${STATS["opportunities_rejected"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}╠════════════════════════════════════════════════════════════════════════╣${NC}"
# Executions section
echo -e "${CYAN}${NC} ${BOLD}⚡ EXECUTIONS${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Attempted: ${BLUE}${STATS["executions_attempted"]}${NC} (${exec_rate}/min) ${CYAN}${NC}"
echo -e "${CYAN}${NC} Successful: ${GREEN}${STATS["executions_successful"]}${NC} (${success_pct}%) ${CYAN}${NC}"
echo -e "${CYAN}${NC} Failed: ${RED}${STATS["executions_failed"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Flash Loans: ${PURPLE}${STATS["flash_loans_initiated"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Tx Submitted:${BLUE}${STATS["transactions_submitted"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}╠════════════════════════════════════════════════════════════════════════╣${NC}"
# Errors section
local error_color=$RED
if [[ ${STATS["errors_total"]} -lt 10 ]]; then
error_color=$GREEN
elif [[ ${STATS["errors_total"]} -lt 50 ]]; then
error_color=$YELLOW
fi
echo -e "${CYAN}${NC} ${BOLD}❌ ERRORS${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Total: ${error_color}${STATS["errors_total"]}${NC} (${error_rate_pct}% error rate) ${CYAN}${NC}"
echo -e "${CYAN}${NC} Parsing: ${RED}${STATS["errors_parsing"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} RPC: ${RED}${STATS["errors_rpc"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Validation: ${RED}${STATS["errors_validation"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Zero Addr: ${RED}${STATS["errors_zero_address"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Timeout: ${RED}${STATS["errors_timeout"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Connection: ${RED}${STATS["errors_connection"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Rate Limit: ${RED}${STATS["errors_rate_limit"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}╠════════════════════════════════════════════════════════════════════════╣${NC}"
# Processing section
echo -e "${CYAN}${NC} ${BOLD}📈 PROCESSING${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Blocks: ${BLUE}${STATS["blocks_processed"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Transactions:${BLUE}${STATS["transactions_analyzed"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Swap Events: ${CYAN}${STATS["swap_events_detected"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} DEX Txs: ${CYAN}${STATS["dex_transactions"]}${NC} ${CYAN}${NC}"
echo -e "${CYAN}╠════════════════════════════════════════════════════════════════════════╣${NC}"
# Health section
local health_status=$(get_health_status)
echo -e "${CYAN}${NC} ${BOLD}💊 HEALTH${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Status: $health_status ${CYAN}${NC}"
echo -e "${CYAN}${NC} Uptime: ${GREEN}${hours}h ${minutes}m ${seconds}s${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Success Rate:${GREEN}${success_pct}%${NC} ${CYAN}${NC}"
echo -e "${CYAN}${NC} Error Rate: ${error_color}${error_rate_pct}%${NC} ${CYAN}${NC}"
echo -e "${CYAN}╚════════════════════════════════════════════════════════════════════════╝${NC}"
echo ""
}
# Function to handle opportunity detection
handle_opportunity() {
local line="$1"
local timestamp=$(echo "$line" | awk '{print $1, $2}')
((STATS["opportunities_total"]++))
RECENT_OPPORTUNITIES+=("$(date +%s)")
if echo "$line" | grep -q "isExecutable:true"; then
((STATS["opportunities_executable"]++))
echo -e "${GREEN}[$(date +'%H:%M:%S')] ✅ EXECUTABLE OPPORTUNITY #${STATS["opportunities_executable"]}${NC}"
# Extract profit
if echo "$line" | grep -oP 'netProfitETH:[0-9.]+' &>/dev/null; then
PROFIT=$(echo "$line" | grep -oP 'netProfitETH:[0-9.]+' | cut -d: -f2)
echo -e "${GREEN} 💰 Net Profit: $PROFIT ETH${NC}"
fi
# Extract path
if echo "$line" | grep -oP 'tokenIn:\w+' &>/dev/null; then
TOKEN_IN=$(echo "$line" | grep -oP 'tokenIn:\w+' | cut -d: -f2)
TOKEN_OUT=$(echo "$line" | grep -oP 'tokenOut:\w+' | cut -d: -f2)
echo -e "${CYAN} 🔄 Path: $TOKEN_IN$TOKEN_OUT${NC}"
fi
# Extract DEX info
if echo "$line" | grep -oP 'dex:\w+' &>/dev/null; then
DEX=$(echo "$line" | grep -oP 'dex:\w+' | cut -d: -f2)
echo -e "${BLUE} 🏦 DEX: $DEX${NC}"
fi
else
((STATS["opportunities_rejected"]++))
echo -e "${YELLOW}[$(date +'%H:%M:%S')] 🎯 Opportunity #${STATS["opportunities_total"]} (rejected)${NC}"
# Extract reject reason
if echo "$line" | grep -oP 'rejectReason:[^]]+' &>/dev/null; then
REASON=$(echo "$line" | grep -oP 'rejectReason:[^]]+' | cut -d: -f2 | head -c 70)
echo -e "${RED} ❌ Reason: $REASON${NC}"
fi
fi
}
# Function to handle execution events
handle_execution() {
local line="$1"
if echo "$line" | grep -q "Flash loan initiated"; then
((STATS["flash_loans_initiated"]++))
((STATS["executions_attempted"]++))
echo -e "${PURPLE}[$(date +'%H:%M:%S')] ⚡ FLASH LOAN INITIATED #${STATS["flash_loans_initiated"]}${NC}"
elif echo "$line" | grep -q "Transaction submitted"; then
((STATS["transactions_submitted"]++))
TXHASH=$(echo "$line" | grep -oP '0x[a-fA-F0-9]{64}' | head -1)
echo -e "${GREEN}[$(date +'%H:%M:%S')] 🚀 TRANSACTION SUBMITTED${NC}"
echo -e "${GREEN} 📝 TxHash: $TXHASH${NC}"
echo -e "${GREEN} 🔗 Arbiscan: https://arbiscan.io/tx/$TXHASH${NC}"
elif echo "$line" | grep -q "Trade confirmed\|execution successful"; then
((STATS["executions_successful"]++))
echo -e "${GREEN}[$(date +'%H:%M:%S')] ✅ TRADE CONFIRMED!${NC}"
if echo "$line" | grep -oP 'Profit:.*ETH' &>/dev/null; then
PROFIT=$(echo "$line" | grep -oP 'Profit:.*ETH')
echo -e "${GREEN} 💰 $PROFIT${NC}"
fi
elif echo "$line" | grep -q "execution failed\|Trade failed"; then
((STATS["executions_failed"]++))
echo -e "${RED}[$(date +'%H:%M:%S')] ❌ EXECUTION FAILED${NC}"
if echo "$line" | grep -oP 'error:.*' &>/dev/null; then
ERROR=$(echo "$line" | grep -oP 'error:.*' | head -c 70)
echo -e "${RED} ⚠️ $ERROR${NC}"
fi
elif echo "$line" | grep -q "Executing arbitrage"; then
((STATS["executions_attempted"]++))
echo -e "${BLUE}[$(date +'%H:%M:%S')] ⚡ EXECUTING ARBITRAGE #${STATS["executions_attempted"]}${NC}"
fi
}
# Function to handle errors
handle_error() {
local line="$1"
((STATS["errors_total"]++))
RECENT_ERRORS+=("$(date +%s)")
local error_type="GENERAL"
if echo "$line" | grep -qi "parsing.*failed\|PARSING FAILED\|failed to parse"; then
((STATS["errors_parsing"]++))
error_type="PARSING"
elif echo "$line" | grep -qi "rpc.*error\|rpc.*failed\|connection refused"; then
((STATS["errors_rpc"]++))
error_type="RPC"
elif echo "$line" | grep -qi "validation.*failed\|invalid.*input"; then
((STATS["errors_validation"]++))
error_type="VALIDATION"
elif echo "$line" | grep -qi "0x0000000000000000000000000000000000000000\|zero.*address"; then
((STATS["errors_zero_address"]++))
error_type="ZERO_ADDRESS"
elif echo "$line" | grep -qi "timeout\|deadline exceeded"; then
((STATS["errors_timeout"]++))
error_type="TIMEOUT"
elif echo "$line" | grep -qi "connection.*failed\|connection.*lost\|context.*canceled"; then
((STATS["errors_connection"]++))
error_type="CONNECTION"
elif echo "$line" | grep -qi "rate.*limit\|too many requests\|429"; then
((STATS["errors_rate_limit"]++))
error_type="RATE_LIMIT"
fi
echo -e "${RED}[$(date +'%H:%M:%S')] ❌ ERROR ($error_type) #${STATS["errors_total"]}${NC}"
# Extract error message
local error_msg=$(echo "$line" | grep -oP 'error[=:].*' | head -c 100)
if [[ -n "$error_msg" ]]; then
echo -e "${RED} ⚠️ $error_msg${NC}"
fi
# Alert on high error count
if [[ ${STATS["errors_total"]} -gt $ALERT_ERROR_THRESHOLD ]] && [[ $((${STATS["errors_total"]} % 10)) -eq 0 ]]; then
echo -e "${RED}${BOLD} 🚨 ALERT: Error count exceeds threshold ($ALERT_ERROR_THRESHOLD)${NC}"
fi
}
# Function to handle processing events
handle_processing() {
local line="$1"
if echo "$line" | grep -qi "Block.*Processing.*transactions\|Processing block"; then
((STATS["blocks_processed"]++))
# Extract block number
if echo "$line" | grep -oP 'block[=: ]+\d+' &>/dev/null; then
BLOCK=$(echo "$line" | grep -oP '\d+' | head -1)
echo -e "${BLUE}[$(date +'%H:%M:%S')] 📦 Block #$BLOCK processed${NC}"
fi
elif echo "$line" | grep -qi "DEX transactions\|Found.*DEX"; then
((STATS["dex_transactions"]++))
elif echo "$line" | grep -qi "swap.*event\|Swap detected"; then
((STATS["swap_events_detected"]++))
elif echo "$line" | grep -qi "Analyzing transaction"; then
((STATS["transactions_analyzed"]++))
fi
}
# Main monitoring loop
main() {
display_header
local line_count=0
local last_stats_update=0
tail -f "$LOG_FILE" | while IFS= read -r line; do
((line_count++))
LAST_ACTIVITY=$(date +%s)
# Handle different event types
if echo "$line" | grep -qi "OPPORTUNITY DETECTED"; then
handle_opportunity "$line"
echo ""
elif echo "$line" | grep -qi "ERROR\|WARN\|failed"; then
handle_error "$line"
echo ""
elif echo "$line" | grep -qi "Flash loan\|Transaction submitted\|Trade confirmed\|execution\|Executing arbitrage"; then
handle_execution "$line"
echo ""
elif echo "$line" | grep -qi "Block\|Processing\|DEX\|swap.*event"; then
handle_processing "$line"
fi
# Update stats display periodically (only when count actually changes)
local current_count=${STATS["opportunities_total"]}
if [[ $((current_count % UPDATE_INTERVAL)) -eq 0 ]] && [[ $current_count -gt 0 ]] && [[ $current_count -ne $last_stats_update ]]; then
last_stats_update=$current_count
display_stats
fi
done
}
# Trap Ctrl+C for clean exit
trap 'echo -e "\n${YELLOW}Monitoring stopped.${NC}"; display_stats; exit 0' SIGINT SIGTERM
# Run main monitoring
main