From d69d76a73feabd61d653c99ae42075d733b74bee Mon Sep 17 00:00:00 2001 From: Kunal Arora <55632507+aroralanuk@users.noreply.github.com> Date: Thu, 5 Oct 2023 16:26:39 -0400 Subject: [PATCH 1/2] Aggregation hook deployer (#2769) Co-authored-by: Yorke Rhodes fixes https://github.com/hyperlane-xyz/issues/issues/624 --- solidity/contracts/Mailbox.sol | 4 + solidity/hardhat.config.ts | 2 +- typescript/helloworld/hardhat.config.ts | 2 +- .../helloworld/src/test/helloworld.test.ts | 4 +- .../config/environments/mainnet2/core.ts | 44 +++++++-- .../infra/config/environments/mainnet2/igp.ts | 22 ++--- .../infra/config/environments/test/core.ts | 37 +++++-- .../infra/config/environments/test/hooks.ts | 16 --- .../infra/config/environments/test/igp.ts | 19 ++-- .../infra/config/environments/test/index.ts | 2 - .../config/environments/testnet3/core.ts | 44 +++++++-- typescript/infra/scripts/deploy.ts | 19 +--- typescript/infra/scripts/helloworld/utils.ts | 2 +- typescript/infra/scripts/utils.ts | 6 +- typescript/infra/src/config/environment.ts | 2 - .../sdk/src/core/CoreDeployer.hardhat-test.ts | 10 +- .../sdk/src/core/HyperlaneCoreDeployer.ts | 46 ++++----- typescript/sdk/src/core/TestCoreDeployer.ts | 4 +- .../sdk/src/deploy/HyperlaneDeployer.ts | 20 ++-- .../deploy/HyperlaneProxyFactoryDeployer.ts | 40 ++++++++ typescript/sdk/src/deploy/contracts.ts | 29 ++++++ typescript/sdk/src/gas/HyperlaneIgpChecker.ts | 10 -- .../sdk/src/gas/HyperlaneIgpDeployer.ts | 25 ----- typescript/sdk/src/gas/contracts.ts | 5 +- typescript/sdk/src/gas/types.ts | 2 - .../sdk/src/hook/HyperlaneHookDeployer.ts | 97 +++++++++++++++++-- typescript/sdk/src/hook/contracts.ts | 9 +- typescript/sdk/src/hook/types.ts | 29 +++++- typescript/sdk/src/index.ts | 25 +++-- .../ism/HyperlaneIsmFactory.hardhat-test.ts | 6 +- typescript/sdk/src/ism/HyperlaneIsmFactory.ts | 34 ++++--- .../src/ism/HyperlaneIsmFactoryDeployer.ts | 80 --------------- typescript/sdk/src/ism/contracts.ts | 6 +- typescript/sdk/src/test/testUtils.ts | 10 +- 34 files changed, 427 insertions(+), 285 deletions(-) delete mode 100644 typescript/infra/config/environments/test/hooks.ts create mode 100644 typescript/sdk/src/deploy/HyperlaneProxyFactoryDeployer.ts create mode 100644 typescript/sdk/src/deploy/contracts.ts delete mode 100644 typescript/sdk/src/ism/HyperlaneIsmFactoryDeployer.ts diff --git a/solidity/contracts/Mailbox.sol b/solidity/contracts/Mailbox.sol index 59b0d63b18..a444d46c8d 100644 --- a/solidity/contracts/Mailbox.sol +++ b/solidity/contracts/Mailbox.sol @@ -297,6 +297,10 @@ contract Mailbox is IMailbox, Indexed, Versioned, OwnableUpgradeable { /// INTERACTIONS /// uint256 requiredValue = requiredHook.quoteDispatch(metadata, message); + // if underpaying, defer to required hook's reverting behavior + if (msg.value < requiredValue) { + requiredValue = msg.value; + } requiredHook.postDispatch{value: requiredValue}(metadata, message); hook.postDispatch{value: msg.value - requiredValue}(metadata, message); diff --git a/solidity/hardhat.config.ts b/solidity/hardhat.config.ts index f26c74ded9..d206cb8aed 100644 --- a/solidity/hardhat.config.ts +++ b/solidity/hardhat.config.ts @@ -27,7 +27,7 @@ module.exports = { typechain: { outDir: './types', target: 'ethers-v5', - alwaysGenerateOverloads: false, + alwaysGenerateOverloads: true, }, mocha: { bail: true, diff --git a/typescript/helloworld/hardhat.config.ts b/typescript/helloworld/hardhat.config.ts index 7c2e51c6fc..01d6077e4f 100644 --- a/typescript/helloworld/hardhat.config.ts +++ b/typescript/helloworld/hardhat.config.ts @@ -21,6 +21,6 @@ module.exports = { typechain: { outDir: './src/types', target: 'ethers-v5', - alwaysGenerateOverloads: false, // should overloads with full signatures like deposit(uint256) be generated always, even if there are no overloads? + alwaysGenerateOverloads: true, }, }; diff --git a/typescript/helloworld/src/test/helloworld.test.ts b/typescript/helloworld/src/test/helloworld.test.ts index 8e02d8a2e2..9ab3784de6 100644 --- a/typescript/helloworld/src/test/helloworld.test.ts +++ b/typescript/helloworld/src/test/helloworld.test.ts @@ -80,9 +80,9 @@ describe('HelloWorld', async () => { const body = 'Hello'; await expect( local.sendHelloWorld(remoteDomain, body, { - value: (await quoteGasPayment(body)).sub(1), + value: 0, }), - ).to.be.revertedWith('insufficient interchain gas payment'); + ).to.be.revertedWith('StaticProtocolFee: insufficient protocol fee'); }); it('handles a message', async () => { diff --git a/typescript/infra/config/environments/mainnet2/core.ts b/typescript/infra/config/environments/mainnet2/core.ts index a83839c4b6..ca40b0530f 100644 --- a/typescript/infra/config/environments/mainnet2/core.ts +++ b/typescript/infra/config/environments/mainnet2/core.ts @@ -1,9 +1,20 @@ -import { ChainMap, CoreConfig, HookType } from '@hyperlane-xyz/sdk'; +import { BigNumber, ethers } from 'ethers'; + +import { + AggregationHookConfig, + ChainMap, + CoreConfig, + HookType, + IgpHookConfig, + MerkleTreeHookConfig, + ProtocolFeeHookConfig, +} from '@hyperlane-xyz/sdk'; import { objMap } from '@hyperlane-xyz/utils'; import { aggregationIsm } from '../../aggregationIsm'; import { Contexts } from '../../contexts'; +import { igp } from './igp'; import { owners } from './owners'; export const core: ChainMap = objMap(owners, (local, owner) => { @@ -23,15 +34,32 @@ export const core: ChainMap = objMap(owners, (local, owner) => { }; } + const merkleHook: MerkleTreeHookConfig = { + type: HookType.MERKLE_TREE, + }; + + const igpHook: IgpHookConfig = { + type: HookType.INTERCHAIN_GAS_PAYMASTER, + ...igp[local], + }; + + const defaultHook: AggregationHookConfig = { + type: HookType.AGGREGATION, + hooks: [merkleHook, igpHook], + }; + + const requiredHook: ProtocolFeeHookConfig = { + type: HookType.PROTOCOL_FEE, + maxProtocolFee: ethers.utils.parseUnits('1', 'gwei'), // 1 gwei of native token + protocolFee: BigNumber.from(1), // 1 wei + beneficiary: owner, + owner, + }; + return { owner, - upgrade, defaultIsm, - defaultHook: { - type: HookType.INTERCHAIN_GAS_PAYMASTER, - }, - requiredHook: { - type: HookType.MERKLE_TREE, - }, + defaultHook, + requiredHook, }; }); diff --git a/typescript/infra/config/environments/mainnet2/igp.ts b/typescript/infra/config/environments/mainnet2/igp.ts index e2410fe5e5..59b1ab7e56 100644 --- a/typescript/infra/config/environments/mainnet2/igp.ts +++ b/typescript/infra/config/environments/mainnet2/igp.ts @@ -8,7 +8,6 @@ import { import { exclude, objMap } from '@hyperlane-xyz/utils'; import { MainnetChains, supportedChainNames } from './chains'; -import { core } from './core'; import { owners } from './owners'; // TODO: make this generic @@ -25,20 +24,21 @@ function getGasOracles(local: MainnetChains) { } export const igp: ChainMap = objMap(owners, (chain, owner) => { + const overhead = Object.fromEntries( + exclude(chain, supportedChainNames).map((remote) => [ + remote, + multisigIsmVerificationCost( + defaultMultisigIsmConfigs[remote].threshold, + defaultMultisigIsmConfigs[remote].validators.length, + ), + ]), + ); + return { owner, oracleKey: DEPLOYER_ADDRESS, beneficiary: KEY_FUNDER_ADDRESS, gasOracleType: getGasOracles(chain), - overhead: Object.fromEntries( - exclude(chain, supportedChainNames).map((remote) => [ - remote, - multisigIsmVerificationCost( - defaultMultisigIsmConfigs[remote].threshold, - defaultMultisigIsmConfigs[remote].validators.length, - ), - ]), - ), - upgrade: core[chain].upgrade, + overhead, }; }); diff --git a/typescript/infra/config/environments/test/core.ts b/typescript/infra/config/environments/test/core.ts index 1cfb5dc9d2..73370f214a 100644 --- a/typescript/infra/config/environments/test/core.ts +++ b/typescript/infra/config/environments/test/core.ts @@ -1,13 +1,20 @@ +import { BigNumber, ethers } from 'ethers'; + import { + AggregationHookConfig, ChainMap, CoreConfig, HookType, + IgpHookConfig, + MerkleTreeHookConfig, ModuleType, RoutingIsmConfig, } from '@hyperlane-xyz/sdk'; +import { ProtocolFeeHookConfig } from '@hyperlane-xyz/sdk/src/hook/types'; import { objMap } from '@hyperlane-xyz/utils'; import { aggregationIsm } from './aggregationIsm'; +import { igp } from './igp'; import { chainToValidator } from './multisigIsm'; import { owners } from './owners'; @@ -22,14 +29,32 @@ export const core: ChainMap = objMap(owners, (local, owner) => { ), }; + const merkleHook: MerkleTreeHookConfig = { + type: HookType.MERKLE_TREE, + }; + + const igpHook: IgpHookConfig = { + type: HookType.INTERCHAIN_GAS_PAYMASTER, + ...igp[local], + }; + + const defaultHook: AggregationHookConfig = { + type: HookType.AGGREGATION, + hooks: [merkleHook, igpHook], + }; + + const requiredHook: ProtocolFeeHookConfig = { + type: HookType.PROTOCOL_FEE, + maxProtocolFee: ethers.utils.parseUnits('1', 'gwei'), // 1 gwei of native token + protocolFee: BigNumber.from(1), // 1 wei + beneficiary: owner, + owner, + }; + return { owner, defaultIsm, - defaultHook: { - type: HookType.INTERCHAIN_GAS_PAYMASTER, - }, - requiredHook: { - type: HookType.MERKLE_TREE, - }, + defaultHook, + requiredHook, }; }); diff --git a/typescript/infra/config/environments/test/hooks.ts b/typescript/infra/config/environments/test/hooks.ts deleted file mode 100644 index 5fd8296b4a..0000000000 --- a/typescript/infra/config/environments/test/hooks.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { ChainMap } from '@hyperlane-xyz/sdk'; -import { MerkleTreeHookConfig } from '@hyperlane-xyz/sdk/dist/hook/types'; -import { HookType } from '@hyperlane-xyz/sdk/src/hook/types'; -import { objMap } from '@hyperlane-xyz/utils'; - -import { owners } from './owners'; - -export const merkleTree: ChainMap = objMap( - owners, - (_, __) => { - const config: MerkleTreeHookConfig = { - type: HookType.MERKLE_TREE, - }; - return config; - }, -); diff --git a/typescript/infra/config/environments/test/igp.ts b/typescript/infra/config/environments/test/igp.ts index 833c86c24a..6590c933ab 100644 --- a/typescript/infra/config/environments/test/igp.ts +++ b/typescript/infra/config/environments/test/igp.ts @@ -20,19 +20,20 @@ function getGasOracles(local: TestChains) { } export const igp: ChainMap = objMap(owners, (chain, owner) => { + const overhead = Object.fromEntries( + exclude(chain, chainNames).map((remote) => [ + remote, + multisigIsmVerificationCost( + multisigIsm[remote].threshold, + multisigIsm[remote].validators.length, + ), + ]), + ); return { owner, oracleKey: owner, beneficiary: owner, gasOracleType: getGasOracles(chain), - overhead: Object.fromEntries( - exclude(chain, chainNames).map((remote) => [ - remote, - multisigIsmVerificationCost( - multisigIsm[remote].threshold, - multisigIsm[remote].validators.length, - ), - ]), - ), + overhead, }; }); diff --git a/typescript/infra/config/environments/test/index.ts b/typescript/infra/config/environments/test/index.ts index 6004ff82cd..a458f47a08 100644 --- a/typescript/infra/config/environments/test/index.ts +++ b/typescript/infra/config/environments/test/index.ts @@ -8,7 +8,6 @@ import { agents } from './agent'; import { testConfigs } from './chains'; import { core } from './core'; import { storageGasOracleConfig } from './gas-oracle'; -import { merkleTree } from './hooks'; import { igp } from './igp'; import { infra } from './infra'; import { owners } from './owners'; @@ -18,7 +17,6 @@ export const environment: EnvironmentConfig = { chainMetadataConfigs: testConfigs, agents, core, - hook: merkleTree, igp, owners, infra, diff --git a/typescript/infra/config/environments/testnet3/core.ts b/typescript/infra/config/environments/testnet3/core.ts index 82de2834a9..536fa771ff 100644 --- a/typescript/infra/config/environments/testnet3/core.ts +++ b/typescript/infra/config/environments/testnet3/core.ts @@ -1,21 +1,51 @@ -import { ChainMap, CoreConfig, HookType } from '@hyperlane-xyz/sdk'; +import { BigNumber, ethers } from 'ethers'; + +import { + AggregationHookConfig, + ChainMap, + CoreConfig, + HookType, + IgpHookConfig, + MerkleTreeHookConfig, + ProtocolFeeHookConfig, +} from '@hyperlane-xyz/sdk'; import { objMap } from '@hyperlane-xyz/utils'; import { aggregationIsm } from '../../aggregationIsm'; import { Contexts } from '../../contexts'; +import { igp } from './igp'; import { owners } from './owners'; export const core: ChainMap = objMap(owners, (local, owner) => { const defaultIsm = aggregationIsm('testnet3', local, Contexts.Hyperlane); + + const merkleHook: MerkleTreeHookConfig = { + type: HookType.MERKLE_TREE, + }; + + const igpHook: IgpHookConfig = { + type: HookType.INTERCHAIN_GAS_PAYMASTER, + ...igp[local], + }; + + const defaultHook: AggregationHookConfig = { + type: HookType.AGGREGATION, + hooks: [merkleHook, igpHook], + }; + + const requiredHook: ProtocolFeeHookConfig = { + type: HookType.PROTOCOL_FEE, + maxProtocolFee: ethers.utils.parseUnits('1', 'gwei'), // 1 gwei of native token + protocolFee: BigNumber.from(1), // 1 wei + beneficiary: owner, + owner, + }; + return { owner, defaultIsm, - defaultHook: { - type: HookType.INTERCHAIN_GAS_PAYMASTER, - }, - requiredHook: { - type: HookType.MERKLE_TREE, - }, + defaultHook, + requiredHook, }; }); diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index 8d0a800082..bd52c0625a 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -5,10 +5,9 @@ import { ChainMap, HyperlaneCoreDeployer, HyperlaneDeployer, - HyperlaneHookDeployer, HyperlaneIgpDeployer, HyperlaneIsmFactory, - HyperlaneIsmFactoryDeployer, + HyperlaneProxyFactoryDeployer, InterchainAccountDeployer, InterchainQueryDeployer, LiquidityLayerDeployer, @@ -61,24 +60,16 @@ async function main() { let config: ChainMap = {}; let deployer: HyperlaneDeployer; - if (module === Modules.ISM_FACTORY) { + if (module === Modules.PROXY_FACTORY) { config = objMap(envConfig.core, (_chain) => true); - deployer = new HyperlaneIsmFactoryDeployer(multiProvider); + deployer = new HyperlaneProxyFactoryDeployer(multiProvider); } else if (module === Modules.CORE) { config = envConfig.core; const ismFactory = HyperlaneIsmFactory.fromAddressesMap( - getAddresses(environment, Modules.ISM_FACTORY), + getAddresses(environment, Modules.PROXY_FACTORY), multiProvider, ); deployer = new HyperlaneCoreDeployer(multiProvider, ismFactory); - } else if (module === Modules.HOOK) { - if (!envConfig.hook) { - throw new Error(`No hook config for ${environment}`); - } - config = envConfig.hook; - const core = getAddresses(environment, Modules.CORE); - const mailboxes = objMap(core, (_, contracts) => contracts.mailbox); - deployer = new HyperlaneHookDeployer(multiProvider, mailboxes); } else if (module === Modules.INTERCHAIN_GAS_PAYMASTER) { config = envConfig.igp; deployer = new HyperlaneIgpDeployer(multiProvider); @@ -123,7 +114,7 @@ async function main() { true, // use deployer as owner ); const ismFactory = HyperlaneIsmFactory.fromAddressesMap( - getAddresses(environment, Modules.ISM_FACTORY), + getAddresses(environment, Modules.PROXY_FACTORY), multiProvider, ); deployer = new HelloWorldDeployer(multiProvider, ismFactory); diff --git a/typescript/infra/scripts/helloworld/utils.ts b/typescript/infra/scripts/helloworld/utils.ts index e0a45ae0ba..d71480cd19 100644 --- a/typescript/infra/scripts/helloworld/utils.ts +++ b/typescript/infra/scripts/helloworld/utils.ts @@ -14,9 +14,9 @@ import { chainMetadata, filterAddressesToProtocol, hyperlaneEnvironments, + hyperlaneEnvironmentsWithSealevel, igpFactories, } from '@hyperlane-xyz/sdk'; -import { hyperlaneEnvironmentsWithSealevel } from '@hyperlane-xyz/sdk/src'; import { ProtocolType, objMerge } from '@hyperlane-xyz/utils'; import { Contexts } from '../../config/contexts'; diff --git a/typescript/infra/scripts/utils.ts b/typescript/infra/scripts/utils.ts index c9abd0c6f6..d6975fbb6f 100644 --- a/typescript/infra/scripts/utils.ts +++ b/typescript/infra/scripts/utils.ts @@ -42,7 +42,8 @@ import { Role } from '../src/roles'; import { assertContext, assertRole, readJSON } from '../src/utils/utils'; export enum Modules { - ISM_FACTORY = 'ism', + // TODO: change + PROXY_FACTORY = 'ism', CORE = 'core', HOOK = 'hook', INTERCHAIN_GAS_PAYMASTER = 'igp', @@ -55,7 +56,7 @@ export enum Modules { } export const SDK_MODULES = [ - Modules.ISM_FACTORY, + Modules.PROXY_FACTORY, Modules.CORE, Modules.INTERCHAIN_GAS_PAYMASTER, Modules.INTERCHAIN_ACCOUNTS, @@ -323,6 +324,7 @@ export async function getRouterConfig( deployEnvToSdkEnv[environment], multiProvider, ); + // TODO: replace this with core.getRouterConfig const igp = HyperlaneIgp.fromEnvironment( deployEnvToSdkEnv[environment], multiProvider, diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index e02723dc6a..e702dabb56 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -4,7 +4,6 @@ import { ChainMetadata, ChainName, CoreConfig, - HookConfig, HyperlaneEnvironment, IgpConfig, MultiProvider, @@ -38,7 +37,6 @@ export type EnvironmentConfig = { // Each AgentConfig, keyed by the context agents: Partial>; core: ChainMap; - hook?: ChainMap; igp: ChainMap; owners: ChainMap
; infra: InfrastructureConfig; diff --git a/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts b/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts index 92934a52ce..8503847ea6 100644 --- a/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts +++ b/typescript/sdk/src/core/CoreDeployer.hardhat-test.ts @@ -5,8 +5,8 @@ import sinon from 'sinon'; import { TestChains } from '../consts/chains'; import { HyperlaneContractsMap } from '../contracts/types'; +import { HyperlaneProxyFactoryDeployer } from '../deploy/HyperlaneProxyFactoryDeployer'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; -import { HyperlaneIsmFactoryDeployer } from '../ism/HyperlaneIsmFactoryDeployer'; import { MultiProvider } from '../providers/MultiProvider'; import { testCoreConfig } from '../test/testUtils'; import { ChainMap } from '../types'; @@ -27,8 +27,11 @@ describe('core', async () => { before(async () => { const [signer] = await ethers.getSigners(); multiProvider = MultiProvider.createTestMultiProvider({ signer }); - const ismFactoryDeployer = new HyperlaneIsmFactoryDeployer(multiProvider); - const ismFactories = await ismFactoryDeployer.deploy(TestChains); + const proxyFactoryDeployer = new HyperlaneProxyFactoryDeployer( + multiProvider, + ); + coreConfig = testCoreConfig(TestChains); + const ismFactories = await proxyFactoryDeployer.deploy(coreConfig); ismFactory = new HyperlaneIsmFactory(ismFactories, multiProvider); }); @@ -36,7 +39,6 @@ describe('core', async () => { const [signer] = await ethers.getSigners(); // This is kind of awkward and really these tests shouldn't live here multiProvider = MultiProvider.createTestMultiProvider({ signer }); - coreConfig = testCoreConfig(TestChains); }); it('deploys', async () => { diff --git a/typescript/sdk/src/core/HyperlaneCoreDeployer.ts b/typescript/sdk/src/core/HyperlaneCoreDeployer.ts index 52c99178c7..8913c162fc 100644 --- a/typescript/sdk/src/core/HyperlaneCoreDeployer.ts +++ b/typescript/sdk/src/core/HyperlaneCoreDeployer.ts @@ -1,19 +1,18 @@ import debug from 'debug'; import { Mailbox, ValidatorAnnounce } from '@hyperlane-xyz/core'; -import { Address, objMap } from '@hyperlane-xyz/utils'; +import { Address } from '@hyperlane-xyz/utils'; -import { HyperlaneContracts, HyperlaneContractsMap } from '../contracts/types'; +import { HyperlaneContracts } from '../contracts/types'; import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; import { HyperlaneHookDeployer } from '../hook/HyperlaneHookDeployer'; -import { HookFactories } from '../hook/contracts'; import { HookConfig } from '../hook/types'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; import { IsmConfig } from '../ism/types'; import { MultiProvider } from '../providers/MultiProvider'; import { ChainMap, ChainName } from '../types'; -import { CoreFactories, coreFactories } from './contracts'; +import { CoreAddresses, CoreFactories, coreFactories } from './contracts'; import { CoreConfig } from './types'; export class HyperlaneCoreDeployer extends HyperlaneDeployer< @@ -21,23 +20,27 @@ export class HyperlaneCoreDeployer extends HyperlaneDeployer< CoreFactories > { startingBlockNumbers: ChainMap = {}; - deployedHooks: HyperlaneContractsMap = {}; + hookDeployer: HyperlaneHookDeployer; constructor( multiProvider: MultiProvider, readonly ismFactory: HyperlaneIsmFactory, - readonly hookDeployer = new HyperlaneHookDeployer(multiProvider, {}), ) { super(multiProvider, coreFactories, { logger: debug('hyperlane:CoreDeployer'), chainTimeoutMs: 1000 * 60 * 10, // 10 minutes }); + this.hookDeployer = new HyperlaneHookDeployer( + multiProvider, + {}, + ismFactory, + ); } async deployMailbox( chain: ChainName, - proxyAdmin: Address, config: CoreConfig, + proxyAdmin: Address, ): Promise { const cachedMailbox = this.readCache( chain, @@ -60,15 +63,17 @@ export class HyperlaneCoreDeployer extends HyperlaneDeployer< ); const defaultIsm = await this.deployIsm(chain, config.defaultIsm); + + const hookAddresses = { mailbox: mailbox.address, proxyAdmin }; const defaultHook = await this.deployHook( chain, config.defaultHook, - mailbox.address, + hookAddresses, ); const requiredHook = await this.deployHook( chain, config.requiredHook, - mailbox.address, + hookAddresses, ); // configure mailbox @@ -95,17 +100,14 @@ export class HyperlaneCoreDeployer extends HyperlaneDeployer< async deployHook( chain: ChainName, config: HookConfig, - mailbox: Address, + coreAddresses: Partial, ): Promise
{ const hooks = await this.hookDeployer.deployContracts( chain, config, - mailbox, + coreAddresses, ); - this.deployedHooks[chain] = { - ...hooks, - ...this.deployedHooks[chain], - }; + this.addDeployedContracts(chain, hooks); return hooks[config.type].address; } @@ -125,8 +127,9 @@ export class HyperlaneCoreDeployer extends HyperlaneDeployer< const proxyAdmin = await this.deployContract(chain, 'proxyAdmin', []); - const mailbox = await this.deployMailbox(chain, proxyAdmin.address, config); + const mailbox = await this.deployMailbox(chain, config, proxyAdmin.address); + // TODO: remove once agents fetch deployedBlock from mailbox const deployedBlock = await mailbox.deployedBlock(); this.startingBlockNumbers[chain] = deployedBlock.toNumber(); @@ -154,15 +157,4 @@ export class HyperlaneCoreDeployer extends HyperlaneDeployer< validatorAnnounce, }; } - - async deploy( - configMap: ChainMap, - ): Promise> { - const contractsMap = await super.deploy(configMap); - this.deployedContracts = objMap(contractsMap, (chain, core) => ({ - ...core, - ...this.deployedHooks[chain], - })); - return contractsMap; - } } diff --git a/typescript/sdk/src/core/TestCoreDeployer.ts b/typescript/sdk/src/core/TestCoreDeployer.ts index 6e73a492fb..33b91c09c2 100644 --- a/typescript/sdk/src/core/TestCoreDeployer.ts +++ b/typescript/sdk/src/core/TestCoreDeployer.ts @@ -6,7 +6,6 @@ import { import { TestChains } from '../consts/chains'; import { HyperlaneContracts } from '../contracts/types'; -import { HyperlaneHookDeployer } from '../hook/HyperlaneHookDeployer'; import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; import { MultiProvider } from '../providers/MultiProvider'; import { testCoreConfig } from '../test/testUtils'; @@ -26,8 +25,7 @@ const testCoreFactories = { export class TestCoreDeployer extends HyperlaneCoreDeployer { constructor(public readonly multiProvider: MultiProvider) { const ismFactory = new HyperlaneIsmFactory({}, multiProvider); - const hookDeployer = new HyperlaneHookDeployer(multiProvider, {}); - super(multiProvider, ismFactory, hookDeployer); + super(multiProvider, ismFactory); } // deploy a test ISM instead of a real ISM diff --git a/typescript/sdk/src/deploy/HyperlaneDeployer.ts b/typescript/sdk/src/deploy/HyperlaneDeployer.ts index 86aa9177d5..1ea9c61973 100644 --- a/typescript/sdk/src/deploy/HyperlaneDeployer.ts +++ b/typescript/sdk/src/deploy/HyperlaneDeployer.ts @@ -94,15 +94,23 @@ export abstract class HyperlaneDeployer< .getProvider(chain) .getBlockNumber(); await runWithTimeout(this.chainTimeoutMs, async () => { - this.deployedContracts[chain] = await this.deployContracts( - chain, - configMap[chain], - ); + const contracts = await this.deployContracts(chain, configMap[chain]); + this.addDeployedContracts(chain, contracts); }); } return this.deployedContracts; } + protected addDeployedContracts( + chain: ChainName, + contracts: HyperlaneContracts, + ) { + this.deployedContracts[chain] = { + ...this.deployedContracts[chain], + ...contracts, + }; + } + protected async runIf( chain: ChainName, address: string, @@ -398,7 +406,7 @@ export abstract class HyperlaneDeployer< ); } - protected writeCache( + writeCache( chain: ChainName, contractName: K, address: Address, @@ -409,7 +417,7 @@ export abstract class HyperlaneDeployer< this.cachedAddresses[chain][contractName] = address; } - protected readCache( + readCache( chain: ChainName, factory: F, contractName: string, diff --git a/typescript/sdk/src/deploy/HyperlaneProxyFactoryDeployer.ts b/typescript/sdk/src/deploy/HyperlaneProxyFactoryDeployer.ts new file mode 100644 index 0000000000..f4afd51107 --- /dev/null +++ b/typescript/sdk/src/deploy/HyperlaneProxyFactoryDeployer.ts @@ -0,0 +1,40 @@ +import debug from 'debug'; + +import { HyperlaneContracts } from '../contracts/types'; +import { MultiProvider } from '../providers/MultiProvider'; +import { ChainName } from '../types'; + +import { HyperlaneDeployer } from './HyperlaneDeployer'; +import { + ProxyFactoryFactories, + proxyFactoryFactories, + proxyFactoryImplementations, +} from './contracts'; + +export class HyperlaneProxyFactoryDeployer extends HyperlaneDeployer< + any, + ProxyFactoryFactories +> { + constructor(multiProvider: MultiProvider) { + super(multiProvider, proxyFactoryFactories, { + logger: debug('hyperlane:IsmFactoryDeployer'), + }); + } + + async deployContracts( + chain: ChainName, + ): Promise> { + const contracts: any = {}; + for (const factoryName of Object.keys( + this.factories, + ) as (keyof ProxyFactoryFactories)[]) { + const factory = await this.deployContract(chain, factoryName, []); + this.verificationInputs[chain].push({ + name: proxyFactoryImplementations[factoryName], + address: await factory.implementation(), + }); + contracts[factoryName] = factory; + } + return contracts as HyperlaneContracts; + } +} diff --git a/typescript/sdk/src/deploy/contracts.ts b/typescript/sdk/src/deploy/contracts.ts new file mode 100644 index 0000000000..542c245c13 --- /dev/null +++ b/typescript/sdk/src/deploy/contracts.ts @@ -0,0 +1,29 @@ +import { + DomainRoutingIsmFactory__factory, + StaticAggregationHookFactory__factory, + StaticAggregationIsmFactory__factory, + StaticMerkleRootMultisigIsmFactory__factory, + StaticMessageIdMultisigIsmFactory__factory, +} from '@hyperlane-xyz/core'; + +export const proxyFactoryFactories = { + merkleRootMultisigIsmFactory: + new StaticMerkleRootMultisigIsmFactory__factory(), + messageIdMultisigIsmFactory: new StaticMessageIdMultisigIsmFactory__factory(), + aggregationIsmFactory: new StaticAggregationIsmFactory__factory(), + aggregationHookFactory: new StaticAggregationHookFactory__factory(), + routingIsmFactory: new DomainRoutingIsmFactory__factory(), +}; + +export type ProxyFactoryFactories = typeof proxyFactoryFactories; + +type ProxyFactoryImplementations = Record; + +// must match contract names for verification +export const proxyFactoryImplementations: ProxyFactoryImplementations = { + merkleRootMultisigIsmFactory: 'StaticMerkleRootMultisigIsm', + messageIdMultisigIsmFactory: 'StaticMessageIdMultisigIsm', + aggregationIsmFactory: 'StaticAggregationIsm', + aggregationHookFactory: 'StaticAggregationHook', + routingIsmFactory: 'DomaingRoutingIsm', +}; diff --git a/typescript/sdk/src/gas/HyperlaneIgpChecker.ts b/typescript/sdk/src/gas/HyperlaneIgpChecker.ts index 6278ee2f6e..2e7f5e1e2d 100644 --- a/typescript/sdk/src/gas/HyperlaneIgpChecker.ts +++ b/typescript/sdk/src/gas/HyperlaneIgpChecker.ts @@ -27,11 +27,6 @@ export class HyperlaneIgpChecker extends HyperlaneAppChecker< await this.checkBytecodes(chain); await this.checkOverheadInterchainGasPaymaster(chain); await this.checkInterchainGasPaymaster(chain); - - const config = this.configMap[chain]; - if (config.upgrade) { - await this.checkUpgrade(chain, config.upgrade); - } } async checkDomainOwnership(chain: ChainName): Promise { @@ -40,11 +35,6 @@ export class HyperlaneIgpChecker extends HyperlaneAppChecker< const ownableOverrides: Record = { storageGasOracle: config.oracleKey, }; - if (config.upgrade) { - const timelockController = - this.app.getAddresses(chain).timelockController; - ownableOverrides['proxyAdmin'] = timelockController; - } await super.checkOwnership(chain, config.owner, ownableOverrides); } diff --git a/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts b/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts index 6fa1947edc..c8b6d85fd3 100644 --- a/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts +++ b/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts @@ -1,12 +1,9 @@ import debug from 'debug'; -import { ethers } from 'ethers'; import { InterchainGasPaymaster, ProxyAdmin, StorageGasOracle, - TimelockController, - TimelockController__factory, } from '@hyperlane-xyz/core'; import { eqAddress } from '@hyperlane-xyz/utils'; @@ -87,27 +84,6 @@ export class HyperlaneIgpDeployer extends HyperlaneDeployer< // NB: To share ProxyAdmins with HyperlaneCore, ensure the ProxyAdmin // is loaded into the contract cache. const proxyAdmin = await this.deployContract(chain, 'proxyAdmin', []); - let timelockController: TimelockController; - if (config.upgrade) { - timelockController = await this.deployTimelock( - chain, - config.upgrade.timelock, - ); - await this.transferOwnershipOfContracts( - chain, - timelockController.address, - { proxyAdmin }, - ); - } else { - // mock this for consistent serialization - timelockController = TimelockController__factory.connect( - ethers.constants.AddressZero, - this.multiProvider.getProvider(chain), - ); - await this.transferOwnershipOfContracts(chain, config.owner, { - proxyAdmin, - }); - } const storageGasOracle = await this.deployStorageGasOracle(chain); const interchainGasPaymaster = await this.deployInterchainGasPaymaster( @@ -128,7 +104,6 @@ export class HyperlaneIgpDeployer extends HyperlaneDeployer< return { proxyAdmin, - timelockController, storageGasOracle, interchainGasPaymaster, }; diff --git a/typescript/sdk/src/gas/contracts.ts b/typescript/sdk/src/gas/contracts.ts index e33bfb5ede..0dfe6d8f6e 100644 --- a/typescript/sdk/src/gas/contracts.ts +++ b/typescript/sdk/src/gas/contracts.ts @@ -1,14 +1,13 @@ import { InterchainGasPaymaster__factory, + ProxyAdmin__factory, StorageGasOracle__factory, } from '@hyperlane-xyz/core'; -import { proxiedFactories } from '../router/types'; - export const igpFactories = { interchainGasPaymaster: new InterchainGasPaymaster__factory(), storageGasOracle: new StorageGasOracle__factory(), - ...proxiedFactories, + proxyAdmin: new ProxyAdmin__factory(), }; export type IgpFactories = typeof igpFactories; diff --git a/typescript/sdk/src/gas/types.ts b/typescript/sdk/src/gas/types.ts index 65a64a0896..ca0c0485ab 100644 --- a/typescript/sdk/src/gas/types.ts +++ b/typescript/sdk/src/gas/types.ts @@ -3,7 +3,6 @@ import { BigNumber } from 'ethers'; import { InterchainGasPaymaster } from '@hyperlane-xyz/core'; import type { Address } from '@hyperlane-xyz/utils'; -import { UpgradeConfig } from '../deploy/proxy'; import type { CheckerViolation } from '../deploy/types'; import { ChainMap } from '../types'; @@ -16,7 +15,6 @@ export type IgpConfig = { beneficiary: Address; gasOracleType: ChainMap; oracleKey: Address; - upgrade?: UpgradeConfig; overhead: ChainMap; }; diff --git a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts index 614c4dac44..72ff2195eb 100644 --- a/typescript/sdk/src/hook/HyperlaneHookDeployer.ts +++ b/typescript/sdk/src/hook/HyperlaneHookDeployer.ts @@ -1,14 +1,27 @@ import debug from 'debug'; -import { Address } from '@hyperlane-xyz/utils'; +import { + StaticAggregationHook__factory, + StaticProtocolFee, +} from '@hyperlane-xyz/core'; import { HyperlaneContracts } from '../contracts/types'; +import { CoreAddresses } from '../core/contracts'; import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; +import { HyperlaneIgpDeployer } from '../gas/HyperlaneIgpDeployer'; +import { IgpFactories } from '../gas/contracts'; +import { HyperlaneIsmFactory } from '../ism/HyperlaneIsmFactory'; import { MultiProvider } from '../providers/MultiProvider'; import { ChainMap, ChainName } from '../types'; import { HookFactories, hookFactories } from './contracts'; -import { HookConfig, HookType } from './types'; +import { + AggregationHookConfig, + HookConfig, + HookType, + IgpHookConfig, + ProtocolFeeHookConfig, +} from './types'; export class HyperlaneHookDeployer extends HyperlaneDeployer< HookConfig, @@ -16,26 +29,94 @@ export class HyperlaneHookDeployer extends HyperlaneDeployer< > { constructor( multiProvider: MultiProvider, - readonly mailboxes: ChainMap
, + readonly core: ChainMap>, + readonly ismFactory: HyperlaneIsmFactory, + readonly igpDeployer = new HyperlaneIgpDeployer(multiProvider), ) { super(multiProvider, hookFactories, { - logger: debug('hyperlane:HyperlaneHookDeployer'), + logger: debug('hyperlane:HookDeployer'), }); } async deployContracts( chain: ChainName, config: HookConfig, - mailbox = this.mailboxes[chain], + coreAddresses = this.core[chain], ): Promise> { + // other simple hooks can go here if (config.type === HookType.MERKLE_TREE) { + const mailbox = coreAddresses.mailbox; + if (!mailbox) { + throw new Error(`Mailbox address is required for ${config.type}`); + } const hook = await this.deployContract(chain, config.type, [mailbox]); return { [config.type]: hook } as any; } else if (config.type === HookType.INTERCHAIN_GAS_PAYMASTER) { - const hook = await this.deployContract(chain, config.type, []); + return this.deployIgp(chain, config, coreAddresses) as any; + } else if (config.type === HookType.AGGREGATION) { + return this.deployAggregation(chain, config, coreAddresses); + } else if (config.type === HookType.PROTOCOL_FEE) { + const hook = await this.deployProtocolFee(chain, config); return { [config.type]: hook } as any; - } else { - throw new Error(`Unexpected hook type: ${JSON.stringify(config)}`); } + + throw new Error(`Unexpected hook type: ${JSON.stringify(config)}`); + } + + async deployProtocolFee( + chain: ChainName, + config: ProtocolFeeHookConfig, + ): Promise { + return this.deployContract(chain, HookType.PROTOCOL_FEE, [ + config.maxProtocolFee, + config.protocolFee, + config.beneficiary, + config.owner, + ]); + } + + async deployIgp( + chain: ChainName, + config: IgpHookConfig, + coreAddresses = this.core[chain], + ): Promise> { + if (coreAddresses.proxyAdmin) { + this.igpDeployer.writeCache( + chain, + 'proxyAdmin', + coreAddresses.proxyAdmin, + ); + } + const igpContracts = await this.igpDeployer.deployContracts(chain, config); + this.addDeployedContracts(chain, igpContracts); + return igpContracts; + } + + async deployAggregation( + chain: ChainName, + config: AggregationHookConfig, + coreAddresses = this.core[chain], + ): Promise> { + const aggregatedHooks: string[] = []; + let hooks: any = {}; + for (const hookConfig of config.hooks) { + const subhooks = await this.deployContracts( + chain, + hookConfig, + coreAddresses, + ); + aggregatedHooks.push(subhooks[hookConfig.type].address); + hooks = { ...hooks, ...subhooks }; + } + const address = await this.ismFactory.deployStaticAddressSet( + chain, + this.ismFactory.getContracts(chain).aggregationHookFactory, + aggregatedHooks, + ); + hooks[HookType.AGGREGATION] = StaticAggregationHook__factory.connect( + address, + this.multiProvider.getSignerOrProvider(chain), + ); + return hooks; } } diff --git a/typescript/sdk/src/hook/contracts.ts b/typescript/sdk/src/hook/contracts.ts index c5b3a32997..9e5782d6ec 100644 --- a/typescript/sdk/src/hook/contracts.ts +++ b/typescript/sdk/src/hook/contracts.ts @@ -1,14 +1,17 @@ import { + InterchainGasPaymaster__factory, MerkleTreeHook__factory, - TestInterchainGasPaymaster__factory, + StaticAggregationHook__factory, + StaticProtocolFee__factory, } from '@hyperlane-xyz/core'; import { HookType } from './types'; export const hookFactories = { [HookType.MERKLE_TREE]: new MerkleTreeHook__factory(), - [HookType.INTERCHAIN_GAS_PAYMASTER]: - new TestInterchainGasPaymaster__factory(), + [HookType.PROTOCOL_FEE]: new StaticProtocolFee__factory(), + [HookType.INTERCHAIN_GAS_PAYMASTER]: new InterchainGasPaymaster__factory(), // unused + [HookType.AGGREGATION]: new StaticAggregationHook__factory(), // unused }; export type HookFactories = typeof hookFactories; diff --git a/typescript/sdk/src/hook/types.ts b/typescript/sdk/src/hook/types.ts index 40d9c326b9..72d7a435c5 100644 --- a/typescript/sdk/src/hook/types.ts +++ b/typescript/sdk/src/hook/types.ts @@ -1,14 +1,39 @@ +import { BigNumber } from 'ethers'; + +import { Address } from '@hyperlane-xyz/utils'; + +import { IgpConfig } from '../gas/types'; + export enum HookType { MERKLE_TREE = 'merkleTreeHook', INTERCHAIN_GAS_PAYMASTER = 'interchainGasPaymaster', + AGGREGATION = 'aggregationHook', + PROTOCOL_FEE = 'protocolFee', } export type MerkleTreeHookConfig = { type: HookType.MERKLE_TREE; }; -export type IgpHookConfig = { +export type AggregationHookConfig = { + type: HookType.AGGREGATION; + hooks: Array; +}; + +export type IgpHookConfig = IgpConfig & { type: HookType.INTERCHAIN_GAS_PAYMASTER; }; -export type HookConfig = MerkleTreeHookConfig | IgpHookConfig; +export type ProtocolFeeHookConfig = { + type: HookType.PROTOCOL_FEE; + maxProtocolFee: BigNumber; + protocolFee: BigNumber; + beneficiary: Address; + owner: Address; +}; + +export type HookConfig = + | MerkleTreeHookConfig + | AggregationHookConfig + | IgpHookConfig + | ProtocolFeeHookConfig; diff --git a/typescript/sdk/src/index.ts b/typescript/sdk/src/index.ts index 7b7cbc77a9..5202e0371e 100644 --- a/typescript/sdk/src/index.ts +++ b/typescript/sdk/src/index.ts @@ -73,6 +73,7 @@ export { } from './core/types'; export { HyperlaneAppChecker } from './deploy/HyperlaneAppChecker'; export { DeployerOptions, HyperlaneDeployer } from './deploy/HyperlaneDeployer'; +export { HyperlaneProxyFactoryDeployer } from './deploy/HyperlaneProxyFactoryDeployer'; export { CheckerViolation, OwnerViolation, @@ -108,12 +109,18 @@ export { IgpViolationType, } from './gas/types'; export { HyperlaneHookDeployer } from './hook/HyperlaneHookDeployer'; -export { HookConfig, HookType, MerkleTreeHookConfig } from './hook/types'; +export { + AggregationHookConfig, + HookConfig, + HookType, + IgpHookConfig, + MerkleTreeHookConfig, + ProtocolFeeHookConfig, +} from './hook/types'; export { HyperlaneIsmFactory, collectValidators, } from './ism/HyperlaneIsmFactory'; -export { HyperlaneIsmFactoryDeployer } from './ism/HyperlaneIsmFactoryDeployer'; export { AggregationIsmConfig, DeployedIsm, @@ -135,19 +142,18 @@ export { AgentLogFormat, AgentLogLevel, AgentSigner, - AgentSignerKeyType, - AgentSignerHexKey, AgentSignerAwsKey, + AgentSignerHexKey, + AgentSignerKeyType, AgentSignerNode, - buildAgentConfig, - RpcConsensusType, - ValidatorConfig, GasPaymentEnforcement, - RelayerConfig, GasPaymentEnforcementPolicyType, + RelayerConfig, + RpcConsensusType, ScraperConfig, + ValidatorConfig, + buildAgentConfig, } from './metadata/agentConfig'; -export { MatchingList } from './metadata/matchingList'; export { ChainMetadata, ChainMetadataSchema, @@ -162,6 +168,7 @@ export { HyperlaneDeploymentArtifacts, HyperlaneDeploymentArtifactsSchema, } from './metadata/deploymentArtifacts'; +export { MatchingList } from './metadata/matchingList'; export { InterchainAccount } from './middleware/account/InterchainAccount'; export { InterchainAccountChecker } from './middleware/account/InterchainAccountChecker'; export { diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts index 5e8cd0b446..cf12f7ee63 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.hardhat-test.ts @@ -4,6 +4,7 @@ import { ethers } from 'hardhat'; import { error } from '@hyperlane-xyz/utils'; import { TestChains } from '../consts/chains'; +import { HyperlaneProxyFactoryDeployer } from '../deploy/HyperlaneProxyFactoryDeployer'; import { MultiProvider } from '../providers/MultiProvider'; import { randomAddress, randomInt } from '../test/testUtils'; @@ -11,7 +12,6 @@ import { HyperlaneIsmFactory, moduleMatchesConfig, } from './HyperlaneIsmFactory'; -import { HyperlaneIsmFactoryDeployer } from './HyperlaneIsmFactoryDeployer'; import { AggregationIsmConfig, IsmConfig, @@ -79,8 +79,8 @@ describe('HyperlaneIsmFactory', async () => { const multiProvider = MultiProvider.createTestMultiProvider({ signer }); - const deployer = new HyperlaneIsmFactoryDeployer(multiProvider); - const contracts = await deployer.deploy([chain]); + const deployer = new HyperlaneProxyFactoryDeployer(multiProvider); + const contracts = await deployer.deploy({ [chain]: {} }); factory = new HyperlaneIsmFactory(contracts, multiProvider); }); diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts index a3ab7fe5c6..b44a2d6215 100644 --- a/typescript/sdk/src/ism/HyperlaneIsmFactory.ts +++ b/typescript/sdk/src/ism/HyperlaneIsmFactory.ts @@ -7,6 +7,7 @@ import { IInterchainSecurityModule__factory, IMultisigIsm__factory, IRoutingIsm__factory, + StaticAddressSetFactory, StaticAggregationIsm__factory, StaticThresholdAddressSetFactory, } from '@hyperlane-xyz/core'; @@ -22,7 +23,7 @@ import { HyperlaneAddressesMap, HyperlaneContracts } from '../contracts/types'; import { MultiProvider } from '../providers/MultiProvider'; import { ChainMap, ChainName } from '../types'; -import { IsmFactoryFactories, ismFactoryFactories } from './contracts'; +import { FactoryFactories, factoryFactories } from './contracts'; import { AggregationIsmConfig, DeployedIsm, @@ -32,7 +33,7 @@ import { RoutingIsmConfig, } from './types'; -export class HyperlaneIsmFactory extends HyperlaneApp { +export class HyperlaneIsmFactory extends HyperlaneApp { static fromEnvironment( env: Env, multiProvider: MultiProvider, @@ -50,7 +51,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { ): HyperlaneIsmFactory { const helper = appFromAddressesMapHelper( addressesMap, - ismFactoryFactories, + factoryFactories, multiProvider, ); return new HyperlaneIsmFactory( @@ -112,7 +113,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { ? this.getContracts(chain).merkleRootMultisigIsmFactory : this.getContracts(chain).messageIdMultisigIsmFactory; - const address = await this.deployThresholdFactory( + const address = await this.deployStaticAddressSet( chain, multisigIsmFactory, config.validators, @@ -179,7 +180,7 @@ export class HyperlaneIsmFactory extends HyperlaneApp { for (const module of config.modules) { addresses.push((await this.deploy(chain, module)).address); } - const address = await this.deployThresholdFactory( + const address = await this.deployStaticAddressSet( chain, aggregationIsmFactory, addresses, @@ -188,24 +189,31 @@ export class HyperlaneIsmFactory extends HyperlaneApp { return IAggregationIsm__factory.connect(address, signer); } - private async deployThresholdFactory( + async deployStaticAddressSet( chain: ChainName, - factory: StaticThresholdAddressSetFactory, + factory: StaticThresholdAddressSetFactory | StaticAddressSetFactory, values: Address[], - threshold: number, + threshold = values.length, ): Promise
{ const sorted = [...values].sort(); - const address = await factory.getAddress(sorted, threshold); - const provider = this.multiProvider.getProvider(chain); - const code = await provider.getCode(address); + const address = await factory['getAddress(address[],uint8)']( + sorted, + threshold, + ); + const code = await this.multiProvider.getProvider(chain).getCode(address); if (code === '0x') { this.logger( `Deploying new ${threshold} of ${values.length} address set to ${chain}`, ); const overrides = this.multiProvider.getTransactionOverrides(chain); - const hash = await factory.deploy(sorted, threshold, overrides); + const hash = await factory['deploy(address[],uint8)']( + sorted, + threshold, + overrides, + ); await this.multiProvider.handleTx(chain, hash); + // TODO: add proxy verification artifact? } else { this.logger( `Recovered ${threshold} of ${values.length} address set on ${chain}`, @@ -331,7 +339,7 @@ export async function moduleMatchesConfig( moduleAddress: Address, config: IsmConfig, multiProvider: MultiProvider, - contracts: HyperlaneContracts, + contracts: HyperlaneContracts, _origin?: ChainName, ): Promise { if (typeof config === 'string') { diff --git a/typescript/sdk/src/ism/HyperlaneIsmFactoryDeployer.ts b/typescript/sdk/src/ism/HyperlaneIsmFactoryDeployer.ts deleted file mode 100644 index 6afd8f2ade..0000000000 --- a/typescript/sdk/src/ism/HyperlaneIsmFactoryDeployer.ts +++ /dev/null @@ -1,80 +0,0 @@ -import debug from 'debug'; - -import { isObject } from '@hyperlane-xyz/utils'; - -import { HyperlaneContracts, HyperlaneContractsMap } from '../contracts/types'; -import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; -import { MultiProvider } from '../providers/MultiProvider'; -import { ChainMap, ChainName } from '../types'; - -import { IsmFactoryFactories, ismFactoryFactories } from './contracts'; - -export class HyperlaneIsmFactoryDeployer extends HyperlaneDeployer< - boolean, - IsmFactoryFactories -> { - constructor(multiProvider: MultiProvider) { - super(multiProvider, ismFactoryFactories, { - logger: debug('hyperlane:IsmFactoryDeployer'), - }); - } - - async deploy( - config: ChainName[] | ChainMap, - ): Promise> { - if (isObject(config)) { - return super.deploy(config as ChainMap); - } else { - return super.deploy( - Object.fromEntries((config as ChainName[]).map((c) => [c, true])), - ); - } - } - - async deployContracts( - chain: ChainName, - ): Promise> { - const merkleRootMultisigIsmFactory = await this.deployContract( - chain, - 'merkleRootMultisigIsmFactory', - [], - ); - this.verificationInputs[chain].push({ - name: 'StaticMerkleRootMultisigIsm', - address: await merkleRootMultisigIsmFactory.implementation(), - }); - const messageIdMultisigIsmFactory = await this.deployContract( - chain, - 'messageIdMultisigIsmFactory', - [], - ); - this.verificationInputs[chain].push({ - name: 'StaticMessageIdMultisigIsm', - address: await messageIdMultisigIsmFactory.implementation(), - }); - const aggregationIsmFactory = await this.deployContract( - chain, - 'aggregationIsmFactory', - [], - ); - this.verificationInputs[chain].push({ - name: 'StaticAggregationIsm', - address: await aggregationIsmFactory.implementation(), - }); - const routingIsmFactory = await this.deployContract( - chain, - 'routingIsmFactory', - [], - ); - this.verificationInputs[chain].push({ - name: 'DomaingRoutingIsm', - address: await routingIsmFactory.implementation(), - }); - return { - merkleRootMultisigIsmFactory, - messageIdMultisigIsmFactory, - aggregationIsmFactory, - routingIsmFactory, - }; - } -} diff --git a/typescript/sdk/src/ism/contracts.ts b/typescript/sdk/src/ism/contracts.ts index dc85245865..f5517dd462 100644 --- a/typescript/sdk/src/ism/contracts.ts +++ b/typescript/sdk/src/ism/contracts.ts @@ -1,16 +1,18 @@ import { DomainRoutingIsmFactory__factory, + StaticAggregationHookFactory__factory, StaticAggregationIsmFactory__factory, StaticMerkleRootMultisigIsmFactory__factory, StaticMessageIdMultisigIsmFactory__factory, } from '@hyperlane-xyz/core'; -export const ismFactoryFactories = { +export const factoryFactories = { merkleRootMultisigIsmFactory: new StaticMerkleRootMultisigIsmFactory__factory(), messageIdMultisigIsmFactory: new StaticMessageIdMultisigIsmFactory__factory(), aggregationIsmFactory: new StaticAggregationIsmFactory__factory(), + aggregationHookFactory: new StaticAggregationHookFactory__factory(), routingIsmFactory: new DomainRoutingIsmFactory__factory(), }; -export type IsmFactoryFactories = typeof ismFactoryFactories; +export type FactoryFactories = typeof factoryFactories; diff --git a/typescript/sdk/src/test/testUtils.ts b/typescript/sdk/src/test/testUtils.ts index 33880ae64d..1f78cc7d37 100644 --- a/typescript/sdk/src/test/testUtils.ts +++ b/typescript/sdk/src/test/testUtils.ts @@ -1,4 +1,4 @@ -import { ethers } from 'ethers'; +import { BigNumber, ethers } from 'ethers'; import { Address, objMap } from '@hyperlane-xyz/utils'; @@ -66,10 +66,14 @@ export function testCoreConfig(chains: ChainName[]): ChainMap { ), }, defaultHook: { - type: HookType.INTERCHAIN_GAS_PAYMASTER, + type: HookType.MERKLE_TREE, }, requiredHook: { - type: HookType.MERKLE_TREE, + type: HookType.PROTOCOL_FEE, + maxProtocolFee: ethers.utils.parseUnits('1', 'gwei'), // 1 gwei of native token + protocolFee: BigNumber.from(1), // 1 wei + beneficiary: nonZeroAddress, + owner: nonZeroAddress, }, }, ]), From 35c176fe900faadb385c2b8826eb67e816e6a53f Mon Sep 17 00:00:00 2001 From: Kunal Arora <55632507+aroralanuk@users.noreply.github.com> Date: Thu, 5 Oct 2023 16:54:07 -0400 Subject: [PATCH 2/2] Testnet4 deployment (#2781) fixes https://github.com/hyperlane-xyz/issues/issues/574 --- .github/workflows/node.yml | 2 +- .../m20230309_000001_create_table_domain.rs | 8 - rust/hyperlane-core/src/chain.rs | 16 +- typescript/infra/config/aggregationIsm.ts | 4 +- typescript/infra/config/environments/index.ts | 4 +- .../environments/testnet3/validators.ts | 220 ------------ .../{testnet3 => testnet4}/agent.ts | 0 .../{testnet3 => testnet4}/chains.ts | 7 +- .../{testnet3 => testnet4}/core.ts | 2 +- .../core/verification.json | 0 .../create2/addresses.json | 0 .../create2/verification.json | 0 .../{testnet3 => testnet4}/funding.ts | 0 .../{testnet3 => testnet4}/gas-oracle.ts | 10 + .../{testnet3 => testnet4}/helloworld.ts | 0 .../helloworld/hyperlane/addresses.json | 0 .../helloworld/hyperlane/verification.json | 0 .../helloworld/rc/addresses.json | 0 .../helloworld/rc/verification.json | 0 .../{testnet3 => testnet4}/igp.ts | 0 .../{testnet3 => testnet4}/index.ts | 0 .../{testnet3 => testnet4}/infrastructure.ts | 10 +- .../ism/verification.json | 0 .../{testnet3 => testnet4}/liquidityLayer.ts | 0 .../{testnet3 => testnet4}/middleware.ts | 0 .../middleware/accounts/verification.json | 0 .../middleware/liquidity-layer/addresses.json | 0 .../liquidity-layer/verification.json | 0 .../middleware/queries/verification.json | 0 .../{testnet3 => testnet4}/owners.ts | 0 .../testquerysender/addresses.json | 0 .../testquerysender/verification.json | 0 .../testrecipient/addresses.json | 0 .../testrecipient/verification.json | 0 .../{testnet3 => testnet4}/token-bridge.ts | 0 .../environments/testnet4/validators.ts | 315 ++++++++++++++++++ typescript/infra/config/multisigIsm.ts | 4 +- .../infra/config/rcMultisigIsmConfigs.ts | 38 ++- .../infra/helm/helloworld-kathy/values.yaml | 8 +- .../helm/liquidity-layer-relayers/values.yaml | 2 +- .../infra/scripts/announce-validators.ts | 2 +- typescript/infra/scripts/deploy.ts | 2 +- .../funding/fund-keys-from-deployer.ts | 8 +- typescript/infra/scripts/helloworld/kathy.ts | 2 +- typescript/infra/scripts/helloworld/utils.ts | 2 +- .../scripts/middleware/portal-relayer.ts | 2 +- typescript/infra/src/config/environment.ts | 2 +- typescript/infra/src/funding/key-funder.ts | 3 +- typescript/sdk/src/consts/chainMetadata.ts | 131 ++++++++ typescript/sdk/src/consts/chains.ts | 20 +- typescript/sdk/src/consts/multisigIsm.ts | 95 ++++-- 51 files changed, 616 insertions(+), 303 deletions(-) delete mode 100644 typescript/infra/config/environments/testnet3/validators.ts rename typescript/infra/config/environments/{testnet3 => testnet4}/agent.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/chains.ts (82%) rename typescript/infra/config/environments/{testnet3 => testnet4}/core.ts (94%) rename typescript/infra/config/environments/{testnet3 => testnet4}/core/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/create2/addresses.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/create2/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/funding.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/gas-oracle.ts (86%) rename typescript/infra/config/environments/{testnet3 => testnet4}/helloworld.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/helloworld/hyperlane/addresses.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/helloworld/hyperlane/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/helloworld/rc/addresses.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/helloworld/rc/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/igp.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/index.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/infrastructure.ts (86%) rename typescript/infra/config/environments/{testnet3 => testnet4}/ism/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/liquidityLayer.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/middleware.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/middleware/accounts/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/middleware/liquidity-layer/addresses.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/middleware/liquidity-layer/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/middleware/queries/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/owners.ts (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/testquerysender/addresses.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/testquerysender/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/testrecipient/addresses.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/testrecipient/verification.json (100%) rename typescript/infra/config/environments/{testnet3 => testnet4}/token-bridge.ts (100%) create mode 100644 typescript/infra/config/environments/testnet4/validators.ts diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml index 3fb7897d3e..335b9dec16 100644 --- a/.github/workflows/node.yml +++ b/.github/workflows/node.yml @@ -120,7 +120,7 @@ jobs: # needs: [yarn-build] # strategy: # matrix: - # environment: [testnet3, mainnet2] + # environment: [testnet4, mainnet2] # module: [ism, core, igp, ica, helloworld] # steps: diff --git a/rust/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs b/rust/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs index 38416859f2..e674d34898 100644 --- a/rust/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs +++ b/rust/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs @@ -182,14 +182,6 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: true, is_deprecated: false, }, - RawDomain { - name: "zksync2testnet", - token: "ETH", - domain: 280, - chain_id: 280, - is_test_net: true, - is_deprecated: false, - }, ]; #[derive(DeriveMigrationName)] diff --git a/rust/hyperlane-core/src/chain.rs b/rust/hyperlane-core/src/chain.rs index e037bf0de4..c727bfb746 100644 --- a/rust/hyperlane-core/src/chain.rs +++ b/rust/hyperlane-core/src/chain.rs @@ -54,6 +54,7 @@ pub enum KnownHyperlaneDomain { Polygon = 137, Mumbai = 80001, + PolygonZkEvmTestnet = 1442, Avalanche = 43114, Fuji = 43113, @@ -76,8 +77,7 @@ pub enum KnownHyperlaneDomain { MoonbaseAlpha = 1287, Gnosis = 100, - - Zksync2Testnet = 280, + Chiado = 10200, // -- Local test chains -- /// Test1 local chain @@ -94,6 +94,11 @@ pub enum KnownHyperlaneDomain { SealevelTest1 = 13375, /// Sealevel local chain 1 SealevelTest2 = 13376, + + // -- v3 testnets -- + LineaGoerli = 59140, + BaseGoerli = 84531, + ScrollSepolia = 534351, } #[derive(Clone)] @@ -182,12 +187,11 @@ impl KnownHyperlaneDomain { many_to_one!(match self { Mainnet: [ Ethereum, Avalanche, Arbitrum, Polygon, Optimism, BinanceSmartChain, Celo, - Moonbeam, - Gnosis + Moonbeam, Gnosis ], Testnet: [ Goerli, Mumbai, Fuji, ArbitrumGoerli, OptimismGoerli, BinanceSmartChainTestnet, - Alfajores, MoonbaseAlpha, Zksync2Testnet, Sepolia + Alfajores, MoonbaseAlpha, Sepolia, PolygonZkEvmTestnet, LineaGoerli, BaseGoerli, ScrollSepolia, Chiado ], LocalTestChain: [Test1, Test2, Test3, FuelTest1, SealevelTest1, SealevelTest2], }) @@ -200,7 +204,7 @@ impl KnownHyperlaneDomain { HyperlaneDomainProtocol::Ethereum: [ Ethereum, Goerli, Sepolia, Polygon, Mumbai, Avalanche, Fuji, Arbitrum, ArbitrumGoerli, Optimism, OptimismGoerli, BinanceSmartChain, BinanceSmartChainTestnet, Celo, Gnosis, - Alfajores, Moonbeam, MoonbaseAlpha, Zksync2Testnet, Test1, Test2, Test3 + Alfajores, Moonbeam, MoonbaseAlpha, PolygonZkEvmTestnet, LineaGoerli, BaseGoerli, ScrollSepolia, Chiado, Test1, Test2, Test3 ], HyperlaneDomainProtocol::Fuel: [FuelTest1], HyperlaneDomainProtocol::Sealevel: [SealevelTest1, SealevelTest2], diff --git a/typescript/infra/config/aggregationIsm.ts b/typescript/infra/config/aggregationIsm.ts index 945886498c..8d084eb04d 100644 --- a/typescript/infra/config/aggregationIsm.ts +++ b/typescript/infra/config/aggregationIsm.ts @@ -14,11 +14,11 @@ import { DeployEnvironment } from '../src/config'; import { Contexts } from './contexts'; import { owners as mainnet2Owners } from './environments/mainnet2/owners'; import { owners as testOwners } from './environments/test/owners'; -import { owners as testnet3Owners } from './environments/testnet3/owners'; +import { owners as testnet4Owners } from './environments/testnet4/owners'; import { multisigIsms } from './multisigIsm'; const owners = { - testnet3: testnet3Owners, + testnet4: testnet4Owners, mainnet2: mainnet2Owners, test: testOwners, }; diff --git a/typescript/infra/config/environments/index.ts b/typescript/infra/config/environments/index.ts index 3079c420ad..7080679122 100644 --- a/typescript/infra/config/environments/index.ts +++ b/typescript/infra/config/environments/index.ts @@ -1,9 +1,9 @@ import { environment as mainnet2 } from './mainnet2'; import { environment as test } from './test'; -import { environment as testnet3 } from './testnet3'; +import { environment as testnet4 } from './testnet4'; export const environments = { test, - testnet3, + testnet4, mainnet2, }; diff --git a/typescript/infra/config/environments/testnet3/validators.ts b/typescript/infra/config/environments/testnet3/validators.ts deleted file mode 100644 index b08d10b04f..0000000000 --- a/typescript/infra/config/environments/testnet3/validators.ts +++ /dev/null @@ -1,220 +0,0 @@ -import { chainMetadata } from '@hyperlane-xyz/sdk'; - -import { ValidatorBaseChainConfigMap } from '../../../src/config/agent'; -import { Contexts } from '../../contexts'; -import { validatorBaseConfigsFn } from '../utils'; - -import { environment } from './chains'; - -export const validatorChainConfig = ( - context: Contexts, -): ValidatorBaseChainConfigMap => { - const validatorsConfig = validatorBaseConfigsFn(environment, context); - return { - alfajores: { - interval: 5, - reorgPeriod: chainMetadata.alfajores.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0xe6072396568e73ce6803b12b7e04164e839f1e54', - '0x9f177f51289b22515f41f95872e1511391b8e105', - '0x15f77400845eb1c971ad08de050861d5508cad6c', - ], - [Contexts.ReleaseCandidate]: [ - '0x45e5c228b38e1cf09e9a3423ed0cf4862c4bf3de', - '0x30c40c29dc21896ccc510c581ce0c88ba5552467', - '0xc60ef4fc6f9530fdb37b1cf4c2c16a6764e6f723', - ], - }, - 'alfajores', - ), - }, - fuji: { - interval: 5, - reorgPeriod: chainMetadata.fuji.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0x9fa19ead5ec76e437948b35e227511b106293c40', - '0x227e7d6507762ece0c94678f8c103eff9d682476', - '0x2379e43740e4aa4fde48cf4f00a3106df1d8420d', - ], - [Contexts.ReleaseCandidate]: [ - '0xd81ba169170a9b582812cf0e152d2c168572e21f', - '0x05900a676389219c934ba0de3fcd625dbbac0cc0', - '0x1bf7d94ddcca25a8b139b6d21fd396fe959f21c8', - ], - }, - 'fuji', - ), - }, - mumbai: { - interval: 5, - reorgPeriod: chainMetadata.mumbai.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0x0a664ea799447da6b15645cf8b9e82072a68343f', - '0x6ae6f12929a960aba24ba74ea310e3d37d0ac045', - '0x51f70c047cd73bc7873273707501568857a619c4', - ], - [Contexts.ReleaseCandidate]: [ - '0xb537c4ce34e1cad718be52aa30b095e416eae46a', - '0x5dbddee458d5943f9c5daea28736f569aeeed7a5', - '0x688fd80884a23680c2c80970a357b74558d8a25e', - ], - }, - 'mumbai', - ), - }, - bsctestnet: { - interval: 5, - reorgPeriod: chainMetadata.bsctestnet.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0x23338c8714976dd4a57eaeff17cbd26d7e275c08', - '0x85a618d7450ebc37e0d682371f08dac94eec7a76', - '0x95b76562e4ba1791a27ba4236801271c9115b141', - ], - [Contexts.ReleaseCandidate]: [ - '0x77f80ef5b18977e15d81aea8dd3a88e7df4bc0eb', - '0x87044ecdcba9c2ada89554dd85f16344160bdeb7', - '0x1e0bdd7de5573d010bd8681fa282ece5bc77180e', - ], - }, - 'bsctestnet', - ), - }, - goerli: { - interval: 5, - reorgPeriod: chainMetadata.goerli.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0xf43fbd072fd38e1121d4b3b0b8a35116bbb01ea9', - '0xa33020552a21f35e75bd385c6ab95c3dfa82d930', - '0x0bba4043ff242f8bf3f39bafa8930a84d644d947', - ], - [Contexts.ReleaseCandidate]: [ - '0x9597ddb4ad2af237665559574b820596bb77ae7a', - '0x1e88fbc51c88627be1da98feaa5ba9a2f302bb7e', - '0x57d4db75e762ebf2fc8725dc7c3194fbefa492fc', - ], - }, - 'goerli', - ), - }, - sepolia: { - interval: 5, - reorgPeriod: chainMetadata.sepolia.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0xbc748ee311f5f2d1975d61cdf531755ce8ce3066', - '0xc4233b2bfe5aec08964a94b403052abb3eafcf07', - '0x6b36286c19f5c10bdc139ea9ee7f82287303f61d', - ], - [Contexts.ReleaseCandidate]: [ - '0x183f15924f3a464c54c9393e8d268eb44d2b208c', - '0x90ec2ea0229f921602f3aca97c5fd85849a2e85c', - '0x18cf2f76d604d6f6470d924678221fb556347fbd', - ], - }, - 'sepolia', - ), - }, - moonbasealpha: { - interval: 5, - reorgPeriod: chainMetadata.moonbasealpha.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0x890c2aeac157c3f067f3e42b8afc797939c59a32', - '0x1b06d6fe69b972ed7420c83599d5a5c0fc185904', - '0xe70b85206a968a99a597581f0fa09c99e7681093', - ], - [Contexts.ReleaseCandidate]: [ - '0xbeaf158f85d7b64ced36b8aea0bbc4cd0f2d1a5d', - '0x9b81c45fce282177ecc828eb8fddf07fc3512808', - '0x15a183fb89807c4036006e028d4871fb797113b2', - ], - }, - 'moonbasealpha', - ), - }, - optimismgoerli: { - interval: 5, - reorgPeriod: chainMetadata.optimismgoerli.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0xbb8d77eefbecc55db6e5a19b0fc3dc290776f189', - '0x69792508b4ddaa3ca52241ccfcd1e0b119a1ee65', - '0x11ddb46c6b653e0cdd7ad5bee32ae316e18f8453', - ], - [Contexts.ReleaseCandidate]: [ - '0x1d6798671ac532f2bf30c3a5230697a4695705e4', - '0xbc763cb587b9d0bf52360393a84660ea24db7057', - '0xee331cba457352ce282a1bc1696e6d2defb6be26', - ], - }, - 'optimismgoerli', - ), - }, - arbitrumgoerli: { - interval: 5, - reorgPeriod: chainMetadata.arbitrumgoerli.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0xce798fa21e323f6b24d9838a10ffecdefdfc4f30', - '0xa792d39dca4426927e0f00c1618d61c9cb41779d', - '0xdf181fcc11dfac5d01467e4547101a856dd5aa04', - ], - [Contexts.ReleaseCandidate]: [ - '0x6d13367c7cd713a4ea79a2552adf824bf1ecdd5e', - '0x3a99b6590c7f18d0a77a1879990f34a908958fe1', - '0xb77da6c29eca52b89c0fa6d220462f03258e14a9', - ], - }, - 'arbitrumgoerli', - ), - }, - proteustestnet: { - interval: 5, - reorgPeriod: chainMetadata.proteustestnet.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0x79fc73656abb9eeaa5ee853c4569124f5bdaf9d8', - '0x72840388d5ab57323bc4f6e6d3ddedfd5cc911f0', - '0xd4b2a50c53fc6614bb3cd3198e0fdc03f5da973f', - ], - [Contexts.ReleaseCandidate]: [ - '0xc2ccc4eab0e8d441235d661e39341ae16c3bf8cd', - ], - }, - 'proteustestnet', - ), - }, - solanadevnet: { - interval: 10, - reorgPeriod: chainMetadata.solanadevnet.blocks!.reorgPeriod!, - validators: validatorsConfig( - { - [Contexts.Hyperlane]: [ - '0xec0f73dbc5b1962a20f7dcbe07c98414025b0c43', - '0x9c20a149dfa09ea9f77f5a7ca09ed44f9c025133', - '0x967c5ecdf2625ae86580bd203b630abaaf85cd62', - ], - [Contexts.ReleaseCandidate]: [ - '0x21b9eff4d1a6d3122596c7fb80315bf094b6e5c2', - ], - }, - 'solanadevnet', - ), - }, - }; -}; diff --git a/typescript/infra/config/environments/testnet3/agent.ts b/typescript/infra/config/environments/testnet4/agent.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/agent.ts rename to typescript/infra/config/environments/testnet4/agent.ts diff --git a/typescript/infra/config/environments/testnet3/chains.ts b/typescript/infra/config/environments/testnet4/chains.ts similarity index 82% rename from typescript/infra/config/environments/testnet3/chains.ts rename to typescript/infra/config/environments/testnet4/chains.ts index 7523789e93..ccdf63ff89 100644 --- a/typescript/infra/config/environments/testnet3/chains.ts +++ b/typescript/infra/config/environments/testnet4/chains.ts @@ -4,7 +4,10 @@ import { AgentChainNames, Role } from '../../../src/roles'; export const testnetConfigs: ChainMap = { alfajores: chainMetadata.alfajores, + basegoerli: chainMetadata.basegoerli, fuji: chainMetadata.fuji, + chiado: chainMetadata.chiado, + lineagoerli: chainMetadata.lineagoerli, mumbai: { ...chainMetadata.mumbai, transactionOverrides: { @@ -14,10 +17,12 @@ export const testnetConfigs: ChainMap = { }, bsctestnet: chainMetadata.bsctestnet, goerli: chainMetadata.goerli, + scrollsepolia: chainMetadata.scrollsepolia, sepolia: chainMetadata.sepolia, moonbasealpha: chainMetadata.moonbasealpha, optimismgoerli: chainMetadata.optimismgoerli, arbitrumgoerli: chainMetadata.arbitrumgoerli, + polygonzkevmtestnet: chainMetadata.polygonzkevmtestnet, }; // "Blessed" chains that we want core contracts for. @@ -25,7 +30,7 @@ export type TestnetChains = keyof typeof testnetConfigs; export const supportedChainNames = Object.keys( testnetConfigs, ) as TestnetChains[]; -export const environment = 'testnet3'; +export const environment = 'testnet4'; const validatorChainNames = [ ...supportedChainNames, diff --git a/typescript/infra/config/environments/testnet3/core.ts b/typescript/infra/config/environments/testnet4/core.ts similarity index 94% rename from typescript/infra/config/environments/testnet3/core.ts rename to typescript/infra/config/environments/testnet4/core.ts index 536fa771ff..6339a26535 100644 --- a/typescript/infra/config/environments/testnet3/core.ts +++ b/typescript/infra/config/environments/testnet4/core.ts @@ -18,7 +18,7 @@ import { igp } from './igp'; import { owners } from './owners'; export const core: ChainMap = objMap(owners, (local, owner) => { - const defaultIsm = aggregationIsm('testnet3', local, Contexts.Hyperlane); + const defaultIsm = aggregationIsm('testnet4', local, Contexts.Hyperlane); const merkleHook: MerkleTreeHookConfig = { type: HookType.MERKLE_TREE, diff --git a/typescript/infra/config/environments/testnet3/core/verification.json b/typescript/infra/config/environments/testnet4/core/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/core/verification.json rename to typescript/infra/config/environments/testnet4/core/verification.json diff --git a/typescript/infra/config/environments/testnet3/create2/addresses.json b/typescript/infra/config/environments/testnet4/create2/addresses.json similarity index 100% rename from typescript/infra/config/environments/testnet3/create2/addresses.json rename to typescript/infra/config/environments/testnet4/create2/addresses.json diff --git a/typescript/infra/config/environments/testnet3/create2/verification.json b/typescript/infra/config/environments/testnet4/create2/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/create2/verification.json rename to typescript/infra/config/environments/testnet4/create2/verification.json diff --git a/typescript/infra/config/environments/testnet3/funding.ts b/typescript/infra/config/environments/testnet4/funding.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/funding.ts rename to typescript/infra/config/environments/testnet4/funding.ts diff --git a/typescript/infra/config/environments/testnet3/gas-oracle.ts b/typescript/infra/config/environments/testnet4/gas-oracle.ts similarity index 86% rename from typescript/infra/config/environments/testnet3/gas-oracle.ts rename to typescript/infra/config/environments/testnet4/gas-oracle.ts index 4325105bc4..b1d1fbc1f2 100644 --- a/typescript/infra/config/environments/testnet3/gas-oracle.ts +++ b/typescript/infra/config/environments/testnet4/gas-oracle.ts @@ -27,6 +27,11 @@ const gasPrices: ChainMap = { moonbasealpha: ethers.utils.parseUnits('5', 'gwei'), optimismgoerli: ethers.utils.parseUnits('0.5', 'gwei'), arbitrumgoerli: ethers.utils.parseUnits('0.5', 'gwei'), + basegoerli: ethers.utils.parseUnits('0.2', 'gwei'), + scrollsepolia: ethers.utils.parseUnits('0.5', 'gwei'), + lineagoerli: ethers.utils.parseUnits('1', 'gwei'), + polygonzkevmtestnet: ethers.utils.parseUnits('1', 'gwei'), + chiado: ethers.utils.parseUnits('2', 'gwei'), }; // Used to categorize rarity of testnet tokens & approximate exchange rates. @@ -55,6 +60,11 @@ const chainTokenRarity: ChainMap = { moonbasealpha: Rarity.Common, optimismgoerli: Rarity.Mythic, arbitrumgoerli: Rarity.Mythic, + basegoerli: Rarity.Mythic, + scrollsepolia: Rarity.Rare, + lineagoerli: Rarity.Rare, + polygonzkevmtestnet: Rarity.Common, + chiado: Rarity.Common, }; // Gets the "value" of a testnet chain diff --git a/typescript/infra/config/environments/testnet3/helloworld.ts b/typescript/infra/config/environments/testnet4/helloworld.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/helloworld.ts rename to typescript/infra/config/environments/testnet4/helloworld.ts diff --git a/typescript/infra/config/environments/testnet3/helloworld/hyperlane/addresses.json b/typescript/infra/config/environments/testnet4/helloworld/hyperlane/addresses.json similarity index 100% rename from typescript/infra/config/environments/testnet3/helloworld/hyperlane/addresses.json rename to typescript/infra/config/environments/testnet4/helloworld/hyperlane/addresses.json diff --git a/typescript/infra/config/environments/testnet3/helloworld/hyperlane/verification.json b/typescript/infra/config/environments/testnet4/helloworld/hyperlane/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/helloworld/hyperlane/verification.json rename to typescript/infra/config/environments/testnet4/helloworld/hyperlane/verification.json diff --git a/typescript/infra/config/environments/testnet3/helloworld/rc/addresses.json b/typescript/infra/config/environments/testnet4/helloworld/rc/addresses.json similarity index 100% rename from typescript/infra/config/environments/testnet3/helloworld/rc/addresses.json rename to typescript/infra/config/environments/testnet4/helloworld/rc/addresses.json diff --git a/typescript/infra/config/environments/testnet3/helloworld/rc/verification.json b/typescript/infra/config/environments/testnet4/helloworld/rc/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/helloworld/rc/verification.json rename to typescript/infra/config/environments/testnet4/helloworld/rc/verification.json diff --git a/typescript/infra/config/environments/testnet3/igp.ts b/typescript/infra/config/environments/testnet4/igp.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/igp.ts rename to typescript/infra/config/environments/testnet4/igp.ts diff --git a/typescript/infra/config/environments/testnet3/index.ts b/typescript/infra/config/environments/testnet4/index.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/index.ts rename to typescript/infra/config/environments/testnet4/index.ts diff --git a/typescript/infra/config/environments/testnet3/infrastructure.ts b/typescript/infra/config/environments/testnet4/infrastructure.ts similarity index 86% rename from typescript/infra/config/environments/testnet3/infrastructure.ts rename to typescript/infra/config/environments/testnet4/infrastructure.ts index 9ad695ee17..99a694a61c 100644 --- a/typescript/infra/config/environments/testnet3/infrastructure.ts +++ b/typescript/infra/config/environments/testnet4/infrastructure.ts @@ -31,14 +31,14 @@ export const infrastructure: InfrastructureConfig = { name: 'external-secrets', version: '0.5.1', }, - gcpServiceAccountName: 'k8s-external-secrets-testnet3', + gcpServiceAccountName: 'k8s-external-secrets-testnet4', accessibleGCPSecretPrefixes: [ 'hyperlane-testnet-', 'testnet-', - 'hyperlane-testnet3-', - 'flowcarbon-testnet3-', - 'rc-testnet3-', - 'testnet3-', + 'hyperlane-testnet4-', + 'flowcarbon-testnet4-', + 'rc-testnet4-', + 'testnet4-', ], }, }; diff --git a/typescript/infra/config/environments/testnet3/ism/verification.json b/typescript/infra/config/environments/testnet4/ism/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/ism/verification.json rename to typescript/infra/config/environments/testnet4/ism/verification.json diff --git a/typescript/infra/config/environments/testnet3/liquidityLayer.ts b/typescript/infra/config/environments/testnet4/liquidityLayer.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/liquidityLayer.ts rename to typescript/infra/config/environments/testnet4/liquidityLayer.ts diff --git a/typescript/infra/config/environments/testnet3/middleware.ts b/typescript/infra/config/environments/testnet4/middleware.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/middleware.ts rename to typescript/infra/config/environments/testnet4/middleware.ts diff --git a/typescript/infra/config/environments/testnet3/middleware/accounts/verification.json b/typescript/infra/config/environments/testnet4/middleware/accounts/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/middleware/accounts/verification.json rename to typescript/infra/config/environments/testnet4/middleware/accounts/verification.json diff --git a/typescript/infra/config/environments/testnet3/middleware/liquidity-layer/addresses.json b/typescript/infra/config/environments/testnet4/middleware/liquidity-layer/addresses.json similarity index 100% rename from typescript/infra/config/environments/testnet3/middleware/liquidity-layer/addresses.json rename to typescript/infra/config/environments/testnet4/middleware/liquidity-layer/addresses.json diff --git a/typescript/infra/config/environments/testnet3/middleware/liquidity-layer/verification.json b/typescript/infra/config/environments/testnet4/middleware/liquidity-layer/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/middleware/liquidity-layer/verification.json rename to typescript/infra/config/environments/testnet4/middleware/liquidity-layer/verification.json diff --git a/typescript/infra/config/environments/testnet3/middleware/queries/verification.json b/typescript/infra/config/environments/testnet4/middleware/queries/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/middleware/queries/verification.json rename to typescript/infra/config/environments/testnet4/middleware/queries/verification.json diff --git a/typescript/infra/config/environments/testnet3/owners.ts b/typescript/infra/config/environments/testnet4/owners.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/owners.ts rename to typescript/infra/config/environments/testnet4/owners.ts diff --git a/typescript/infra/config/environments/testnet3/testquerysender/addresses.json b/typescript/infra/config/environments/testnet4/testquerysender/addresses.json similarity index 100% rename from typescript/infra/config/environments/testnet3/testquerysender/addresses.json rename to typescript/infra/config/environments/testnet4/testquerysender/addresses.json diff --git a/typescript/infra/config/environments/testnet3/testquerysender/verification.json b/typescript/infra/config/environments/testnet4/testquerysender/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/testquerysender/verification.json rename to typescript/infra/config/environments/testnet4/testquerysender/verification.json diff --git a/typescript/infra/config/environments/testnet3/testrecipient/addresses.json b/typescript/infra/config/environments/testnet4/testrecipient/addresses.json similarity index 100% rename from typescript/infra/config/environments/testnet3/testrecipient/addresses.json rename to typescript/infra/config/environments/testnet4/testrecipient/addresses.json diff --git a/typescript/infra/config/environments/testnet3/testrecipient/verification.json b/typescript/infra/config/environments/testnet4/testrecipient/verification.json similarity index 100% rename from typescript/infra/config/environments/testnet3/testrecipient/verification.json rename to typescript/infra/config/environments/testnet4/testrecipient/verification.json diff --git a/typescript/infra/config/environments/testnet3/token-bridge.ts b/typescript/infra/config/environments/testnet4/token-bridge.ts similarity index 100% rename from typescript/infra/config/environments/testnet3/token-bridge.ts rename to typescript/infra/config/environments/testnet4/token-bridge.ts diff --git a/typescript/infra/config/environments/testnet4/validators.ts b/typescript/infra/config/environments/testnet4/validators.ts new file mode 100644 index 0000000000..7216ad3419 --- /dev/null +++ b/typescript/infra/config/environments/testnet4/validators.ts @@ -0,0 +1,315 @@ +import { chainMetadata } from '@hyperlane-xyz/sdk'; + +import { ValidatorBaseChainConfigMap } from '../../../src/config/agent'; +import { Contexts } from '../../contexts'; +import { validatorBaseConfigsFn } from '../utils'; + +import { environment } from './chains'; + +export const validatorChainConfig = ( + context: Contexts, +): ValidatorBaseChainConfigMap => { + const validatorsConfig = validatorBaseConfigsFn(environment, context); + return { + alfajores: { + interval: 5, + reorgPeriod: chainMetadata.alfajores.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x2233a5ce12f814bd64c9cdd73410bb8693124d40', + '0xba279f965489d90f90490e3c49e860e0b43c2ae6', + '0x86485dcec5f7bb8478dd251676372d054dea6653', + ], + [Contexts.ReleaseCandidate]: [ + '0xace978aaa61d9ee44fe3ab147fd227e0e66b8909', + '0x6c8bfdfb8c40aba10cc9fb2cf0e3e856e0e5dbb3', + '0x54c65eb7677e6086cdde3d5ccef89feb2103a11d', + ], + }, + 'alfajores', + ), + }, + basegoerli: { + interval: 5, + reorgPeriod: chainMetadata.basegoerli.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xf6eddda696dcd3bf10f7ce8a02db31ef2e775a03', + '0x5a7d05cebf5db4dde9b2fedcefa76fb58fa05071', + '0x9260a6c7d54cbcbed28f8668679cd1fa3a203b25', + ], + [Contexts.ReleaseCandidate]: [ + '0x81983e03363351b63848867bd76687cc80b9ff37', + '0x36de434527b8f83851d83f1b1d72ec11a5903533', + '0x4b65f7527c267e420bf62a0c5a139cb8c3906277', + ], + }, + 'basegoerli', + ), + }, + fuji: { + interval: 5, + reorgPeriod: chainMetadata.fuji.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xd8154f73d04cc7f7f0c332793692e6e6f6b2402e', + '0x895ae30bc83ff1493b9cf7781b0b813d23659857', + '0x43e915573d9f1383cbf482049e4a012290759e7f', + ], + [Contexts.ReleaseCandidate]: [ + '0xfc419f9ba3c56c55e28844ade491d428f5a77d55', + '0x0a636e76df4124b092cabb4321d6aaef9defb514', + '0xbf86037899efe97bca4cea865607e10b849b5878', + ], + }, + 'fuji', + ), + }, + chiado: { + interval: 5, + reorgPeriod: chainMetadata.chiado.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x12b1d1354441b900e0a36659ae54c3a9d5d22c57', + '0x06c3757a4b7a912828e523bb8a5f980ddc297356', + '0x0874967a145d70b799ebe9ed861ab7c93faef95a', + ], + [Contexts.ReleaseCandidate]: [ + '0x7572ffd8af1abc02cc1d234ac750d387fd6768a0', + '0x31b37a32657cf2915d434b409ee86978058fa91c', + '0x32495780512fce64a45aca55ccc02202e9018dc5', + ], + }, + 'chiado', + ), + }, + lineagoerli: { + interval: 5, + reorgPeriod: chainMetadata.lineagoerli.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xd767ea1206b8295d7e1267ddd00e56d34f278db6', + '0x4a5d7085ca93c22fbc994dd97857c98fcc745674', + '0x8327779c3c31fa1ffc7f0c9ffae33e4d804bbd8f', + ], + [Contexts.ReleaseCandidate]: [ + '0x52e2c6db923124e646011d172dea644e1cafe583', + '0x48d540e94ff1acb886df6bfed2b7a92568639364', + '0xe99e3acc543a535b8eeae98f3d6f39015efe0cd0', + ], + }, + 'lineagoerli', + ), + }, + mumbai: { + interval: 5, + reorgPeriod: chainMetadata.mumbai.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xebc301013b6cd2548e347c28d2dc43ec20c068f2', + '0x315db9868fc8813b221b1694f8760ece39f45447', + '0x17517c98358c5937c5d9ee47ce1f5b4c2b7fc9f5', + ], + [Contexts.ReleaseCandidate]: [ + '0x7fc2981964427f09e317eda559f506bfd37f1ccb', + '0x954168cf13faeaa248d412e145a17dc697556636', + '0x98a9f2610e44246ac0c749c20a07a6eb192ce9eb', + ], + }, + 'mumbai', + ), + }, + bsctestnet: { + interval: 5, + reorgPeriod: chainMetadata.bsctestnet.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x242d8a855a8c932dec51f7999ae7d1e48b10c95e', + '0xf620f5e3d25a3ae848fec74bccae5de3edcd8796', + '0x1f030345963c54ff8229720dd3a711c15c554aeb', + ], + [Contexts.ReleaseCandidate]: [ + '0x6353c7402626054c824bd0eca721f82b725e2b4d', + '0xcb5be62b19c52b78cd3993c71c3fa74d821475ae', + '0xc50ddb8f03133611853b7f03ffe0a8098e08ae15', + ], + }, + 'bsctestnet', + ), + }, + goerli: { + interval: 5, + reorgPeriod: chainMetadata.goerli.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x05a9b5efe9f61f9142453d8e9f61565f333c6768', + '0x43a96c7dfbd8187c95013d6ee8665650cbdb2673', + '0x7940a12c050e24e1839c21ecb12f65afd84e8c5b', + ], + [Contexts.ReleaseCandidate]: [ + '0x6b32af7592948cbec6893363f77c08252d0ce0d7', + '0x4711d476a5929840196def397a156c5253b44b96', + '0xb0add42f2a4b824ba5fab2628f930dc1dcfc40f8', + ], + }, + 'goerli', + ), + }, + scrollsepolia: { + interval: 5, + reorgPeriod: chainMetadata.scrollsepolia.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xbe18dbd758afb367180260b524e6d4bcd1cb6d05', + '0x9a11ed23ae962974018ab45bc133caabff7b3271', + '0x7867bea3c9761fe64e6d124b171f91fd5dd79644', + ], + [Contexts.ReleaseCandidate]: [ + '0x50d939d66f114350f322eb8b2e9f01fbc401d4c9', + '0x10fa7a657a06a47bcca1bacc436d61619e5d104c', + '0xa0f1cf3b23bd0f8a5e2ad438657097b8287816b4', + ], + }, + 'scrollsepolia', + ), + }, + sepolia: { + interval: 5, + reorgPeriod: chainMetadata.sepolia.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xb22b65f202558adf86a8bb2847b76ae1036686a5', + '0x469f0940684d147defc44f3647146cb90dd0bc8e', + '0xd3c75dcf15056012a4d74c483a0c6ea11d8c2b83', + ], + [Contexts.ReleaseCandidate]: [ + '0x49f253c0dab33be1573d6c2769b3d9e584d91f82', + '0x13b51805e9af68e154778d973165f32e10b7446b', + '0x7f699c3fc3de4928f1c0abfba1eac3fbb5a00d1b', + ], + }, + 'sepolia', + ), + }, + moonbasealpha: { + interval: 5, + reorgPeriod: chainMetadata.moonbasealpha.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x521877064bd7ac7500d300f162c8c47c256a2f9c', + '0xbc1c70f58ae0459d4b8a013245420a893837d568', + '0x01e42c2c44af81dda1ac16fec76fea2a7a54a44c', + ], + [Contexts.ReleaseCandidate]: [ + '0x376260b40b2ba2100890f27de1eb18a2774f54d1', + '0x776623e8be8d7218940b7c77d02162af4ff97985', + '0xb4c81facd992a6c7c4a187bcce35a6fc968399a0', + ], + }, + 'moonbasealpha', + ), + }, + optimismgoerli: { + interval: 5, + reorgPeriod: chainMetadata.optimismgoerli.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x79e58546e2faca865c6732ad5f6c4951051c4d67', + '0x7bbfe1bb7146aad7df309c637987d856179ebbc1', + '0xf3d2fb4d53c2bb6a88cec040e0d87430fcee4e40', + ], + [Contexts.ReleaseCandidate]: [ + '0xed4cf9bf144457c927d7a39613c812c53f296283', + '0xec6b5ddfd20ee64ff0dcbc7472ad757dce151685', + '0x4acd2983a51f1c33c2ab41669184c7679e0316f1', + ], + }, + 'optimismgoerli', + ), + }, + arbitrumgoerli: { + interval: 5, + reorgPeriod: chainMetadata.arbitrumgoerli.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x071c8d135845ae5a2cb73f98d681d519014c0a8b', + '0x1bcf03360989f15cbeb174c188288f2c6d2760d7', + '0xc1590eaaeaf380e7859564c5ebcdcc87e8369e0d', + ], + [Contexts.ReleaseCandidate]: [ + '0x869f67e89b5c0826a3c2f2ba72e6ae1d8a1952ff', + '0x9be82c7a063b47b2d04c890daabcb666b670a9a4', + '0x92c62f4b9cd60a7fe4216d1f12134d34cf827c41', + ], + }, + 'arbitrumgoerli', + ), + }, + polygonzkevmtestnet: { + interval: 5, + reorgPeriod: chainMetadata.polygonzkevmtestnet.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x3f06b725bc9648917eb11c414e9f8d76fd959550', + '0x27bfc57679d9dd4ab2e870f5ed7ec0b339a0b636', + '0xd476548222f43206d0abaa30e46e28670aa7859c', + ], + [Contexts.ReleaseCandidate]: [ + '0x2d0214068e5d8e49c638b5a4c70c75080204be21', + '0x989bbbfa753431169556f69be1b0a496b252e8a6', + '0x292d5788587bb5efd5c2c911115527e57f50cd05', + ], + }, + 'polygonzkevmtestnet', + ), + }, + proteustestnet: { + interval: 5, + reorgPeriod: chainMetadata.proteustestnet.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0x79fc73656abb9eeaa5ee853c4569124f5bdaf9d8', + '0x72840388d5ab57323bc4f6e6d3ddedfd5cc911f0', + '0xd4b2a50c53fc6614bb3cd3198e0fdc03f5da973f', + ], + [Contexts.ReleaseCandidate]: [ + '0xc2ccc4eab0e8d441235d661e39341ae16c3bf8cd', + ], + }, + 'proteustestnet', + ), + }, + solanadevnet: { + interval: 10, + reorgPeriod: chainMetadata.solanadevnet.blocks!.reorgPeriod!, + validators: validatorsConfig( + { + [Contexts.Hyperlane]: [ + '0xec0f73dbc5b1962a20f7dcbe07c98414025b0c43', + '0x9c20a149dfa09ea9f77f5a7ca09ed44f9c025133', + '0x967c5ecdf2625ae86580bd203b630abaaf85cd62', + ], + [Contexts.ReleaseCandidate]: [ + '0x21b9eff4d1a6d3122596c7fb80315bf094b6e5c2', + ], + }, + 'solanadevnet', + ), + }, + }; +}; diff --git a/typescript/infra/config/multisigIsm.ts b/typescript/infra/config/multisigIsm.ts index 232c1f32fe..f584519aad 100644 --- a/typescript/infra/config/multisigIsm.ts +++ b/typescript/infra/config/multisigIsm.ts @@ -11,12 +11,12 @@ import { DeployEnvironment } from '../src/config'; import { Contexts } from './contexts'; import { supportedChainNames as mainnet2Chains } from './environments/mainnet2/chains'; import { chainNames as testChains } from './environments/test/chains'; -import { supportedChainNames as testnet3Chains } from './environments/testnet3/chains'; +import { supportedChainNames as testnet4Chains } from './environments/testnet4/chains'; import { rcMultisigIsmConfigs } from './rcMultisigIsmConfigs'; const chains = { mainnet2: mainnet2Chains, - testnet3: testnet3Chains, + testnet4: testnet4Chains, test: testChains, }; diff --git a/typescript/infra/config/rcMultisigIsmConfigs.ts b/typescript/infra/config/rcMultisigIsmConfigs.ts index e787b9e65c..e5b89e1f71 100644 --- a/typescript/infra/config/rcMultisigIsmConfigs.ts +++ b/typescript/infra/config/rcMultisigIsmConfigs.ts @@ -59,38 +59,58 @@ export const rcMultisigIsmConfigs: ChainMap = { // ----------------- Testnets ----------------- alfajores: { threshold: 1, - validators: ['0x45e5c228b38e1cf09e9a3423ed0cf4862c4bf3de'], + validators: ['0xace978aaa61d9ee44fe3ab147fd227e0e66b8909'], + }, + basegoerli: { + threshold: 1, + validators: ['0x81983e03363351b63848867bd76687cc80b9ff37'], }, fuji: { threshold: 1, - validators: ['0xd81ba169170a9b582812cf0e152d2c168572e21f'], + validators: ['0xfc419f9ba3c56c55e28844ade491d428f5a77d55'], + }, + chiado: { + threshold: 1, + validators: ['0x7572ffd8af1abc02cc1d234ac750d387fd6768a0'], + }, + lineagoerli: { + threshold: 1, + validators: ['0x52e2c6db923124e646011d172dea644e1cafe583'], }, mumbai: { threshold: 1, - validators: ['0xb537c4ce34e1cad718be52aa30b095e416eae46a'], + validators: ['0x7fc2981964427f09e317eda559f506bfd37f1ccb'], }, bsctestnet: { threshold: 1, - validators: ['0x77f80ef5b18977e15d81aea8dd3a88e7df4bc0eb'], + validators: ['0x6353c7402626054c824bd0eca721f82b725e2b4d'], }, goerli: { threshold: 1, - validators: ['0x9597ddb4ad2af237665559574b820596bb77ae7a'], + validators: ['0x6b32af7592948cbec6893363f77c08252d0ce0d7'], + }, + scrollsepolia: { + threshold: 1, + validators: ['0x50d939d66f114350f322eb8b2e9f01fbc401d4c9'], }, sepolia: { threshold: 1, - validators: ['0x183f15924f3a464c54c9393e8d268eb44d2b208c'], + validators: ['0x49f253c0dab33be1573d6c2769b3d9e584d91f82'], }, moonbasealpha: { threshold: 1, - validators: ['0xbeaf158f85d7b64ced36b8aea0bbc4cd0f2d1a5d'], + validators: ['0x376260b40b2ba2100890f27de1eb18a2774f54d1'], }, optimismgoerli: { threshold: 1, - validators: ['0x1d6798671ac532f2bf30c3a5230697a4695705e4'], + validators: ['0xed4cf9bf144457c927d7a39613c812c53f296283'], }, arbitrumgoerli: { threshold: 1, - validators: ['0x6d13367c7cd713a4ea79a2552adf824bf1ecdd5e'], + validators: ['0x869f67e89b5c0826a3c2f2ba72e6ae1d8a1952ff'], + }, + polygonzkevmtestnet: { + threshold: 1, + validators: ['0x2d0214068e5d8e49c638b5a4c70c75080204be21'], }, }; diff --git a/typescript/infra/helm/helloworld-kathy/values.yaml b/typescript/infra/helm/helloworld-kathy/values.yaml index 3c4b9519da..a6a75048f2 100644 --- a/typescript/infra/helm/helloworld-kathy/values.yaml +++ b/typescript/infra/helm/helloworld-kathy/values.yaml @@ -2,7 +2,7 @@ image: repository: gcr.io/hyperlane-labs-dev/hyperlane-monorepo tag: hyperlane: - runEnv: testnet3 + runEnv: testnet4 context: hyperlane # Only used for fetching secrets, so all chains should be included regardless of being skipped chains: [] @@ -10,10 +10,10 @@ hyperlane: chainsToSkip: [] cycleOnce: false cronjob: - schedule: "0 * * * *" + schedule: '0 * * * *' successfulJobsHistoryLimit: 3 failedJobsHistoryLimit: 3 externalSecrets: clusterSecretStore: -nameOverride: "" -fullnameOverride: "" +nameOverride: '' +fullnameOverride: '' diff --git a/typescript/infra/helm/liquidity-layer-relayers/values.yaml b/typescript/infra/helm/liquidity-layer-relayers/values.yaml index 6fc46fb5e6..95651f852a 100644 --- a/typescript/infra/helm/liquidity-layer-relayers/values.yaml +++ b/typescript/infra/helm/liquidity-layer-relayers/values.yaml @@ -2,7 +2,7 @@ image: repository: gcr.io/abacus-labs-dev/hyperlane-monorepo tag: abacus: - runEnv: testnet3 + runEnv: testnet4 # Used for fetching secrets chains: [] externalSecrets: diff --git a/typescript/infra/scripts/announce-validators.ts b/typescript/infra/scripts/announce-validators.ts index 7e14ea6652..6df8e3e15f 100644 --- a/typescript/infra/scripts/announce-validators.ts +++ b/typescript/infra/scripts/announce-validators.ts @@ -22,7 +22,7 @@ function getArgs() { .choices('chain', AllChains) .describe( 'location', - 'location, e.g. s3://hyperlane-testnet3-goerli-validator-0/us-east-1', + 'location, e.g. s3://hyperlane-testnet4-goerli-validator-0/us-east-1', ) .string('location') .check(({ context, chain, location }) => { diff --git a/typescript/infra/scripts/deploy.ts b/typescript/infra/scripts/deploy.ts index bd52c0625a..b9ed4d1f75 100644 --- a/typescript/infra/scripts/deploy.ts +++ b/typescript/infra/scripts/deploy.ts @@ -50,7 +50,7 @@ async function main() { // TODO: make this more generic const deployerAddress = - environment === 'testnet3' + environment === 'testnet4' ? '0xfaD1C94469700833717Fa8a3017278BC1cA8031C' : '0xa7ECcdb9Be08178f896c26b7BbD8C3D4E844d9Ba'; diff --git a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts index c93ca3057e..988a2f9e5e 100644 --- a/typescript/infra/scripts/funding/fund-keys-from-deployer.ts +++ b/typescript/infra/scripts/funding/fund-keys-from-deployer.ts @@ -108,6 +108,12 @@ const desiredBalancePerChain: ChainMap = { optimismgoerli: '0.5', arbitrumgoerli: '0.5', gnosis: '0.1', + basegoerli: '0.05', + scrollsepolia: '0.05', + lineagoerli: '0.1', + polygonzkevmtestnet: '0.01', + chiado: '0.0001', + // unused test1: '0', test2: '0', @@ -169,7 +175,7 @@ const igpClaimThresholdPerChain: ChainMap = { // context provided in --contexts-and-roles, which requires the appropriate credentials. // // Example usage: -// ts-node ./scripts/funding/fund-keys-from-deployer.ts -e testnet3 --context hyperlane --contexts-and-roles rc=relayer +// ts-node ./scripts/funding/fund-keys-from-deployer.ts -e testnet4 --context hyperlane --contexts-and-roles rc=relayer async function main() { const { environment, ...argv } = await getArgs() .string('f') diff --git a/typescript/infra/scripts/helloworld/kathy.ts b/typescript/infra/scripts/helloworld/kathy.ts index 7cbc208d4b..9aeeaaccbc 100644 --- a/typescript/infra/scripts/helloworld/kathy.ts +++ b/typescript/infra/scripts/helloworld/kathy.ts @@ -31,7 +31,7 @@ import { Contexts } from '../../config/contexts'; import { hyperlaneHelloworld, releaseCandidateHelloworld, -} from '../../config/environments/testnet3/helloworld'; +} from '../../config/environments/testnet4/helloworld'; import { CloudAgentKey } from '../../src/agents/keys'; import { DeployEnvironment } from '../../src/config/environment'; import { Role } from '../../src/roles'; diff --git a/typescript/infra/scripts/helloworld/utils.ts b/typescript/infra/scripts/helloworld/utils.ts index d71480cd19..489e22e99d 100644 --- a/typescript/infra/scripts/helloworld/utils.ts +++ b/typescript/infra/scripts/helloworld/utils.ts @@ -69,7 +69,7 @@ export async function getHelloWorldMultiProtocolApp( const multiProtocolProvider = MultiProtocolProvider.fromMultiProvider(multiProvider); // Hacking around infra code limitations, we may need to add solana manually - // because the it's not in typescript/infra/config/environments/testnet3/chains.ts + // because the it's not in typescript/infra/config/environments/testnet4/chains.ts // Adding it there breaks many things if (!multiProtocolProvider.getKnownChainNames().includes('solanadevnet')) { multiProtocolProvider.addChain(chainMetadata.solanadevnet); diff --git a/typescript/infra/scripts/middleware/portal-relayer.ts b/typescript/infra/scripts/middleware/portal-relayer.ts index 3b46d9e835..bb2d7f9749 100644 --- a/typescript/infra/scripts/middleware/portal-relayer.ts +++ b/typescript/infra/scripts/middleware/portal-relayer.ts @@ -7,7 +7,7 @@ import { } from '@hyperlane-xyz/sdk'; import { error, log } from '@hyperlane-xyz/utils'; -import { bridgeAdapterConfigs } from '../../config/environments/testnet3/token-bridge'; +import { bridgeAdapterConfigs } from '../../config/environments/testnet4/token-bridge'; import { readJSON, sleep } from '../../src/utils/utils'; import { getArgs, diff --git a/typescript/infra/src/config/environment.ts b/typescript/infra/src/config/environment.ts index e702dabb56..a99e87b4bf 100644 --- a/typescript/infra/src/config/environment.ts +++ b/typescript/infra/src/config/environment.ts @@ -64,5 +64,5 @@ export const deployEnvToSdkEnv: Record< > = { test: 'testnet', // TODO: remove this mainnet2: 'mainnet', - testnet3: 'testnet', + testnet4: 'testnet', }; diff --git a/typescript/infra/src/funding/key-funder.ts b/typescript/infra/src/funding/key-funder.ts index 68de1e7433..8f4c8a67f8 100644 --- a/typescript/infra/src/funding/key-funder.ts +++ b/typescript/infra/src/funding/key-funder.ts @@ -9,7 +9,6 @@ export async function runKeyFunderHelmCommand( keyFunderConfig: KeyFunderConfig, ) { const values = getKeyFunderHelmValues(agentConfig, keyFunderConfig); - if (helmCommand === HelmCommand.InstallOrUpgrade) { // Delete secrets to avoid them being stale try { @@ -45,7 +44,7 @@ function getKeyFunderHelmValues( hyperlane: { runEnv: agentConfig.runEnv, // Only used for fetching RPC urls as env vars - chains: agentConfig.contextChainNames, + chains: agentConfig.contextChainNames.relayer, // temporary hack contextFundingFrom: keyFunderConfig.contextFundingFrom, contextsAndRolesToFund: keyFunderConfig.contextsAndRolesToFund, connectionType: keyFunderConfig.connectionType, diff --git a/typescript/sdk/src/consts/chainMetadata.ts b/typescript/sdk/src/consts/chainMetadata.ts index 78aa6c1c1a..b0f995bce0 100644 --- a/typescript/sdk/src/consts/chainMetadata.ts +++ b/typescript/sdk/src/consts/chainMetadata.ts @@ -135,6 +135,33 @@ export const avalanche: ChainMetadata = { 'https://safe-transaction-avalanche.safe.global/', }; +export const basegoerli: ChainMetadata = { + chainId: 84531, + domainId: 84531, + name: Chains.basegoerli, + protocol: ProtocolType.Ethereum, + displayName: 'Base Goerli', + nativeToken: etherToken, + rpcUrls: [ + { http: 'https://base-goerli.publicnode.com' }, + { http: 'https://goerli.base.org' }, + ], + blockExplorers: [ + { + name: 'BaseScan', + url: 'https://goerli.basescan.org', + apiUrl: 'https://api-goerli.basescan.org/api', + family: ExplorerFamily.Etherscan, + }, + ], + blocks: { + confirmations: 1, + reorgPeriod: 1, + estimateBlockTime: 3, + }, + isTestnet: true, +}; + export const bsc: ChainMetadata = { chainId: 56, domainId: 56, @@ -188,6 +215,30 @@ export const bsctestnet: ChainMetadata = { isTestnet: true, }; +export const chiado: ChainMetadata = { + chainId: 10200, + domainId: 10200, + name: Chains.chiado, + protocol: ProtocolType.Ethereum, + displayName: 'Chiado', + nativeToken: xDaiToken, + rpcUrls: [{ http: 'https://gnosis-chiado.publicnode.com' }], + blockExplorers: [ + { + name: 'GnosisScan', + url: 'https://gnosis-chiado.blockscout.com', + apiUrl: 'https://gnosis-chiado.blockscout.com/api', + family: ExplorerFamily.Blockscout, + }, + ], + blocks: { + confirmations: 1, + reorgPeriod: 14, + estimateBlockTime: 5, + }, + isTestnet: true, +}; + export const celo: ChainMetadata = { chainId: 42220, domainId: 42220, @@ -309,6 +360,30 @@ export const goerli: ChainMetadata = { isTestnet: true, }; +export const lineagoerli: ChainMetadata = { + chainId: 59140, + domainId: 59140, + name: Chains.lineagoerli, + protocol: ProtocolType.Ethereum, + displayName: 'Linea Goerli', + nativeToken: etherToken, + rpcUrls: [{ http: 'https://rpc.goerli.linea.build' }], + blockExplorers: [ + { + name: 'Linea Explorer', + url: 'https://explorer.goerli.linea.build/', + apiUrl: 'https://explorer.goerli.linea.build/api', + family: ExplorerFamily.Blockscout, + }, + ], + blocks: { + confirmations: 1, + reorgPeriod: 2, + estimateBlockTime: 12, + }, + isTestnet: true, +}; + export const sepolia: ChainMetadata = { chainId: 11155111, domainId: 11155111, @@ -333,6 +408,33 @@ export const sepolia: ChainMetadata = { isTestnet: true, }; +export const scrollsepolia: ChainMetadata = { + chainId: 534351, + domainId: 534351, + name: Chains.scrollsepolia, + protocol: ProtocolType.Ethereum, + displayName: 'Scroll Sepolia', + nativeToken: etherToken, + rpcUrls: [ + { http: 'https://sepolia-rpc.scroll.io' }, + { http: 'https://scroll-public.scroll-testnet.quiknode.pro' }, + ], + blockExplorers: [ + { + name: 'Scroll Explorer', + url: 'https://sepolia-blockscout.scroll.io', + apiUrl: 'https://sepolia-blockscout.scroll.io/api', + family: ExplorerFamily.Blockscout, + }, + ], + blocks: { + confirmations: 1, + reorgPeriod: 1, + estimateBlockTime: 3, + }, + isTestnet: true, +}; + export const moonbasealpha: ChainMetadata = { chainId: 1287, domainId: 1287, @@ -728,6 +830,30 @@ export const solanadevnet: ChainMetadata = { isTestnet: true, }; +export const polygonzkevmtestnet: ChainMetadata = { + protocol: ProtocolType.Ethereum, + chainId: 1442, + domainId: 1442, + name: Chains.polygonzkevmtestnet, + displayName: 'Polygon zkEVM Testnet', + nativeToken: etherToken, + rpcUrls: [{ http: 'https://rpc.public.zkevm-test.net' }], + blockExplorers: [ + { + name: 'PolygonScan', + url: 'https://testnet-zkevm.polygonscan.com/', + apiUrl: 'https://api-testnet-zkevm.polygonscan.com/api', + family: ExplorerFamily.Etherscan, + }, + ], + blocks: { + confirmations: 1, + reorgPeriod: 1, + estimateBlockTime: 3, + }, + isTestnet: true, +}; + /** * Collection maps * @@ -739,12 +865,16 @@ export const chainMetadata: ChainMap = { arbitrum, arbitrumgoerli, avalanche, + basegoerli, bsc, bsctestnet, + chiado, celo, ethereum, fuji, goerli, + lineagoerli, + scrollsepolia, sepolia, moonbasealpha, moonbeam, @@ -752,6 +882,7 @@ export const chainMetadata: ChainMap = { optimism, optimismgoerli, polygon, + polygonzkevmtestnet, gnosis, proteustestnet, test1, diff --git a/typescript/sdk/src/consts/chains.ts b/typescript/sdk/src/consts/chains.ts index 20dea0674c..5f9085aa62 100644 --- a/typescript/sdk/src/consts/chains.ts +++ b/typescript/sdk/src/consts/chains.ts @@ -7,27 +7,32 @@ export enum Chains { arbitrum = 'arbitrum', arbitrumgoerli = 'arbitrumgoerli', avalanche = 'avalanche', + basegoerli = 'basegoerli', bsc = 'bsc', bsctestnet = 'bsctestnet', celo = 'celo', + chiado = 'chiado', ethereum = 'ethereum', fuji = 'fuji', + gnosis = 'gnosis', goerli = 'goerli', + lineagoerli = 'lineagoerli', + scrollsepolia = 'scrollsepolia', sepolia = 'sepolia', moonbasealpha = 'moonbasealpha', moonbeam = 'moonbeam', mumbai = 'mumbai', + nautilus = 'nautilus', optimism = 'optimism', optimismgoerli = 'optimismgoerli', polygon = 'polygon', - gnosis = 'gnosis', + polygonzkevmtestnet = 'polygonzkevmtestnet', + proteustestnet = 'proteustestnet', + solana = 'solana', + solanadevnet = 'solanadevnet', test1 = 'test1', test2 = 'test2', test3 = 'test3', - solanadevnet = 'solanadevnet', - proteustestnet = 'proteustestnet', - solana = 'solana', - nautilus = 'nautilus', } export type CoreChainName = keyof typeof Chains; @@ -58,12 +63,17 @@ export const Mainnets: Array = [ export const Testnets: Array = [ Chains.alfajores, Chains.arbitrumgoerli, + Chains.basegoerli, Chains.bsctestnet, + Chains.chiado, Chains.fuji, + Chains.lineagoerli, Chains.goerli, Chains.moonbasealpha, Chains.mumbai, Chains.optimismgoerli, + Chains.polygonzkevmtestnet, + Chains.scrollsepolia, Chains.sepolia, ]; diff --git a/typescript/sdk/src/consts/multisigIsm.ts b/typescript/sdk/src/consts/multisigIsm.ts index 805c3ae07b..1bdf0ea008 100644 --- a/typescript/sdk/src/consts/multisigIsm.ts +++ b/typescript/sdk/src/consts/multisigIsm.ts @@ -102,73 +102,114 @@ export const defaultMultisigIsmConfigs: ChainMap = { alfajores: { threshold: 2, validators: [ - '0xe6072396568e73ce6803b12b7e04164e839f1e54', - '0x9f177f51289b22515f41f95872e1511391b8e105', - '0x15f77400845eb1c971ad08de050861d5508cad6c', + '0x2233a5ce12f814bd64c9cdd73410bb8693124d40', + '0xba279f965489d90f90490e3c49e860e0b43c2ae6', + '0x86485dcec5f7bb8478dd251676372d054dea6653', + ], + }, + basegoerli: { + threshold: 2, + validators: [ + '0xf6eddda696dcd3bf10f7ce8a02db31ef2e775a03', + '0x5a7d05cebf5db4dde9b2fedcefa76fb58fa05071', + '0x9260a6c7d54cbcbed28f8668679cd1fa3a203b25', ], }, fuji: { threshold: 2, validators: [ - '0x9fa19ead5ec76e437948b35e227511b106293c40', - '0x227e7d6507762ece0c94678f8c103eff9d682476', - '0x2379e43740e4aa4fde48cf4f00a3106df1d8420d', + '0xd8154f73d04cc7f7f0c332793692e6e6f6b2402e', + '0x895ae30bc83ff1493b9cf7781b0b813d23659857', + '0x43e915573d9f1383cbf482049e4a012290759e7f', + ], + }, + chiado: { + threshold: 2, + validators: [ + '0x06c3757a4b7a912828e523bb8a5f980ddc297356', + '0x0874967a145d70b799ebe9ed861ab7c93faef95a', + '0xd767ea1206b8295d7e1267ddd00e56d34f278db6', + ], + }, + lineagoerli: { + threshold: 2, + validators: [ + '0xd767ea1206b8295d7e1267ddd00e56d34f278db6', + '0x4a5d7085ca93c22fbc994dd97857c98fcc745674', + '0x8327779c3c31fa1ffc7f0c9ffae33e4d804bbd8f', ], }, mumbai: { threshold: 2, validators: [ - '0x0a664ea799447da6b15645cf8b9e82072a68343f', - '0x6ae6f12929a960aba24ba74ea310e3d37d0ac045', - '0x51f70c047cd73bc7873273707501568857a619c4', + '0xebc301013b6cd2548e347c28d2dc43ec20c068f2', + '0x315db9868fc8813b221b1694f8760ece39f45447', + '0x17517c98358c5937c5d9ee47ce1f5b4c2b7fc9f5', ], }, bsctestnet: { threshold: 2, validators: [ - '0x23338c8714976dd4a57eaeff17cbd26d7e275c08', - '0x85a618d7450ebc37e0d682371f08dac94eec7a76', - '0x95b76562e4ba1791a27ba4236801271c9115b141', + '0x242d8a855a8c932dec51f7999ae7d1e48b10c95e', + '0xf620f5e3d25a3ae848fec74bccae5de3edcd8796', + '0x1f030345963c54ff8229720dd3a711c15c554aeb', ], }, goerli: { threshold: 2, validators: [ - '0xf43fbd072fd38e1121d4b3b0b8a35116bbb01ea9', - '0xa33020552a21f35e75bd385c6ab95c3dfa82d930', - '0x0bba4043ff242f8bf3f39bafa8930a84d644d947', + '0x05a9b5efe9f61f9142453d8e9f61565f333c6768', + '0x43a96c7dfbd8187c95013d6ee8665650cbdb2673', + '0x7940a12c050e24e1839c21ecb12f65afd84e8c5b', + ], + }, + scrollsepolia: { + threshold: 2, + validators: [ + '0xbe18dbd758afb367180260b524e6d4bcd1cb6d05', + '0x9a11ed23ae962974018ab45bc133caabff7b3271', + '0x7867bea3c9761fe64e6d124b171f91fd5dd79644', ], }, sepolia: { threshold: 2, validators: [ - '0xbc748ee311f5f2d1975d61cdf531755ce8ce3066', - '0xc4233b2bfe5aec08964a94b403052abb3eafcf07', - '0x6b36286c19f5c10bdc139ea9ee7f82287303f61d', + '0xb22b65f202558adf86a8bb2847b76ae1036686a5', + '0x469f0940684d147defc44f3647146cb90dd0bc8e', + '0xd3c75dcf15056012a4d74c483a0c6ea11d8c2b83', ], }, moonbasealpha: { threshold: 2, validators: [ - '0x890c2aeac157c3f067f3e42b8afc797939c59a32', - '0x1b06d6fe69b972ed7420c83599d5a5c0fc185904', - '0xe70b85206a968a99a597581f0fa09c99e7681093', + '0x521877064bd7ac7500d300f162c8c47c256a2f9c', + '0xbc1c70f58ae0459d4b8a013245420a893837d568', + '0x01e42c2c44af81dda1ac16fec76fea2a7a54a44c', ], }, optimismgoerli: { threshold: 2, validators: [ - '0xbb8d77eefbecc55db6e5a19b0fc3dc290776f189', - '0x69792508b4ddaa3ca52241ccfcd1e0b119a1ee65', - '0x11ddb46c6b653e0cdd7ad5bee32ae316e18f8453', + '0x79e58546e2faca865c6732ad5f6c4951051c4d67', + '0x7bbfe1bb7146aad7df309c637987d856179ebbc1', + '0xf3d2fb4d53c2bb6a88cec040e0d87430fcee4e40', ], }, arbitrumgoerli: { threshold: 2, validators: [ - '0xce798fa21e323f6b24d9838a10ffecdefdfc4f30', - '0xa792d39dca4426927e0f00c1618d61c9cb41779d', - '0xdf181fcc11dfac5d01467e4547101a856dd5aa04', + '0x071c8d135845ae5a2cb73f98d681d519014c0a8b', + '0x1bcf03360989f15cbeb174c188288f2c6d2760d7', + '0xc1590eaaeaf380e7859564c5ebcdcc87e8369e0d', + ], + }, + + polygonzkevmtestnet: { + threshold: 2, + validators: [ + '0x3f06b725bc9648917eb11c414e9f8d76fd959550', + '0x27bfc57679d9dd4ab2e870f5ed7ec0b339a0b636', + '0xd476548222f43206d0abaa30e46e28670aa7859c', ], }, };