From 6260895dd722e09adaa93139bb6bc6ec00e2a491 Mon Sep 17 00:00:00 2001 From: Paul <108695806+pxrl@users.noreply.github.com> Date: Fri, 13 Dec 2024 18:29:35 +0100 Subject: [PATCH] improve: Support testing chain adapters w/o token defs (#799) --- package.json | 4 +-- tasks/enableL1TokenAcrossEcosystem.ts | 42 ++------------------------- tasks/testChainAdapter.ts | 17 ++++------- tasks/types.ts | 3 ++ tasks/utils.ts | 41 ++++++++++++++++++++++++++ yarn.lock | 8 ++--- 6 files changed, 57 insertions(+), 58 deletions(-) create mode 100644 tasks/types.ts diff --git a/package.json b/package.json index bdf0927e9..061b03104 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@across-protocol/contracts", - "version": "3.0.17", + "version": "3.0.18", "author": "UMA Team", "license": "AGPL-3.0-only", "repository": { @@ -39,7 +39,7 @@ "pre-commit-hook": "sh scripts/preCommitHook.sh" }, "dependencies": { - "@across-protocol/constants": "^3.1.21", + "@across-protocol/constants": "^3.1.22", "@coral-xyz/anchor": "^0.30.1", "@defi-wonderland/smock": "^2.3.4", "@eth-optimism/contracts": "^0.5.40", diff --git a/tasks/enableL1TokenAcrossEcosystem.ts b/tasks/enableL1TokenAcrossEcosystem.ts index b937e3919..b6d414f78 100644 --- a/tasks/enableL1TokenAcrossEcosystem.ts +++ b/tasks/enableL1TokenAcrossEcosystem.ts @@ -1,46 +1,8 @@ import { task } from "hardhat/config"; import assert from "assert"; -import { askYesNoQuestion, minimalSpokePoolInterface } from "./utils"; import { CHAIN_IDs, MAINNET_CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../utils/constants"; - -type TokenSymbol = keyof typeof TOKEN_SYMBOLS_MAP; - -/** - * Given a token symbol, determine whether it is a valid key for the TOKEN_SYMBOLS_MAP object. - */ -function isTokenSymbol(symbol: unknown): symbol is TokenSymbol { - return TOKEN_SYMBOLS_MAP[symbol as TokenSymbol] !== undefined; -} - -/** - * Given a token symbol from the HubPool chain and a remote chain ID, resolve the relevant token symbol and address. - */ -function resolveTokenOnChain( - mainnetSymbol: string, - chainId: number -): { symbol: TokenSymbol; address: string } | undefined { - assert(isTokenSymbol(mainnetSymbol), `Unrecognised token symbol (${mainnetSymbol})`); - let symbol = mainnetSymbol as TokenSymbol; - - // Handle USDC special case where L1 USDC is mapped to different token symbols on L2s. - if (mainnetSymbol === "USDC") { - const symbols = ["USDC", "USDC.e", "USDbC", "USDzC"] as TokenSymbol[]; - const tokenSymbol = symbols.find((symbol) => TOKEN_SYMBOLS_MAP[symbol]?.addresses[chainId]); - if (!isTokenSymbol(tokenSymbol)) { - return; - } - symbol = tokenSymbol; - } else if (symbol === "DAI" && chainId === CHAIN_IDs.BLAST) { - symbol = "USDB"; - } - - const address = TOKEN_SYMBOLS_MAP[symbol].addresses[chainId]; - if (!address) { - return; - } - - return { symbol, address }; -} +import { askYesNoQuestion, resolveTokenOnChain, isTokenSymbol, minimalSpokePoolInterface } from "./utils"; +import { TokenSymbol } from "./types"; const { ARBITRUM, OPTIMISM } = CHAIN_IDs; const NO_SYMBOL = "----"; diff --git a/tasks/testChainAdapter.ts b/tasks/testChainAdapter.ts index 2a889ffa5..72d278373 100644 --- a/tasks/testChainAdapter.ts +++ b/tasks/testChainAdapter.ts @@ -3,7 +3,7 @@ import { getMnemonic } from "@uma/common"; import { task } from "hardhat/config"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../utils/constants"; -import { askYesNoQuestion } from "./utils"; +import { askYesNoQuestion, resolveTokenOnChain } from "./utils"; // Chain adapter names are not 1:1 consistent with chain names, so some overrides are needed. const chains = { @@ -23,8 +23,6 @@ task("testChainAdapter", "Verify a chain adapter") const signer = new ethers.Wallet.fromMnemonic(getMnemonic()).connect(provider); const hubChainId = await getChainId(); - const { address: hubPoolAddress, abi: hubPoolAbi } = await deployments.get("HubPool"); - const hubPool = new ethers.Contract(hubPoolAddress, hubPoolAbi, provider); const spokeChainId = parseInt(args.chain); const [spokeName] = Object.entries(CHAIN_IDs).find(([, chainId]) => chainId === spokeChainId) ?? []; @@ -38,15 +36,10 @@ task("testChainAdapter", "Verify a chain adapter") const tokenAddress = TOKEN_SYMBOLS_MAP[tokenSymbol].addresses[hubChainId]; // For USDC this will resolve to native USDC on CCTP-enabled chains. - const l2Token = await hubPool.poolRebalanceRoute(spokeChainId, tokenAddress); - if (l2Token === ethers.constants.AddressZero) { - const proceed = await askYesNoQuestion( - `\t\nWARNING: ${tokenSymbol} maps to address ${l2Token} on chain ${spokeChainId}\n\t\nProceed ?` - ); - if (!proceed) process.exit(0); - } else { - console.log(`Resolved ${tokenSymbol} l2 token address on chain ${spokeChainId}: ${l2Token}.`); - } + const _l2Token = resolveTokenOnChain(tokenSymbol, spokeChainId); + assert(_l2Token !== undefined, `Token ${tokenSymbol} is not known on chain ${spokeChainId}`); + const l2Token = _l2Token.address; + console.log(`Resolved ${tokenSymbol} l2 token address on chain ${spokeChainId}: ${l2Token}.`); const erc20 = (await ethers.getContractFactory("ExpandedERC20")).attach(tokenAddress); let balance = await erc20.balanceOf(adapterAddress); diff --git a/tasks/types.ts b/tasks/types.ts new file mode 100644 index 000000000..7bfb843f4 --- /dev/null +++ b/tasks/types.ts @@ -0,0 +1,3 @@ +import { TOKEN_SYMBOLS_MAP } from "../utils/constants"; + +export type TokenSymbol = keyof typeof TOKEN_SYMBOLS_MAP; diff --git a/tasks/utils.ts b/tasks/utils.ts index ec61e4264..785f4e69b 100644 --- a/tasks/utils.ts +++ b/tasks/utils.ts @@ -1,5 +1,9 @@ +import assert from "assert"; import { ethers } from "ethers"; import readline from "readline"; +import { CHAIN_IDs, TOKEN_SYMBOLS_MAP } from "../utils/constants"; +import { TokenSymbol } from "./types"; + export const zeroAddress = ethers.constants.AddressZero; export const minimalSpokePoolInterface = [ @@ -160,3 +164,40 @@ export async function askYesNoQuestion(query: string): Promise { if (ans.toLowerCase() === "n") return false; return askYesNoQuestion(query); } + +/** + * Given a token symbol from the HubPool chain and a remote chain ID, resolve the relevant token symbol and address. + */ +export function resolveTokenOnChain( + mainnetSymbol: string, + chainId: number +): { symbol: TokenSymbol; address: string } | undefined { + assert(isTokenSymbol(mainnetSymbol), `Unrecognised token symbol (${mainnetSymbol})`); + let symbol = mainnetSymbol as TokenSymbol; + + // Handle USDC special case where L1 USDC is mapped to different token symbols on L2s. + if (mainnetSymbol === "USDC") { + const symbols = ["USDC", "USDC.e", "USDbC", "USDzC"] as TokenSymbol[]; + const tokenSymbol = symbols.find((symbol) => TOKEN_SYMBOLS_MAP[symbol]?.addresses[chainId]); + if (!isTokenSymbol(tokenSymbol)) { + return; + } + symbol = tokenSymbol; + } else if (symbol === "DAI" && chainId === CHAIN_IDs.BLAST) { + symbol = "USDB"; + } + + const address = TOKEN_SYMBOLS_MAP[symbol].addresses[chainId]; + if (!address) { + return; + } + + return { symbol, address }; +} + +/** + * Given a token symbol, determine whether it is a valid key for the TOKEN_SYMBOLS_MAP object. + */ +export function isTokenSymbol(symbol: unknown): symbol is TokenSymbol { + return TOKEN_SYMBOLS_MAP[symbol as TokenSymbol] !== undefined; +} diff --git a/yarn.lock b/yarn.lock index 9f2213ba2..6d1aae15e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,10 +2,10 @@ # yarn lockfile v1 -"@across-protocol/constants@^3.1.21": - version "3.1.21" - resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.21.tgz#e5852daa51b4e1a215a32672c252287fea593256" - integrity sha512-ajDGLpsbmse3XYPFKsih98RO/CSzpRj4iiPIzfOUvmslBfm3vIYj5nVdLKahgPumsQ+Yq2W3+PF+ZSr6Ac3tRg== +"@across-protocol/constants@^3.1.22": + version "3.1.22" + resolved "https://registry.yarnpkg.com/@across-protocol/constants/-/constants-3.1.22.tgz#888fb6852b9781aa9f872ac44e888d7bf2a643c7" + integrity sha512-l9CteL0FGHPPIbLaAztANpm/uNk8jV7hmDuecAToZdqAgqcN9E9Hfi44Fflr6H882uVsNlTU0/h1oWkTeifUnA== "@across-protocol/contracts@^0.1.4": version "0.1.4"