feat(infra): supporting generating warp configs for EVM routes (#4248)
### Description - Add in code configs for EVM base warp routes - Allow checker tooling (check-deploy) to read and run against the config - Read Warp addresses from registry when run check-deploy for warp modules ### Drive-by changes - clean up ISM config comparison violation message to handle ISM addressed ### Related issues <!-- - Fixes #[issue number here] --> ### Backward compatibility Yes ### Testing Manualpull/4292/head
parent
021f4bf97d
commit
72aa438e27
@ -0,0 +1,49 @@ |
|||||||
|
import { ethers } from 'ethers'; |
||||||
|
|
||||||
|
import { |
||||||
|
ChainMap, |
||||||
|
RouterConfig, |
||||||
|
TokenRouterConfig, |
||||||
|
TokenType, |
||||||
|
buildAggregationIsmConfigs, |
||||||
|
defaultMultisigConfigs, |
||||||
|
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
import { tokens } from '../../../../../src/config/warp.js'; |
||||||
|
|
||||||
|
export const getAncient8EthereumUSDCWarpConfig = async ( |
||||||
|
routerConfig: ChainMap<RouterConfig>, |
||||||
|
): Promise<ChainMap<TokenRouterConfig>> => { |
||||||
|
const ismConfig = buildAggregationIsmConfigs( |
||||||
|
'ethereum', |
||||||
|
['ancient8'], |
||||||
|
defaultMultisigConfigs, |
||||||
|
).ancient8; |
||||||
|
|
||||||
|
const ethereum: TokenRouterConfig = { |
||||||
|
...routerConfig.ethereum, |
||||||
|
type: TokenType.collateral, |
||||||
|
token: tokens.ethereum.USDC, |
||||||
|
interchainSecurityModule: ismConfig, |
||||||
|
// This hook was recovered from running the deploy script
|
||||||
|
// for the hook module. The hook configuration is the Ethereum
|
||||||
|
// default hook for the Ancient8 remote (no routing).
|
||||||
|
hook: '0x19b2cF952b70b217c90FC408714Fbc1acD29A6A8', |
||||||
|
}; |
||||||
|
|
||||||
|
// @ts-ignore - The types as they stand require a synthetic to specify
|
||||||
|
// TokenMetadata, but in practice these are actually inferred from a
|
||||||
|
// collateral config. To avoid needing to specify the TokenMetadata, just
|
||||||
|
// ts-ignore for synthetic tokens.
|
||||||
|
const ancient8: TokenRouterConfig = { |
||||||
|
...routerConfig.ancient8, |
||||||
|
type: TokenType.synthetic, |
||||||
|
// Uses the default ISM
|
||||||
|
interchainSecurityModule: ethers.constants.AddressZero, |
||||||
|
}; |
||||||
|
|
||||||
|
return { |
||||||
|
ethereum, |
||||||
|
ancient8, |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,45 @@ |
|||||||
|
import { ethers } from 'ethers'; |
||||||
|
|
||||||
|
import { |
||||||
|
ChainMap, |
||||||
|
RouterConfig, |
||||||
|
TokenRouterConfig, |
||||||
|
TokenType, |
||||||
|
buildAggregationIsmConfigs, |
||||||
|
defaultMultisigConfigs, |
||||||
|
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
import { tokens } from '../../../../../src/config/warp.js'; |
||||||
|
|
||||||
|
export const getEthereumInevmUSDCWarpConfig = async ( |
||||||
|
routerConfig: ChainMap<RouterConfig>, |
||||||
|
): Promise<ChainMap<TokenRouterConfig>> => { |
||||||
|
// TODO: seems to be evidence that this ISM should have been set https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/3233/commits/dc8d50c9c49cdea8417fbe9dad090dc13f078fff
|
||||||
|
// checker tooling suggests that it has not been set zero address for ISM is being used
|
||||||
|
// run yarn tsx ./scripts/check-deploy.ts -e mainnet3 -f ethereum -m warp --warpRouteId USDC/ethereum-inevm
|
||||||
|
|
||||||
|
const ismConfig = buildAggregationIsmConfigs( |
||||||
|
'ethereum', |
||||||
|
['inevm'], |
||||||
|
defaultMultisigConfigs, |
||||||
|
).inevm; |
||||||
|
|
||||||
|
const ethereum: TokenRouterConfig = { |
||||||
|
...routerConfig.ethereum, |
||||||
|
type: TokenType.collateral, |
||||||
|
token: tokens.ethereum.USDC, |
||||||
|
hook: '0xb87AC8EA4533AE017604E44470F7c1E550AC6F10', // aggregation of IGP and Merkle, arbitrary config not supported for now
|
||||||
|
interchainSecurityModule: ismConfig, |
||||||
|
}; |
||||||
|
|
||||||
|
const inevm: TokenRouterConfig = { |
||||||
|
...routerConfig.inevm, |
||||||
|
type: TokenType.synthetic, |
||||||
|
interchainSecurityModule: ethers.constants.AddressZero, |
||||||
|
}; |
||||||
|
|
||||||
|
return { |
||||||
|
ethereum, |
||||||
|
inevm, |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,44 @@ |
|||||||
|
import { ethers } from 'ethers'; |
||||||
|
|
||||||
|
import { |
||||||
|
ChainMap, |
||||||
|
RouterConfig, |
||||||
|
TokenRouterConfig, |
||||||
|
TokenType, |
||||||
|
buildAggregationIsmConfigs, |
||||||
|
defaultMultisigConfigs, |
||||||
|
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
import { tokens } from '../../../../../src/config/warp.js'; |
||||||
|
|
||||||
|
export const getEthereumInevmUSDTWarpConfig = async ( |
||||||
|
routerConfig: ChainMap<RouterConfig>, |
||||||
|
): Promise<ChainMap<TokenRouterConfig>> => { |
||||||
|
// TODO: there may be evidence that this ISM should have been set https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/3233/commits/dc8d50c9c49cdea8417fbe9dad090dc13f078fff, although the USDC token address is being used in the commit
|
||||||
|
// checker tooling suggests that this ISM has not been set, zero address for ISM is being used
|
||||||
|
// run yarn tsx ./scripts/check-deploy.ts -e mainnet3 -f ethereum -m warp --warpRouteId USDT/ethereum-inevm
|
||||||
|
const ismConfig = buildAggregationIsmConfigs( |
||||||
|
'ethereum', |
||||||
|
['inevm'], |
||||||
|
defaultMultisigConfigs, |
||||||
|
).inevm; |
||||||
|
|
||||||
|
const ethereum: TokenRouterConfig = { |
||||||
|
...routerConfig.ethereum, |
||||||
|
type: TokenType.collateral, |
||||||
|
token: tokens.ethereum.USDT, |
||||||
|
hook: '0xb87AC8EA4533AE017604E44470F7c1E550AC6F10', |
||||||
|
interchainSecurityModule: ismConfig, |
||||||
|
}; |
||||||
|
|
||||||
|
const inevm: TokenRouterConfig = { |
||||||
|
...routerConfig.inevm, |
||||||
|
type: TokenType.synthetic, |
||||||
|
interchainSecurityModule: ethers.constants.AddressZero, |
||||||
|
}; |
||||||
|
|
||||||
|
return { |
||||||
|
ethereum, |
||||||
|
inevm, |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,40 @@ |
|||||||
|
import { |
||||||
|
ChainMap, |
||||||
|
RouterConfig, |
||||||
|
TokenRouterConfig, |
||||||
|
TokenType, |
||||||
|
buildAggregationIsmConfigs, |
||||||
|
defaultMultisigConfigs, |
||||||
|
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
export const getEthereumVictionETHWarpConfig = async ( |
||||||
|
routerConfig: ChainMap<RouterConfig>, |
||||||
|
): Promise<ChainMap<TokenRouterConfig>> => { |
||||||
|
const ismConfig = buildAggregationIsmConfigs( |
||||||
|
'ethereum', |
||||||
|
['viction'], |
||||||
|
defaultMultisigConfigs, |
||||||
|
).viction; |
||||||
|
|
||||||
|
const viction: TokenRouterConfig = { |
||||||
|
...routerConfig.viction, |
||||||
|
type: TokenType.synthetic, |
||||||
|
name: 'ETH', |
||||||
|
symbol: 'ETH', |
||||||
|
decimals: 18, |
||||||
|
totalSupply: 0, |
||||||
|
gas: 50_000, |
||||||
|
}; |
||||||
|
|
||||||
|
const ethereum: TokenRouterConfig = { |
||||||
|
...routerConfig.ethereum, |
||||||
|
type: TokenType.native, |
||||||
|
gas: 65_000, |
||||||
|
interchainSecurityModule: ismConfig, |
||||||
|
}; |
||||||
|
|
||||||
|
return { |
||||||
|
viction, |
||||||
|
ethereum, |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,44 @@ |
|||||||
|
import { |
||||||
|
ChainMap, |
||||||
|
RouterConfig, |
||||||
|
TokenRouterConfig, |
||||||
|
TokenType, |
||||||
|
buildAggregationIsmConfigs, |
||||||
|
defaultMultisigConfigs, |
||||||
|
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
import { tokens } from '../../../../../src/config/warp.js'; |
||||||
|
|
||||||
|
export const getEthereumVictionUSDCWarpConfig = async ( |
||||||
|
routerConfig: ChainMap<RouterConfig>, |
||||||
|
): Promise<ChainMap<TokenRouterConfig>> => { |
||||||
|
// commit that the config was copied from https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/3067/commits/7ed5b460034ea5e140c6ff86bcd6baf6ebb824c4#diff-fab5dd1a27c76e4310699c57ccf92ab6274ef0acf17e079b17270cedf4057775R109
|
||||||
|
const ismConfig = buildAggregationIsmConfigs( |
||||||
|
'ethereum', |
||||||
|
['viction'], |
||||||
|
defaultMultisigConfigs, |
||||||
|
).viction; |
||||||
|
|
||||||
|
const viction: TokenRouterConfig = { |
||||||
|
...routerConfig.viction, |
||||||
|
type: TokenType.synthetic, |
||||||
|
name: 'USDC', |
||||||
|
symbol: 'USDC', |
||||||
|
decimals: 18, |
||||||
|
totalSupply: 0, |
||||||
|
gas: 75_000, |
||||||
|
}; |
||||||
|
|
||||||
|
const ethereum: TokenRouterConfig = { |
||||||
|
...routerConfig.ethereum, |
||||||
|
type: TokenType.collateral, |
||||||
|
token: tokens.ethereum.USDC, |
||||||
|
gas: 65_000, |
||||||
|
interchainSecurityModule: ismConfig, |
||||||
|
}; |
||||||
|
|
||||||
|
return { |
||||||
|
viction, |
||||||
|
ethereum, |
||||||
|
}; |
||||||
|
}; |
@ -0,0 +1,43 @@ |
|||||||
|
import { |
||||||
|
ChainMap, |
||||||
|
RouterConfig, |
||||||
|
TokenRouterConfig, |
||||||
|
TokenType, |
||||||
|
buildAggregationIsmConfigs, |
||||||
|
defaultMultisigConfigs, |
||||||
|
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
|
import { tokens } from '../../../../../src/config/warp.js'; |
||||||
|
|
||||||
|
export const getEthereumVictionUSDTWarpConfig = async ( |
||||||
|
routerConfig: ChainMap<RouterConfig>, |
||||||
|
): Promise<ChainMap<TokenRouterConfig>> => { |
||||||
|
const ismConfig = buildAggregationIsmConfigs( |
||||||
|
'ethereum', |
||||||
|
['viction'], |
||||||
|
defaultMultisigConfigs, |
||||||
|
).viction; |
||||||
|
|
||||||
|
const viction: TokenRouterConfig = { |
||||||
|
...routerConfig.viction, |
||||||
|
type: TokenType.synthetic, |
||||||
|
name: 'USDT', |
||||||
|
symbol: 'USDT', |
||||||
|
decimals: 6, |
||||||
|
totalSupply: 0, |
||||||
|
gas: 75_000, |
||||||
|
}; |
||||||
|
|
||||||
|
const ethereum: TokenRouterConfig = { |
||||||
|
...routerConfig.ethereum, |
||||||
|
type: TokenType.collateral, |
||||||
|
token: tokens.ethereum.USDT, |
||||||
|
gas: 65_000, |
||||||
|
interchainSecurityModule: ismConfig, |
||||||
|
}; |
||||||
|
|
||||||
|
return { |
||||||
|
viction, |
||||||
|
ethereum, |
||||||
|
}; |
||||||
|
}; |
@ -1,73 +1,63 @@ |
|||||||
import { ethers } from 'ethers'; |
|
||||||
|
|
||||||
import { |
import { |
||||||
ChainMap, |
ChainMap, |
||||||
HyperlaneIsmFactory, |
|
||||||
MultiProvider, |
MultiProvider, |
||||||
|
RouterConfig, |
||||||
TokenRouterConfig, |
TokenRouterConfig, |
||||||
TokenType, |
|
||||||
buildAggregationIsmConfigs, |
|
||||||
defaultMultisigConfigs, |
|
||||||
} from '@hyperlane-xyz/sdk'; |
} from '@hyperlane-xyz/sdk'; |
||||||
|
|
||||||
import { Modules, getAddresses } from '../scripts/agent-utils.js'; |
|
||||||
import { getHyperlaneCore } from '../scripts/core-utils.js'; |
import { getHyperlaneCore } from '../scripts/core-utils.js'; |
||||||
import { EnvironmentConfig } from '../src/config/environment.js'; |
import { EnvironmentConfig } from '../src/config/environment.js'; |
||||||
import { tokens } from '../src/config/warp.js'; |
|
||||||
|
|
||||||
import { DEPLOYER } from './environments/mainnet3/owners.js'; |
import { getAncient8EthereumUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getAncient8EthereumUSDCWarpConfig.js'; |
||||||
|
import { getEthereumInevmUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumInevmUSDCWarpConfig.js'; |
||||||
|
import { getEthereumInevmUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumInevmUSDTWarpConfig.js'; |
||||||
|
import { getEthereumVictionETHWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionETHWarpConfig.js'; |
||||||
|
import { getEthereumVictionUSDCWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionUSDCWarpConfig.js'; |
||||||
|
import { getEthereumVictionUSDTWarpConfig } from './environments/mainnet3/warp/configGetters/getEthereumVictionUSDTWarpConfig.js'; |
||||||
|
|
||||||
|
export enum WarpRouteIds { |
||||||
|
Ancient8EthereumUSDC = 'USDC/ancient8-ethereum', |
||||||
|
ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismEZETH = 'EZETH/arbitrum-base-blast-bsc-ethereum-fraxtal-linea-mode-optimism', |
||||||
|
ArbitrumNeutronEclip = 'ECLIP/arbitrum-neutron', |
||||||
|
ArbitrumNeutronTIA = 'TIA/arbitrum-neutron', |
||||||
|
EthereumInevmUSDC = 'USDC/ethereum-inevm', |
||||||
|
EthereumInevmUSDT = 'USDT/ethereum-inevm', |
||||||
|
EthereumVictionETH = 'ETH/ethereum-viction', |
||||||
|
EthereumVictionUSDC = 'USDC/ethereum-viction', |
||||||
|
EthereumVictionUSDT = 'USDT/ethereum-viction', |
||||||
|
InevmInjectiveINJ = 'INJ/inevm-injective', |
||||||
|
MantapacificNeutronTIA = 'TIA/mantapacific-neutron', |
||||||
|
} |
||||||
|
|
||||||
|
export const warpConfigGetterMap: Record< |
||||||
|
string, |
||||||
|
(routerConfig: ChainMap<RouterConfig>) => Promise<ChainMap<TokenRouterConfig>> |
||||||
|
> = { |
||||||
|
[WarpRouteIds.Ancient8EthereumUSDC]: getAncient8EthereumUSDCWarpConfig, |
||||||
|
[WarpRouteIds.EthereumInevmUSDC]: getEthereumInevmUSDCWarpConfig, |
||||||
|
[WarpRouteIds.EthereumInevmUSDT]: getEthereumInevmUSDTWarpConfig, |
||||||
|
// [WarpRouteIds.ArbitrumNeutronEclip]: getArbitrumNeutronEclipWarpConfig, // TODO
|
||||||
|
// [WarpRouteIds.ArbitrumNeutronTIA]: getArbitrumNeutronTiaWarpConfig, // TODO
|
||||||
|
// [WarpRouteIds.ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismEZETH]: getArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismEZETHWarpConfig, // TODO
|
||||||
|
// [WarpRouteIds.InevmInjectiveINJ]: getInevmInjectiveINJWarpConfig, // TODO
|
||||||
|
[WarpRouteIds.EthereumVictionETH]: getEthereumVictionETHWarpConfig, |
||||||
|
[WarpRouteIds.EthereumVictionUSDC]: getEthereumVictionUSDCWarpConfig, |
||||||
|
[WarpRouteIds.EthereumVictionUSDT]: getEthereumVictionUSDTWarpConfig, |
||||||
|
// [WarpRouteIds.MantapacificNeutronTIA]: getEthereumVictionUSDTWarpConfig, // TODO
|
||||||
|
}; |
||||||
|
|
||||||
export async function getWarpConfig( |
export async function getWarpConfig( |
||||||
multiProvider: MultiProvider, |
multiProvider: MultiProvider, |
||||||
envConfig: EnvironmentConfig, |
envConfig: EnvironmentConfig, |
||||||
|
warpRouteId: string, |
||||||
): Promise<ChainMap<TokenRouterConfig>> { |
): Promise<ChainMap<TokenRouterConfig>> { |
||||||
const { core } = await getHyperlaneCore(envConfig.environment, multiProvider); |
const { core } = await getHyperlaneCore(envConfig.environment, multiProvider); |
||||||
const ismFactory = HyperlaneIsmFactory.fromAddressesMap( |
|
||||||
getAddresses(envConfig.environment, Modules.PROXY_FACTORY), |
|
||||||
multiProvider, |
|
||||||
); |
|
||||||
|
|
||||||
const owner = DEPLOYER; |
|
||||||
|
|
||||||
// "Manually" deploying an ISM because the warp deployer doesn't support
|
|
||||||
// ISM objects at the moment, and the deploy involves strictly recoverable ISMs.
|
|
||||||
const ism = await ismFactory.deploy({ |
|
||||||
destination: 'ethereum', |
|
||||||
config: buildAggregationIsmConfigs( |
|
||||||
'ethereum', |
|
||||||
['ancient8'], |
|
||||||
defaultMultisigConfigs, |
|
||||||
).ancient8, |
|
||||||
}); |
|
||||||
|
|
||||||
const routerConfig = core.getRouterConfig(envConfig.owners); |
const routerConfig = core.getRouterConfig(envConfig.owners); |
||||||
|
|
||||||
const ethereum: TokenRouterConfig = { |
const warpConfigGetter = warpConfigGetterMap[warpRouteId]; |
||||||
...routerConfig.ethereum, |
if (!warpConfigGetter) { |
||||||
type: TokenType.collateral, |
throw new Error(`Unknown warp route: ${warpRouteId}`); |
||||||
token: tokens.ethereum.USDC, |
} |
||||||
interchainSecurityModule: ism.address, |
|
||||||
// This hook was recovered from running the deploy script
|
|
||||||
// for the hook module. The hook configuration is the Ethereum
|
|
||||||
// default hook for the Ancient8 remote (no routing).
|
|
||||||
hook: '0x19b2cF952b70b217c90FC408714Fbc1acD29A6A8', |
|
||||||
owner, |
|
||||||
}; |
|
||||||
|
|
||||||
// @ts-ignore - The types as they stand require a synthetic to specify
|
|
||||||
// TokenMetadata, but in practice these are actually inferred from a
|
|
||||||
// collateral config. To avoid needing to specify the TokenMetadata, just
|
|
||||||
// ts-ignore for synthetic tokens.
|
|
||||||
const ancient8: TokenRouterConfig = { |
|
||||||
...routerConfig.ancient8, |
|
||||||
type: TokenType.synthetic, |
|
||||||
// Uses the default ISM
|
|
||||||
interchainSecurityModule: ethers.constants.AddressZero, |
|
||||||
owner, |
|
||||||
}; |
|
||||||
|
|
||||||
return { |
return warpConfigGetter(routerConfig); |
||||||
ethereum, |
|
||||||
ancient8, |
|
||||||
}; |
|
||||||
} |
} |
||||||
|
@ -0,0 +1,23 @@ |
|||||||
|
import { getRegistry } from '../config/registry.js'; |
||||||
|
|
||||||
|
async function main() { |
||||||
|
const registry = await getRegistry(); |
||||||
|
|
||||||
|
const registryContents = await registry.listRegistryContent(); |
||||||
|
|
||||||
|
const warpRoutes = registryContents.deployments.warpRoutes; |
||||||
|
const warpRouteIds = Object.keys(warpRoutes); |
||||||
|
|
||||||
|
const warpRouteIdsTable = warpRouteIds.map((warpRouteId) => { |
||||||
|
return { 'Warp Route IDs': warpRouteId }; |
||||||
|
}); |
||||||
|
|
||||||
|
console.table(warpRouteIdsTable, ['Warp Route IDs']); |
||||||
|
} |
||||||
|
|
||||||
|
main() |
||||||
|
.then() |
||||||
|
.catch((e) => { |
||||||
|
console.error(e); |
||||||
|
process.exit(1); |
||||||
|
}); |
Loading…
Reference in new issue