package utils import ( "fmt" "strings" "github.com/ethereum/go-ethereum/common" "github.com/fraktal/mev-beta/internal/validation" ) // SafeAddressConverter provides validated address conversion functions type SafeAddressConverter struct { validator *validation.AddressValidator } // NewSafeAddressConverter creates a new safe address converter func NewSafeAddressConverter() *SafeAddressConverter { return &SafeAddressConverter{ validator: validation.NewAddressValidator(), } } // SafeConversionResult contains the result of a safe address conversion type SafeConversionResult struct { Address common.Address IsValid bool Error error Warnings []string } // SafeHexToAddress safely converts a hex string to an address with validation func (c *SafeAddressConverter) SafeHexToAddress(hexStr string) *SafeConversionResult { result := &SafeConversionResult{ Address: common.Address{}, IsValid: false, Warnings: []string{}, } // Basic input validation if hexStr == "" { result.Error = fmt.Errorf("empty hex string") return result } // Normalize hex string normalizedHex := strings.ToLower(strings.TrimSpace(hexStr)) if !strings.HasPrefix(normalizedHex, "0x") { normalizedHex = "0x" + normalizedHex } // Length validation if len(normalizedHex) != 42 { // 0x + 40 hex chars result.Error = fmt.Errorf("invalid hex string length: %d, expected 42", len(normalizedHex)) return result } // Use comprehensive address validation validationResult := c.validator.ValidateAddress(normalizedHex) if !validationResult.IsValid { result.Error = fmt.Errorf("address validation failed: %v", validationResult.ErrorMessages) return result } // Check corruption score if validationResult.CorruptionScore > 50 { result.Error = fmt.Errorf("high corruption score (%d), refusing conversion", validationResult.CorruptionScore) return result } // Add warnings for moderate corruption if validationResult.CorruptionScore > 10 { result.Warnings = append(result.Warnings, fmt.Sprintf("moderate corruption score: %d", validationResult.CorruptionScore)) } // Add warnings from validation if len(validationResult.WarningMessages) > 0 { result.Warnings = append(result.Warnings, validationResult.WarningMessages...) } // Convert to address result.Address = common.HexToAddress(normalizedHex) result.IsValid = true return result } // SafeHexToAddressSlice safely converts multiple hex strings to addresses func (c *SafeAddressConverter) SafeHexToAddressSlice(hexStrings []string) ([]common.Address, []error) { addresses := make([]common.Address, 0, len(hexStrings)) errors := make([]error, 0) for i, hexStr := range hexStrings { result := c.SafeHexToAddress(hexStr) if !result.IsValid { errors = append(errors, fmt.Errorf("address %d (%s): %v", i, hexStr, result.Error)) continue } addresses = append(addresses, result.Address) } return addresses, errors } // MustSafeHexToAddress safely converts hex string to address, panics on failure // Only use for hardcoded known-good addresses func (c *SafeAddressConverter) MustSafeHexToAddress(hexStr string) common.Address { result := c.SafeHexToAddress(hexStr) if !result.IsValid { panic(fmt.Sprintf("invalid address conversion: %s -> %v", hexStr, result.Error)) } return result.Address } // TryHexToAddress attempts conversion with fallback to zero address func (c *SafeAddressConverter) TryHexToAddress(hexStr string) (common.Address, bool) { result := c.SafeHexToAddress(hexStr) return result.Address, result.IsValid } // Global converter instance for convenience var globalConverter = NewSafeAddressConverter() // Global convenience functions // SafeHexToAddress is a global convenience function for safe address conversion func SafeHexToAddress(hexStr string) *SafeConversionResult { return globalConverter.SafeHexToAddress(hexStr) } // TryHexToAddress is a global convenience function for address conversion with fallback func TryHexToAddress(hexStr string) (common.Address, bool) { return globalConverter.TryHexToAddress(hexStr) } // MustSafeHexToAddress is a global convenience function for known-good addresses func MustSafeHexToAddress(hexStr string) common.Address { return globalConverter.MustSafeHexToAddress(hexStr) }