Skip to content

Commit

Permalink
feat: Add FeeHook and Swell to pzEth (#4974)
Browse files Browse the repository at this point in the history
### Description

<!--
What's included in this PR?
-->

### Drive-by changes

<!--
Are there any minor or drive-by changes also included?
-->

### Related issues

<!--
- Fixes #[issue number here]
-->

### Backward compatibility

<!--
Are these changes backward compatible? Are there any infrastructure
implications, e.g. changes that would prohibit deploying older commits
using this infra tooling?

Yes/No
-->

### Testing

<!--
What kind of testing have these changes undergone?

None/Manual/Unit Tests
-->

---------

Co-authored-by: Trevor Porter <[email protected]>
  • Loading branch information
ltyu and tkporter authored Dec 12, 2024
1 parent c351026 commit fd20bb1
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 28 deletions.
9 changes: 9 additions & 0 deletions .changeset/dull-pianos-kiss.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
'@hyperlane-xyz/helloworld': minor
'@hyperlane-xyz/widgets': minor
'@hyperlane-xyz/infra': minor
'@hyperlane-xyz/cli': minor
'@hyperlane-xyz/sdk': minor
---

Add FeeHook and Swell to pz and ez eth config generator. Bump up Registry 6.6.0
2 changes: 1 addition & 1 deletion .registryrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
c7891cdf0fc6a1541c41e19251611c9152ee8bf9
bde63f7c32e8d169d7e3163b14b5bb25bd3d5042
3 changes: 3 additions & 0 deletions rust/main/config/mainnet_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,9 @@
"protocolFee": "0x8B05BF30F6247a90006c5837eA63C7905D79e6d8",
"proxyAdmin": "0x75EE15Ee1B4A75Fa3e2fDF5DF3253c25599cc659",
"rpcUrls": [
{
"http": "https://rpc.ankr.com/eth"
},
{
"http": "https://ethereum.publicnode.com"
},
Expand Down
2 changes: 1 addition & 1 deletion typescript/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"dependencies": {
"@aws-sdk/client-kms": "^3.577.0",
"@aws-sdk/client-s3": "^3.577.0",
"@hyperlane-xyz/registry": "6.3.0",
"@hyperlane-xyz/registry": "6.6.0",
"@hyperlane-xyz/sdk": "7.3.0",
"@hyperlane-xyz/utils": "7.3.0",
"@inquirer/core": "9.0.10",
Expand Down
2 changes: 1 addition & 1 deletion typescript/helloworld/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"version": "7.3.0",
"dependencies": {
"@hyperlane-xyz/core": "5.8.3",
"@hyperlane-xyz/registry": "6.3.0",
"@hyperlane-xyz/registry": "6.6.0",
"@hyperlane-xyz/sdk": "7.3.0",
"@openzeppelin/contracts-upgradeable": "^4.9.3",
"ethers": "^5.7.2"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import { parseEther } from 'ethers/lib/utils.js';

import { Mailbox__factory } from '@hyperlane-xyz/core';
import {
ChainMap,
ChainName,
HookConfig,
HookType,
HypTokenRouterConfig,
IsmType,
MultisigConfig,
TokenType,
buildAggregationIsmConfigs,
} from '@hyperlane-xyz/sdk';
import { symmetricDifference } from '@hyperlane-xyz/utils';
import { Address, assert, symmetricDifference } from '@hyperlane-xyz/utils';

import { getEnvironmentConfig } from '../../../../../scripts/core-utils.js';
import { getRegistry as getMainnet3Registry } from '../../chains.js';
import rawTokenPrices from '../../tokenPrices.json';

const tokenPrices: ChainMap<string> = rawTokenPrices;
const chainsToDeploy = [
'arbitrum',
'optimism',
Expand All @@ -23,7 +32,33 @@ const chainsToDeploy = [
'zircuit',
'taiko',
'sei',
'swell',
];
export const MAX_PROTOCOL_FEE = parseEther('100').toString(); // Changing this will redeploy the PROTOCOL_FEE hook

export function getProtocolFee(chain: ChainName) {
return (0.5 / Number(tokenPrices[chain])).toFixed(10).toString(); // ~$0.50 USD
}

export function getRenzoHook(
defaultHook: Address,
chain: ChainName,
): HookConfig {
return {
type: HookType.AGGREGATION,
hooks: [
defaultHook,
{
type: HookType.PROTOCOL_FEE,
owner: ezEthSafes[chain],
beneficiary: ezEthSafes[chain],
protocolFee: parseEther(getProtocolFee(chain)).toString(),
maxProtocolFee: MAX_PROTOCOL_FEE,
},
],
};
}

const lockboxChain = 'ethereum';
// over the default 100k to account for xerc20 gas + ISM overhead over the default ISM https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/49f41d9759fd515bfd89e6e22e799c41b27b4119/typescript/sdk/src/router/GasRouterDeployer.ts#L14
const warpRouteOverheadGas = 200_000;
Expand All @@ -41,6 +76,7 @@ const xERC20: Record<(typeof chainsToDeploy)[number], string> = {
zircuit: '0x2416092f143378750bb29b79eD961ab195CcEea5',
taiko: '0x2416092f143378750bb29b79eD961ab195CcEea5',
sei: '0x6DCfbF4729890043DFd34A93A2694E5303BA2703', // redEth
swell: '0x2416092f143378750bb29b79eD961ab195CcEea5',
};

export const ezEthValidators: ChainMap<MultisigConfig> = {
Expand Down Expand Up @@ -164,6 +200,16 @@ export const ezEthValidators: ChainMap<MultisigConfig> = {
{ address: '0x952df7f0cb8611573a53dd7cbf29768871d9f8b0', alias: 'Renzo' },
],
},
swell: {
threshold: 1,
validators: [
{
address: '0x9eadf9217be22d9878e0e464727a2176d5c69ff8',
alias: 'Luganodes',
},
{ address: '0xb6b9b4bd4eb6eb3aef5e9826e7f8b8455947f67c', alias: 'Renzo' },
],
},
};

export const ezEthSafes: Record<string, string> = {
Expand All @@ -179,11 +225,65 @@ export const ezEthSafes: Record<string, string> = {
zircuit: '0x8410927C286A38883BC23721e640F31D3E3E79F8',
taiko: '0x8410927C286A38883BC23721e640F31D3E3E79F8',
sei: '0x0e60fd361fF5b90088e1782e6b21A7D177d462C5',
swell: '0x435E8c9652Da151292F3981bbf663EBEB6668501',
};

const existingProxyAdmins: ChainMap<{ address: string; owner: string }> = {
arbitrum: {
address: '0xdcB558d5C0F9A35C53Fa343c77eD0d346576e2Cf',
owner: ezEthSafes.arbitrum,
},
optimism: {
address: '0xa50910ae66Df6A5F8e85dac032FD45BC2b7be6fF',
owner: ezEthSafes.optimism,
},
base: {
address: '0xec1DdF05ff85D2B22B7d27E5b5E0B82961B7D889',
owner: ezEthSafes.base,
},
blast: {
address: '0xA26F8cE2E21A503bf9e18c213965d7BC14997F48',
owner: ezEthSafes.blast,
},
bsc: {
address: '0x486b39378f99f073A3043C6Aabe8666876A8F3C5',
owner: ezEthSafes.bsc,
},
mode: {
address: '0x2F78F22a1D7491500C9ED9352b8239fbAbcDd84E',
owner: ezEthSafes.mode,
},
fraxtal: {
address: '0x8bB69721B4E9b9df08bEdaeaA193008C7317Db59',
owner: ezEthSafes.fraxtal,
},
linea: {
address: '0x2F78F22a1D7491500C9ED9352b8239fbAbcDd84E',
owner: ezEthSafes.linea,
},
ethereum: {
address: '0x2F78F22a1D7491500C9ED9352b8239fbAbcDd84E',
owner: ezEthSafes.ethereum,
},
zircuit: {
address: '0xec1DdF05ff85D2B22B7d27E5b5E0B82961B7D889',
owner: ezEthSafes.zircuit,
},
sei: {
address: '0x33219fEF24C198d979F05d692a17507E41a0A73e',
owner: ezEthSafes.sei,
},
taiko: {
address: '0xA3666f8a327AADB666F1906A38B17937e5F11f92',
owner: ezEthSafes.taiko,
},
};

export const getRenzoEZETHWarpConfig = async (): Promise<
ChainMap<HypTokenRouterConfig>
> => {
const config = getEnvironmentConfig('mainnet3');
const multiProvider = await config.getMultiProvider();
const registry = await getMainnet3Registry();

const validatorDiff = symmetricDifference(
Expand Down Expand Up @@ -222,6 +322,15 @@ export const getRenzoEZETHWarpConfig = async (): Promise<
await Promise.all(
chainsToDeploy.map(
async (chain): Promise<[string, HypTokenRouterConfig]> => {
const addresses = await registry.getChainAddresses(chain);
assert(addresses, 'No addresses in Registry');
const { mailbox } = addresses;

const mailboxContract = Mailbox__factory.connect(
mailbox,
multiProvider.getProvider(chain),
);
const defaultHook = await mailboxContract.defaultHook();
const ret: [string, HypTokenRouterConfig] = [
chain,
{
Expand All @@ -233,7 +342,7 @@ export const getRenzoEZETHWarpConfig = async (): Promise<
token: chain === lockboxChain ? lockbox : xERC20[chain],
owner: ezEthSafes[chain],
gas: warpRouteOverheadGas,
mailbox: (await registry.getChainAddresses(chain))!.mailbox,
mailbox,
interchainSecurityModule: {
type: IsmType.AGGREGATION,
threshold: 2,
Expand All @@ -254,6 +363,8 @@ export const getRenzoEZETHWarpConfig = async (): Promise<
},
],
},
hook: getRenzoHook(defaultHook, chain),
proxyAdmin: existingProxyAdmins[chain],
},
];

Expand Down
Original file line number Diff line number Diff line change
@@ -1,37 +1,58 @@
import { Mailbox__factory } from '@hyperlane-xyz/core';
import {
ChainMap,
HypTokenRouterConfig,
IsmType,
TokenType,
buildAggregationIsmConfigs,
} from '@hyperlane-xyz/sdk';
import { symmetricDifference } from '@hyperlane-xyz/utils';
import { assert, symmetricDifference } from '@hyperlane-xyz/utils';

import { getEnvironmentConfig } from '../../../../../scripts/core-utils.js';
import { getRegistry as getMainnet3Registry } from '../../chains.js';

import { ezEthSafes, ezEthValidators } from './getRenzoEZETHWarpConfig.js';
import {
ezEthSafes,
ezEthValidators,
getRenzoHook,
} from './getRenzoEZETHWarpConfig.js';

const lockbox = '0xbC5511354C4A9a50DE928F56DB01DD327c4e56d5';
const xERC20 = '0x9cb41CD74D01ae4b4f640EC40f7A60cA1bCF83E7';
const lockboxChain = 'ethereum';
// over the default 100k to account for xerc20 gas + ISM overhead over the default ISM https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/49f41d9759fd515bfd89e6e22e799c41b27b4119/typescript/sdk/src/router/GasRouterDeployer.ts#L14
const warpRouteOverheadGas = 200_000;

const chainsToDeploy = ['ethereum', 'zircuit'];
const chainsToDeploy = ['ethereum', 'swell', 'zircuit'];

const pzEthValidators = {
ethereum: ezEthValidators.ethereum,
zircuit: ezEthValidators.zircuit,
swell: ezEthValidators.swell,
};

const pzEthSafes: Record<string, string> = {
ethereum: ezEthSafes.ethereum,
zircuit: ezEthSafes.zircuit,
swell: ezEthSafes.swell,
};

const existingProxyAdmins: ChainMap<{ address: string; owner: string }> = {
ethereum: {
address: '0x4f4671Ce69c9af15e33eB7Cf6D1358d1B39Af3bF',
owner: '0xD1e6626310fD54Eceb5b9a51dA2eC329D6D4B68A',
},
zircuit: {
address: '0x8b789B4A56675240c9f0985B467752b870c75711',
owner: '0x8410927C286A38883BC23721e640F31D3E3E79F8',
},
};

export const getRenzoPZETHWarpConfig = async (): Promise<
ChainMap<HypTokenRouterConfig>
> => {
const config = getEnvironmentConfig('mainnet3');
const multiProvider = await config.getMultiProvider();
const registry = await getMainnet3Registry();

const validatorDiff = symmetricDifference(
Expand Down Expand Up @@ -59,6 +80,15 @@ export const getRenzoPZETHWarpConfig = async (): Promise<
await Promise.all(
chainsToDeploy.map(
async (chain): Promise<[string, HypTokenRouterConfig]> => {
const addresses = await registry.getChainAddresses(chain);
assert(addresses, 'No addresses in Registry');
const { mailbox } = addresses;

const mailboxContract = Mailbox__factory.connect(
mailbox,
multiProvider.getProvider(chain),
);
const defaultHook = await mailboxContract.defaultHook();
const ret: [string, HypTokenRouterConfig] = [
chain,
{
Expand All @@ -70,7 +100,7 @@ export const getRenzoPZETHWarpConfig = async (): Promise<
token: chain === lockboxChain ? lockbox : xERC20,
owner: pzEthSafes[chain],
gas: warpRouteOverheadGas,
mailbox: (await registry.getChainAddresses(chain))!.mailbox,
mailbox,
interchainSecurityModule: {
type: IsmType.AGGREGATION,
threshold: 2,
Expand All @@ -91,6 +121,8 @@ export const getRenzoPZETHWarpConfig = async (): Promise<
},
],
},
hook: getRenzoHook(defaultHook, chain),
proxyAdmin: existingProxyAdmins[chain],
},
];

Expand Down
4 changes: 2 additions & 2 deletions typescript/infra/config/environments/mainnet3/warp/warpIds.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export enum WarpRouteIds {
Ancient8EthereumUSDC = 'USDC/ancient8-ethereum',
ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismSeiTaikoZircuitEZETH = 'EZETH/arbitrum-base-blast-bsc-ethereum-fraxtal-linea-mode-optimism-sei-taiko-zircuit',
ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismSeiSwellTaikoZircuitEZETH = 'EZETH/arbitrum-base-blast-bsc-ethereum-fraxtal-linea-mode-optimism-sei-swell-taiko-zircuit',
ArbitrumBaseEnduranceUSDC = 'USDC/arbitrum-base-endurance',
ArbitrumEthereumZircuitAMPHRETH = 'AMPHRETH/arbitrum-ethereum-zircuit',
ArbitrumNeutronEclip = 'ECLIP/arbitrum-neutron',
Expand All @@ -24,7 +24,7 @@ export enum WarpRouteIds {
EthereumVictionETH = 'ETH/ethereum-viction',
EthereumVictionUSDC = 'USDC/ethereum-viction',
EthereumVictionUSDT = 'USDT/ethereum-viction',
EthereumZircuitPZETH = 'PZETH/ethereum-zircuit',
EthereumSwellZircuitPZETH = 'PZETH/ethereum-swell-zircuit',
EthereumBscLumiaLUMIA = 'LUMIA/bsc-ethereum-lumia',
InevmInjectiveINJ = 'INJ/inevm-injective',
MantapacificNeutronTIA = 'TIA/mantapacific-neutron',
Expand Down
4 changes: 2 additions & 2 deletions typescript/infra/config/warp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ export const warpConfigGetterMap: Record<string, WarpConfigGetter> = {
[WarpRouteIds.EthereumInevmUSDT]: getEthereumInevmUSDTWarpConfig,
[WarpRouteIds.ArbitrumNeutronEclip]: getArbitrumNeutronEclipWarpConfig,
[WarpRouteIds.ArbitrumNeutronTIA]: getArbitrumNeutronTiaWarpConfig,
[WarpRouteIds.ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismSeiTaikoZircuitEZETH]:
[WarpRouteIds.ArbitrumBaseBlastBscEthereumFraxtalLineaModeOptimismSeiSwellTaikoZircuitEZETH]:
getRenzoEZETHWarpConfig,
[WarpRouteIds.InevmInjectiveINJ]: getInevmInjectiveINJWarpConfig,
[WarpRouteIds.EthereumFlowCbBTC]: getEthereumFlowCbBTCWarpConfig,
[WarpRouteIds.EthereumSeiFastUSD]: getEthereumSeiFastUSDWarpConfig,
[WarpRouteIds.EthereumVictionETH]: getEthereumVictionETHWarpConfig,
[WarpRouteIds.EthereumVictionUSDC]: getEthereumVictionUSDCWarpConfig,
[WarpRouteIds.EthereumVictionUSDT]: getEthereumVictionUSDTWarpConfig,
[WarpRouteIds.EthereumZircuitPZETH]: getRenzoPZETHWarpConfig,
[WarpRouteIds.EthereumSwellZircuitPZETH]: getRenzoPZETHWarpConfig,
[WarpRouteIds.EthereumBscLumiaLUMIA]: getEthereumBscLUMIAWarpConfig,
[WarpRouteIds.MantapacificNeutronTIA]: getMantapacificNeutronTiaWarpConfig,
[WarpRouteIds.EclipseEthereumApxEth]: getEclipseEthereumApxEthWarpConfig,
Expand Down
2 changes: 1 addition & 1 deletion typescript/infra/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"@ethersproject/providers": "*",
"@google-cloud/secret-manager": "^5.5.0",
"@hyperlane-xyz/helloworld": "7.3.0",
"@hyperlane-xyz/registry": "6.3.0",
"@hyperlane-xyz/registry": "6.6.0",
"@hyperlane-xyz/sdk": "7.3.0",
"@hyperlane-xyz/utils": "7.3.0",
"@inquirer/prompts": "3.3.2",
Expand Down
10 changes: 5 additions & 5 deletions typescript/sdk/src/router/HyperlaneRouterChecker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { ethers } from 'ethers';
import {
AddressBytes32,
addressToBytes32,
assert,
eqAddress,
isZeroishAddress,
rootLogger,
Expand Down Expand Up @@ -68,10 +67,11 @@ export class HyperlaneRouterChecker<
}

if (config.hook) {
assert(
typeof config.hook === 'string',
'Hook objects not supported in router checker',
);
if (typeof config.hook !== 'string')
return this.logger.info(
`Hook objects not supported in router checker for HookConfig: ${config.hook}`,
);

const hook = await router.hook();
if (!eqAddress(hook, config.hook as string)) {
this.addViolation({
Expand Down
2 changes: 1 addition & 1 deletion typescript/widgets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
"@eslint/js": "^9.15.0",
"@hyperlane-xyz/registry": "6.3.0",
"@hyperlane-xyz/registry": "6.6.0",
"@storybook/addon-essentials": "^7.6.14",
"@storybook/addon-interactions": "^7.6.14",
"@storybook/addon-links": "^7.6.14",
Expand Down
Loading

0 comments on commit fd20bb1

Please sign in to comment.