From e3e6809140554375d008745dd98afbc8717b3026 Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Wed, 1 May 2024 22:20:33 +1000 Subject: [PATCH] feat(TokenClient): Support querying additional USDC deployments (#1467) This is the minimum change required to unconditionally query USDC aliases on non-mainnet chains. Post-CCTP this could be refactored, such that there is a more common/ central handling of token aliases. That would also be useful if Tether ever does something similar to CCTP. --- src/clients/TokenClient.ts | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/clients/TokenClient.ts b/src/clients/TokenClient.ts index f8d513470..bdeceffd0 100644 --- a/src/clients/TokenClient.ts +++ b/src/clients/TokenClient.ts @@ -5,6 +5,7 @@ import { BigNumber, bnZero, Contract, + dedupArray, ERC20, isDefined, MAX_SAFE_ALLOWANCE, @@ -16,6 +17,7 @@ import { toBN, winston, getRedisCache, + TOKEN_SYMBOLS_MAP, } from "../utils"; type TokenDataType = { [chainId: number]: { [token: string]: { balance: BigNumber; allowance: BigNumber } } }; @@ -214,16 +216,31 @@ export class TokenClient { hubPoolTokens: string[], signer: Signer ): Promise> { + const { hubPoolClient } = this; const tokens = hubPoolTokens .map((address) => { + let tokenAddrs: string[] = []; try { - const spokePoolToken = this.hubPoolClient.getL2TokenForL1TokenAtBlock(address, chainId); - return new Contract(spokePoolToken, ERC20.abi, signer); + const spokePoolToken = hubPoolClient.getL2TokenForL1TokenAtBlock(address, chainId); + tokenAddrs.push(spokePoolToken); } catch { - return undefined; + // No known deployment for this token on the SpokePool. + } + + // If the HubPool token is USDC then it might map to multiple tokens on the destination chain. + const { symbol } = hubPoolClient.getL1Tokens().find((hubPoolToken) => hubPoolToken.address === address); + if (symbol === "USDC") { + // At the moment, constants-v3 defines native usdc as _USDC. + const usdcAliases = ["_USDC", "USDC.e", "USDbC"]; // After constants-v3 update: ["USDC.e", "USDbC"] + usdcAliases + .map((symbol) => TOKEN_SYMBOLS_MAP[symbol]?.addresses[chainId]) + .filter(isDefined) + .forEach((address) => tokenAddrs.push(address)); + tokenAddrs = dedupArray(tokenAddrs); } + return tokenAddrs.filter(isDefined).map((address) => new Contract(address, ERC20.abi, signer)); }) - .filter(isDefined); + .flat(); const tokenData = Object.fromEntries( await Promise.all(