- 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>
159 lines
7.1 KiB
Go
159 lines
7.1 KiB
Go
package validation
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
)
|
|
|
|
// KnownContractRegistry maintains a registry of known contract addresses and their types
|
|
// This prevents misclassification of well-known contracts (like major ERC-20 tokens)
|
|
type KnownContractRegistry struct {
|
|
erc20Tokens map[common.Address]string
|
|
pools map[common.Address]string
|
|
routers map[common.Address]string
|
|
}
|
|
|
|
// NewKnownContractRegistry creates a new registry populated with known Arbitrum contracts
|
|
func NewKnownContractRegistry() *KnownContractRegistry {
|
|
registry := &KnownContractRegistry{
|
|
erc20Tokens: make(map[common.Address]string),
|
|
pools: make(map[common.Address]string),
|
|
routers: make(map[common.Address]string),
|
|
}
|
|
|
|
// Populate known ERC-20 tokens on Arbitrum (CRITICAL: These should NEVER be treated as pools)
|
|
registry.addKnownERC20Tokens()
|
|
registry.addKnownPools()
|
|
registry.addKnownRouters()
|
|
|
|
return registry
|
|
}
|
|
|
|
// addKnownERC20Tokens adds all major ERC-20 tokens on Arbitrum
|
|
func (r *KnownContractRegistry) addKnownERC20Tokens() {
|
|
// Major ERC-20 tokens that were being misclassified as pools
|
|
r.erc20Tokens[common.HexToAddress("0x82aF49447D8a07e3bd95BD0d56f35241523fBab1")] = "WETH" // Wrapped Ether
|
|
r.erc20Tokens[common.HexToAddress("0xaf88d065e77c8cC2239327C5EDb3A432268e5831")] = "USDC" // USD Coin
|
|
r.erc20Tokens[common.HexToAddress("0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9")] = "USDT" // Tether USD
|
|
r.erc20Tokens[common.HexToAddress("0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8")] = "USDC.e" // Bridged USDC
|
|
r.erc20Tokens[common.HexToAddress("0x912CE59144191C1204E64559FE8253a0e49E6548")] = "ARB" // Arbitrum Token
|
|
r.erc20Tokens[common.HexToAddress("0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f")] = "WBTC" // Wrapped Bitcoin
|
|
r.erc20Tokens[common.HexToAddress("0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1")] = "DAI" // Dai Stablecoin
|
|
r.erc20Tokens[common.HexToAddress("0x17FC002b466eEc40DaE837Fc4bE5c67993ddBd6F")] = "FRAX" // Frax
|
|
r.erc20Tokens[common.HexToAddress("0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978")] = "CRV" // Curve DAO Token
|
|
r.erc20Tokens[common.HexToAddress("0x539bdE0d7Dbd336b79148AA742883198BBF60342")] = "MAGIC" // MAGIC
|
|
r.erc20Tokens[common.HexToAddress("0xf97f4df75117a78c1A5a0DBb814Af92458539FB4")] = "LINK" // Chainlink Token
|
|
r.erc20Tokens[common.HexToAddress("0xfc5A1A6EB076a2C7aD06eD22C90d7E710E35ad0a")] = "GMX" // GMX
|
|
r.erc20Tokens[common.HexToAddress("0x6C2C06790b3E3E3c38e12Ee22F8183b37a13EE55")] = "DPX" // Dopex Governance Token
|
|
r.erc20Tokens[common.HexToAddress("0x10393c20975cF177a3513071bC110f7962CD67da")] = "JONES" // JonesDAO
|
|
r.erc20Tokens[common.HexToAddress("0x4e352cf164e64adcbad318c3a1e222e9eba4ce42")] = "MCB" // MCDEX Token
|
|
r.erc20Tokens[common.HexToAddress("0x23A941036Ae778Ac51Ab04CEa08Ed6e2AF33b49")] = "RDNT" // Radiant Capital
|
|
r.erc20Tokens[common.HexToAddress("0x6694340fc020c5E6B96567843da2df01b2CE1eb6")] = "STG" // Stargate Finance
|
|
r.erc20Tokens[common.HexToAddress("0x3082CC23568eA640225c2467653dB90e9250AaA0")] = "RDNT" // Radiant (alternative)
|
|
r.erc20Tokens[common.HexToAddress("0x51fC0f6660482Ea73330E414eFd7808811a57Fa2")] = "PREMIA" // Premia
|
|
r.erc20Tokens[common.HexToAddress("0x69Eb4FA4a2fbd498C257C57Ea8b7655a2559A581")] = "DODO" // DODO
|
|
}
|
|
|
|
// addKnownPools adds known liquidity pools
|
|
func (r *KnownContractRegistry) addKnownPools() {
|
|
// Major Uniswap V3 pools on Arbitrum
|
|
r.pools[common.HexToAddress("0xC31E54c7a869B9FcBEcc14363CF510d1c41fa443")] = "USDC/WETH-0.05%"
|
|
r.pools[common.HexToAddress("0x17c14D2c404D167802b16C450d3c99F88F2c4F4d")] = "USDC/WETH-0.3%"
|
|
r.pools[common.HexToAddress("0x641C00A822e8b671738d32a431a4Fb6074E5c79d")] = "WETH/ARB-0.3%"
|
|
r.pools[common.HexToAddress("0xdE64C63e6BaD1Ff18f4F1bdc9d1e7Bbfb5E0B6FD")] = "USDT/USDC-0.01%"
|
|
r.pools[common.HexToAddress("0x2f5e87C9312fa29aed5c179E456625D79015299c")] = "WBTC/WETH-0.05%"
|
|
}
|
|
|
|
// addKnownRouters adds known router contracts
|
|
func (r *KnownContractRegistry) addKnownRouters() {
|
|
// Uniswap V3 SwapRouter
|
|
r.routers[common.HexToAddress("0xE592427A0AEce92De3Edee1F18E0157C05861564")] = "UniswapV3Router"
|
|
// Uniswap V3 SwapRouter02
|
|
r.routers[common.HexToAddress("0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45")] = "UniswapV3Router02"
|
|
// SushiSwap Router
|
|
r.routers[common.HexToAddress("0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506")] = "SushiSwapRouter"
|
|
// Camelot Router
|
|
r.routers[common.HexToAddress("0xc873fEcbd354f5A56E00E710B90EF4201db2448d")] = "CamelotRouter"
|
|
}
|
|
|
|
// IsKnownERC20 checks if an address is a known ERC-20 token
|
|
func (r *KnownContractRegistry) IsKnownERC20(address common.Address) (bool, string) {
|
|
name, exists := r.erc20Tokens[address]
|
|
return exists, name
|
|
}
|
|
|
|
// IsKnownPool checks if an address is a known liquidity pool
|
|
func (r *KnownContractRegistry) IsKnownPool(address common.Address) (bool, string) {
|
|
name, exists := r.pools[address]
|
|
return exists, name
|
|
}
|
|
|
|
// IsKnownRouter checks if an address is a known router contract
|
|
func (r *KnownContractRegistry) IsKnownRouter(address common.Address) (bool, string) {
|
|
name, exists := r.routers[address]
|
|
return exists, name
|
|
}
|
|
|
|
// GetContractType returns the type of a known contract
|
|
func (r *KnownContractRegistry) GetContractType(address common.Address) (ContractType, string) {
|
|
if isERC20, name := r.IsKnownERC20(address); isERC20 {
|
|
return ContractTypeERC20Token, name
|
|
}
|
|
if isPool, name := r.IsKnownPool(address); isPool {
|
|
return ContractTypeUniswapV3Pool, name
|
|
}
|
|
if isRouter, name := r.IsKnownRouter(address); isRouter {
|
|
return ContractTypeRouter, name
|
|
}
|
|
return ContractTypeUnknown, ""
|
|
}
|
|
|
|
// ValidatePoolCall validates if a pool-specific operation should be allowed on an address
|
|
func (r *KnownContractRegistry) ValidatePoolCall(address common.Address, operation string) error {
|
|
if isERC20, name := r.IsKnownERC20(address); isERC20 {
|
|
return &ValidationError{
|
|
Code: "INVALID_POOL_OPERATION",
|
|
Message: fmt.Sprintf("Attempted pool operation '%s' on known ERC-20 token %s (%s)", operation, name, address.Hex()),
|
|
Context: map[string]interface{}{
|
|
"address": address.Hex(),
|
|
"token_name": name,
|
|
"operation": operation,
|
|
"issue": "ERC-20 tokens do not have pool-specific functions like slot0()",
|
|
},
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetCorruptionPattern analyzes an address for known corruption patterns
|
|
func (r *KnownContractRegistry) GetCorruptionPattern(address common.Address) string {
|
|
hexAddr := address.Hex()
|
|
|
|
// Check for zero address
|
|
if address == (common.Address{}) {
|
|
return "ZERO_ADDRESS"
|
|
}
|
|
|
|
// Check for mostly zeros with small values
|
|
if strings.HasSuffix(hexAddr, "0000000000000000000000000000000000000000") {
|
|
return "TRAILING_ZEROS"
|
|
}
|
|
|
|
// Check for leading zeros with small values
|
|
if strings.HasPrefix(hexAddr, "0x00000000") {
|
|
return "LEADING_ZEROS_CORRUPTION"
|
|
}
|
|
|
|
// Check for embedded WETH/USDC patterns (indicates address extraction issues)
|
|
if strings.Contains(strings.ToLower(hexAddr), "82af49447d8a07e3bd95bd0d56f35241523fbab1") {
|
|
return "EMBEDDED_WETH_PATTERN"
|
|
}
|
|
if strings.Contains(strings.ToLower(hexAddr), "af88d065e77c8cc2239327c5edb3a432268e5831") {
|
|
return "EMBEDDED_USDC_PATTERN"
|
|
}
|
|
|
|
return "OTHER_CORRUPTION"
|
|
}
|