From a9881dc1281c95dbc5974e97400d1c4263203e7e Mon Sep 17 00:00:00 2001 From: Paul Balaji Date: Wed, 27 Mar 2024 18:06:04 +0000 Subject: [PATCH] fix: warp route deployment verification (#3494) --- typescript/cli/src/deploy/warp.ts | 4 +- .../sdk/src/deploy/HyperlaneDeployer.ts | 41 +++++++++++-- .../sdk/src/deploy/verify/ContractVerifier.ts | 10 ++- typescript/sdk/src/token/contracts.ts | 16 ++++- typescript/sdk/src/token/deploy.ts | 61 +++++++++++++------ 5 files changed, 103 insertions(+), 29 deletions(-) diff --git a/typescript/cli/src/deploy/warp.ts b/typescript/cli/src/deploy/warp.ts index d5a288e54..515443e44 100644 --- a/typescript/cli/src/deploy/warp.ts +++ b/typescript/cli/src/deploy/warp.ts @@ -267,7 +267,7 @@ async function executeDeploy(params: DeployParams) { log('Writing deployment artifacts'); writeTokenDeploymentArtifacts(contractsFilePath, deployedContracts, params); - writeWarpUiTokenConfig(tokenConfigPath, deployedContracts, params); + writeWarpConfig(tokenConfigPath, deployedContracts, params); logBlue('Deployment is complete!'); logBlue(`Contract address artifacts are in ${contractsFilePath}`); @@ -330,7 +330,7 @@ function writeTokenDeploymentArtifacts( writeJson(filePath, artifacts); } -function writeWarpUiTokenConfig( +function writeWarpConfig( filePath: string, contracts: HyperlaneContractsMap, { configMap, metadata }: DeployParams, diff --git a/typescript/sdk/src/deploy/HyperlaneDeployer.ts b/typescript/sdk/src/deploy/HyperlaneDeployer.ts index d3b406252..f06fdb5fb 100644 --- a/typescript/sdk/src/deploy/HyperlaneDeployer.ts +++ b/typescript/sdk/src/deploy/HyperlaneDeployer.ts @@ -384,9 +384,23 @@ export abstract class HyperlaneDeployer< return contract; } - async deployContract( + /** + * Deploys a contract with a specified name. + * + * This is a generic function capable of deploying any contract type, defined within the `Factories` type, to a specified chain. + * + * @param {ChainName} chain - The name of the chain on which the contract is to be deployed. + * @param {K} contractKey - The key identifying the factory to use for deployment. + * @param {string} contractName - The name of the contract to deploy. This must match the contract source code. + * @param {Parameters} constructorArgs - Arguments for the contract's constructor. + * @param {Parameters>['initialize']>?} initializeArgs - Optional arguments for the contract's initialization function. + * @param {boolean} shouldRecover - Flag indicating whether to attempt recovery if deployment fails. + * @returns {Promise[K]>} A promise that resolves to the deployed contract instance. + */ + async deployContractWithName( chain: ChainName, - contractName: K, + contractKey: K, + contractName: string, constructorArgs: Parameters, initializeArgs?: Parameters< Awaited>['initialize'] @@ -395,8 +409,8 @@ export abstract class HyperlaneDeployer< ): Promise[K]> { const contract = await this.deployContractFromFactory( chain, - this.factories[contractName], - contractName.toString(), + this.factories[contractKey], + contractName, constructorArgs, initializeArgs, shouldRecover, @@ -405,6 +419,25 @@ export abstract class HyperlaneDeployer< return contract; } + async deployContract( + chain: ChainName, + contractKey: K, + constructorArgs: Parameters, + initializeArgs?: Parameters< + Awaited>['initialize'] + >, + shouldRecover = true, + ): Promise[K]> { + return this.deployContractWithName( + chain, + contractKey, + contractKey.toString(), + constructorArgs, + initializeArgs, + shouldRecover, + ); + } + protected async changeAdmin( chain: ChainName, proxy: ITransparentUpgradeableProxy, diff --git a/typescript/sdk/src/deploy/verify/ContractVerifier.ts b/typescript/sdk/src/deploy/verify/ContractVerifier.ts index f28939b95..4b567b773 100644 --- a/typescript/sdk/src/deploy/verify/ContractVerifier.ts +++ b/typescript/sdk/src/deploy/verify/ContractVerifier.ts @@ -73,7 +73,11 @@ export class ContractVerifier { verificationLogger: Logger, options?: FormOptions, ): Promise { - const { apiUrl, family } = this.multiProvider.getExplorerApi(chain); + const { + apiUrl, + family, + apiKey = this.apiKeys[chain], + } = this.multiProvider.getExplorerApi(chain); const params = new URLSearchParams(); params.set('module', 'contract'); params.set('action', action); @@ -84,8 +88,8 @@ export class ContractVerifier { } // only include apikey if provided & not blockscout - if (family !== ExplorerFamily.Blockscout && this.apiKeys[chain]) { - params.set('apikey', this.apiKeys[chain]); + if (family !== ExplorerFamily.Blockscout && apiKey) { + params.set('apikey', apiKey); } const url = new URL(apiUrl); diff --git a/typescript/sdk/src/token/contracts.ts b/typescript/sdk/src/token/contracts.ts index 542a04dc4..a361ae5f0 100644 --- a/typescript/sdk/src/token/contracts.ts +++ b/typescript/sdk/src/token/contracts.ts @@ -14,6 +14,15 @@ import { import { TokenType } from './config'; +export const hypERC20contracts = { + [TokenType.fastCollateral]: 'FastHypERC20Collateral', + [TokenType.fastSynthetic]: 'FastHypERC20', + [TokenType.synthetic]: 'HypERC20', + [TokenType.collateral]: 'HypERC20Collateral', + [TokenType.collateralVault]: 'HypERC20CollateralVaultDeposit', + [TokenType.native]: 'HypNative', + [TokenType.nativeScaled]: 'HypNativeScaled', +}; export const hypERC20factories = { [TokenType.fastCollateral]: new FastHypERC20Collateral__factory(), [TokenType.fastSynthetic]: new FastHypERC20__factory(), @@ -25,13 +34,18 @@ export const hypERC20factories = { }; export type HypERC20Factories = typeof hypERC20factories; +export const hypERC721contracts = { + [TokenType.collateralUri]: 'HypERC721URICollateral', + [TokenType.collateral]: 'HypERC721Collateral', + [TokenType.syntheticUri]: 'HypERC721URIStorage', + [TokenType.synthetic]: 'HypERC721', +}; export const hypERC721factories = { [TokenType.collateralUri]: new HypERC721URICollateral__factory(), [TokenType.collateral]: new HypERC721Collateral__factory(), [TokenType.syntheticUri]: new HypERC721URIStorage__factory(), [TokenType.synthetic]: new HypERC721__factory(), }; - export type HypERC721Factories = typeof hypERC721factories; export type TokenFactories = HypERC20Factories | HypERC721Factories; diff --git a/typescript/sdk/src/token/deploy.ts b/typescript/sdk/src/token/deploy.ts index 849da0c06..6a12b38db 100644 --- a/typescript/sdk/src/token/deploy.ts +++ b/typescript/sdk/src/token/deploy.ts @@ -44,7 +44,9 @@ import { import { HypERC20Factories, HypERC721Factories, + hypERC20contracts, hypERC20factories, + hypERC721contracts, hypERC721factories, } from './contracts'; @@ -134,27 +136,29 @@ export class HypERC20Deployer extends GasRouterDeployer< chain: ChainName, config: HypERC20CollateralConfig, ): Promise { - let contractName: + let tokenType: | TokenType.fastCollateral | TokenType.collateral | TokenType.collateralVault; switch (config.type) { case TokenType.fastSynthetic || TokenType.fastCollateral: - contractName = TokenType.fastCollateral; + tokenType = TokenType.fastCollateral; break; case TokenType.collateral: - contractName = TokenType.collateral; + tokenType = TokenType.collateral; break; case TokenType.collateralVault: - contractName = TokenType.collateralVault; + tokenType = TokenType.collateralVault; break; default: throw new Error(`Unknown collateral type ${config.type}`); } - return this.deployContract(chain, contractName, [ - config.token, - config.mailbox, - ]); + return this.deployContractWithName( + chain, + tokenType, + hypERC20contracts[tokenType], + [config.token, config.mailbox], + ); } protected async deployNative( @@ -162,12 +166,19 @@ export class HypERC20Deployer extends GasRouterDeployer< config: HypNativeConfig, ): Promise { if (config.scale) { - return this.deployContract(chain, TokenType.nativeScaled, [ - config.scale, - config.mailbox, - ]); + return this.deployContractWithName( + chain, + TokenType.nativeScaled, + hypERC20contracts[TokenType.nativeScaled], + [config.scale, config.mailbox], + ); } else { - return this.deployContract(chain, TokenType.native, [config.mailbox]); + return this.deployContractWithName( + chain, + TokenType.native, + hypERC20contracts[TokenType.native], + [config.mailbox], + ); } } @@ -175,9 +186,13 @@ export class HypERC20Deployer extends GasRouterDeployer< chain: ChainName, config: HypERC20Config, ): Promise { - const router: HypERC20 = await this.deployContract( + const tokenType = isFastConfig(config) + ? TokenType.fastSynthetic + : TokenType.synthetic; + const router: HypERC20 = await this.deployContractWithName( chain, - isFastConfig(config) ? TokenType.fastSynthetic : TokenType.synthetic, + tokenType, + hypERC20contracts[tokenType], [config.decimals, config.mailbox], ); try { @@ -326,9 +341,13 @@ export class HypERC721Deployer extends GasRouterDeployer< chain: ChainName, config: HypERC721CollateralConfig, ): Promise { - return this.deployContract( + const tokenType = isUriConfig(config) + ? TokenType.collateralUri + : TokenType.collateral; + return this.deployContractWithName( chain, - isUriConfig(config) ? TokenType.collateralUri : TokenType.collateral, + tokenType, + hypERC721contracts[tokenType], [config.token, config.mailbox], ); } @@ -337,9 +356,13 @@ export class HypERC721Deployer extends GasRouterDeployer< chain: ChainName, config: HypERC721Config, ): Promise { - const router = await this.deployContract( + const tokenType = isUriConfig(config) + ? TokenType.syntheticUri + : TokenType.synthetic; + const router = await this.deployContractWithName( chain, - isUriConfig(config) ? TokenType.syntheticUri : TokenType.synthetic, + tokenType, + hypERC721contracts[tokenType], [config.mailbox], ); await this.multiProvider.handleTx(