- Added comprehensive bounds checking to prevent buffer overruns in multicall parsing - Implemented graduated validation system (Strict/Moderate/Permissive) to reduce false positives - Added LRU caching system for address validation with 10-minute TTL - Enhanced ABI decoder with missing Universal Router and Arbitrum-specific DEX signatures - Fixed duplicate function declarations and import conflicts across multiple files - Added error recovery mechanisms with multiple fallback strategies - Updated tests to handle new validation behavior for suspicious addresses - Fixed parser test expectations for improved validation system - Applied gofmt formatting fixes to ensure code style compliance - Fixed mutex copying issues in monitoring package by introducing MetricsSnapshot - Resolved critical security vulnerabilities in heuristic address extraction - Progress: Updated TODO audit from 10% to 35% complete 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
123 lines
4.4 KiB
Go
123 lines
4.4 KiB
Go
// 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
|
|
}
|