package main import ( "context" "fmt" "log" "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) func main() { // Pool to identify poolAddr := common.HexToAddress("0xC6962004f452bE9203591991D15f6b388e09E8D0") fmt.Println("========================================") fmt.Printf("Identifying Pool: %s\n", poolAddr.Hex()) fmt.Println("========================================") fmt.Println() // Connect to Arbitrum client, err := ethclient.Dial("https://arb1.arbitrum.io/rpc") if err != nil { log.Fatal("Failed to connect:", err) } ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // First check if contract exists code, err := client.CodeAt(ctx, poolAddr, nil) if err != nil { log.Fatal("Failed to get contract code:", err) } if len(code) == 0 { fmt.Println("❌ NO CONTRACT AT THIS ADDRESS") return } fmt.Printf("✅ Contract exists (%d bytes)\n", len(code)) fmt.Println() // Method selectors for detection selectors := map[string][]byte{ "token0": {0x0d, 0xfe, 0x16, 0x81}, // Common to many DEXs "token1": {0xd2, 0x12, 0x20, 0xa7}, // Correct selector for token1() "fee": {0xdd, 0xca, 0x3f, 0x43}, // UniswapV3 "slot0": {0x38, 0x50, 0xc7, 0xbd}, // UniswapV3 "globalState": {0x13, 0xaf, 0x40, 0x35}, // Algebra "getReserves": {0x09, 0x02, 0xf1, 0xac}, // UniswapV2 "liquidity": {0x1a, 0x68, 0x6d, 0x0f}, // UniswapV3 "factory": {0xc4, 0x5a, 0x01, 0x55}, // Common "tickSpacing": {0xd0, 0xc9, 0x38, 0x91}, // UniswapV3 "maxLiquidityPerTick": {0x70, 0xcf, 0x75, 0x4a}, // UniswapV3 "sqrtPriceX96": {0x88, 0x5a, 0xdb, 0x02}, // Some V3 variants "observations": {0x25, 0x2c, 0x09, 0xd7}, // UniswapV3 "feeGrowthGlobal0X128": {0xf3, 0x05, 0x83, 0x99}, // UniswapV3 "feeGrowthGlobal1X128": {0x46, 0x14, 0x16, 0x27}, // UniswapV3 } fmt.Println("Testing Method Signatures:") fmt.Println("--------------------------") results := make(map[string]bool) tokenAddresses := make(map[string]common.Address) for name, selector := range selectors { result, err := client.CallContract(ctx, ethereum.CallMsg{ To: &poolAddr, Data: selector, }, nil) if err == nil && len(result) > 0 { results[name] = true fmt.Printf("✅ %s(): SUCCESS", name) // Extract token addresses if applicable if name == "token0" || name == "token1" { if len(result) >= 32 { addr := common.BytesToAddress(result[12:32]) tokenAddresses[name] = addr fmt.Printf(" -> %s", addr.Hex()) } } // Show fee value if name == "fee" && len(result) >= 32 { // Fee is uint24, stored in the last 3 bytes of the 32-byte word fee := uint32(result[29])<<16 | uint32(result[30])<<8 | uint32(result[31]) fmt.Printf(" -> %d (%.2f%%)", fee, float64(fee)/10000) } fmt.Println() } else { results[name] = false if err != nil { fmt.Printf("❌ %s(): FAILED - %v\n", name, err) } else { fmt.Printf("❌ %s(): FAILED - empty result\n", name) } } } fmt.Println() fmt.Println("Analysis:") fmt.Println("---------") // Analyze results hasToken0 := results["token0"] hasToken1 := results["token1"] hasFee := results["fee"] hasSlot0 := results["slot0"] hasGlobalState := results["globalState"] hasGetReserves := results["getReserves"] hasLiquidity := results["liquidity"] hasTickSpacing := results["tickSpacing"] hasMaxLiquidityPerTick := results["maxLiquidityPerTick"] hasFeeGrowthGlobal0 := results["feeGrowthGlobal0X128"] hasFeeGrowthGlobal1 := results["feeGrowthGlobal1X128"] fmt.Printf("Has token0/token1: %v/%v\n", hasToken0, hasToken1) fmt.Printf("Has fee: %v\n", hasFee) fmt.Printf("Has slot0: %v\n", hasSlot0) fmt.Printf("Has globalState: %v\n", hasGlobalState) fmt.Printf("Has getReserves: %v\n", hasGetReserves) fmt.Printf("Has liquidity: %v\n", hasLiquidity) fmt.Printf("Has tickSpacing: %v\n", hasTickSpacing) fmt.Printf("Has maxLiquidityPerTick: %v\n", hasMaxLiquidityPerTick) fmt.Printf("Has feeGrowthGlobal0/1: %v/%v\n", hasFeeGrowthGlobal0, hasFeeGrowthGlobal1) fmt.Println() fmt.Println("========================================") fmt.Println("IDENTIFICATION RESULT:") fmt.Println("========================================") // Identification logic if hasToken0 && hasToken1 && hasSlot0 && hasFee && hasTickSpacing && hasMaxLiquidityPerTick { fmt.Println("✅ Pool Type: UNISWAP V3") fmt.Println(" Confidence: 95%") fmt.Println(" Reason: Has all UniswapV3 signature methods") if token0, ok := tokenAddresses["token0"]; ok { fmt.Printf(" Token0: %s\n", token0.Hex()) } if token1, ok := tokenAddresses["token1"]; ok { fmt.Printf(" Token1: %s\n", token1.Hex()) } } else if hasToken0 && hasToken1 && hasGlobalState && !hasSlot0 { fmt.Println("✅ Pool Type: ALGEBRA-BASED (Camelot/QuickSwap V3)") fmt.Println(" Confidence: 90%") fmt.Println(" Reason: Has globalState instead of slot0") } else if hasToken0 && hasToken1 && hasGetReserves && !hasSlot0 && !hasGlobalState { fmt.Println("✅ Pool Type: UNISWAP V2 / SUSHISWAP") fmt.Println(" Confidence: 85%") fmt.Println(" Reason: Has getReserves, no slot0/globalState") } else if hasToken0 && hasToken1 { fmt.Println("⚠️ Pool Type: UNKNOWN DEX") fmt.Println(" Confidence: 30%") fmt.Println(" Reason: Has basic token methods but doesn't match known patterns") } else { fmt.Println("❌ Pool Type: NOT A STANDARD AMM POOL") fmt.Println(" Reason: Missing basic token methods") } // Additional checks fmt.Println() fmt.Println("Additional Information:") fmt.Println("----------------------") // Check factory factorySelector := []byte{0xc4, 0x5a, 0x01, 0x55} factoryResult, err := client.CallContract(ctx, ethereum.CallMsg{ To: &poolAddr, Data: factorySelector, }, nil) if err == nil && len(factoryResult) >= 32 { factory := common.BytesToAddress(factoryResult[12:32]) fmt.Printf("Factory: %s\n", factory.Hex()) // Check known factories knownFactories := map[common.Address]string{ common.HexToAddress("0x1F98431c8aD98523631AE4a59f267346ea31F984"): "UniswapV3 Factory", common.HexToAddress("0xc35DADB65012eC5796536bD9864eD8773aBc74C4"): "Sushiswap Factory", common.HexToAddress("0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865"): "PancakeSwap V3 Factory", } if name, known := knownFactories[factory]; known { fmt.Printf(" ✅ Known Factory: %s\n", name) } } // Try to get current price/state if hasSlot0 { slot0Selector := []byte{0x38, 0x50, 0xc7, 0xbd} slot0Result, err := client.CallContract(ctx, ethereum.CallMsg{ To: &poolAddr, Data: slot0Selector, }, nil) if err == nil && len(slot0Result) >= 32 { fmt.Println("Slot0 data available (price and tick info)") } } }