Minor fixes to get LL deploys running smoothly (#2125)

### Description

This PR makes some minor modifications to the deployment structure for
the Liquidity Layer. The most important thing is the embedding of the
`proxyAdmin` addresses in the LL addresses file which is not pretty, but
I did not want to put it in the SDK right now either, but could be
convinced.

In the process of running this, the LL router IGPs have been updated
which is non-material, but otherwise the deploy script runs as a no-op
now.
pull/2167/head
Nam Chu Hoai 2 years ago committed by GitHub
parent 35bcd97805
commit 482c8e77f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      typescript/infra/config/environments/testnet3/index.ts
  2. 0
      typescript/infra/config/environments/testnet3/liquidityLayer.ts
  3. 15
      typescript/infra/config/environments/testnet3/middleware/liquidity-layer/addresses.json
  4. 12
      typescript/infra/scripts/deploy.ts
  5. 19
      typescript/infra/scripts/middleware/circle-relayer.ts
  6. 6
      typescript/infra/src/config/environment.ts
  7. 2
      typescript/infra/src/middleware/liquidity-layer-relayer.ts
  8. 4
      typescript/sdk/src/deploy/HyperlaneDeployer.ts
  9. 51
      typescript/sdk/src/middleware/liquidity-layer/LiquidityLayerRouterDeployer.ts
  10. 2
      typescript/sdk/src/router/HyperlaneRouterDeployer.ts
  11. 12
      typescript/sdk/src/router/ProxiedRouterDeployer.ts

@ -13,6 +13,7 @@ import { storageGasOracleConfig } from './gas-oracle';
import { helloWorld } from './helloworld';
import { igp } from './igp';
import { infrastructure } from './infrastructure';
import { bridgeAdapterConfigs } from './liquidityLayer';
import { liquidityLayerRelayerConfig } from './middleware';
import { owners } from './owners';
@ -39,6 +40,9 @@ export const environment: EnvironmentConfig = {
helloWorld,
owners,
keyFunderConfig,
liquidityLayerRelayerConfig,
liquidityLayerConfig: {
bridgeAdapters: bridgeAdapterConfigs,
relayer: liquidityLayerRelayerConfig,
},
storageGasOracleConfig,
};

@ -2,23 +2,28 @@
"goerli": {
"circleBridgeAdapter": "0xfe9d88aA85c5917822C804b949BcEDE832C02ce2",
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
"proxyAdmin": "0x8f919348F9C4619A196Acb5e377f49E5E2C0B569",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
},
"fuji": {
"circleBridgeAdapter": "0xfe9d88aA85c5917822C804b949BcEDE832C02ce2",
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
"proxyAdmin": "0x13474f85b808034C911B7697dee60B7d8d50ee36",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
},
"mumbai": {
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
"proxyAdmin": "0x96b49e136581f8dfF370aDB3015D48465572a318",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
},
"bsctestnet": {
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
"proxyAdmin": "0xfB149BC17dD3FE858fA64D678bA0c706DEac61eE",
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
},
"alfajores": {
"portalAdapter": "0x68D753982e89CC083917863F6dc9738448B91ef9",
"router": "0x2abe0860D81FB4242C748132bD69D125D88eaE26"
"liquidityLayerRouter": "0x2abe0860D81FB4242C748132bD69D125D88eaE26",
"proxyAdmin": "0x4e4D563e2cBFC35c4BC16003685443Fae2FA702f"
}
}

@ -14,7 +14,6 @@ import {
objMap,
} from '@hyperlane-xyz/sdk';
import { bridgeAdapterConfigs } from '../config/environments/test/liquidityLayer';
import { deployEnvToSdkEnv } from '../src/config/environment';
import { deployWithArtifacts } from '../src/deploy';
import { TestQuerySenderDeployer } from '../src/testcontracts/testquerysender';
@ -73,12 +72,17 @@ async function main() {
config = await getRouterConfig(environment, multiProvider);
deployer = new InterchainQueryDeployer(multiProvider);
} else if (module === Modules.LIQUIDITY_LAYER) {
deployer = new LiquidityLayerDeployer(multiProvider);
const routerConfig = await getRouterConfig(environment, multiProvider);
config = objMap(bridgeAdapterConfigs, (chain, conf) => ({
if (!envConfig.liquidityLayerConfig) {
throw new Error(`No liquidity layer config for ${environment}`);
}
config = objMap(
envConfig.liquidityLayerConfig.bridgeAdapters,
(chain, conf) => ({
...conf,
...routerConfig[chain],
}));
}),
);
deployer = new LiquidityLayerDeployer(multiProvider);
} else if (module === Modules.TEST_RECIPIENT) {
deployer = new TestRecipientDeployer(multiProvider);

@ -1,13 +1,13 @@
import path from 'path';
import {
Chains,
LiquidityLayerApp,
attachContractsMap,
liquidityLayerFactories,
objFilter,
} from '@hyperlane-xyz/sdk';
import { LiquidityLayerConfig } from '@hyperlane-xyz/sdk/dist/middleware/liquidity-layer/LiquidityLayerRouterDeployer';
import { bridgeAdapterConfigs } from '../../config/environments/testnet3/token-bridge';
import { readJSON, sleep } from '../../src/utils/utils';
import {
getEnvironment,
@ -18,6 +18,11 @@ import {
async function check() {
const environment = await getEnvironment();
const config = getEnvironmentConfig(environment);
if (config.liquidityLayerConfig === undefined) {
throw new Error(`No liquidity layer config found for ${environment}`);
}
const multiProvider = await config.getMultiProvider();
const dir = path.join(
__dirname,
@ -27,14 +32,20 @@ async function check() {
);
const addresses = readJSON(dir, 'addresses.json');
const contracts = attachContractsMap(addresses, liquidityLayerFactories);
const app = new LiquidityLayerApp(
contracts,
multiProvider,
bridgeAdapterConfigs,
config.liquidityLayerConfig.bridgeAdapters,
);
while (true) {
for (const chain of [Chains.goerli, Chains.fuji]) {
for (const chain of Object.keys(
objFilter(
config.liquidityLayerConfig.bridgeAdapters,
(_, config): config is LiquidityLayerConfig => !!config.circle,
),
)) {
const txHashes = await app.fetchCircleMessageTransactions(chain);
const circleDispatches = (

@ -1,5 +1,6 @@
import {
AgentConnectionType,
BridgeAdapterConfig,
ChainMap,
ChainMetadata,
ChainName,
@ -44,7 +45,10 @@ export type EnvironmentConfig = {
) => Promise<MultiProvider>;
helloWorld?: Partial<Record<Contexts, HelloWorldConfig>>;
keyFunderConfig?: KeyFunderConfig;
liquidityLayerRelayerConfig?: LiquidityLayerRelayerConfig;
liquidityLayerConfig?: {
bridgeAdapters: ChainMap<BridgeAdapterConfig>;
relayer: LiquidityLayerRelayerConfig;
};
storageGasOracleConfig?: AllStorageGasOracleConfigs;
};

@ -59,7 +59,7 @@ function getLiquidityLayerRelayerHelmValues(
export function getLiquidityLayerRelayerConfig(
coreConfig: EnvironmentConfig,
): LiquidityLayerRelayerConfig {
const relayerConfig = coreConfig.liquidityLayerRelayerConfig;
const relayerConfig = coreConfig.liquidityLayerConfig?.relayer;
if (!relayerConfig) {
throw new Error(
`Environment ${coreConfig.environment} does not have a LiquidityLayerRelayerConfig config`,

@ -148,7 +148,9 @@ export abstract class HyperlaneDeployer<
connectionClient: HyperlaneConnectionClient,
config: ConnectionClientConfig,
): Promise<void> {
this.logger(`Initializing connection client on ${local}...`);
this.logger(
`Initializing connection client (if not already) on ${local}...`,
);
await this.runIfOwner(local, connectionClient, async () => {
// set mailbox if not already set (and configured)
if (config.mailbox !== (await connectionClient.mailbox())) {

@ -12,7 +12,7 @@ import { MultiProvider } from '../../providers/MultiProvider';
import { ProxiedRouterDeployer } from '../../router/ProxiedRouterDeployer';
import { RouterConfig } from '../../router/types';
import { ChainMap, ChainName } from '../../types';
import { objMap } from '../../utils/objects';
import { objFilter, objMap } from '../../utils/objects';
import { LiquidityLayerFactories, liquidityLayerFactories } from './contracts';
@ -93,18 +93,32 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
this.logger(`Enroll CircleBridgeAdapters with each other`);
// Hack to allow use of super.enrollRemoteRouters
await super.enrollRemoteRouters(
objMap(contractsMap, (_, contracts) => ({
objMap(
objFilter(
contractsMap,
(_, c): c is HyperlaneContracts<LiquidityLayerFactories> =>
!!c.circleBridgeAdapter,
),
(_, contracts) => ({
liquidityLayerRouter: contracts.circleBridgeAdapter,
})) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>,
}),
) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>,
configMap,
);
this.logger(`Enroll PortalAdapters with each other`);
// Hack to allow use of super.enrollRemoteRouters
await super.enrollRemoteRouters(
objMap(contractsMap, (_, contracts) => ({
objMap(
objFilter(
contractsMap,
(_, c): c is HyperlaneContracts<LiquidityLayerFactories> =>
!!c.portalAdapter,
),
(_, contracts) => ({
liquidityLayerRouter: contracts.portalAdapter,
})) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>,
}),
) as unknown as HyperlaneContractsMap<LiquidityLayerFactories>,
configMap,
);
}
@ -115,6 +129,9 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
chain: ChainName,
config: LiquidityLayerConfig,
): Promise<HyperlaneContracts<LiquidityLayerFactories>> {
// This is just the temp owner for contracts, and HyperlaneRouterDeployer#transferOwnership actually sets the configured owner
const deployer = await this.multiProvider.getSignerAddress(chain);
const routerContracts = await super.deployContracts(chain, config);
const bridgeAdapters: Partial<
@ -125,7 +142,7 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
bridgeAdapters.circleBridgeAdapter = await this.deployCircleBridgeAdapter(
chain,
config.circle,
config.owner,
deployer,
routerContracts.liquidityLayerRouter,
);
}
@ -133,7 +150,7 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
bridgeAdapters.portalAdapter = await this.deployPortalAdapter(
chain,
config.portal,
config.owner,
deployer,
routerContracts.liquidityLayerRouter,
);
}
@ -173,9 +190,11 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
this.logger(
`Set wormhole domain ${wormholeDomain} for hyperlane domain ${hyperlaneDomain}`,
);
await this.multiProvider.handleTx(
await this.runIfOwner(chain, portalAdapter, () =>
this.multiProvider.handleTx(
chain,
portalAdapter.addDomain(hyperlaneDomain, wormholeDomain),
),
);
}
@ -186,12 +205,14 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
)
) {
this.logger('Set Portal as LiquidityLayerAdapter on Router');
await this.multiProvider.handleTx(
await this.runIfOwner(chain, portalAdapter, () =>
this.multiProvider.handleTx(
chain,
router.setLiquidityLayerAdapter(
adapterConfig.type,
portalAdapter.address,
),
),
);
}
@ -223,9 +244,11 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
)
) {
this.logger(`Set USDC token contract`);
await this.multiProvider.handleTx(
await this.runIfOwner(chain, circleBridgeAdapter, () =>
this.multiProvider.handleTx(
chain,
circleBridgeAdapter.addToken(adapterConfig.usdcAddress, 'USDC'),
),
);
}
// Set domain mappings
@ -242,9 +265,11 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
this.logger(
`Set circle domain ${circleDomain} for hyperlane domain ${hyperlaneDomain}`,
);
await this.multiProvider.handleTx(
await this.runIfOwner(chain, circleBridgeAdapter, () =>
this.multiProvider.handleTx(
chain,
circleBridgeAdapter.addDomain(hyperlaneDomain, circleDomain),
),
);
}
@ -255,12 +280,14 @@ export class LiquidityLayerDeployer extends ProxiedRouterDeployer<
)
) {
this.logger('Set Circle as LiquidityLayerAdapter on Router');
await this.multiProvider.handleTx(
await this.runIfOwner(chain, circleBridgeAdapter, () =>
this.multiProvider.handleTx(
chain,
router.setLiquidityLayerAdapter(
adapterConfig.type,
circleBridgeAdapter.address,
),
),
);
}

@ -115,7 +115,7 @@ export abstract class HyperlaneRouterDeployer<
// skip if no enrollments are needed
if (domains.length === 0) {
return;
continue;
}
await super.runIfOwner(chain, this.router(contracts), async () => {

@ -1,4 +1,5 @@
import { Router } from '@hyperlane-xyz/core';
import { eqAddress } from '@hyperlane-xyz/utils/dist/src/utils';
import { HyperlaneContracts } from '../contracts';
import { ChainName } from '../types';
@ -50,13 +51,18 @@ export abstract class ProxiedRouterDeployer<
await this.initializeArgs(chain, config),
);
await super.runIfOwner(chain, proxyAdmin, async () => {
this.logger(`Checking ownership of proxy admin to ${config.owner}`);
if (!eqAddress(await proxyAdmin.owner(), config.owner)) {
this.logger(`Transferring ownership of proxy admin to ${config.owner}`);
await super.runIfOwner(chain, proxyAdmin, () =>
this.multiProvider.handleTx(
return this.multiProvider.handleTx(
chain,
proxyAdmin.transferOwnership(config.owner),
),
);
}
return;
});
return {
[this.routerContractName]: proxiedRouter,

Loading…
Cancel
Save