From 0cc294dec6897a78e93d18019970a05a58d082d6 Mon Sep 17 00:00:00 2001 From: Danil Nemirovsky Date: Fri, 10 Jan 2025 13:18:28 +0000 Subject: [PATCH 1/5] feat: Upgrade Validators and Scraper to latest version (#5143) ### Description Upgrade Validators and Scraper to latest version ### Related issues - Fixes [#[issue number here]](https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/5113) ### Backward compatibility Yes ### Testing Change was tested in RC --------- Co-authored-by: Danil Nemirovsky <4614623+ameten@users.noreply.github.com> --- typescript/infra/config/environments/mainnet3/agent.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/typescript/infra/config/environments/mainnet3/agent.ts b/typescript/infra/config/environments/mainnet3/agent.ts index cb3ef7eb59..15be7f1540 100644 --- a/typescript/infra/config/environments/mainnet3/agent.ts +++ b/typescript/infra/config/environments/mainnet3/agent.ts @@ -640,7 +640,7 @@ const hyperlane: RootAgentConfig = { validators: { docker: { repo, - tag: '706f69b-20250107-230151', + tag: '2d4963c-20250109-221753', }, rpcConsensusType: RpcConsensusType.Quorum, chains: validatorChainConfig(Contexts.Hyperlane), @@ -650,7 +650,7 @@ const hyperlane: RootAgentConfig = { rpcConsensusType: RpcConsensusType.Fallback, docker: { repo, - tag: '706f69b-20250107-230151', + tag: '2d4963c-20250109-221753', }, resources: scraperResources, }, From 65e7d7215c7768d3a4dbb4f8fa56138a8b2e76cd Mon Sep 17 00:00:00 2001 From: xeno097 Date: Fri, 10 Jan 2025 11:32:57 -0400 Subject: [PATCH 2/5] feat(infra): form warp routes (#5138) ### Description Adds the config getters for newly deployed warp routes that connect base ethereum and form Related registry PR: - https://github.com/hyperlane-xyz/hyperlane-registry/pull/477 ### Drive-by changes - NO ### Related issues - ### Backward compatibility - YES ### Testing - CLI - UI --- .registryrc | 2 +- .../getBaseFormAIXBTWarpConfig.ts | 38 +++++++++++++++++++ .../getBaseFormGAMEWarpConfig.ts | 38 +++++++++++++++++++ .../getEthereumFormWBTCWarpConfig.ts | 38 +++++++++++++++++++ .../getEthereumFormWSTETHWarpConfig.ts | 38 +++++++++++++++++++ .../environments/mainnet3/warp/warpIds.ts | 4 ++ typescript/infra/config/warp.ts | 8 ++++ typescript/infra/src/config/warp.ts | 3 ++ typescript/infra/src/warp/helm.ts | 2 +- 9 files changed, 169 insertions(+), 2 deletions(-) create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormAIXBTWarpConfig.ts create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormGAMEWarpConfig.ts create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWBTCWarpConfig.ts create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWSTETHWarpConfig.ts diff --git a/.registryrc b/.registryrc index c80c30c543..824e6518bd 100644 --- a/.registryrc +++ b/.registryrc @@ -1 +1 @@ -62ccc4da05f48d62a5a0fd5d1498b68b596c627b +690e04993fc72d57b8008224c69d52245495a6c0 diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormAIXBTWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormAIXBTWarpConfig.ts new file mode 100644 index 0000000000..48fac9ebe0 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormAIXBTWarpConfig.ts @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +import { ChainMap, HypTokenRouterConfig, TokenType } from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +const formSafes: ChainMap
= { + base: '0xFCdf33C6461fE8476AA0b7aC92D631d58c4e0d84', + form: '0x41B624412B529409A437f08Ef80bCabE81053650', +}; + +export const getBaseFormAIXBTWarpConfig = async ( + routerConfig: ChainMap, +): Promise> => { + const base: HypTokenRouterConfig = { + ...routerConfig.base, + owner: formSafes.base, + type: TokenType.collateral, + token: tokens.base.AIXBT, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + const form: HypTokenRouterConfig = { + ...routerConfig.form, + owner: formSafes.form, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + return { + form, + base, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormGAMEWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormGAMEWarpConfig.ts new file mode 100644 index 0000000000..c6d071e62b --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getBaseFormGAMEWarpConfig.ts @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +import { ChainMap, HypTokenRouterConfig, TokenType } from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +const formSafes: ChainMap
= { + base: '0xFCdf33C6461fE8476AA0b7aC92D631d58c4e0d84', + form: '0x41B624412B529409A437f08Ef80bCabE81053650', +}; + +export const getBaseFormGAMEWarpConfig = async ( + routerConfig: ChainMap, +): Promise> => { + const base: HypTokenRouterConfig = { + ...routerConfig.base, + owner: formSafes.base, + type: TokenType.collateral, + token: tokens.base.GAME, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + const form: HypTokenRouterConfig = { + ...routerConfig.form, + owner: formSafes.form, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + return { + form, + base, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWBTCWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWBTCWarpConfig.ts new file mode 100644 index 0000000000..c7a1491fd1 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWBTCWarpConfig.ts @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +import { ChainMap, HypTokenRouterConfig, TokenType } from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +const formSafes: ChainMap
= { + ethereum: '0xec5ad23e29203301B2C1a765718Cc1de7A8d3FbF', + form: '0x41B624412B529409A437f08Ef80bCabE81053650', +}; + +export const getEthereumFormWBTCWarpConfig = async ( + routerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + owner: formSafes.ethereum, + type: TokenType.collateral, + token: tokens.ethereum.WBTC, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + const form: HypTokenRouterConfig = { + ...routerConfig.form, + owner: formSafes.form, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + return { + form, + ethereum, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWSTETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWSTETHWarpConfig.ts new file mode 100644 index 0000000000..b0cce79a35 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumFormWSTETHWarpConfig.ts @@ -0,0 +1,38 @@ +import { ethers } from 'ethers'; + +import { ChainMap, HypTokenRouterConfig, TokenType } from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +const formSafes: ChainMap
= { + ethereum: '0xec5ad23e29203301B2C1a765718Cc1de7A8d3FbF', + form: '0x41B624412B529409A437f08Ef80bCabE81053650', +}; + +export const getEthereumFormWSTETHWarpConfig = async ( + routerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + owner: formSafes.ethereum, + type: TokenType.collateral, + token: tokens.ethereum.WSTETH, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + const form: HypTokenRouterConfig = { + ...routerConfig.form, + owner: formSafes.form, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }; + + return { + form, + ethereum, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts index aa48bea0cf..14da057bb1 100644 --- a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts +++ b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts @@ -42,4 +42,8 @@ export enum WarpRouteIds { ArbitrumBaseBlastBscEthereumGnosisLiskMantleModeOptimismPolygonScrollZeroNetworkZoraMainnet = 'ETH/arbitrum-base-blast-bsc-ethereum-gnosis-lisk-mantle-mode-optimism-polygon-scroll-zeronetwork-zoramainnet', AppchainBaseUSDC = 'USDC/appchain-base', BobaBsquaredSwellUBTC = 'UBTC/boba-bsquared-swell', + EthereumFormWBTC = 'WBTC/ethereum-form', + EthereumFormWSTETH = 'WSTETH/ethereum-form', + BaseFormAIXBT = 'AIXBT/base-form', + BaseFormGAME = 'GAME/base-form', } diff --git a/typescript/infra/config/warp.ts b/typescript/infra/config/warp.ts index cb5c2d72e9..dec816d15b 100644 --- a/typescript/infra/config/warp.ts +++ b/typescript/infra/config/warp.ts @@ -20,6 +20,8 @@ import { getArbitrumEthereumMantleModePolygonScrollZeroNetworkUSDTWarpConfig } f import { getArbitrumEthereumZircuitAmphrETHWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumEthereumZircuitAmphrETHWarpConfig.js'; import { getArbitrumNeutronEclipWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumNeutronEclipWarpConfig.js'; import { getArbitrumNeutronTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getArbitrumNeutronTiaWarpConfig.js'; +import { getBaseFormAIXBTWarpConfig } from './environments/mainnet3/warp/configGetters/getBaseFormAIXBTWarpConfig.js'; +import { getBaseFormGAMEWarpConfig } from './environments/mainnet3/warp/configGetters/getBaseFormGAMEWarpConfig.js'; import { getBaseZeroNetworkCBBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getBaseZeroNetworkCBBTCWarpConfig.js'; import { getBobaBsquaredSwellUBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getBobaBsquaredSwellUBTCWarpConfig.js'; import { getEclipseEthereumApxEthWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseEthereumApxETHWarpConfig.js'; @@ -30,6 +32,8 @@ import { getEclipseStrideTiaWarpConfig } from './environments/mainnet3/warp/conf import { getEclipseStrideStTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getEclipseStrideTIAWarpConfig.js'; import { getEthereumBscLUMIAWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumBscLumiaLUMIAWarpConfig.js'; import { getEthereumFlowCbBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumFlowCbBTCWarpConfig.js'; +import { getEthereumFormWBTCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumFormWBTCWarpConfig.js'; +import { getEthereumFormWSTETHWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumFormWSTETHWarpConfig.js'; import { getEthereumInevmUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.js'; import { getEthereumInevmUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.js'; import { getEthereumInkUSDCConfig } from './environments/mainnet3/warp/configGetters/getEthereumInkUSDCWarpConfig.js'; @@ -88,6 +92,10 @@ export const warpConfigGetterMap: Record = { [WarpRouteIds.AppchainBaseUSDC]: getAppChainBaseUSDCWarpConfig, [WarpRouteIds.BobaBsquaredSwellUBTC]: getBobaBsquaredSwellUBTCWarpConfig, [WarpRouteIds.EthereumZircuitRe7LRT]: getEthereumZircuitRe7LRTWarpConfig, + [WarpRouteIds.EthereumFormWBTC]: getEthereumFormWBTCWarpConfig, + [WarpRouteIds.EthereumFormWSTETH]: getEthereumFormWSTETHWarpConfig, + [WarpRouteIds.BaseFormAIXBT]: getBaseFormAIXBTWarpConfig, + [WarpRouteIds.BaseFormGAME]: getBaseFormGAMEWarpConfig, }; export async function getWarpConfig( diff --git a/typescript/infra/src/config/warp.ts b/typescript/infra/src/config/warp.ts index 3a0ddb4110..6c8ff29132 100644 --- a/typescript/infra/src/config/warp.ts +++ b/typescript/infra/src/config/warp.ts @@ -14,6 +14,7 @@ export const tokens: ChainMap> = { weETHs: '0x917cee801a67f933f2e6b33fc0cd1ed2d5909d88', pumpBTCsei: '0xe9ebd666954B7F0B5B044704c86B126651f6235d', Re7LRT: '0x84631c0d0081FDe56DeB72F6DE77abBbF6A9f93a', + WSTETH: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', }, sei: { fastUSD: '0x37a4dD9CED2b19Cfe8FAC251cd727b5787E45269', @@ -21,6 +22,8 @@ export const tokens: ChainMap> = { base: { cbBTC: '0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf', USDC: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913', + AIXBT: '0x4F9Fd6Be4a90f2620860d680c0d4d5Fb53d1A825', + GAME: '0x1C4CcA7C5DB003824208aDDA61Bd749e55F463a3', }, bsquared: { uBTC: '0x796e4D53067FF374B89b2Ac101ce0c1f72ccaAc2', diff --git a/typescript/infra/src/warp/helm.ts b/typescript/infra/src/warp/helm.ts index 98af5bc507..be9b752f88 100644 --- a/typescript/infra/src/warp/helm.ts +++ b/typescript/infra/src/warp/helm.ts @@ -28,7 +28,7 @@ export class WarpRouteMonitorHelmManager extends HelmManager { return { image: { repository: 'gcr.io/abacus-labs-dev/hyperlane-monorepo', - tag: '6da7f6f-20250109-210231', + tag: '20a0c4b-20250109-221853', }, warpRouteId: this.warpRouteId, fullnameOverride: this.helmReleaseName, From fc80df5b4aad38c44deeaba02be6261701ca398a Mon Sep 17 00:00:00 2001 From: Jason Guo <33064781+Xaroz@users.noreply.github.com> Date: Fri, 10 Jan 2025 10:43:05 -0600 Subject: [PATCH 3/5] feat(infra): add rstETH/ethereum-zircuit warp route config (#5129) ### Description Adds rstETH/ethereum-zircuit warp route config ### Drive-by changes Add dummy soon owner ### Related issues ### Backward compatibility Yes ### Testing CLI testing --- .changeset/rare-windows-deny.md | 5 +++ .registryrc | 2 +- config.yaml | 12 ++++++ .../getEthereumZircuitRstETHWarpConfig.ts | 39 +++++++++++++++++++ .../environments/mainnet3/warp/warpIds.ts | 1 + typescript/infra/config/warp.ts | 2 + typescript/infra/src/config/warp.ts | 1 + 7 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 .changeset/rare-windows-deny.md create mode 100644 config.yaml create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumZircuitRstETHWarpConfig.ts diff --git a/.changeset/rare-windows-deny.md b/.changeset/rare-windows-deny.md new file mode 100644 index 0000000000..c744963c9c --- /dev/null +++ b/.changeset/rare-windows-deny.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/infra': minor +--- + +Add rstETH/ethereum-zircuit warp config diff --git a/.registryrc b/.registryrc index 824e6518bd..f1d8706f5d 100644 --- a/.registryrc +++ b/.registryrc @@ -1 +1 @@ -690e04993fc72d57b8008224c69d52245495a6c0 +115d44069109f3ef43caeed5632f6255d9a3390a diff --git a/config.yaml b/config.yaml new file mode 100644 index 0000000000..feb0260b65 --- /dev/null +++ b/config.yaml @@ -0,0 +1,12 @@ +ethereum: + type: collateral + token: "0x7a4EffD87C2f3C55CA251080b1343b605f327E3a" + owner: "0xDA0d054265bB30F4f32C92066428FE57513E7ee1" + mailbox: "0xc005dc82818d67AF737725bD4bf75435d065D239" + interchainSecurityModule: "0x0000000000000000000000000000000000000000" +zircuit: + type: synthetic + owner: "0xA1895dF8AE7b7678E82E76b167A24c82Fb83ec9A" + mailbox: "0xc2FbB9411186AB3b1a6AFCCA702D1a80B48b197c" + interchainSecurityModule: "0x0000000000000000000000000000000000000000" + diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumZircuitRstETHWarpConfig.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumZircuitRstETHWarpConfig.ts new file mode 100644 index 0000000000..755714c719 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getEthereumZircuitRstETHWarpConfig.ts @@ -0,0 +1,39 @@ +import { ethers } from 'ethers'; + +import { ChainMap, HypTokenRouterConfig, TokenType } from '@hyperlane-xyz/sdk'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +const RstETHSafes = { + ethereum: '0xDA0d054265bB30F4f32C92066428FE57513E7ee1', + zircuit: '0xA1895dF8AE7b7678E82E76b167A24c82Fb83ec9A', +}; + +const ISM_CONFIG = ethers.constants.AddressZero; // Default ISM + +export const getEthereumZircuitRstETHWarpConfig = async ( + routerConfig: ChainMap, +): Promise> => { + const ethereum: HypTokenRouterConfig = { + ...routerConfig.ethereum, + owner: RstETHSafes.ethereum, + type: TokenType.collateral, + token: tokens.ethereum.rstETH, + interchainSecurityModule: ISM_CONFIG, + }; + + const zircuit: HypTokenRouterConfig = { + ...routerConfig.zircuit, + owner: RstETHSafes.zircuit, + type: TokenType.synthetic, + interchainSecurityModule: ISM_CONFIG, + }; + + return { + ethereum, + zircuit, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts index 14da057bb1..32db67821f 100644 --- a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts +++ b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts @@ -42,6 +42,7 @@ export enum WarpRouteIds { ArbitrumBaseBlastBscEthereumGnosisLiskMantleModeOptimismPolygonScrollZeroNetworkZoraMainnet = 'ETH/arbitrum-base-blast-bsc-ethereum-gnosis-lisk-mantle-mode-optimism-polygon-scroll-zeronetwork-zoramainnet', AppchainBaseUSDC = 'USDC/appchain-base', BobaBsquaredSwellUBTC = 'UBTC/boba-bsquared-swell', + EthereumZircuitRstETH = 'rstETH/ethereum-zircuit', EthereumFormWBTC = 'WBTC/ethereum-form', EthereumFormWSTETH = 'WSTETH/ethereum-form', BaseFormAIXBT = 'AIXBT/base-form', diff --git a/typescript/infra/config/warp.ts b/typescript/infra/config/warp.ts index dec816d15b..75da6ba959 100644 --- a/typescript/infra/config/warp.ts +++ b/typescript/infra/config/warp.ts @@ -43,6 +43,7 @@ import { getEthereumVictionETHWarpConfig } from './environments/mainnet3/warp/co import { getEthereumVictionUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.js'; import { getEthereumVictionUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.js'; import { getEthereumZircuitRe7LRTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumZircuitRe7LRTWarpConfig.js'; +import { getEthereumZircuitRstETHWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumZircuitRstETHWarpConfig.js'; import { getInevmInjectiveINJWarpConfig } from './environments/mainnet3/warp/configGetters/getInevmInjectiveINJWarpConfig.js'; import { getMantapacificNeutronTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.js'; import { getRenzoEZETHWarpConfig } from './environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.js'; @@ -92,6 +93,7 @@ export const warpConfigGetterMap: Record = { [WarpRouteIds.AppchainBaseUSDC]: getAppChainBaseUSDCWarpConfig, [WarpRouteIds.BobaBsquaredSwellUBTC]: getBobaBsquaredSwellUBTCWarpConfig, [WarpRouteIds.EthereumZircuitRe7LRT]: getEthereumZircuitRe7LRTWarpConfig, + [WarpRouteIds.EthereumZircuitRstETH]: getEthereumZircuitRstETHWarpConfig, [WarpRouteIds.EthereumFormWBTC]: getEthereumFormWBTCWarpConfig, [WarpRouteIds.EthereumFormWSTETH]: getEthereumFormWSTETHWarpConfig, [WarpRouteIds.BaseFormAIXBT]: getBaseFormAIXBTWarpConfig, diff --git a/typescript/infra/src/config/warp.ts b/typescript/infra/src/config/warp.ts index 6c8ff29132..e3a04dda95 100644 --- a/typescript/infra/src/config/warp.ts +++ b/typescript/infra/src/config/warp.ts @@ -14,6 +14,7 @@ export const tokens: ChainMap> = { weETHs: '0x917cee801a67f933f2e6b33fc0cd1ed2d5909d88', pumpBTCsei: '0xe9ebd666954B7F0B5B044704c86B126651f6235d', Re7LRT: '0x84631c0d0081FDe56DeB72F6DE77abBbF6A9f93a', + rstETH: '0x7a4EffD87C2f3C55CA251080b1343b605f327E3a', WSTETH: '0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0', }, sei: { From 79c61c8919d3fb2d1f83bd7e9904a6394a40cad2 Mon Sep 17 00:00:00 2001 From: Paul Balaji <10051819+paulbalaji@users.noreply.github.com> Date: Fri, 10 Jan 2025 17:02:52 +0000 Subject: [PATCH 4/5] feat: support safe tx parsing for zksync chains (#5042) ### Description 1. correctly generate core config for zksync chains - copied from `pb/zksync` https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/pb/zksync/typescript/infra/config/environments/mainnet3/core.ts - note the storage aggregation ism was not around when doing the first zksync chain deploys, and we haven't gone back and updated the config generation yet to include this - required so we infer the correct config for zksync changes and don't assume it's the same as non-zksync chains 2. update ISM reader to return storagemultisigism types on zksync - since static ISMs are not supported on zksync - the moduleType is the same, so the reader has to determine if it's static/storage - note: at the moment on non-zksync we assume it's a static multisig/aggregation ISM - required so we correctly compare the config vs onchain config ### Drive-by changes ### Related issues ### Backward compatibility ### Testing - these changes were used to verify SAFE txs for the last couple of batches - the config changes have also been used in production on zksync chains since October 23rd 2024 [`26d198a` (#4761)](https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/4761/commits/26d198a18fe0dce0ebf28ab75c32788e7104e2fc#diff-d4db62438f3fd9acf24be52093e81d126292859f9f48c81aa1704d41fe8ddf1a) --- .changeset/eleven-carrots-shave.md | 5 ++ .../config/environments/mainnet3/core.ts | 90 ++++++++++++++----- .../config/environments/testnet4/core.ts | 88 +++++++++++++----- typescript/sdk/src/ism/EvmIsmReader.ts | 25 +++++- 4 files changed, 165 insertions(+), 43 deletions(-) create mode 100644 .changeset/eleven-carrots-shave.md diff --git a/.changeset/eleven-carrots-shave.md b/.changeset/eleven-carrots-shave.md new file mode 100644 index 0000000000..ef5f577bdb --- /dev/null +++ b/.changeset/eleven-carrots-shave.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/sdk': patch +--- + +Fix the return type of multisig and aggregation ISMs for zksync-stack chains. diff --git a/typescript/infra/config/environments/mainnet3/core.ts b/typescript/infra/config/environments/mainnet3/core.ts index b0655ae785..eb8315a690 100644 --- a/typescript/infra/config/environments/mainnet3/core.ts +++ b/typescript/infra/config/environments/mainnet3/core.ts @@ -4,9 +4,11 @@ import { AggregationHookConfig, AggregationIsmConfig, ChainMap, + ChainTechnicalStack, CoreConfig, FallbackRoutingHookConfig, HookType, + IgpConfig, IsmType, MerkleTreeHookConfig, MultisigConfig, @@ -20,10 +22,15 @@ import { } from '@hyperlane-xyz/sdk'; import { Address, objMap } from '@hyperlane-xyz/utils'; +import { getChain } from '../../registry.js'; + import { igp } from './igp.js'; import { DEPLOYER, ethereumChainOwners } from './owners.js'; import { supportedChainNames } from './supportedChainNames.js'; +// There are no static ISMs or hooks for zkSync, this means +// that the default ISM is a routing ISM and the default hook +// is a fallback routing hook. export const core: ChainMap = objMap( ethereumChainOwners, (local, owner) => { @@ -33,11 +40,26 @@ export const core: ChainMap = objMap( .map((origin) => [origin, defaultMultisigConfigs[origin]]), ); + const isZksyncChain = + getChain(local).technicalStack === ChainTechnicalStack.ZkSync; + + // zkSync uses a different ISM for the merkle root const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => - multisigConfigToIsmConfig(IsmType.MERKLE_ROOT_MULTISIG, multisig); + multisigConfigToIsmConfig( + isZksyncChain + ? IsmType.STORAGE_MERKLE_ROOT_MULTISIG + : IsmType.MERKLE_ROOT_MULTISIG, + multisig, + ); + // zkSync uses a different ISM for the message ID const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => - multisigConfigToIsmConfig(IsmType.MESSAGE_ID_MULTISIG, multisig); + multisigConfigToIsmConfig( + isZksyncChain + ? IsmType.STORAGE_MESSAGE_ID_MULTISIG + : IsmType.MESSAGE_ID_MULTISIG, + multisig, + ); const routingIsm: RoutingIsmConfig = { type: IsmType.ROUTING, @@ -52,17 +74,30 @@ export const core: ChainMap = objMap( ...owner, }; + // No static aggregation ISM support on zkSync + const defaultZkSyncIsm = (): RoutingIsmConfig => ({ + type: IsmType.ROUTING, + domains: objMap( + originMultisigs, + (_, multisig): MultisigIsmConfig => messageIdIsm(multisig), + ), + ...owner, + }); + const pausableIsm: PausableIsmConfig = { type: IsmType.PAUSABLE, paused: false, owner: DEPLOYER, // keep pausable hot }; - const defaultIsm: AggregationIsmConfig = { - type: IsmType.AGGREGATION, - modules: [routingIsm, pausableIsm], - threshold: 2, - }; + // No static aggregation ISM support on zkSync + const defaultIsm: AggregationIsmConfig | RoutingIsmConfig = isZksyncChain + ? defaultZkSyncIsm() + : { + type: IsmType.AGGREGATION, + modules: [routingIsm, pausableIsm], + threshold: 2, + }; const merkleHook: MerkleTreeHookConfig = { type: HookType.MERKLE_TREE, @@ -75,30 +110,45 @@ export const core: ChainMap = objMap( paused: false, owner: DEPLOYER, // keep pausable hot }; - const aggregationHooks = objMap( + + // No static aggregation hook support on zkSync + const defaultHookDomains = objMap( originMultisigs, - (_origin, _): AggregationHookConfig => ({ - type: HookType.AGGREGATION, - hooks: [pausableHook, merkleHook, igpHook], - }), + (_origin, _): AggregationHookConfig | IgpConfig => { + return isZksyncChain + ? igpHook + : { + type: HookType.AGGREGATION, + hooks: [pausableHook, merkleHook, igpHook], + }; + }, ); + const defaultHook: FallbackRoutingHookConfig = { type: HookType.FALLBACK_ROUTING, ...owner, - domains: aggregationHooks, + domains: defaultHookDomains, fallback: merkleHook, }; if (typeof owner.owner !== 'string') { throw new Error('beneficiary must be a string'); } - const requiredHook: ProtocolFeeHookConfig = { - type: HookType.PROTOCOL_FEE, - maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token - protocolFee: BigNumber.from(0).toString(), // 0 wei - beneficiary: owner.owner as Address, // Owner can be AccountConfig - ...owner, - }; + + // No aggregation hook support on zkSync, so we ignore protocolFee + // and make the merkleTreeHook required + const requiredHook: ProtocolFeeHookConfig | MerkleTreeHookConfig = + isZksyncChain + ? { + type: HookType.MERKLE_TREE, + } + : { + type: HookType.PROTOCOL_FEE, + maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token + protocolFee: BigNumber.from(0).toString(), // 0 wei + beneficiary: owner.owner as Address, // Owner can be AccountConfig + ...owner, + }; return { defaultIsm, diff --git a/typescript/infra/config/environments/testnet4/core.ts b/typescript/infra/config/environments/testnet4/core.ts index e40fafb051..a76ab9fd3c 100644 --- a/typescript/infra/config/environments/testnet4/core.ts +++ b/typescript/infra/config/environments/testnet4/core.ts @@ -4,9 +4,11 @@ import { AggregationHookConfig, AggregationIsmConfig, ChainMap, + ChainTechnicalStack, CoreConfig, FallbackRoutingHookConfig, HookType, + IgpConfig, IsmType, MerkleTreeHookConfig, MultisigConfig, @@ -36,11 +38,26 @@ export const core: ChainMap = objMap( .map((origin) => [origin, defaultMultisigConfigs[origin]]), ); - const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => - multisigConfigToIsmConfig(IsmType.MERKLE_ROOT_MULTISIG, multisig); + const isZksyncChain = + getChain(local).technicalStack === ChainTechnicalStack.ZkSync; + // zkSync uses a different ISM for the merkle root + const merkleRoot = (multisig: MultisigConfig): MultisigIsmConfig => + multisigConfigToIsmConfig( + isZksyncChain + ? IsmType.STORAGE_MERKLE_ROOT_MULTISIG + : IsmType.MERKLE_ROOT_MULTISIG, + multisig, + ); + + // zkSync uses a different ISM for the message ID const messageIdIsm = (multisig: MultisigConfig): MultisigIsmConfig => - multisigConfigToIsmConfig(IsmType.MESSAGE_ID_MULTISIG, multisig); + multisigConfigToIsmConfig( + isZksyncChain + ? IsmType.STORAGE_MESSAGE_ID_MULTISIG + : IsmType.MESSAGE_ID_MULTISIG, + multisig, + ); const routingIsm: RoutingIsmConfig = { type: IsmType.ROUTING, @@ -55,17 +72,30 @@ export const core: ChainMap = objMap( ...ownerConfig, }; + // No static aggregation ISM support on zkSync + const defaultZkSyncIsm = (): RoutingIsmConfig => ({ + type: IsmType.ROUTING, + domains: objMap( + originMultisigs, + (_, multisig): MultisigIsmConfig => messageIdIsm(multisig), + ), + ...ownerConfig, + }); + const pausableIsm: PausableIsmConfig = { type: IsmType.PAUSABLE, paused: false, ...ownerConfig, }; - const defaultIsm: AggregationIsmConfig = { - type: IsmType.AGGREGATION, - modules: [routingIsm, pausableIsm], - threshold: 2, - }; + // No static aggregation ISM support on zkSync + const defaultIsm: AggregationIsmConfig | RoutingIsmConfig = isZksyncChain + ? defaultZkSyncIsm() + : { + type: IsmType.AGGREGATION, + modules: [routingIsm, pausableIsm], + threshold: 2, + }; const merkleHook: MerkleTreeHookConfig = { type: HookType.MERKLE_TREE, @@ -79,28 +109,44 @@ export const core: ChainMap = objMap( ...ownerConfig, }; - const aggregationHooks = objMap( + // No static aggregation hook support on zkSync + const defaultHookDomains = objMap( originMultisigs, - (_origin, _): AggregationHookConfig => ({ - type: HookType.AGGREGATION, - hooks: [pausableHook, merkleHook, igpHook], - }), + (_origin, _): AggregationHookConfig | IgpConfig => { + return isZksyncChain + ? igpHook + : { + type: HookType.AGGREGATION, + hooks: [pausableHook, merkleHook, igpHook], + }; + }, ); const defaultHook: FallbackRoutingHookConfig = { type: HookType.FALLBACK_ROUTING, ...ownerConfig, - domains: aggregationHooks, + domains: defaultHookDomains, fallback: merkleHook, }; - const requiredHook: ProtocolFeeHookConfig = { - type: HookType.PROTOCOL_FEE, - maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token - protocolFee: BigNumber.from(1).toString(), // 1 wei of native token - beneficiary: ownerConfig.owner as Address, - ...ownerConfig, - }; + if (typeof ownerConfig.owner !== 'string') { + throw new Error('beneficiary must be a string'); + } + + // No aggregation hook support on zkSync, so we ignore protocolFee + // and make the merkleTreeHook required + const requiredHook: ProtocolFeeHookConfig | MerkleTreeHookConfig = + isZksyncChain + ? { + type: HookType.MERKLE_TREE, + } + : { + type: HookType.PROTOCOL_FEE, + maxProtocolFee: ethers.utils.parseUnits('1', 'gwei').toString(), // 1 gwei of native token + protocolFee: BigNumber.from(1).toString(), // 1 wei of native token + beneficiary: ownerConfig.owner as Address, + ...ownerConfig, + }; return { defaultIsm, diff --git a/typescript/sdk/src/ism/EvmIsmReader.ts b/typescript/sdk/src/ism/EvmIsmReader.ts index a6d0751188..2848fd18ec 100644 --- a/typescript/sdk/src/ism/EvmIsmReader.ts +++ b/typescript/sdk/src/ism/EvmIsmReader.ts @@ -23,6 +23,7 @@ import { import { DEFAULT_CONTRACT_READ_CONCURRENCY } from '../consts/concurrency.js'; import { DispatchedMessage } from '../core/types.js'; +import { ChainTechnicalStack } from '../metadata/chainMetadataTypes.js'; import { MultiProvider } from '../providers/MultiProvider.js'; import { ChainNameOrId } from '../types.js'; import { HyperlaneReader } from '../utils/HyperlaneReader.js'; @@ -62,6 +63,7 @@ export interface IsmReader { export class EvmIsmReader extends HyperlaneReader implements IsmReader { protected readonly logger = rootLogger.child({ module: 'EvmIsmReader' }); + protected isZkSyncChain: boolean; constructor( protected readonly multiProvider: MultiProvider, @@ -72,6 +74,12 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { protected readonly messageContext?: DispatchedMessage, ) { super(multiProvider, chain); + + // So we can distinguish between Storage/Static ISMs + const chainTechnicalStack = this.multiProvider.getChainMetadata( + this.chain, + ).technicalStack; + this.isZkSyncChain = chainTechnicalStack === ChainTechnicalStack.ZkSync; } async deriveIsmConfig(address: Address): Promise { @@ -208,9 +216,14 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { async (module) => this.deriveIsmConfig(module), ); + // If it's a zkSync chain, it must be a StorageAggregationIsm + const ismType = this.isZkSyncChain + ? IsmType.STORAGE_AGGREGATION + : IsmType.AGGREGATION; + return { address, - type: IsmType.AGGREGATION, + type: ismType, modules: ismConfigs, threshold, }; @@ -227,11 +240,19 @@ export class EvmIsmReader extends HyperlaneReader implements IsmReader { `expected module type to be ${ModuleType.MERKLE_ROOT_MULTISIG} or ${ModuleType.MESSAGE_ID_MULTISIG}, got ${moduleType}`, ); - const ismType = + let ismType = moduleType === ModuleType.MERKLE_ROOT_MULTISIG ? IsmType.MERKLE_ROOT_MULTISIG : IsmType.MESSAGE_ID_MULTISIG; + // If it's a zkSync chain, it must be a StorageMultisigIsm + if (this.isZkSyncChain) { + ismType = + moduleType === ModuleType.MERKLE_ROOT_MULTISIG + ? IsmType.STORAGE_MERKLE_ROOT_MULTISIG + : IsmType.STORAGE_MESSAGE_ID_MULTISIG; + } + const [validators, threshold] = await ism.validatorsAndThreshold( ethers.constants.AddressZero, ); From 576558778ad7261f26356da2faa054da95a5c156 Mon Sep 17 00:00:00 2001 From: xeno097 Date: Fri, 10 Jan 2025 16:35:56 -0400 Subject: [PATCH 5/5] feat(infra): added superseed USDT and OP config getters (#5130) ### Description Adds config getters for OP and USDT routes on supersede Related registry PRs: - https://github.com/hyperlane-xyz/hyperlane-registry/pull/473 - https://github.com/hyperlane-xyz/hyperlane-registry/pull/474 ### Drive-by changes - NO ### Related issues - ### Backward compatibility - YES ### Testing - CLI - UI --- .../configGetters/getSuperseedWarpConfigs.ts | 55 +++++++++++++++++++ .../environments/mainnet3/warp/warpIds.ts | 2 + typescript/infra/config/warp.ts | 6 ++ typescript/infra/src/config/warp.ts | 1 + 4 files changed, 64 insertions(+) create mode 100644 typescript/infra/config/environments/mainnet3/warp/configGetters/getSuperseedWarpConfigs.ts diff --git a/typescript/infra/config/environments/mainnet3/warp/configGetters/getSuperseedWarpConfigs.ts b/typescript/infra/config/environments/mainnet3/warp/configGetters/getSuperseedWarpConfigs.ts new file mode 100644 index 0000000000..e10d681579 --- /dev/null +++ b/typescript/infra/config/environments/mainnet3/warp/configGetters/getSuperseedWarpConfigs.ts @@ -0,0 +1,55 @@ +import { ethers } from 'ethers'; + +import { ChainMap, HypTokenRouterConfig, TokenType } from '@hyperlane-xyz/sdk'; +import { Address } from '@hyperlane-xyz/utils'; + +import { + RouterConfigWithoutOwner, + tokens, +} from '../../../../../src/config/warp.js'; + +const safeOwners: ChainMap
= { + ethereum: '0x11BEBBf509248735203BAAAe90c1a27EEE70D567', + superseed: '0x6652010BaCE855DF870D427daA6141c313994929', + optimism: '0x0D493D7E51212bbBF0F1ca4bcfA1E5514C7fEF10', +}; + +export const getEthereumSuperseedUSDTConfig = async ( + routerConfig: ChainMap, +): Promise> => { + return { + ethereum: { + ...routerConfig.ethereum, + owner: safeOwners.ethereum, + type: TokenType.collateral, + token: tokens.ethereum.USDT, + interchainSecurityModule: ethers.constants.AddressZero, + }, + superseed: { + ...routerConfig.superseed, + owner: safeOwners.superseed, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }, + }; +}; + +export const getOptimismSuperseedOPConfig = async ( + routerConfig: ChainMap, +): Promise> => { + return { + optimism: { + ...routerConfig.optimism, + owner: safeOwners.optimism, + type: TokenType.collateral, + token: tokens.optimism.OP, + interchainSecurityModule: ethers.constants.AddressZero, + }, + superseed: { + ...routerConfig.superseed, + owner: safeOwners.superseed, + type: TokenType.synthetic, + interchainSecurityModule: ethers.constants.AddressZero, + }, + }; +}; diff --git a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts index 32db67821f..780ebc079c 100644 --- a/typescript/infra/config/environments/mainnet3/warp/warpIds.ts +++ b/typescript/infra/config/environments/mainnet3/warp/warpIds.ts @@ -42,6 +42,8 @@ export enum WarpRouteIds { ArbitrumBaseBlastBscEthereumGnosisLiskMantleModeOptimismPolygonScrollZeroNetworkZoraMainnet = 'ETH/arbitrum-base-blast-bsc-ethereum-gnosis-lisk-mantle-mode-optimism-polygon-scroll-zeronetwork-zoramainnet', AppchainBaseUSDC = 'USDC/appchain-base', BobaBsquaredSwellUBTC = 'UBTC/boba-bsquared-swell', + EthereumSuperseedUSDT = 'USDT/ethereum-superseed', + OptimismSuperseedOP = 'OP/optimism-superseed', EthereumZircuitRstETH = 'rstETH/ethereum-zircuit', EthereumFormWBTC = 'WBTC/ethereum-form', EthereumFormWSTETH = 'WSTETH/ethereum-form', diff --git a/typescript/infra/config/warp.ts b/typescript/infra/config/warp.ts index 75da6ba959..5318a9ca2b 100644 --- a/typescript/infra/config/warp.ts +++ b/typescript/infra/config/warp.ts @@ -48,6 +48,10 @@ import { getInevmInjectiveINJWarpConfig } from './environments/mainnet3/warp/con import { getMantapacificNeutronTiaWarpConfig } from './environments/mainnet3/warp/configGetters/getMantapacificNeutronTiaWarpConfig.js'; import { getRenzoEZETHWarpConfig } from './environments/mainnet3/warp/configGetters/getRenzoEZETHWarpConfig.js'; import { getRenzoPZETHWarpConfig } from './environments/mainnet3/warp/configGetters/getRenzoPZETHWarpConfig.js'; +import { + getEthereumSuperseedUSDTConfig, + getOptimismSuperseedOPConfig, +} from './environments/mainnet3/warp/configGetters/getSuperseedWarpConfigs.js'; import { WarpRouteIds } from './environments/mainnet3/warp/warpIds.js'; type WarpConfigGetter = ( @@ -93,6 +97,8 @@ export const warpConfigGetterMap: Record = { [WarpRouteIds.AppchainBaseUSDC]: getAppChainBaseUSDCWarpConfig, [WarpRouteIds.BobaBsquaredSwellUBTC]: getBobaBsquaredSwellUBTCWarpConfig, [WarpRouteIds.EthereumZircuitRe7LRT]: getEthereumZircuitRe7LRTWarpConfig, + [WarpRouteIds.EthereumSuperseedUSDT]: getEthereumSuperseedUSDTConfig, + [WarpRouteIds.OptimismSuperseedOP]: getOptimismSuperseedOPConfig, [WarpRouteIds.EthereumZircuitRstETH]: getEthereumZircuitRstETHWarpConfig, [WarpRouteIds.EthereumFormWBTC]: getEthereumFormWBTCWarpConfig, [WarpRouteIds.EthereumFormWSTETH]: getEthereumFormWSTETHWarpConfig, diff --git a/typescript/infra/src/config/warp.ts b/typescript/infra/src/config/warp.ts index e3a04dda95..48e3425701 100644 --- a/typescript/infra/src/config/warp.ts +++ b/typescript/infra/src/config/warp.ts @@ -54,6 +54,7 @@ export const tokens: ChainMap> = { }, optimism: { USDC: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', + OP: '0x4200000000000000000000000000000000000042', }, gnosis: { WETH: '0x6A023CCd1ff6F2045C3309768eAd9E68F978f6e1',