From 04c78c8cc1e0b5c966f0185cedab0dab8589e5ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B8r=E2=88=82=C2=A1?= <4456749@users.noreply.github.com> Date: Thu, 14 Mar 2024 18:35:04 +0100 Subject: [PATCH 1/5] Detecting and transparently resolving proxy contracts --- hooks/useAbi.ts | 30 ++++++++++++++++---- utils/proxies.ts | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 5 deletions(-) create mode 100644 utils/proxies.ts diff --git a/hooks/useAbi.ts b/hooks/useAbi.ts index 67bec483..a9eb5bf3 100644 --- a/hooks/useAbi.ts +++ b/hooks/useAbi.ts @@ -6,19 +6,39 @@ import { useQuery } from "@tanstack/react-query"; import { isAddress } from "@/utils/evm"; import { PUB_CHAIN, PUB_ETHERSCAN_API_KEY } from "@/constants"; import { useAlerts } from "@/context/Alerts"; +import { getImplementation, isProxyContract } from "@/utils/proxies"; export const useAbi = (contractAddress: Address) => { const { addAlert } = useAlerts(); const publicClient = usePublicClient({ chainId: PUB_CHAIN.id }); + const { data: implementationAddress, isLoading: isLoadingImpl } = + useQuery
({ + queryKey: [contractAddress, !!publicClient], + queryFn: () => { + if (!contractAddress || !publicClient) return null; + + return isProxyContract(publicClient, contractAddress) + .then((isProxy) => { + if (!isProxy) return null; + return getImplementation(publicClient, contractAddress); + }) + .catch(() => null); + }, + }); + + const resolvedAddress = isAddress(implementationAddress) + ? implementationAddress + : contractAddress; + const { data: abi, isLoading, error, } = useQuery+
{decodeCamelCase(selectedAbiItem?.name)}
{abi.name diff --git a/constants.ts b/constants.ts index 05c6c49c..1cf3dd8a 100644 --- a/constants.ts +++ b/constants.ts @@ -22,7 +22,7 @@ export const PUB_DELEGATION_ANNOUNCEMENTS_START_BLOCK = BigInt( // Target chain export const PUB_CHAIN_NAME = (process.env.NEXT_PUBLIC_CHAIN_NAME ?? - "goerli") as ChainName; + "sepolia") as ChainName; export const PUB_CHAIN = getChain(PUB_CHAIN_NAME); // Network and services diff --git a/hooks/useAbi.ts b/hooks/useAbi.ts index a9eb5bf3..86d9028f 100644 --- a/hooks/useAbi.ts +++ b/hooks/useAbi.ts @@ -7,6 +7,9 @@ import { isAddress } from "@/utils/evm"; import { PUB_CHAIN, PUB_ETHERSCAN_API_KEY } from "@/constants"; import { useAlerts } from "@/context/Alerts"; import { getImplementation, isProxyContract } from "@/utils/proxies"; +import { ChainName } from "@/utils/chains"; + +const CHAIN_NAME = PUB_CHAIN.name.toLowerCase() as ChainName; export const useAbi = (contractAddress: Address) => { const { addAlert } = useAlerts(); @@ -14,7 +17,7 @@ export const useAbi = (contractAddress: Address) => { const { data: implementationAddress, isLoading: isLoadingImpl } = useQuery
({ - queryKey: [contractAddress, !!publicClient], + queryKey: ["proxy-check", contractAddress, !!publicClient], queryFn: () => { if (!contractAddress || !publicClient) return null; @@ -25,6 +28,11 @@ export const useAbi = (contractAddress: Address) => { }) .catch(() => null); }, + retry: 4, + refetchOnMount: false, + refetchOnReconnect: false, + retryOnMount: true, + staleTime: Infinity, }); const resolvedAddress = isAddress(implementationAddress) @@ -36,16 +44,13 @@ export const useAbi = (contractAddress: Address) => { isLoading, error, } = useQuery