Skip to content

Commit

Permalink
improve: Support testing chain adapters w/o token defs (#799)
Browse files Browse the repository at this point in the history
  • Loading branch information
pxrl authored Dec 13, 2024
1 parent 7f0cedb commit 6260895
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 58 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -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": {
Expand Down Expand Up @@ -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",
Expand Down
42 changes: 2 additions & 40 deletions tasks/enableL1TokenAcrossEcosystem.ts
Original file line number Diff line number Diff line change
@@ -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 = "----";
Expand Down
17 changes: 5 additions & 12 deletions tasks/testChainAdapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand All @@ -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) ?? [];
Expand All @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions tasks/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { TOKEN_SYMBOLS_MAP } from "../utils/constants";

export type TokenSymbol = keyof typeof TOKEN_SYMBOLS_MAP;
41 changes: 41 additions & 0 deletions tasks/utils.ts
Original file line number Diff line number Diff line change
@@ -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 = [
Expand Down Expand Up @@ -160,3 +164,40 @@ export async function askYesNoQuestion(query: string): Promise<boolean> {
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;
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down

0 comments on commit 6260895

Please sign in to comment.