//go:build integration && legacy && forked // +build integration,legacy,forked package test_main import ( "context" "math/big" "testing" "time" "github.com/ethereum/go-ethereum/common" "github.com/fraktal/mev-beta/internal/logger" "github.com/fraktal/mev-beta/pkg/profitcalc" ) // TestComprehensiveArbitrageSystem demonstrates the complete enhanced arbitrage system func TestComprehensiveArbitrageSystem(t *testing.T) { // Create logger log := logger.New("info", "text", "") t.Log("=== Comprehensive Enhanced Arbitrage System Test ===") // Test 1: Basic Profit Calculation t.Log("\n--- Test 1: Basic Profit Calculation ---") calc := profitcalc.NewProfitCalculator(log) // WETH/USDC pair wethAddr := common.HexToAddress("0x82af49447d8a07e3bd95bd0d56f35241523fbab1") usdcAddr := common.HexToAddress("0xaf88d065e77c8cc2239327c5edb3a432268e5831") opportunity := calc.AnalyzeSwapOpportunity( context.Background(), wethAddr, usdcAddr, big.NewFloat(2.0), // 2 ETH big.NewFloat(4000.0), // 4000 USDC "UniswapV3", ) if opportunity != nil { t.Logf("Basic Profit Analysis:") t.Logf(" ID: %s", opportunity.ID) t.Logf(" Net Profit: %s ETH", calc.FormatEther(opportunity.NetProfit)) t.Logf(" Profit Margin: %.4f%%", opportunity.ProfitMargin*100) t.Logf(" Gas Cost: %s ETH", calc.FormatEther(opportunity.GasCost)) t.Logf(" Executable: %t", opportunity.IsExecutable) t.Logf(" Confidence: %.2f", opportunity.Confidence) t.Logf(" Slippage Risk: %s", opportunity.SlippageRisk) if opportunity.SlippageAnalysis != nil { t.Logf(" Slippage: %.4f%%", opportunity.SlippageAnalysis.EstimatedSlippage*100) t.Logf(" Recommendation: %s", opportunity.SlippageAnalysis.Recommendation) } } else { t.Error("Failed to create basic opportunity") } // Test 2: Opportunity Ranking System t.Log("\n--- Test 2: Opportunity Ranking System ---") ranker := profitcalc.NewOpportunityRanker(log) // Create multiple opportunities with different characteristics testOpportunities := []*profitcalc.SimpleOpportunity{ // High profit opportunity calc.AnalyzeSwapOpportunity(context.Background(), wethAddr, usdcAddr, big.NewFloat(10.0), big.NewFloat(20100.0), "UniswapV3"), // Medium profit opportunity calc.AnalyzeSwapOpportunity(context.Background(), wethAddr, usdcAddr, big.NewFloat(5.0), big.NewFloat(10050.0), "SushiSwap"), // Lower profit opportunity calc.AnalyzeSwapOpportunity(context.Background(), wethAddr, usdcAddr, big.NewFloat(1.0), big.NewFloat(2010.0), "Camelot"), // Small opportunity (might be filtered) calc.AnalyzeSwapOpportunity(context.Background(), wethAddr, usdcAddr, big.NewFloat(0.1), big.NewFloat(200.0), "TraderJoe"), } // Add opportunities to ranker var addedCount int for i, opp := range testOpportunities { if opp != nil { ranked := ranker.AddOpportunity(opp) if ranked != nil { addedCount++ t.Logf("Added Opportunity %d: NetProfit=%s ETH, Confidence=%.2f", i+1, calc.FormatEther(opp.NetProfit), opp.Confidence) } else { t.Logf("Opportunity %d filtered out", i+1) } } } // Get top opportunities topOpps := ranker.GetTopOpportunities(3) t.Logf("\nTop %d Opportunities by Score:", len(topOpps)) for _, opp := range topOpps { t.Logf(" Rank %d: Score=%.4f, NetProfit=%s ETH, Risk=%s", opp.Rank, opp.Score, calc.FormatEther(opp.NetProfit), opp.SlippageRisk) } // Get executable opportunities executable := ranker.GetExecutableOpportunities(5) t.Logf("\nExecutable Opportunities: %d", len(executable)) for _, opp := range executable { t.Logf(" ID=%s, Profit=%s ETH, Confidence=%.2f", opp.ID[:12], calc.FormatEther(opp.NetProfit), opp.Confidence) } // Test 3: Slippage Protection t.Log("\n--- Test 3: Slippage Protection Analysis ---") slippageProtector := profitcalc.NewSlippageProtector(log) // Test different trade sizes for slippage analysis testCases := []struct { name string tradeSize float64 liquidity float64 }{ {"Small trade", 1.0, 1000.0}, // 0.1% of pool {"Medium trade", 50.0, 1000.0}, // 5% of pool {"Large trade", 200.0, 1000.0}, // 20% of pool {"Huge trade", 600.0, 1000.0}, // 60% of pool } currentPrice := big.NewFloat(2000.0) // 1 ETH = 2000 USDC for _, tc := range testCases { tradeAmount := big.NewFloat(tc.tradeSize) poolLiquidity := big.NewFloat(tc.liquidity) analysis := slippageProtector.AnalyzeSlippage(tradeAmount, poolLiquidity, currentPrice) t.Logf("\n%s (%.1f%% of pool):", tc.name, tc.tradeSize/tc.liquidity*100) t.Logf(" Slippage: %.4f%% (%d bps)", analysis.EstimatedSlippage*100, analysis.SlippageBps) t.Logf(" Risk Level: %s", analysis.RiskLevel) t.Logf(" Acceptable: %t", analysis.IsAcceptable) t.Logf(" Recommendation: %s", analysis.Recommendation) t.Logf(" Effective Price: %s", analysis.EffectivePrice.String()) } // Test 4: Gas Price and Fee Calculations t.Log("\n--- Test 4: Gas Price and Fee Calculations ---") // Test gas price updates initialGasPrice := calc.GetCurrentGasPrice() t.Logf("Initial gas price: %s gwei", new(big.Float).Quo(new(big.Float).SetInt(initialGasPrice), big.NewFloat(1e9))) // Update gas price newGasPrice := big.NewInt(2000000000) // 2 gwei calc.UpdateGasPrice(newGasPrice) updatedGasPrice := calc.GetCurrentGasPrice() t.Logf("Updated gas price: %s gwei", new(big.Float).Quo(new(big.Float).SetInt(updatedGasPrice), big.NewFloat(1e9))) // Test updated opportunity with new gas price updatedOpp := calc.AnalyzeSwapOpportunity( context.Background(), wethAddr, usdcAddr, big.NewFloat(1.0), big.NewFloat(2000.0), "UniswapV3", ) if updatedOpp != nil { t.Logf("Updated opportunity with new gas price:") t.Logf(" Gas Cost: %s ETH", calc.FormatEther(updatedOpp.GasCost)) t.Logf(" Net Profit: %s ETH", calc.FormatEther(updatedOpp.NetProfit)) } // Test 5: Statistics and Performance Metrics t.Log("\n--- Test 5: System Statistics ---") stats := ranker.GetStats() t.Logf("Ranking System Statistics:") for key, value := range stats { t.Logf(" %s: %v", key, value) } priceFeedStats := calc.GetPriceFeedStats() t.Logf("\nPrice Feed Statistics:") for key, value := range priceFeedStats { t.Logf(" %s: %v", key, value) } // Test 6: Edge Cases and Error Handling t.Log("\n--- Test 6: Edge Cases and Error Handling ---") // Test with zero amounts zeroOpp := calc.AnalyzeSwapOpportunity( context.Background(), wethAddr, usdcAddr, big.NewFloat(0), big.NewFloat(0), "UniswapV3", ) if zeroOpp != nil { t.Logf("Zero amount opportunity: Executable=%t, Reason=%s", zeroOpp.IsExecutable, zeroOpp.RejectReason) } // Test slippage validation err := slippageProtector.ValidateTradeParameters( big.NewFloat(-1), // Invalid negative amount big.NewFloat(1000), big.NewFloat(100), ) if err != nil { t.Logf("Validation correctly rejected invalid parameters: %v", err) } // Test optimal trade size calculation optimalSize := slippageProtector.CalculateOptimalTradeSize( big.NewFloat(10000), // 10k liquidity 300, // 3% max slippage ) t.Logf("Optimal trade size for 3%% slippage: %s", optimalSize.String()) t.Log("\n=== Comprehensive Test Complete ===") } // TestOpportunityLifecycle tests the complete lifecycle of an arbitrage opportunity func TestOpportunityLifecycle(t *testing.T) { log := logger.New("info", "text", "") t.Log("=== Opportunity Lifecycle Test ===") // Initialize system components calc := profitcalc.NewProfitCalculator(log) ranker := profitcalc.NewOpportunityRanker(log) // Step 1: Discovery t.Log("\n--- Step 1: Opportunity Discovery ---") wethAddr := common.HexToAddress("0x82af49447d8a07e3bd95bd0d56f35241523fbab1") usdcAddr := common.HexToAddress("0xaf88d065e77c8cc2239327c5edb3a432268e5831") opp := calc.AnalyzeSwapOpportunity( context.Background(), wethAddr, usdcAddr, big.NewFloat(5.0), big.NewFloat(10000.0), "UniswapV3", ) if opp == nil { t.Fatal("Failed to discover opportunity") } t.Logf("Discovered opportunity: ID=%s, Profit=%s ETH", opp.ID, calc.FormatEther(opp.NetProfit)) // Step 2: Analysis and Ranking t.Log("\n--- Step 2: Analysis and Ranking ---") ranked := ranker.AddOpportunity(opp) if ranked == nil { t.Fatal("Opportunity was filtered out") } t.Logf("Ranked opportunity: Score=%.4f, Rank=%d, Competition Risk=%.2f", ranked.Score, ranked.Rank, ranked.CompetitionRisk) // Step 3: Validation t.Log("\n--- Step 3: Pre-execution Validation ---") if !opp.IsExecutable { t.Logf("Opportunity not executable: %s", opp.RejectReason) } else { t.Log("Opportunity passed validation checks") // Additional safety checks if opp.SlippageRisk == "Extreme" { t.Log("WARNING: Extreme slippage risk detected") } if opp.Confidence < 0.5 { t.Log("WARNING: Low confidence score") } } // Step 4: Simulate aging t.Log("\n--- Step 4: Opportunity Aging ---") initialScore := ranked.Score time.Sleep(100 * time.Millisecond) // Brief pause to simulate aging // Re-rank to see freshness impact topOpps := ranker.GetTopOpportunities(1) if len(topOpps) > 0 { newScore := topOpps[0].Score t.Logf("Score change due to aging: %.4f -> %.4f", initialScore, newScore) } // Step 5: Statistics t.Log("\n--- Step 5: Final Statistics ---") stats := ranker.GetStats() t.Logf("System processed %v opportunities with %v executable", stats["totalOpportunities"], stats["executableOpportunities"]) t.Log("\n=== Opportunity Lifecycle Test Complete ===") }