#!/bin/bash # Comprehensive codebase audit script # Checks code quality, security, and compliance with SPEC.md set -e PROJECT_ROOT="/docker/mev-beta" cd "$PROJECT_ROOT" || exit 1 # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' info() { echo -e "${BLUE}ℹ${NC} $1"; } success() { echo -e "${GREEN}✓${NC} $1"; } warn() { echo -e "${YELLOW}⚠${NC} $1"; } error() { echo -e "${RED}✗${NC} $1"; } section() { echo -e "\n${CYAN}━━━ $1 ━━━${NC}\n"; } ISSUES_FOUND=0 # Function to report issue report_issue() { local severity=$1 local message=$2 ISSUES_FOUND=$((ISSUES_FOUND + 1)) case "$severity" in critical) error "[CRITICAL] $message" ;; high) error "[HIGH] $message" ;; medium) warn "[MEDIUM] $message" ;; low) warn "[LOW] $message" ;; info) info "[INFO] $message" ;; esac } echo "🔍 MEV Bot Codebase Audit" echo "==========================" echo "Date: $(date)" echo "Path: $PROJECT_ROOT" echo "" # 1. SPEC.md Compliance Check section "1. SPEC.md Compliance" info "Checking for SPEC.md violations..." # Check for hardcoded function selectors if grep -r "0x[0-9a-f]\{8\}" pkg/ --include="*.go" | grep -v "Address" | grep -v "test" | grep -q "selector"; then report_issue "high" "Found hardcoded function selectors (SPEC.md violation: use ABI-based detection)" grep -r "0x[0-9a-f]\{8\}" pkg/ --include="*.go" | grep "selector" | head -5 else success "No hardcoded function selectors found" fi # Check for HTTP RPC usage in sequencer code if grep -r "http://" pkg/sequencer/ --include="*.go" | grep -v "test" | grep -q "rpc"; then report_issue "critical" "HTTP RPC usage in sequencer (SPEC.md violation: use sequencer feed only)" grep -r "http://" pkg/sequencer/ --include="*.go" | head -3 else success "No HTTP RPC in sequencer code" fi # Check for blocking operations in hot paths if grep -r "time.Sleep" pkg/sequencer/ pkg/pools/ --include="*.go" | grep -v "test" | grep -q "."; then report_issue "medium" "Found blocking Sleep operations in hot path" grep -r "time.Sleep" pkg/sequencer/ pkg/pools/ --include="*.go" | head -3 else success "No blocking Sleep operations in hot paths" fi # Check for manual ABI files if find bindings/ -name "*.json" -type f | grep -v "_abi.json" | grep -q "."; then warn "Found manual ABI files (should use Foundry-generated ABIs)" find bindings/ -name "*.json" -type f | grep -v "_abi.json" else success "No manual ABI files found" fi # 2. Go Code Quality section "2. Go Code Quality" info "Running go vet..." if podman exec mev-go-dev sh -c "cd /workspace && go vet ./pkg/... ./cmd/..." 2>&1 | grep -q "^"; then report_issue "high" "go vet found issues" podman exec mev-go-dev sh -c "cd /workspace && go vet ./pkg/... ./cmd/..." 2>&1 | head -10 else success "go vet passed" fi info "Checking for TODO/FIXME comments..." TODO_COUNT=$(grep -r "TODO\|FIXME" pkg/ cmd/ --include="*.go" | wc -l) if [ "$TODO_COUNT" -gt 0 ]; then warn "Found $TODO_COUNT TODO/FIXME comments" grep -r "TODO\|FIXME" pkg/ cmd/ --include="*.go" | head -5 else success "No TODO/FIXME comments" fi info "Checking for panics in production code..." PANIC_COUNT=$(grep -r "panic(" pkg/ --include="*.go" | grep -v "_test.go" | wc -l) if [ "$PANIC_COUNT" -gt 0 ]; then report_issue "high" "Found $PANIC_COUNT panic() calls in production code" grep -r "panic(" pkg/ --include="*.go" | grep -v "_test.go" | head -5 else success "No panic() in production code" fi # 3. Security Audit section "3. Security Audit" info "Checking for potential security issues..." # Check for hardcoded private keys if grep -r "0x[0-9a-f]\{64\}" . --include="*.go" --include="*.env" | grep -i "private\|key" | grep -q "."; then report_issue "critical" "Potential hardcoded private key found" else success "No hardcoded private keys detected" fi # Check for SQL injection risks (should not be any, but check anyway) if grep -r "Query.*+\|Exec.*+" pkg/ --include="*.go" | grep -v "test" | grep -q "."; then report_issue "high" "Potential SQL injection risk (string concatenation in queries)" else success "No SQL injection risks" fi # Check for command injection risks if grep -r "exec.Command.*+\|os.System" pkg/ --include="*.go" | grep -v "test" | grep -q "."; then report_issue "high" "Potential command injection risk" else success "No command injection risks" fi # Check for unsafe pointer usage if grep -r "unsafe\." pkg/ --include="*.go" | grep -v "test" | grep -q "."; then warn "Found unsafe package usage" grep -r "unsafe\." pkg/ --include="*.go" | grep -v "test" else success "No unsafe package usage" fi # 4. Concurrency Safety section "4. Concurrency Safety" info "Checking for race condition risks..." # Check for shared state without locks if grep -r "var.*=.*make(map\|var.*\[\]" pkg/ --include="*.go" | grep -v "test" | grep -v "const" | grep -q "."; then warn "Found package-level maps/slices (potential race condition)" info "Verify these are protected by sync.Mutex or sync.RWMutex" fi # Check for mutex usage MUTEX_COUNT=$(grep -r "sync.Mutex\|sync.RWMutex" pkg/ --include="*.go" | grep -v "test" | wc -l) info "Found $MUTEX_COUNT mutex declarations" # Check for channel usage CHAN_COUNT=$(grep -r "make(chan\|chan " pkg/ --include="*.go" | grep -v "test" | wc -l) info "Found $CHAN_COUNT channel declarations" if [ "$CHAN_COUNT" -lt 5 ]; then report_issue "medium" "Low channel usage (SPEC.md requires channel-based architecture)" fi # 5. Error Handling section "5. Error Handling" info "Checking error handling patterns..." # Check for ignored errors IGNORED_ERRORS=$(grep -r "_ =" pkg/ --include="*.go" | grep -v "test" | grep "err" | wc -l) if [ "$IGNORED_ERRORS" -gt 0 ]; then warn "Found $IGNORED_ERRORS potentially ignored errors" grep -r "_ =" pkg/ --include="*.go" | grep -v "test" | grep "err" | head -5 else success "No ignored errors found" fi # Check for proper error wrapping if ! grep -r "fmt.Errorf.*%w" pkg/ --include="*.go" | grep -q "."; then warn "Limited use of error wrapping (consider using %w for error context)" fi # 6. Documentation section "6. Documentation" info "Checking documentation coverage..." # Count exported functions without comments EXPORTED_FUNCS=$(grep -r "^func [A-Z]" pkg/ --include="*.go" | grep -v "test" | wc -l) DOCUMENTED_FUNCS=$(grep -rB1 "^func [A-Z]" pkg/ --include="*.go" | grep "^//" | wc -l) DOC_COVERAGE=$((DOCUMENTED_FUNCS * 100 / (EXPORTED_FUNCS + 1))) info "Documentation coverage: $DOC_COVERAGE% ($DOCUMENTED_FUNCS/$EXPORTED_FUNCS)" if [ "$DOC_COVERAGE" -lt 80 ]; then warn "Documentation coverage below 80%" else success "Good documentation coverage" fi # 7. Test Coverage section "7. Test Coverage" info "Checking test coverage..." TEST_FILES=$(find pkg/ -name "*_test.go" | wc -l) GO_FILES=$(find pkg/ -name "*.go" | grep -v "_test.go" | wc -l) TEST_RATIO=$((TEST_FILES * 100 / (GO_FILES + 1))) info "Test file ratio: $TEST_RATIO% ($TEST_FILES test files for $GO_FILES source files)" if [ "$TEST_RATIO" -lt 50 ]; then warn "Test coverage may be low (< 50% test files)" fi # 8. Dependencies section "8. Dependency Audit" info "Checking for outdated dependencies..." if [ -f "go.mod" ]; then podman exec mev-go-dev sh -c "cd /workspace && go list -u -m all 2>/dev/null | grep '\[' || echo 'All dependencies up to date'" fi # 9. Contract Bindings section "9. Contract Bindings" info "Verifying contract bindings..." BINDING_COUNT=$(find bindings/ -name "*.go" -type f | wc -l) info "Found $BINDING_COUNT generated binding files" if [ "$BINDING_COUNT" -lt 2 ]; then report_issue "high" "Very few contract bindings (expected UniswapV2, UniswapV3, etc.)" fi # Check bindings are used for binding_pkg in uniswap_v2 uniswap_v3; do if grep -r "\".*bindings/$binding_pkg\"" pkg/ --include="*.go" | grep -q "."; then success "Bindings package $binding_pkg is used" else warn "Bindings package $binding_pkg may not be used" fi done # 10. Build & Compile Check section "10. Build Verification" info "Verifying code compiles..." if podman exec mev-go-dev sh -c "cd /workspace && go build ./..." 2>&1 | grep -q "error"; then report_issue "critical" "Code does not compile" podman exec mev-go-dev sh -c "cd /workspace && go build ./..." 2>&1 | grep "error" | head -10 else success "Code compiles successfully" fi # 11. File Organization section "11. File Organization" info "Checking file organization..." # Check for large files LARGE_FILES=$(find pkg/ -name "*.go" -type f -size +1000k) if [ -n "$LARGE_FILES" ]; then warn "Found large files (>1MB) - consider splitting:" echo "$LARGE_FILES" fi # Check for deeply nested packages DEEP_PACKAGES=$(find pkg/ -type d -printf '%d %p\n' | awk '$1 > 5 {print $2}') if [ -n "$DEEP_PACKAGES" ]; then warn "Found deeply nested packages (>5 levels):" echo "$DEEP_PACKAGES" fi # 12. Git Status section "12. Git Status" info "Checking uncommitted changes..." UNCOMMITTED=$(git status --porcelain | wc -l) if [ "$UNCOMMITTED" -gt 0 ]; then warn "Found $UNCOMMITTED uncommitted changes" git status --short | head -10 else success "No uncommitted changes" fi # Summary section "Audit Summary" if [ "$ISSUES_FOUND" -eq 0 ]; then success "✅ Audit complete - No issues found!" exit 0 else warn "⚠️ Audit complete - Found $ISSUES_FOUND potential issues" echo "" echo "Review the issues above and address critical/high severity items." exit 1 fi