Files
mev-beta/docs/DEBUG_GUIDE_BLOCKERS.md

8.3 KiB

MEV Bot Blocker - Debug & Fix Guide

Quick Navigation

  • Blocker #1 Root Cause: /home/administrator/projects/mev-beta/pkg/events/parser.go
  • Blocker #2 Root Cause: /home/administrator/projects/mev-beta/pkg/arbitrage/multihop.go (lines 522-644)
  • Blocker #6 Root Cause: /home/administrator/projects/mev-beta/pkg/arbitrage/service.go
  • Blocker #10 Root Cause: /home/administrator/projects/mev-beta/pkg/arbitrum/parser/core.go

Blocker #1: Zero Amount Extraction (HIGHEST PRIORITY)

Symptom

Amount In: 0.000000 tokens
Amount Out: 0.000000 tokens
rejectReason: negative profit after gas and slippage costs

Files to Examine

  1. /home/administrator/projects/mev-beta/pkg/events/parser.go

    • Look for Swap event parsing
    • Search for: amount0, amount1, Amount0, Amount1
  2. /home/administrator/projects/mev-beta/pkg/arbitrum/parser/core.go

    • Look for Uniswap V3 Swap event signature
    • 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67
  3. /home/administrator/projects/mev-beta/pkg/arbitrum/l2_parser.go

    • Check how events are extracted from logs
    • Validate event signature matching

Debug Steps

# 1. Add logging to see what amounts are extracted
# File: pkg/events/parser.go
# Add before returning from ParseSwapEvent:
logger.Debug(fmt.Sprintf("PARSED AMOUNTS: amount0=%s amount1=%s", event.Amount0, event.Amount1))

# 2. Compare to raw event data
# Check: Are amounts in wei? Need to divide by token decimals?
# Example: 1000000000000000000 wei = 1.0 with 18 decimals

# 3. Verify event signature
# Uniswap V3 Swap: 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67
# Should decode: (sender, recipient, amount0, amount1, sqrtPriceX96, liquidity, tick)

What to Look For

  • Event signature mismatch (V2 vs V3 signatures are different)
  • Token decimal handling (need to convert from wei)
  • Signed integer handling (Swap amounts can be negative in V3)
  • Wrong field extraction (getting liquidity instead of amount)

Expected Fix

Once amounts are correctly extracted:

// Should see real amounts like:
amount0: 1000000000000000000 (1.0 WETH)
amount1: 2000000000 (2000 USDC @ 6 decimals)
// NOT: 0

Blocker #2: Empty Token Graph

Symptom

⚠️  Start token 0x82aF49... has no adjacent tokens in graph!

Files to Examine

  1. /home/administrator/projects/mev-beta/pkg/arbitrage/multihop.go

    • Lines 502-644: updateTokenGraph() function
    • Lines 522-594: Hardcoded pool initialization
    • Lines 646-659: addPoolToGraph() and addEdge()
  2. /home/administrator/projects/mev-beta/pkg/pools/discovery.go

    • Where 314 cached pools are loaded
    • Pool structure definition (lines 45-61)

Debug Steps

# 1. Check what pools are being loaded
# File: pkg/pools/discovery.go
grep -n "loadPersistedData\|LoadPools" pkg/pools/discovery.go

# 2. Verify pool cache exists and has data
ls -la data/pools.json
head -20 data/pools.json | jq '.[0]'

# 3. Add logging to see token graph building
# File: pkg/arbitrage/multihop.go line 628
# Add after line 628:
logger.Info(fmt.Sprintf("DEBUG: Graph has %d vertices", len(adjacencyList)))
for token, edges := range adjacencyList {
    logger.Info(fmt.Sprintf("  Token %s has %d connections", token.Hex()[:8], len(edges)))
}

# 4. Check if pools are being added to graph
# Should see something like:
# ✅ Token graph updated with 314/314 high-liquidity pools
# But currently shows: 8/8 hardcoded pools only

What to Look For

  • Hardcoded pool list (lines 522-594) has only 8 pools
  • Cached 314 pools are never read into the graph
  • No connection between pool discovery and token graph
  • Graph is populated at service startup only, never updated

Expected Fix

// Current code (WRONG):
pools := []*PoolInfo{
    // 8 hardcoded pools only
    { Address: 0xC31E..., Token0: WETH, Token1: USDC, ... },
    // ...
}

// Should be (CORRECT):
// Load 314 pools from cache and add them all to graph
cachedPools := pd.GetAllPools()  // Get from PoolDiscovery
for _, pool := range cachedPools {
    mhs.addPoolToGraph(pool)
}
// Result: 314 pools, 1000+ graph connections

Blocker #6: Execution Pipeline Disconnected

Symptom

2025/11/02 15:22:38 [INFO] Arbitrage Service Stats
    Executed: 0
    Successful: 0

Files to Examine

  1. /home/administrator/projects/mev-beta/pkg/arbitrage/service.go

    • Lines 80-130: ArbitrageService struct definition
    • Look for: ExecuteArbitrage(), executor, flashExecutor
  2. /home/administrator/projects/mev-beta/pkg/scanner/market/scanner.go

    • Lines 86-89: SetOpportunityForwarder()
    • Look for: opportunityForwarder.ExecuteArbitrage()
  3. /home/administrator/projects/mev-beta/pkg/arbitrage/executor.go

    • Look for: Execute() method that actually submits transactions

Debug Steps

# 1. Search for Execute calls on the executor
grep -n "\.Execute\|ExecuteArbitrage" pkg/arbitrage/service.go
# Expected: Should find multiple calls
# Actual: Likely finds NONE

# 2. Check if opportunityForwarder is actually used
grep -n "opportunityForwarder\." pkg/scanner/market/scanner.go
# Expected: Should call ExecuteArbitrage for valid opportunities
# Actual: Likely only sets it, never calls it

# 3. Check ArbitrageService.Start() to see what goroutines are started
grep -n "go.*(" pkg/arbitrage/service.go | head -20
# Should see: execution loop, monitoring loop, etc.
# Likely missing: execution loop that actually calls executor

What to Look For

  • Opportunity forwarder is set but never used
  • No goroutine in ArbitrageService.Start() that processes opportunities
  • Executor and FlashExecutor exist but are never invoked
  • Missing event loop that listens for valid opportunities

Expected Fix

// Current code (WRONG):
func (as *ArbitrageService) Start() error {
    as.isRunning = true
    go as.monitorLoop()  // Only monitoring, no execution
    return nil
}

// Should be (CORRECT):
func (as *ArbitrageService) Start() error {
    as.isRunning = true
    go as.opportunityLoop()      // Listen for valid opportunities
    go as.executionLoop()        // Execute profitable trades
    go as.monitoringLoop()       // Monitor results
    return nil
}

// New method:
func (as *ArbitrageService) opportunityLoop() {
    for {
        select {
        case opp := <-as.opportunityChannel:
            if opp.IsExecutable {
                as.executeOpportunity(opp)
            }
        }
    }
}

Blocker #10: Event Parser Extracts Zero Amounts

Same as Blocker #1

See section "Blocker #1: Zero Amount Extraction" above.


Verification Checklist

After each fix, verify:

  • Event parser extracts non-zero amounts
  • Amounts are in correct decimal format (wei vs human readable)
  • Token graph has 100+ connections
  • Profit calculator receives valid amounts
  • At least 50 opportunities marked as isExecutable:true per minute
  • Executor methods are called for valid opportunities
  • First transaction submits successfully
  • Transaction is confirmed on-chain
  • Profit is positive

Files to Modify (Summary)

Blocker File Lines Issue
#1 pkg/events/parser.go ? Amount extraction
#1 pkg/arbitrum/parser/core.go ? Event signature/parsing
#2 pkg/arbitrage/multihop.go 502-644 Connect pool cache to graph
#6 pkg/arbitrage/service.go 80-150 Add execution loop
#6 pkg/scanner/market/scanner.go 86-89 Actually use forwarder
#10 pkg/arbitrum/l2_parser.go ? Log parsing

Expected Timeline

  1. Hour 1-2: Debug event parser, identify why amounts are zero
  2. Hour 2-3: Fix event parser amount extraction
  3. Hour 3-4: Connect token graph to pool cache
  4. Hour 4-5: Verify 50%+ opportunities are executable
  5. Hour 5-7: Connect execution pipeline
  6. Hour 7-8: Test first arbitrage execution
  7. Hour 8-10: Debug and fix any execution issues
  8. Hour 10+: Monitor first profitable trades

Emergency Debug Command

If system is running and still showing zero amounts:

# Check current amount extraction in real-time
tail -f logs/mev_bot.log | grep -i "Amount In\|Amount Out\|amount.*0x"

# Should show real amounts like:
# Amount In: 1000000000000000000 tokens
# Amount Out: 2000000000 tokens

# If shows zeros, event parser is broken (Blocker #1)