// Package main for initializing the exchange system package exchanges import ( "context" "fmt" "github.com/ethereum/go-ethereum/ethclient" "github.com/fraktal/mev-beta/internal/logger" "github.com/fraktal/mev-beta/pkg/math" ) // InitializeExchangeSystem initializes the complete exchange system with all components func InitializeExchangeSystem(client *ethclient.Client, logger *logger.Logger, config *DeploymentConfig) (*ExchangeRegistry, *CrossExchangeArbitrageFinder, error) { // Validate configuration if err := config.Validate(); err != nil { return nil, nil, fmt.Errorf("invalid configuration: %w", err) } // Create exchange registry registry := NewExchangeRegistry(client, logger) // Load exchange configurations for the target chain // This uses the existing LoadArbitrumExchanges function which already has // configurations for Uniswap V3, SushiSwap, Curve, and Balancer on Arbitrum if err := registry.LoadArbitrumExchanges(); err != nil { return nil, nil, fmt.Errorf("failed to load exchange configurations: %w", err) } // Initialize pricing engine (this is already implemented in math package) engine := math.NewExchangePricingEngine() // Register Uniswap V2 (if not already registered in LoadArbitrumExchanges) if _, exists := registry.exchanges[math.ExchangeUniswapV2]; !exists { RegisterUniswapV2WithRegistry(registry) } // Initialize all exchange components if err := registry.InitializeExchangeComponents(engine); err != nil { return nil, nil, fmt.Errorf("failed to initialize exchange components: %w", err) } // Register additional exchange implementations RegisterBalancerWithRegistry(registry) RegisterPancakeSwapWithRegistry(registry) RegisterDexAggregatorWithRegistry(registry) // Create arbitrage finder arbitrageFinder := NewCrossExchangeArbitrageFinder(client, logger, registry, engine) // Set arbitrage parameters from config arbitrageFinder.minSpread.SetFloat64(config.Arbitrage.MinSpreadPercentage / 100) // Convert percentage to decimal arbitrageFinder.minProfit.SetUint64(uint64(config.MinProfit * 1e18)) // Convert ETH to wei return registry, arbitrageFinder, nil } // RunArbitrageOpportunitySearch runs a search for arbitrage opportunities func RunArbitrageOpportunitySearch(ctx context.Context, finder *CrossExchangeArbitrageFinder, tokenA, tokenB string) error { tokenAAddr := StringToAddress(tokenA) tokenBAddr := StringToAddress(tokenB) opportunities, err := finder.FindArbitrageOpportunities(ctx, tokenAAddr, tokenBAddr) if err != nil { return fmt.Errorf("error finding arbitrage opportunities: %w", err) } // Process and log opportunities for _, opp := range opportunities { fmt.Printf("Arbitrage Opportunity Found:\n") fmt.Printf(" Token Pair: %s -> %s\n", opp.TokenIn.Hex(), opp.TokenOut.Hex()) fmt.Printf(" Buy Exchange: %s\n", opp.BuyExchange) fmt.Printf(" Sell Exchange: %s\n", opp.SellExchange) spreadPercentFloat, _ := opp.SpreadPercent.Float64() fmt.Printf(" Spread: %.4f%%\n", spreadPercentFloat*100) fmt.Printf(" Estimated Profit: %s ETH\n", opp.Profit.String()) fmt.Printf(" Net Profit: %s ETH (after gas)\n", opp.NetProfit.String()) fmt.Printf(" ROI: %.4f%%\n", opp.ROI) fmt.Printf(" Confidence: %.2f\n", opp.Confidence) fmt.Println() } return nil } // StringToAddress converts a string to common.Address func StringToAddress(s string) [20]byte { // In a real implementation, this would properly validate the string // and return the address. For this example, we'll use a simplified version. addr := [20]byte{} for i := 0; i < len(s) && i < 20; i++ { addr[i] = s[i] } return addr } // RunSystemHealthCheck performs a health check of the exchange system func RunSystemHealthCheck(registry *ExchangeRegistry) map[string]interface{} { health := make(map[string]interface{}) // Check if registry has exchanges exchanges := registry.GetAllExchanges() health["exchanges_count"] = len(exchanges) health["exchanges"] = func() []string { var names []string for _, ex := range exchanges { names = append(names, ex.Name) } return names }() // Check if all required interfaces are registered health["pool_detectors_registered"] = len(registry.poolDetectors) > 0 health["liquidity_fetchers_registered"] = len(registry.liquidityFetchers) > 0 health["swap_routers_registered"] = len(registry.swapRouters) > 0 // Add more health checks as needed health["status"] = "healthy" return health }