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() { // Connect to Arbitrum client, err := ethclient.Dial("https://arb1.arbitrum.io/rpc") if err != nil { log.Fatal("Failed to connect:", err) } // Test pools that were "failing" pools := []string{ "0x6f38e884725a116C9C7fBF208e79FE8828a2595F", "0x2f5e87C9312fa29aed5c179E456625D79015299c", "0xB1026b8e7276e7AC75410F1fcbbe21796e8f7526", } // Function selectors token0Selector := []byte{0x0d, 0xfe, 0x16, 0x81} // token0() token1Selector := []byte{0xd2, 0x1c, 0xec, 0xd4} // token1() - NOTE: Different from what's in the code! for _, poolHex := range pools { poolAddress := common.HexToAddress(poolHex) fmt.Printf("\nTesting pool: %s\n", poolHex) fmt.Println("=" + "=" + "=" + "=" + "=" + "=" + "=" + "=" + "=") // Create timeout context ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // Test token0() token0Data, err := client.CallContract(ctx, ethereum.CallMsg{ To: &poolAddress, Data: token0Selector, }, nil) if err != nil { fmt.Printf(" token0() ERROR: %v\n", err) } else { if len(token0Data) >= 32 { token0 := common.BytesToAddress(token0Data[12:32]) fmt.Printf(" token0() SUCCESS: %s\n", token0.Hex()) } else { fmt.Printf(" token0() INVALID DATA: %x\n", token0Data) } } // Test token1() token1Data, err := client.CallContract(ctx, ethereum.CallMsg{ To: &poolAddress, Data: token1Selector, }, nil) if err != nil { fmt.Printf(" token1() ERROR: %v\n", err) } else { if len(token1Data) >= 32 { token1 := common.BytesToAddress(token1Data[12:32]) fmt.Printf(" token1() SUCCESS: %s\n", token1.Hex()) } else { fmt.Printf(" token1() INVALID DATA: %x\n", token1Data) } } cancel() } // Now let's check what selector is actually being used in the error messages fmt.Println("\nChecking token1() selector:") fmt.Printf(" Correct V3 selector: 0xd21220a7\n") fmt.Printf(" Our code selector: 0x%x\n", token1Selector) }