Files
mev-beta/docs/FAST_MVP_PLAN.md
Gemini Agent 52f0ecfc1c docs: update planning with real issue - need cross-protocol arbitrage
FINDINGS:
- Reserve refresh WAS already implemented and working
- Real issue: only 9 V2 pools, no V3 pools, same-protocol only
- Same-protocol (V2→V2) markets too efficient for public RPC bot
- Need cross-protocol (V2↔V3) arbitrage for real opportunities

PRIORITY FIXES:
1. Add UniswapV3 pool discovery (HIGH impact, 2 hrs)
2. Enable cross-protocol arbitrage detection (HIGH impact, 4 hrs)
3. Add more DEXs: SushiSwap, Camelot (MEDIUM impact, 3 hrs)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-30 17:49:33 -06:00

885 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# MEV Bot - Fast MVP Plan (4-5 Weeks)
**Objective**: Deploy profitable arbitrage bot in 4-5 weeks with minimal viable features
**Strategy**: Validate business model quickly, then decide whether to scale
**Capital**: Start with 0.5-1 ETH, scale if profitable
---
## 🎯 Core Philosophy
**Ship fast, validate profitability, iterate based on real data.**
We're cutting everything that's not essential:
- ❌ No 13+ protocols (just UniswapV2 + UniswapV3)
- ❌ No 4-hop arbitrage (just 2-hop)
- ❌ No sequencer integration yet (regular RPC first)
- ❌ No batch execution (single trades only)
- ❌ No fancy dashboard (basic metrics only)
**We CAN add these later if the bot is profitable.**
---
## 📅 4-Week Timeline
### **Week 1: Core Parsers** (Dec 1-7)
**Goal**: Parse UniswapV2 and UniswapV3 swaps accurately
#### Day 1-2: UniswapV2 Parser
- [ ] Implement Swap event parsing
- [ ] Handle Mint/Burn events
- [ ] Extract tokens from pool cache
- [ ] Decimal scaling (USDC 6, WBTC 8, WETH 18)
- [ ] 100% test coverage
- [ ] Integration test with real Arbitrum tx
**Success Criteria**:
- Parse any UniswapV2 swap on Arbitrum
- No zero addresses
- Correct decimal handling
- Tests pass: `make test-coverage`
#### Day 3-5: UniswapV3 Parser
- [ ] Parse V3 Swap events (signed amounts)
- [ ] Handle sqrtPriceX96 and tick
- [ ] Concentrated liquidity basics
- [ ] Multi-hop swap support
- [ ] 100% test coverage
- [ ] Integration tests
**Success Criteria**:
- Parse any UniswapV3 swap on Arbitrum
- Handle negative amounts correctly
- Proper tick/liquidity tracking
#### Day 6-7: Pool Discovery
- [ ] Fetch all UniswapV2 pools on Arbitrum
- [ ] Fetch all UniswapV3 pools on Arbitrum
- [ ] Populate pool cache
- [ ] Get initial reserves
- [ ] ~500-1000 pools total
**Success Criteria**:
- Pool cache has major trading pairs (WETH/USDC, WETH/ARB, etc.)
- Reserves are accurate
- Cache lookup is fast (<1ms)
---
### **Week 2: Arbitrage Detection** (Dec 8-14)
**Goal**: Find profitable 2-hop arbitrage opportunities
#### Day 1-2: Market Graph
- [ ] Build graph from pool cache
- [ ] Nodes = tokens, Edges = pools
- [ ] Efficient adjacency list representation
- [ ] Unit tests
**Example**:
```
WETH --[UniV2 Pool]-- USDC
WETH --[UniV3 Pool]-- USDC
ARB --[UniV2 Pool]-- WETH
```
#### Day 3-4: Path Finder (2-Hop Only)
- [ ] Find circular paths: Token A → Token B → Token A
- [ ] BFS algorithm (simple, fast)
- [ ] Limit to 2 hops maximum
- [ ] Filter by minimum liquidity ($10k+)
- [ ] Unit tests with mock graph
**Example Arbitrage**:
```
Buy USDC with WETH on UniV2 (cheaper)
Sell USDC for WETH on UniV3 (more expensive)
Profit = difference - gas
```
#### Day 5-6: Profitability Calculator
- [ ] Calculate swap output (AMM formula)
- [ ] Account for fees (0.3% UniV2, 0.05-1% UniV3)
- [ ] Estimate gas cost (~150k gas per hop)
- [ ] Calculate net profit
- [ ] Filter: only opportunities >0.01 ETH profit
**Formula**:
```
Gross Profit = Output Amount - Input Amount
Gas Cost = Gas Used × Gas Price
Net Profit = Gross Profit - Gas Cost
Only execute if Net Profit > 0.01 ETH
```
#### Day 7: Integration & Testing
- [ ] End-to-end test: Pool cache → Graph → Paths → Profit
- [ ] Test with historical Arbitrum data
- [ ] Verify calculations match real outcomes
- [ ] Performance: <50ms per detection
---
### **Week 3: Execution Engine** (Dec 15-21)
**Goal**: Execute profitable arbitrage trades
#### Day 1-2: Transaction Builder
- [ ] Build swap transaction for UniswapV2
- [ ] Build swap transaction for UniswapV3
- [ ] Calculate exact input/output amounts
- [ ] Add slippage tolerance (0.5%)
- [ ] Unit tests
#### Day 3-4: Execution Logic
- [ ] Connect to Arbitrum RPC (Alchemy/Infura)
- [ ] Get wallet nonce
- [ ] Estimate gas
- [ ] Set gas price (current + 10%)
- [ ] Sign transaction
- [ ] Submit to network
- [ ] Wait for confirmation
- [ ] Handle reverts gracefully
**Simple Flow**:
```go
func (e *Executor) Execute(opportunity *Opportunity) error {
// 1. Build transaction
tx := e.buildArbitrageTx(opportunity)
// 2. Estimate gas
gas, err := e.client.EstimateGas(tx)
if err != nil {
return err
}
tx.Gas = gas * 1.1 // 10% buffer
// 3. Get gas price
gasPrice, _ := e.client.SuggestGasPrice()
tx.GasPrice = gasPrice * 1.1 // 10% higher to ensure inclusion
// 4. Check still profitable after gas
netProfit := opportunity.GrossProfit - (gas * gasPrice)
if netProfit < minProfit {
return ErrNotProfitable
}
// 5. Sign and send
signedTx, _ := types.SignTx(tx, e.signer, e.privateKey)
err = e.client.SendTransaction(ctx, signedTx)
// 6. Wait for confirmation
receipt, err := e.waitForReceipt(signedTx.Hash())
// 7. Record result
e.recordTrade(opportunity, receipt)
return err
}
```
#### Day 5-6: Basic Risk Management
- [ ] Circuit breaker: Stop after 3 failed trades in a row
- [ ] Max loss limit: Stop after -0.1 ETH total loss
- [ ] Slippage protection: Revert if output < expected × 99.5%
- [ ] Position limit: Max 0.5 ETH per trade
- [ ] Cooldown: Wait 1 minute after circuit breaker trips
#### Day 7: Testnet Testing
- [ ] Deploy to Arbitrum Sepolia testnet
- [ ] Test full flow: Detect → Execute → Confirm
- [ ] Verify trades succeed
- [ ] Check profit calculations
- [ ] Fix any bugs
---
### **Week 4: Monitoring & Deployment** (Dec 22-28)
**Goal**: Deploy to mainnet with real capital
#### Day 1-2: Basic Metrics
- [ ] Count opportunities found
- [ ] Count trades executed
- [ ] Count successful vs failed
- [ ] Track total profit/loss
- [ ] Track gas spent
- [ ] Simple logging to file
**Metrics to track**:
```
Opportunities Found: 127
Trades Executed: 23
Successful: 18 (78%)
Failed: 5 (22%)
Gross Profit: 0.42 ETH
Gas Spent: 0.15 ETH
Net Profit: 0.27 ETH
ROI: 54% (on 0.5 ETH capital)
```
#### Day 3: Mainnet Preparation
- [ ] Security audit of wallet handling
- [ ] Create dedicated bot wallet
- [ ] Fund with 0.5 ETH test capital
- [ ] Set conservative limits:
- Max 0.1 ETH per trade
- Max 10 trades per day
- Stop after -0.05 ETH loss
- [ ] Backup private key securely
#### Day 4-5: Shadow Mode (24 hours)
- [ ] Run bot in shadow mode (detect but don't execute)
- [ ] Log all opportunities
- [ ] Calculate theoretical profit
- [ ] Verify no false positives
- [ ] Check for edge cases
**Example Log**:
```
[2024-12-22 10:15:23] OPPORTUNITY FOUND
Path: WETH → USDC (UniV2) → WETH (UniV3)
Input: 0.1 ETH
Expected Output: 0.1023 ETH
Gross Profit: 0.0023 ETH ($4.60)
Gas Cost: 0.0008 ETH ($1.60)
Net Profit: 0.0015 ETH ($3.00)
Action: WOULD EXECUTE (shadow mode)
```
#### Day 6-7: Live Deployment (Carefully!)
- [ ] Switch to live mode
- [ ] Start with VERY conservative limits
- [ ] Monitor constantly (first 24 hours)
- [ ] Be ready to kill switch if needed
**First Day Checklist**:
- [ ] Bot detects opportunities ✅
- [ ] Profit calculations are accurate ✅
- [ ] Trades execute successfully ✅
- [ ] No unexpected reverts ✅
- [ ] Gas costs as expected ✅
- [ ] Net profit is positive ✅
---
## 🎯 Success Criteria for Fast MVP
### **Minimum Viable Success** (Worth continuing):
- ✅ Bot runs for 7 days without crashes
- ✅ Executes at least 5 trades
- ✅ Success rate >50%
- ✅ Net profit >0 (even $10 is validation)
- ✅ No major bugs or losses
### **Strong Success** (Scale up immediately):
- ✅ Net profit >10% in first week
- ✅ Success rate >70%
- ✅ Consistent daily opportunities
- ✅ No circuit breaker trips
- ✅ Clear path to scaling
### **Failure** (Pivot or abandon):
- ❌ Net loss after 7 days
- ❌ Success rate <30%
- ❌ Circuit breaker trips repeatedly
- ❌ No arbitrage opportunities
- ❌ Competition too fierce
---
## 🔍 What We're NOT Building (Yet)
These are explicitly OUT OF SCOPE for Fast MVP:
### Deferred to "Scale-Up Phase" (if MVP is profitable):
1. **More DEX Protocols**
- Curve, Balancer, SushiSwap, Camelot
- Add in Week 5-6 if MVP works
2. **Sequencer Integration**
- Front-running via sequencer feed
- Add in Week 6-7 if needed for competitiveness
3. **Multi-Hop Arbitrage**
- 3-hop and 4-hop paths
- Add if 2-hop is saturated
4. **Batch Execution**
- Multicall for gas savings
- Add when trade volume justifies it
5. **Advanced Gas Optimization**
- Dynamic gas strategies
- EIP-1559 optimization
- Add if gas is eating profits
6. **Fancy Dashboard**
- Grafana, Prometheus
- Real-time monitoring
- Add when operating at scale
7. **Flashbots Integration**
- Not available on Arbitrum anyway
- May never be needed
---
## 📊 Realistic Expectations
### Week 1 Projections (Very Conservative):
```
Capital: 0.5 ETH
Trades: 3-5 per day
Success Rate: 50% (learning phase)
Avg Profit per Success: 0.005 ETH
Avg Gas per Trade: 0.002 ETH
Daily Net:
Success: 2 × 0.005 = 0.01 ETH
Failed Gas: 3 × 0.002 = 0.006 ETH
Net: 0.004 ETH per day
Weekly: 0.028 ETH (5.6% ROI)
```
### If This Works, Week 2-4:
```
Capital: 1.0 ETH (increase after validation)
Trades: 10 per day (more confidence)
Success Rate: 70% (optimization)
Avg Profit: 0.008 ETH
Daily Net: 0.035 ETH
Weekly: 0.245 ETH (24.5% ROI)
```
### If This REALLY Works (Month 2-3):
- Add more DEX protocols → more opportunities
- Add sequencer → better execution
- Scale capital to 5-10 ETH
- Target: 50-100% monthly ROI
---
## 🚨 Risk Management
### Hard Limits (Circuit Breakers):
```yaml
max_loss_per_day: 0.05 ETH
max_loss_per_week: 0.1 ETH
max_consecutive_failures: 3
max_trade_size: 0.1 ETH
max_trades_per_day: 20
max_gas_price: 0.5 gwei (Arbitrum is cheap)
circuit_breaker_cooldown: 1 hour
emergency_stop_loss: 0.2 ETH total
```
### Manual Oversight:
- [ ] Check metrics every 6 hours (first week)
- [ ] Review all failed trades
- [ ] Adjust limits based on results
- [ ] Be ready to pause if needed
### Emergency Stop:
```bash
# Kill switch command
pkill -f mev-bot
# Or via API
curl -X POST http://localhost:8080/emergency-stop
```
---
## 📦 Minimal Tech Stack
### Core Dependencies:
- **Language**: Go 1.21+
- **Ethereum Client**: go-ethereum (geth)
- **RPC Provider**: Alchemy or Infura (free tier is fine)
- **Database**: SQLite (simple, no postgres needed yet)
- **Logging**: Standard Go `log` package
- **Metrics**: Simple file-based logs
### Infrastructure:
- **Hosting**: Local machine or cheap VPS ($5/month)
- **Monitoring**: Tail logs + manual checks
- **Alerts**: None (you'll check manually)
### Later (if profitable):
- Upgrade to dedicated server
- Add Prometheus + Grafana
- Set up PagerDuty alerts
- Use PostgreSQL for analytics
---
## 🎬 Implementation Order (Detailed)
### Week 1: Days 1-2 (UniswapV2 Parser)
```bash
# Create feature branch
git checkout -b feature/v2/parsers/uniswap-v2-mvp
# Implement
touch pkg/parsers/uniswap_v2.go
touch pkg/parsers/uniswap_v2_test.go
# Focus areas:
1. Swap event signature: 0xd78ad95f...
2. ABI decoding: amount0In, amount1In, amount0Out, amount1Out
3. Token extraction from pool cache
4. Decimal scaling (critical!)
5. Validation (no zero addresses)
# Test with real data
# Example: https://arbiscan.io/tx/0x...
# Parse real Uniswap V2 swap on Arbitrum
# Achieve 100% coverage
go test ./pkg/parsers/... -coverprofile=coverage.out
go tool cover -html=coverage.out
```
### Week 1: Days 3-5 (UniswapV3 Parser)
```bash
git checkout -b feature/v2/parsers/uniswap-v3-mvp
# Key differences from V2:
1. Signed amounts (int256, not uint256)
2. sqrtPriceX96 (Q64.96 fixed point)
3. Tick and liquidity
4. Fee tiers (0.05%, 0.3%, 1%)
# Math helpers needed:
func sqrtPriceX96ToPrice(sqrtPriceX96 *big.Int) *big.Float
func calculateSwapOutput(pool *Pool, amountIn *big.Int) *big.Int
```
### Week 2: Days 1-4 (Arbitrage Detection)
```bash
git checkout -b feature/v2/arbitrage/basic-detection
# File structure:
pkg/arbitrage/
├── graph.go # Market graph
├── pathfinder.go # 2-hop BFS
├── profitability.go # Profit calculation
└── detector.go # Main detector
# Key algorithm:
For each token pair (A, B):
Find all pools: A → B
For each pool P1:
For each other pool P2:
If P1.price != P2.price:
Calculate arbitrage profit
If profit > minProfit:
Emit opportunity
```
### Week 3: Days 1-6 (Execution Engine)
```bash
git checkout -b feature/v2/execution/basic-executor
# Critical path:
1. Build swap calldata
2. Estimate gas
3. Calculate gas cost
4. Verify still profitable
5. Sign transaction
6. Send to network
7. Wait for receipt
8. Handle success/failure
# Test on testnet FIRST!
ARBITRUM_RPC=https://sepolia-rollup.arbitrum.io/rpc
```
### Week 4: Days 1-7 (Deployment)
```bash
# Shadow mode config:
SHADOW_MODE=true
LOG_LEVEL=debug
MIN_PROFIT=0.01
# Go live:
SHADOW_MODE=false
MAX_TRADE_SIZE=0.1
MAX_TRADES_PER_DAY=10
CIRCUIT_BREAKER_LOSS=0.05
```
---
## 🎯 Decision Points
### After Week 2 (Arbitrage Detection):
**Question**: Are there enough profitable opportunities?
Run detection against historical data:
```bash
go run cmd/historical-analysis/main.go \
--start-block 150000000 \
--end-block 150001000 \
--min-profit 0.01
```
**If <5 opportunities per day**:
- ❌ Stop and reconsider strategy
- Maybe try different DEXs
- Maybe lower profit threshold
**If >10 opportunities per day**:
- ✅ Continue to execution phase
### After Week 3 (Testnet):
**Question**: Do trades execute successfully?
**If success rate <50%**:
- Debug execution logic
- Check gas estimation
- Verify slippage calculations
**If success rate >70%**:
- ✅ Proceed to mainnet
### After Week 4 Day 7 (First Week Live):
**Question**: Is this profitable?
**If net profit >0**:
- ✅ Continue for another week
- Consider scaling capital
**If net profit <0**:
- Analyze why:
- Competition too fierce?
- Gas too expensive?
- Calculations wrong?
- Decide: Fix and retry, or pivot?
---
## 🔄 What Happens After 4 Weeks?
### Scenario A: MVP is Profitable ✅
**Next Steps**:
1. Increase capital to 2-5 ETH
2. Add more DEX protocols (Curve, Balancer)
3. Implement 3-hop arbitrage
4. Add sequencer integration (for speed)
5. Build proper monitoring dashboard
6. Scale to 20-50% monthly ROI
**Timeline**: 4 more weeks to "Full MVP"
### Scenario B: MVP is Break-Even ⚖️
**Next Steps**:
1. Optimize for 2 more weeks
2. Add sequencer (may be the missing piece)
3. Reduce gas costs (batch execution)
4. If still break-even, reconsider
### Scenario C: MVP is Unprofitable ❌
**Analysis**:
- Is Arbitrum too competitive?
- Are opportunities too rare?
- Is our execution too slow?
**Options**:
1. Pivot to different chain (Polygon? Base?)
2. Try different MEV strategy (liquidations?)
3. Abandon and move on
**Key**: We only invested 4 weeks, not 10!
---
## 📋 Week-by-Week Checklist
### Week 1 Checklist:
- [ ] UniswapV2 parser complete (100% coverage)
- [ ] UniswapV3 parser complete (100% coverage)
- [ ] Pool cache populated with major pairs
- [ ] Can parse any swap on Arbitrum
- [ ] All tests passing
### Week 2 Checklist:
- [ ] Market graph built from pools
- [ ] 2-hop pathfinder working
- [ ] Profitability calculator accurate
- [ ] Finding >5 opportunities per day (historical)
- [ ] Detection latency <100ms
### Week 3 Checklist:
- [ ] Can execute swaps on testnet
- [ ] Gas estimation accurate
- [ ] Slippage protection working
- [ ] Circuit breaker tested
- [ ] Success rate >70% on testnet
### Week 4 Checklist:
- [ ] Metrics collection working
- [ ] Shadow mode validated (24 hours)
- [ ] First live trade successful
- [ ] Circuit breaker hasn't tripped
- [ ] Net profit >0 after 7 days
---
## 💡 Key Principles for Fast MVP
### 1. **Simple Over Perfect**
```
❌ Don't: Build a sophisticated gas optimization system
✅ Do: Just use current gas price + 10%
❌ Don't: Support 13 DEX protocols
✅ Do: Start with 2, add more if profitable
❌ Don't: Build a ML model for profit prediction
✅ Do: Simple math: output - input - gas
```
### 2. **Validate Assumptions Fast**
```
Week 1: Can we parse swaps correctly?
Week 2: Are there arbitrage opportunities?
Week 3: Can we execute trades?
Week 4: Is it profitable?
Each week answers ONE key question.
```
### 3. **Fail Fast, Pivot Faster**
```
If Week 2 shows no opportunities → STOP
If Week 3 shows trades fail → FIX or STOP
If Week 4 shows losses → PIVOT or STOP
Don't throw good time after bad.
```
### 4. **Real Data Over Assumptions**
```
Don't assume profitability → TEST IT
Don't assume opportunities exist → MEASURE THEM
Don't assume execution works → VERIFY IT
Shadow mode + small capital = real data
```
---
## 🚀 Let's Start!
Your next immediate action:
```bash
# 1. Review this plan
# 2. If approved, start Week 1 Day 1:
git checkout -b feature/v2/parsers/uniswap-v2-mvp
# Create the parser
touch pkg/parsers/uniswap_v2.go
touch pkg/parsers/uniswap_v2_test.go
# Let's build! 🏗️
```
---
**This plan gets you to profitability validation in 4 weeks with minimal capital risk. After that, you have REAL DATA to decide whether to scale, pivot, or stop.**
**Ready to start Week 1? 🎬**
---
## 🚨 CRITICAL BUG DISCOVERED (Nov 2024)
### Problem: Bot Uses STALE Reserve Data
**Symptom**: Bot ran for 17+ hours, found ZERO arbitrage opportunities.
**Root Cause**: The arbitrage detector uses pool reserves fetched ONCE at startup and never refreshes them.
```go
// CURRENT (BROKEN) FLOW:
1. Bot starts DiscoverMajorPools() fetches reserves ONCE
2. Bot scans every 30s Uses SAME stale reserves
3. Real prices change constantly Bot sees old data
4. Result: ZERO opportunities found (markets look balanced with old data)
```
**Why This Matters**:
- Pool reserves change with EVERY swap on-chain
- Arbitrage opportunities exist for seconds/milliseconds
- Using stale data = guaranteed to miss every opportunity
- 17 hours of runtime = 17 hours of wasted scanning
### Solution: Live Reserve Refresh
**MUST IMPLEMENT** before bot can find real opportunities:
```go
// pkg/discovery/reserve_refresh.go
// RefreshReserves fetches latest reserves from chain for all cached pools
func (d *UniswapV2PoolDiscovery) RefreshReserves(ctx context.Context) error {
pools, _ := d.poolCache.GetByLiquidity(ctx, big.NewInt(0), 10000)
for _, pool := range pools {
// Call getReserves() on each pool contract
reserves, err := d.fetchReservesFromChain(ctx, pool.Address)
if err != nil {
continue // Skip failed pools
}
// Update cache with fresh reserves
pool.Reserve0 = reserves.Reserve0
pool.Reserve1 = reserves.Reserve1
pool.LastUpdated = time.Now()
d.poolCache.Update(ctx, pool)
}
return nil
}
```
**Integration in main.go**:
```go
// BEFORE each scan, refresh reserves
for range ticker.C {
// NEW: Refresh reserves from chain
if err := poolDiscovery.RefreshReserves(ctx); err != nil {
logger.Error("failed to refresh reserves", "error", err)
}
// Then scan for opportunities (with fresh data!)
opportunities, err := detector.ScanForOpportunities(ctx, blockNumber)
// ...
}
```
### Implementation Priority: HIGHEST
| Task | Priority | Estimated Time |
|------|----------|----------------|
| Create `reserve_refresh.go` | P0 | 30 min |
| Add `RefreshReserves()` method | P0 | 30 min |
| Call refresh before each scan | P0 | 15 min |
| Test with live data | P0 | 30 min |
| **Total** | **CRITICAL** | **~2 hours** |
### Verification Test
After implementing reserve refresh:
```bash
# Run bot with verbose logging
./bin/mev-flashloan --min-profit 5 --interval 10s --verbose
# Expected output (after fix):
# - Reserve values should CHANGE between scans
# - Some opportunities should be found (even if small)
# - If still 0 opportunities after 1 hour, lower min-profit further
```
### Why This Wasn't Caught Earlier
1. Unit tests use mock data (don't need live reserves)
2. Integration tests check parsing, not live detection
3. Bot "worked" (no crashes) but with stale data
4. Need live mainnet testing with reserve updates
### Lesson Learned
**Always test with LIVE data before declaring production-ready.**
Static test data can hide critical bugs like stale caches.
---
## 🔍 UPDATE: Reserve Refresh Already Implemented (Nov 30, 2024)
Upon inspection, **reserve refresh was already implemented** in:
- `pkg/discovery/reserve_refresh.go` - V2 pools
- `pkg/discovery/reserve_refresh_v3.go` - V3 pools
- `cmd/mev-flashloan/main.go` lines 141-149 - Called before each scan
**The REAL issues are:**
### 1. Limited Pool Coverage
- Only 9 UniswapV2 pools discovered
- No UniswapV3 pools in cache (only parsing, not discovering)
- Need 100+ pools for meaningful arbitrage opportunities
### 2. Same-Protocol Only
- Current detector only checks V2→V2 arbitrage
- REAL opportunities are V2→V3 cross-protocol
- Same-protocol markets are too efficient
### 3. Market Efficiency
- Professional MEV bots with:
- Flashbots/private mempools
- Sequencer-level access
- Submillisecond execution
- Public RPC bot can't compete on same-protocol arb
### Required Fixes (Priority Order):
| Fix | Impact | Effort |
|-----|--------|--------|
| Add UniswapV3 pool discovery | HIGH | 2 hours |
| Enable cross-protocol arbitrage (V2↔V3) | HIGH | 4 hours |
| Add SushiSwap, Camelot pools | MEDIUM | 3 hours |
| Reduce scan interval to 5s | LOW | 5 min |
| Add sequencer feed integration | HIGH | 8 hours |
### Why Cross-Protocol Matters
```
Same-protocol (V2→V2):
Pool A: 1 WETH = 3000 USDC
Pool B: 1 WETH = 3001 USDC
Difference: 0.03% - Too small, eaten by gas
Cross-protocol (V2→V3):
V2 Pool: 1 WETH = 3000 USDC (constant product)
V3 Pool: 1 WETH = 3050 USDC (concentrated liquidity)
Difference: 1.67% - PROFITABLE!
```
V3 pools have different pricing due to concentrated liquidity,
creating larger arbitrage windows with V2 pools.
---
## 📋 Updated Implementation Checklist
### Immediate Fixes Required:
- [ ] **P0**: Implement `RefreshReserves()` in pool discovery
- [ ] **P0**: Call reserve refresh before each arbitrage scan
- [ ] **P0**: Add logging to show reserve changes between scans
- [ ] **P0**: Test on mainnet - verify opportunities are found
- [ ] **P1**: Add reserve age check (skip pools not updated in >60s)
- [ ] **P1**: Batch RPC calls for efficiency (multicall)
- [ ] **P2**: Add WebSocket subscription for real-time reserve updates
### Performance Considerations:
With 9 pools, refreshing reserves adds:
- ~9 RPC calls per scan (one per pool)
- ~500ms latency (with public RPC)
- Acceptable for 30s scan interval
For scaling to 100+ pools:
- Use multicall to batch reserve fetches
- Consider WebSocket subscriptions
- Target <100ms refresh time