// Package config provides configuration management for the MEV bot package config import ( "fmt" "os" "github.com/ethereum/go-ethereum/common" "gopkg.in/yaml.v3" ) // DEXConfig contains configuration for all supported DEXes type DEXConfig struct { Routers map[string]RouterConfig `yaml:"routers"` Factories map[string]FactoryConfig `yaml:"factories"` TopTokens []string `yaml:"top_tokens"` } // RouterConfig contains configuration for a DEX router type RouterConfig struct { Address string `yaml:"address"` Name string `yaml:"name"` Version string `yaml:"version"` Type string `yaml:"type"` // "router" or "pool" } // FactoryConfig contains configuration for a DEX factory type FactoryConfig struct { Address string `yaml:"address"` Name string `yaml:"name"` } // LoadDEXConfig loads DEX configuration from a YAML file func LoadDEXConfig(path string) (*DEXConfig, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } var config DEXConfig if err := yaml.Unmarshal(data, &config); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } // Validate addresses for name, router := range config.Routers { if !common.IsHexAddress(router.Address) { return nil, fmt.Errorf("invalid router address for %s: %s", name, router.Address) } } for name, factory := range config.Factories { if !common.IsHexAddress(factory.Address) { return nil, fmt.Errorf("invalid factory address for %s: %s", name, factory.Address) } } for i, token := range config.TopTokens { if !common.IsHexAddress(token) { return nil, fmt.Errorf("invalid token address at index %d: %s", i, token) } } return &config, nil } // GetRouterAddress returns the address for a router by name func (c *DEXConfig) GetRouterAddress(name string) (common.Address, bool) { router, ok := c.Routers[name] if !ok { return common.Address{}, false } return common.HexToAddress(router.Address), true } // GetFactoryAddress returns the address for a factory by name func (c *DEXConfig) GetFactoryAddress(name string) (common.Address, bool) { factory, ok := c.Factories[name] if !ok { return common.Address{}, false } return common.HexToAddress(factory.Address), true } // GetTopTokens returns all configured top tokens as addresses func (c *DEXConfig) GetTopTokens() []common.Address { tokens := make([]common.Address, len(c.TopTokens)) for i, token := range c.TopTokens { tokens[i] = common.HexToAddress(token) } return tokens } // IsKnownRouter checks if an address is a known router func (c *DEXConfig) IsKnownRouter(addr common.Address) (RouterConfig, bool) { addrHex := addr.Hex() for _, router := range c.Routers { if router.Address == addrHex { return router, true } } return RouterConfig{}, false } // DefaultDEXConfig returns default configuration for Arbitrum mainnet func DefaultDEXConfig() *DEXConfig { return &DEXConfig{ Routers: map[string]RouterConfig{ "sushiswap": { Address: "0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506", Name: "SushiSwap", Version: "V2", Type: "router", }, "uniswap_v3_router": { Address: "0xE592427A0AEce92De3Edee1F18E0157C05861564", Name: "UniswapV3", Version: "V1", Type: "router", }, "uniswap_v3_router_v2": { Address: "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45", Name: "UniswapV3", Version: "V2", Type: "router", }, "uniswap_universal": { Address: "0xEf1c6E67703c7BD7107eed8303Fbe6EC2554BF6B", Name: "UniswapUniversal", Version: "V1", Type: "router", }, "camelot_v2": { Address: "0xc873fEcbd354f5A56E00E710B90EF4201db2448d", Name: "Camelot", Version: "V2", Type: "router", }, "camelot_v3": { Address: "0x1F721E2E82F6676FCE4eA07A5958cF098D339e18", Name: "Camelot", Version: "V3", Type: "router", }, "balancer": { Address: "0xBA12222222228d8Ba445958a75a0704d566BF2C8", Name: "Balancer", Version: "V2", Type: "vault", }, "curve": { Address: "0x7544Fe3d184b6B55D6B36c3FCA1157eE0Ba30287", Name: "Curve", Version: "V1", Type: "router", }, "kyberswap": { Address: "0x6131B5fae19EA4f9D964eAc0408E4408b66337b5", Name: "KyberSwap", Version: "V1", Type: "router", }, "kyberswap_v2": { Address: "0xC1e7dFE73E1598E3910EF4C7845B68A19f0e8c6F", Name: "KyberSwap", Version: "V2", Type: "router", }, "1inch": { Address: "0x1111111254EEB25477B68fb85Ed929f73A960582", Name: "1inch", Version: "V5", Type: "router", }, "paraswap": { Address: "0xDEF171Fe48CF0115B1d80b88dc8eAB59176FEe57", Name: "Paraswap", Version: "V5", Type: "router", }, }, Factories: map[string]FactoryConfig{ "uniswap_v2": { Address: "0xf1D7CC64Fb4452F05c498126312eBE29f30Fbcf9", Name: "UniswapV2", }, "uniswap_v3": { Address: "0x1F98431c8aD98523631AE4a59f267346ea31F984", Name: "UniswapV3", }, "sushiswap": { Address: "0xc35DADB65012eC5796536bD9864eD8773aBc74C4", Name: "SushiSwap", }, }, TopTokens: []string{ "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1", // WETH "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", // USDC "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9", // USDT "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f", // WBTC "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1", // DAI "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8", // USDC.e }, } }