diff --git a/typescript/sdk/src/gas/HyperlaneIgpChecker.ts b/typescript/sdk/src/gas/HyperlaneIgpChecker.ts index 2c9467f04b..6c8b806486 100644 --- a/typescript/sdk/src/gas/HyperlaneIgpChecker.ts +++ b/typescript/sdk/src/gas/HyperlaneIgpChecker.ts @@ -95,12 +95,13 @@ export class HyperlaneIgpChecker extends HyperlaneAppChecker< const remotes = this.app.remoteChains(local); for (const remote of remotes) { - let expectedOverhead = this.configMap[local].overhead[remote]; + let expectedOverhead = + this.configMap[local].oracleConfig[remote].overhead; if (!expectedOverhead) { this.app.logger( `No overhead configured for ${local} -> ${remote}, defaulting to 0`, ); - expectedOverhead = 0; + expectedOverhead = BigNumber.from(0); } const remoteId = this.multiProvider.getDomainId(remote); diff --git a/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts b/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts index f7c09d36d3..bfa695523c 100644 --- a/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts +++ b/typescript/sdk/src/gas/HyperlaneIgpDeployer.ts @@ -4,16 +4,17 @@ import { InterchainGasPaymaster, ProxyAdmin, StorageGasOracle, + StorageGasOracle__factory, } from '@hyperlane-xyz/core'; -import { eqAddress } from '@hyperlane-xyz/utils'; +import { Address, eqAddress } from '@hyperlane-xyz/utils'; import { HyperlaneContracts } from '../contracts/types'; import { HyperlaneDeployer } from '../deploy/HyperlaneDeployer'; import { MultiProvider } from '../providers/MultiProvider'; -import { ChainName } from '../types'; +import { ChainMap, ChainName } from '../types'; import { IgpFactories, igpFactories } from './contracts'; -import { IgpConfig } from './types'; +import { DomainGasConfig, IgpConfig } from './types'; export class HyperlaneIgpDeployer extends HyperlaneDeployer< IgpConfig, @@ -42,10 +43,10 @@ export class HyperlaneIgpDeployer extends HyperlaneDeployer< ); const gasParamsToSet: InterchainGasPaymaster.GasParamStruct[] = []; - const remotes = Object.keys(config.gasOracleType); + const remotes = Object.keys(config.oracleConfig); for (const remote of remotes) { const remoteId = this.multiProvider.getDomainId(remote); - const newGasOverhead = config.overhead[remote]; + const newGasOverhead = config.oracleConfig[remote].overhead; const currentGasConfig = await igp.destinationGasConfigs(remoteId); if ( @@ -81,6 +82,64 @@ export class HyperlaneIgpDeployer extends HyperlaneDeployer< return this.deployContract(chain, 'storageGasOracle', []); } + async configureStorageGasOracle( + chain: ChainName, + igp: InterchainGasPaymaster, + gasOracleConfig: ChainMap, + ): Promise { + const remotes = Object.keys(gasOracleConfig); + const configsToSet: Record< + Address, + StorageGasOracle.RemoteGasDataConfigStruct[] + > = {}; + for (const remote of remotes) { + const gasOracleAddress = (await igp.destinationGasConfigs(remote)) + .gasOracle; + const gasOracle = StorageGasOracle__factory.connect( + gasOracleAddress, + this.multiProvider.getProvider(chain), + ); + const remoteGasDataConfig = await gasOracle.remoteGasData(remote); + const desiredGasData = gasOracleConfig[remote]; + + if ( + !remoteGasDataConfig.gasPrice.eq(desiredGasData.gasPrice) || + !remoteGasDataConfig.tokenExchangeRate.eq( + desiredGasData.tokenExchangeRate, + ) + ) { + configsToSet[gasOracleAddress].push({ + remoteDomain: this.multiProvider.getDomainId(remote), + ...desiredGasData, + }); + } + } + + const gasOracles = Object.keys(configsToSet); + for (const gasOracle of gasOracles) { + const gasOracleContract = StorageGasOracle__factory.connect( + gasOracle, + this.multiProvider.getProvider(chain), + ); + if (configsToSet[gasOracle].length > 0) { + this.logger( + `Setting gas oracle on ${gasOracle} for ${configsToSet[gasOracle].map( + (config) => config.remoteDomain, + )}`, + ); + await this.runIfOwner(chain, gasOracleContract, async () => + this.multiProvider.handleTx( + chain, + gasOracleContract.setRemoteGasDataConfigs( + configsToSet[gasOracle], + this.multiProvider.getTransactionOverrides(chain), + ), + ), + ); + } + } + } + async deployContracts( chain: ChainName, config: IgpConfig, diff --git a/typescript/sdk/src/gas/types.ts b/typescript/sdk/src/gas/types.ts index ca0c0485ab..891d6a32e4 100644 --- a/typescript/sdk/src/gas/types.ts +++ b/typescript/sdk/src/gas/types.ts @@ -10,12 +10,22 @@ export enum GasOracleContractType { StorageGasOracle = 'StorageGasOracle', } +export type RemoteGasData = { + tokenExchangeRate: BigNumber; + gasPrice: BigNumber; +}; + +export type DomainGasConfig = RemoteGasData & { + type: GasOracleContractType; + overhead: BigNumber; +}; + export type IgpConfig = { owner: Address; beneficiary: Address; gasOracleType: ChainMap; oracleKey: Address; - overhead: ChainMap; + oracleConfig: ChainMap; }; export enum IgpViolationType {