From 2fc3f3c00e6aca50b6b79217d2c381b2c1d27a74 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 11 Oct 2022 21:41:20 -0700 Subject: [PATCH] fix: network token memoization (#4877) * build: upgrade redux-multicall * fix: memoize network token * docs: invalid token --- package.json | 2 +- src/lib/hooks/useCurrency.ts | 60 ++++++++++++++++-------------------- yarn.lock | 8 ++--- 3 files changed, 32 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index c2e89a180d..89c09be1e4 100644 --- a/package.json +++ b/package.json @@ -135,7 +135,7 @@ "@uniswap/governance": "^1.0.2", "@uniswap/liquidity-staker": "^1.0.2", "@uniswap/merkle-distributor": "1.0.1", - "@uniswap/redux-multicall": "^1.1.5", + "@uniswap/redux-multicall": "^1.1.6", "@uniswap/router-sdk": "^1.3.0", "@uniswap/sdk-core": "^3.0.1", "@uniswap/smart-order-router": "^2.10.0", diff --git a/src/lib/hooks/useCurrency.ts b/src/lib/hooks/useCurrency.ts index 469760a68a..5eb326247c 100644 --- a/src/lib/hooks/useCurrency.ts +++ b/src/lib/hooks/useCurrency.ts @@ -31,50 +31,45 @@ function parseStringOrBytes32(str: string | undefined, bytes32: string | undefin */ export function useTokenFromNetwork( tokenAddress: string | null | undefined, - chainId?: number + tokenChainId?: number ): Token | null | undefined { - const web3ReactChainId = useWeb3React().chainId - if (!chainId) chainId = web3ReactChainId - const supportedChain = isSupportedChain(chainId) + const { chainId } = useWeb3React() const formattedAddress = isAddress(tokenAddress) - const tokenContract = useTokenContract(formattedAddress ? formattedAddress : undefined, false) const tokenContractBytes32 = useBytes32TokenContract(formattedAddress ? formattedAddress : undefined, false) + // TODO: Fix redux-multicall so that these values do not reload. const tokenName = useSingleCallResult(tokenContract, 'name', undefined, NEVER_RELOAD) const tokenNameBytes32 = useSingleCallResult(tokenContractBytes32, 'name', undefined, NEVER_RELOAD) const symbol = useSingleCallResult(tokenContract, 'symbol', undefined, NEVER_RELOAD) const symbolBytes32 = useSingleCallResult(tokenContractBytes32, 'symbol', undefined, NEVER_RELOAD) const decimals = useSingleCallResult(tokenContract, 'decimals', undefined, NEVER_RELOAD) + const isLoading = useMemo( + () => decimals.loading || symbol.loading || tokenName.loading, + [decimals.loading, symbol.loading, tokenName.loading] + ) + const parsedDecimals = useMemo(() => decimals.result?.[0], [decimals.result]) + const parsedSymbol = useMemo( + () => parseStringOrBytes32(symbol.result?.[0], symbolBytes32.result?.[0], 'UNKNOWN'), + [symbol.result, symbolBytes32.result] + ) + const parsedName = useMemo( + () => parseStringOrBytes32(tokenName.result?.[0], tokenNameBytes32.result?.[0], 'Unknown Token'), + [tokenName.result, tokenNameBytes32.result] + ) + return useMemo(() => { - if (typeof tokenAddress !== 'string' || !supportedChain || !formattedAddress) return undefined - if (decimals.loading || symbol.loading || tokenName.loading || !chainId) return null - if (decimals.result) { - return new Token( - chainId, - formattedAddress, - decimals.result[0], - parseStringOrBytes32(symbol.result?.[0], symbolBytes32.result?.[0], 'UNKNOWN'), - parseStringOrBytes32(tokenName.result?.[0], tokenNameBytes32.result?.[0], 'Unknown Token') - ) - } - return undefined - }, [ - formattedAddress, - chainId, - supportedChain, - decimals.loading, - decimals.result, - symbol.loading, - symbol.result, - symbolBytes32.result, - tokenAddress, - tokenName.loading, - tokenName.result, - tokenNameBytes32.result, - ]) + // If the token is on another chain, we cannot fetch it on-chain, and it is invalid. + if (tokenChainId !== undefined && tokenChainId !== chainId) return undefined + if (typeof tokenAddress !== 'string' || !isSupportedChain(chainId) || !formattedAddress) return undefined + + if (isLoading || !chainId) return null + if (!parsedDecimals) return undefined + + return new Token(chainId, formattedAddress, parsedDecimals, parsedSymbol, parsedName) + }, [tokenChainId, chainId, tokenAddress, formattedAddress, isLoading, parsedDecimals, parsedSymbol, parsedName]) } type TokenMap = { [address: string]: Token } @@ -109,8 +104,7 @@ export function useCurrencyFromMap(tokens: TokenMap, currencyId?: string | null) const token = useTokenFromMapOrNetwork(tokens, isNative ? undefined : shorthandMatchAddress ?? currencyId) - const supportedChain = isSupportedChain(chainId) - if (currencyId === null || currencyId === undefined || !supportedChain) return null + if (currencyId === null || currencyId === undefined || !isSupportedChain(chainId)) return null // this case so we use our builtin wrapped token instead of wrapped tokens on token lists const wrappedNative = nativeCurrency?.wrapped diff --git a/yarn.lock b/yarn.lock index 5879d65689..f55bf694a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4144,10 +4144,10 @@ resolved "https://registry.npmjs.org/@uniswap/merkle-distributor/-/merkle-distributor-1.0.1.tgz" integrity sha512-5gDiTI5hrXIh5UWTrxKYjw30QQDnpl8ckDSpefldNenDlYO1RKkdUYMYpvrqGi2r7YzLYTlO6+TDlNs6O7hDRw== -"@uniswap/redux-multicall@^1.1.1", "@uniswap/redux-multicall@^1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@uniswap/redux-multicall/-/redux-multicall-1.1.5.tgz#7c097047d489c1624038c0fbbd3d76dc705bf153" - integrity sha512-RSMhfuAX2rPimnevvAAiwoyV2bCGTIKhVHEBOLTMF+oVxYcKKe9hCwx/cffY12t/usXWHlEJ//V7JoxTKI1Lyg== +"@uniswap/redux-multicall@^1.1.1", "@uniswap/redux-multicall@^1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@uniswap/redux-multicall/-/redux-multicall-1.1.6.tgz#27e52d97e359b6de06410fbc6d0699b9e6422707" + integrity sha512-B7kR63dtIJzr9iGITsNYAh8ktDfKEi9Ilsfq0oKxSzAChZmkq9Ss/EZ6/VKSvq1m4rPe+b9CPxZIBdRzpmf2/w== "@uniswap/router-sdk@^1.3.0": version "1.3.0"