From ee442ec2a02843715962a2fb8262e4d86fb7e7d1 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 29 Oct 2024 10:18:15 +0100 Subject: [PATCH 01/34] add new deploy script for automaton deployment --- scripts/optimism/deploy-automaton.ts | 114 ++++++++ utils/deployment.ts | 11 +- utils/optimism/deploymentForAutomaton.ts | 352 +++++++++++++++++++++++ 3 files changed, 474 insertions(+), 3 deletions(-) create mode 100644 scripts/optimism/deploy-automaton.ts create mode 100644 utils/optimism/deploymentForAutomaton.ts diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts new file mode 100644 index 00000000..3a02a8ab --- /dev/null +++ b/scripts/optimism/deploy-automaton.ts @@ -0,0 +1,114 @@ +import env from "../../utils/env"; +import prompt from "../../utils/prompt"; +import network from "../../utils/network"; +import deployment from "../../utils/deployment"; +import { BridgingManagement } from "../../utils/bridging-management"; +import deploymentAll from "../../utils/optimism/deploymentForAutomaton"; +import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-management"; + +async function deploy() { + const networkName = env.network(); + const ethOptNetwork = network.multichain(["eth", "opt"], networkName); + + const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + forking: env.forking() + }); + + const [, optDeployer] = ethOptNetwork.getSigners( + env.string("OPT_DEPLOYER_PRIVATE_KEY"), + { + forking: env.forking() + } + ); + + const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); + + const [l1DeployScript, l2DeployScript] = await deploymentAll({ logger: console }) + .deployAllScript( + { + l1CrossDomainMessenger: deploymentConfig.ethereum.l1CrossDomainMessenger, + l1TokenNonRebasable: deploymentConfig.ethereum.l1TokenNonRebasable, + l1TokenRebasable: deploymentConfig.ethereum.l1RebasableToken, + accountingOracle: deploymentConfig.ethereum.accountingOracle, + l2GasLimitForPushingTokenRate: deploymentConfig.ethereum.l2GasLimitForPushingTokenRate, + + deployer: ethDeployer, + admins: { + proxy: deploymentConfig.ethereum.bridgeProxyAdmin, + bridge: ethDeployer.address + }, + deployOffset: 0, + }, + { + l2CrossDomainMessenger: deploymentConfig.optimism.l2CrossDomainMessenger, + tokenRateOracle: { + tokenRateOutdatedDelay: deploymentConfig.optimism.tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: deploymentConfig.optimism.maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.optimism.maxAllowedTokenRateDeviationPerDayBp, + oldestRateAllowedInPauseTimeSpan: deploymentConfig.optimism.oldestRateAllowedInPauseTimeSpan, + minTimeBetweenTokenRateUpdates: deploymentConfig.optimism.minTimeBetweenTokenRateUpdates, + tokenRate: deploymentConfig.optimism.initialTokenRateValue, + l1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp + }, + l2TokenNonRebasable: { + version: deploymentConfig.optimism.l2TokenNonRebasableDomainVersion + }, + l2TokenRebasable: { + version: deploymentConfig.optimism.l2TokenRebasableDomainVersion + }, + + deployer: optDeployer, + admins: { + proxy: deploymentConfig.optimism.bridgeProxyAdmin, + bridge: optDeployer.address, + }, + deployOffset: 0, + } + ); + + await deployment.printMultiChainDeploymentConfig( + "Deploy Optimism Bridge", + ethDeployer, + optDeployer, + deploymentConfig, + l1DeployScript, + l2DeployScript, + true + ); + + await prompt.proceed(); + + await l1DeployScript.run(); + await l2DeployScript.run(); + + const l1BridgingManagement = new BridgingManagement( + l1DeployScript.bridgeProxyAddress, + ethDeployer, + { logger: console } + ); + + const l2BridgingManagement = new BridgingManagement( + l2DeployScript.tokenBridgeProxyAddress, + optDeployer, + { logger: console } + ); + + const tokenRateOracleManagement = new TokenRateOracleManagement( + l2DeployScript.tokenRateOracleProxyAddress, + optDeployer, + { logger: console } + ); + + await l1BridgingManagement.setup(deploymentConfig.ethereum); + await l2BridgingManagement.setup(deploymentConfig.optimism); + await tokenRateOracleManagement.setup({ + tokenRateOracleAdmin: deploymentConfig.optimism.tokenRateOracleAdmin, + initialTokenRateValue: deploymentConfig.optimism.initialTokenRateValue, + initialTokenRateL1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp, + rateUpdatesEnabled: deploymentConfig.optimism.tokenRateUpdateEnabled, + rateUpdatesDisablers: deploymentConfig.optimism.tokenRateUpdateDisablers, + rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers + }); + + return {l1DeployScript, l2DeployScript}; +} diff --git a/utils/deployment.ts b/utils/deployment.ts index 187d3301..6d2c5444 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -15,6 +15,7 @@ interface EthereumDeploymentConfig extends BridgingManagerSetupConfig { l1TokenBridge: string; lido: string; tokenRateNotifierOwner: string; + l1CrossDomainMessenger: string; } interface OptimismDeploymentConfig extends BridgingManagerSetupConfig { @@ -22,6 +23,8 @@ interface OptimismDeploymentConfig extends BridgingManagerSetupConfig { govBridgeExecutor: string; + l2CrossDomainMessenger: string; + /// Oracle tokenRateOracleProxyAdmin: string; tokenRateOracleAdmin: string; @@ -57,11 +60,12 @@ interface MultiChainDeploymentConfig { export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { return { ethereum: { + l1CrossDomainMessenger: env.address("L1_CROSSDOMAIN_MESSENGER", "0x0000000000000000000000000000000000000000"), l1TokenNonRebasable: env.address("L1_NON_REBASABLE_TOKEN"), l1RebasableToken: env.address("L1_REBASABLE_TOKEN"), accountingOracle: env.address("ACCOUNTING_ORACLE"), l2GasLimitForPushingTokenRate: BigNumber.from(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), - l1TokenBridge: env.address("L1_TOKEN_BRIDGE"), + l1TokenBridge: env.address("L1_TOKEN_BRIDGE", "0x0000000000000000000000000000000000000000"), lido: env.address("LIDO"), tokenRateNotifierOwner: env.address("TOKEN_RATE_NOTIFIER_OWNER"), @@ -76,6 +80,7 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { withdrawalsDisablers: env.addresses("L1_WITHDRAWALS_DISABLERS", []), }, optimism: { + l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER", "0x0000000000000000000000000000000000000000"), govBridgeExecutor: env.address("GOV_BRIDGE_EXECUTOR"), /// TokenRateOracle @@ -94,7 +99,7 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { initialTokenRateL1Timestamp: BigNumber.from(env.string("INITIAL_TOKEN_RATE_L1_TIMESTAMP")), // wstETH - l2TokenNonRebasableAddress: env.address("L2_TOKEN_NON_REBASABLE"), + l2TokenNonRebasableAddress: env.address("L2_TOKEN_NON_REBASABLE", "0x0000000000000000000000000000000000000000"), l2TokenNonRebasableDomainVersion: env.string("L2_TOKEN_NON_REBASABLE_SIGNING_DOMAIN_VERSION"), // stETH @@ -102,7 +107,7 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { l2TokenRebasableProxyAdmin: env.string("L2_TOKEN_REBASABLE_PROXY_ADMIN"), // Bridge - l2TokenBridge: env.address("L2_TOKEN_BRIDGE"), + l2TokenBridge: env.address("L2_TOKEN_BRIDGE", "0x0000000000000000000000000000000000000000"), bridgeProxyAdmin: env.address("L2_PROXY_ADMIN"), bridgeAdmin: env.address("L2_BRIDGE_ADMIN"), diff --git a/utils/optimism/deploymentForAutomaton.ts b/utils/optimism/deploymentForAutomaton.ts new file mode 100644 index 00000000..bf7aec3f --- /dev/null +++ b/utils/optimism/deploymentForAutomaton.ts @@ -0,0 +1,352 @@ +import { assert } from "chai"; +import { BigNumber, Wallet } from "ethers"; +import { OptDeploymentOptions, DeployScriptParams } from "./types"; +import network from "../network"; +import { DeployScript, Logger } from "../deployment/DeployScript"; +import { + ERC20BridgedPermit__factory, + ERC20RebasableBridgedPermit__factory, + L1LidoTokensBridge__factory, + L2ERC20ExtendedTokensBridge__factory, + OssifiableProxy__factory, + TokenRateOracle__factory, + OpStackTokenRatePusher__factory, + IERC20Metadata__factory +} from "../../typechain"; + +interface OptL1DeployScriptParams extends DeployScriptParams { + l1CrossDomainMessenger: string; + accountingOracle: string; + l1TokenNonRebasable: string; + l1TokenRebasable: string; + l2GasLimitForPushingTokenRate: BigNumber; +} + +interface OptL2DeployScriptParams extends DeployScriptParams { + l2TokenNonRebasable: { + name?: string; + symbol?: string; + version: string; + decimals?: number; + }; + l2TokenRebasable: { + name?: string; + symbol?: string; + version: string; + decimals?: number; + }; + tokenRateOracle: { + tokenRateOutdatedDelay: BigNumber; + maxAllowedL2ToL1ClockLag: BigNumber; + maxAllowedTokenRateDeviationPerDayBp: BigNumber; + oldestRateAllowedInPauseTimeSpan: BigNumber; + minTimeBetweenTokenRateUpdates: BigNumber; + tokenRate: BigNumber; + l1Timestamp: BigNumber; + }, + l2CrossDomainMessenger: string; +} + +export class L1DeployAllScript extends DeployScript { + + constructor( + deployer: Wallet, + bridgeImplAddress: string, + bridgeProxyAddress: string, + opStackTokenRatePusherImplAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.bridgeImplAddress = bridgeImplAddress; + this.bridgeProxyAddress = bridgeProxyAddress; + this.opStackTokenRatePusherImplAddress = opStackTokenRatePusherImplAddress; + } + + public bridgeImplAddress: string; + public bridgeProxyAddress: string; + public opStackTokenRatePusherImplAddress: string; +} + +export class L2DeployAllScript extends DeployScript { + + constructor( + deployer: Wallet, + tokenImplAddress: string, + tokenProxyAddress: string, + tokenRebasableImplAddress: string, + tokenRebasableProxyAddress: string, + tokenBridgeImplAddress: string, + tokenBridgeProxyAddress: string, + tokenRateOracleImplAddress: string, + tokenRateOracleProxyAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.tokenImplAddress = tokenImplAddress; + this.tokenProxyAddress = tokenProxyAddress; + this.tokenRebasableImplAddress = tokenRebasableImplAddress; + this.tokenRebasableProxyAddress = tokenRebasableProxyAddress; + this.tokenBridgeImplAddress = tokenBridgeImplAddress; + this.tokenBridgeProxyAddress = tokenBridgeProxyAddress; + this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; + this.tokenRateOracleProxyAddress = tokenRateOracleProxyAddress; + } + + public tokenImplAddress: string; + public tokenProxyAddress: string; + public tokenRebasableImplAddress: string; + public tokenRebasableProxyAddress: string; + public tokenBridgeImplAddress: string; + public tokenBridgeProxyAddress: string; + public tokenRateOracleImplAddress: string; + public tokenRateOracleProxyAddress: string; +} + +/// Deploy all from scratch except Notifier. Uses for automaton script. +/// L1 part +/// L1LidoTokensBridge + Proxy +/// OpStackTokenRatePusher +/// L2 part +/// TokenRateOracle + Proxy +/// ERC20BridgedPermit + Proxy +/// ERC20RebasableBridgedPermit + Proxy +/// L2ERC20ExtendedTokensBridge + Proxy +export default function deploymentAll( + options: OptDeploymentOptions = {} +) { + return { + async deployAllScript( + l1Params: OptL1DeployScriptParams, + l2Params: OptL2DeployScriptParams, + ): Promise<[L1DeployAllScript, L2DeployAllScript]> { + + const [ + expectedL1TokenBridgeImplAddress, + expectedL1TokenBridgeProxyAddress, + expectedL1OpStackTokenRatePusherImplAddress, + ] = await network.predictAddresses(l1Params.deployer, l1Params.deployOffset + 3); + + const [ + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, + expectedL2TokenImplAddress, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + expectedL2TokenBridgeImplAddress, + expectedL2TokenBridgeProxyAddress + ] = await network.predictAddresses(l2Params.deployer, l2Params.deployOffset + 8); + + const l1DeployScript = new L1DeployAllScript( + l1Params.deployer, + expectedL1TokenBridgeImplAddress, + expectedL1TokenBridgeProxyAddress, + expectedL1OpStackTokenRatePusherImplAddress, + options?.logger + ) + .addStep({ + factory: L1LidoTokensBridge__factory, + args: [ + l1Params.l1CrossDomainMessenger, + expectedL2TokenBridgeProxyAddress, + l1Params.l1TokenNonRebasable, + l1Params.l1TokenRebasable, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + l1Params.accountingOracle, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenBridgeImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL1TokenBridgeImplAddress, + l1Params.admins.proxy, + L1LidoTokensBridge__factory.createInterface().encodeFunctionData( + "initialize", + [l1Params.admins.bridge] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenBridgeProxyAddress), + }) + .addStep({ + factory: OpStackTokenRatePusher__factory, + args: [ + l1Params.l1CrossDomainMessenger, + l1Params.l1TokenNonRebasable, + l1Params.accountingOracle, + expectedL2TokenRateOracleProxyAddress, + l1Params.l2GasLimitForPushingTokenRate, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), + }); + + const l1TokenNonRebasableInfo = IERC20Metadata__factory.connect( + l1Params.l1TokenNonRebasable, + l1Params.deployer + ); + + const l1TokenRebasableInfo = IERC20Metadata__factory.connect( + l1Params.l1TokenRebasable, + l1Params.deployer + ); + + const [ + l2TokenNonRebasableDecimals, l2TokenNonRebasableName, l2TokenNonRebasableSymbol, + l2TokenRebasableDecimals, l2TokenRebasableName, l2TokenRebasableSymbol + ] = await Promise.all([ + l1TokenNonRebasableInfo.decimals(), + l2Params.l2TokenNonRebasable?.name ?? l1TokenNonRebasableInfo.name(), + l2Params.l2TokenNonRebasable?.symbol ?? l1TokenNonRebasableInfo.symbol(), + l1TokenRebasableInfo.decimals(), + l2Params.l2TokenRebasable?.name ?? l1TokenRebasableInfo.name(), + l2Params.l2TokenRebasable?.symbol ?? l1TokenRebasableInfo.symbol(), + ]); + + const l2DeployScript = new L2DeployAllScript( + l2Params.deployer, + expectedL2TokenImplAddress, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + expectedL2TokenBridgeImplAddress, + expectedL2TokenBridgeProxyAddress, + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, + options?.logger + ) + .addStep({ + factory: TokenRateOracle__factory, + args: [ + l2Params.l2CrossDomainMessenger, + expectedL2TokenBridgeProxyAddress, + expectedL1OpStackTokenRatePusherImplAddress, + l2Params.tokenRateOracle.tokenRateOutdatedDelay, + l2Params.tokenRateOracle.maxAllowedL2ToL1ClockLag, + l2Params.tokenRateOracle.maxAllowedTokenRateDeviationPerDayBp, + l2Params.tokenRateOracle.oldestRateAllowedInPauseTimeSpan, + l2Params.tokenRateOracle.minTimeBetweenTokenRateUpdates, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRateOracleImplAddress, + l2Params.admins.proxy, + TokenRateOracle__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2Params.admins.bridge, + l2Params.tokenRateOracle.tokenRate, + l2Params.tokenRateOracle.l1Timestamp + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + }) + .addStep({ + factory: ERC20BridgedPermit__factory, + args: [ + l2TokenNonRebasableName, + l2TokenNonRebasableSymbol, + l2Params.l2TokenNonRebasable.version, + l2TokenNonRebasableDecimals, + expectedL2TokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenImplAddress, + l2Params.admins.proxy, + ERC20BridgedPermit__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2TokenNonRebasableName, + l2TokenNonRebasableSymbol, + l2Params.l2TokenNonRebasable.version + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenProxyAddress), + }) + .addStep({ + factory: ERC20RebasableBridgedPermit__factory, + args: [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + l2Params.l2TokenRebasable.version, + l2TokenRebasableDecimals, + expectedL2TokenProxyAddress, + expectedL2TokenRateOracleProxyAddress, + expectedL2TokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRebasableImplAddress, + l2Params.admins.proxy, + ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData( + "initialize", + [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + l2Params.l2TokenRebasable.version + ] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableProxyAddress), + }) + .addStep({ + factory: L2ERC20ExtendedTokensBridge__factory, + args: [ + l2Params.l2CrossDomainMessenger, + expectedL1TokenBridgeProxyAddress, + l1Params.l1TokenNonRebasable, + l1Params.l1TokenRebasable, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenBridgeImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenBridgeImplAddress, + l2Params.admins.proxy, + L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( + "initialize", + [l2Params.admins.bridge] + ), + options?.overrides, + ], + }); + + return [l1DeployScript as L1DeployAllScript, l2DeployScript as L2DeployAllScript]; + }, + }; +} From 8ade9e9016d2231ed18b5355b9d24f9b583e1d8f Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 29 Oct 2024 10:25:00 +0100 Subject: [PATCH 02/34] mark function export --- scripts/optimism/deploy-automaton.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index 3a02a8ab..b9f82182 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -6,7 +6,7 @@ import { BridgingManagement } from "../../utils/bridging-management"; import deploymentAll from "../../utils/optimism/deploymentForAutomaton"; import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-management"; -async function deploy() { +export async function deploy() { const networkName = env.network(); const ethOptNetwork = network.multichain(["eth", "opt"], networkName); From badf3e3f7732c1e838b3184e7f435c8e7c9bf4c7 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 29 Oct 2024 11:25:49 +0100 Subject: [PATCH 03/34] save state in file --- scripts/optimism/deploy-automaton.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index b9f82182..36d8d686 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -5,8 +5,9 @@ import deployment from "../../utils/deployment"; import { BridgingManagement } from "../../utils/bridging-management"; import deploymentAll from "../../utils/optimism/deploymentForAutomaton"; import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-management"; +import * as fs from 'fs'; -export async function deploy() { +async function main() { const networkName = env.network(); const ethOptNetwork = network.multichain(["eth", "opt"], networkName); @@ -110,5 +111,14 @@ export async function deploy() { rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers }); - return {l1DeployScript, l2DeployScript}; + const deployResult = JSON.stringify({ + ethterum: l1DeployScript, + optimism: l2DeployScript + }); + fs.writeFileSync('deployResult.json', JSON.stringify(deployResult, null, 2), 'utf-8'); } + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); From 571d7f9e6781942a2241a61c9ee1f3450980d584 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 29 Oct 2024 22:04:19 +0100 Subject: [PATCH 04/34] update hardhat version --- package-lock.json | 226 ++++++++++----------------- package.json | 2 +- scripts/optimism/deploy-automaton.ts | 13 +- 3 files changed, 93 insertions(+), 148 deletions(-) diff --git a/package-lock.json b/package-lock.json index 2d87dbd2..c15d351a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,7 +39,7 @@ "ethereum-waffle": "^3.4.4", "ethereumjs-util": "^7.0.8", "ethers": "^5.6.2", - "hardhat": "^2.12.2", + "hardhat": "^2.22.15", "hardhat-gas-reporter": "^1.0.8", "prettier": "^2.6.1", "prettier-plugin-solidity": "^1.0.0-beta.13", @@ -1532,131 +1532,82 @@ } }, "node_modules/@nomicfoundation/edr": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.3.5.tgz", - "integrity": "sha512-dPSM9DuI1sr71gqWUMgLo8MjHQWO4+WNDm3iWaT6P4vUFJReZX5qwA5X+3UwIPBry8GvNY084u7yWUvB3/8rqA==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr/-/edr-0.6.4.tgz", + "integrity": "sha512-YgrSuT3yo5ZQkbvBGqQ7hG+RDvz3YygSkddg4tb1Z0Y6pLXFzwrcEwWaJCFAVeeZxdxGfCgGMUYgRVneK+WXkw==", "dev": true, + "dependencies": { + "@nomicfoundation/edr-darwin-arm64": "0.6.4", + "@nomicfoundation/edr-darwin-x64": "0.6.4", + "@nomicfoundation/edr-linux-arm64-gnu": "0.6.4", + "@nomicfoundation/edr-linux-arm64-musl": "0.6.4", + "@nomicfoundation/edr-linux-x64-gnu": "0.6.4", + "@nomicfoundation/edr-linux-x64-musl": "0.6.4", + "@nomicfoundation/edr-win32-x64-msvc": "0.6.4" + }, "engines": { "node": ">= 18" - }, - "optionalDependencies": { - "@nomicfoundation/edr-darwin-arm64": "0.3.5", - "@nomicfoundation/edr-darwin-x64": "0.3.5", - "@nomicfoundation/edr-linux-arm64-gnu": "0.3.5", - "@nomicfoundation/edr-linux-arm64-musl": "0.3.5", - "@nomicfoundation/edr-linux-x64-gnu": "0.3.5", - "@nomicfoundation/edr-linux-x64-musl": "0.3.5", - "@nomicfoundation/edr-win32-x64-msvc": "0.3.5" } }, "node_modules/@nomicfoundation/edr-darwin-arm64": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.5.tgz", - "integrity": "sha512-gIXUIiPMUy6roLHpNlxf15DumU7/YhffUf7XIB+WUjMecaySfTGyZsTGnCMJZqrDyiYqWPyPKwCV/2u/jqFAUg==", - "cpu": [ - "arm64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.6.4.tgz", + "integrity": "sha512-QNQErISLgssV9+qia8sIjRANqtbW8snSDvjspixT/kSQ5ZSGxxctTg7x72wPSrcu8+EBEveIe5uqENIp5GH8HQ==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-darwin-x64": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.5.tgz", - "integrity": "sha512-0MrpOCXUK8gmplpYZ2Cy0holHEylvWoNeecFcrP2WJ5DLQzrB23U5JU2MvUzOJ7aL76Za1VXNBWi/UeTWdHM+w==", - "cpu": [ - "x64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.6.4.tgz", + "integrity": "sha512-cjVmREiwByyc9+oGfvAh49IAw+oVJHF9WWYRD+Tm/ZlSpnEVWxrGNBak2bd/JSYjn+mZE7gmWS4SMRi4nKaLUg==", "dev": true, - "optional": true, - "os": [ - "darwin" - ], "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-arm64-gnu": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.5.tgz", - "integrity": "sha512-aw9f7AZMiY1dZFNePJGKho2k+nEgFgzUAyyukiKfSqUIMXoFXMf1U3Ujv848czrSq9c5XGcdDa2xnEf3daU3xg==", - "cpu": [ - "arm64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.6.4.tgz", + "integrity": "sha512-96o9kRIVD6W5VkgKvUOGpWyUGInVQ5BRlME2Fa36YoNsRQMaKtmYJEU0ACosYES6ZTpYC8U5sjMulvPtVoEfOA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-arm64-musl": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.5.tgz", - "integrity": "sha512-cVFRQjyABBlsbDj+XTczYBfrCHprZ6YNzN8gGGSqAh+UGIJkAIRomK6ar27GyJLNx3HkgbuDoi/9kA0zOo/95w==", - "cpu": [ - "arm64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.6.4.tgz", + "integrity": "sha512-+JVEW9e5plHrUfQlSgkEj/UONrIU6rADTEk+Yp9pbe+mzNkJdfJYhs5JYiLQRP4OjxH4QOrXI97bKU6FcEbt5Q==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-x64-gnu": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.5.tgz", - "integrity": "sha512-CjOg85DfR1Vt0fQWn5U0qi26DATK9tVzo3YOZEyI0JBsnqvk43fUTPv3uUAWBrPIRg5O5kOc9xG13hSpCBBxBg==", - "cpu": [ - "x64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.6.4.tgz", + "integrity": "sha512-nzYWW+fO3EZItOeP4CrdMgDXfaGBIBkKg0Y/7ySpUxLqzut40O4Mb0/+quqLAFkacUSWMlFp8nsmypJfOH5zoA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-linux-x64-musl": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.5.tgz", - "integrity": "sha512-hvX8bBGpBydAVevzK8jsu2FlqVZK1RrCyTX6wGHnltgMuBaoGLHYtNHiFpteOaJw2byYMiORc2bvj+98LhJ0Ew==", - "cpu": [ - "x64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.6.4.tgz", + "integrity": "sha512-QFRoE9qSQ2boRrVeQ1HdzU+XN7NUgwZ1SIy5DQt4d7jCP+5qTNsq8LBNcqhRBOATgO63nsweNUhxX/Suj5r1Sw==", "dev": true, - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">= 18" } }, "node_modules/@nomicfoundation/edr-win32-x64-msvc": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.5.tgz", - "integrity": "sha512-IJXjW13DY5UPsx/eG5DGfXtJ7Ydwrvw/BTZ2Y93lRLHzszVpSmeVmlxjZP5IW2afTSgMLaAAsqNw4NhppRGN8A==", - "cpu": [ - "x64" - ], + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.6.4.tgz", + "integrity": "sha512-2yopjelNkkCvIjUgBGhrn153IBPLwnsDeNiq6oA0WkeM8tGmQi4td+PGi9jAriUDAkc59Yoi2q9hYA6efiY7Zw==", "dev": true, - "optional": true, - "os": [ - "win32" - ], "engines": { "node": ">= 18" } @@ -3531,27 +3482,31 @@ } }, "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.1.tgz", + "integrity": "sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==", "dev": true, "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" + "readdirp": "^4.0.1" }, "engines": { - "node": ">= 8.10.0" + "node": ">= 14.16.0" }, "funding": { "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chokidar/node_modules/readdirp": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.0.2.tgz", + "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==", + "dev": true, + "engines": { + "node": ">= 14.16.0" }, - "optionalDependencies": { - "fsevents": "~2.3.2" + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, "node_modules/ci-info": { @@ -15071,14 +15026,14 @@ } }, "node_modules/hardhat": { - "version": "2.22.3", - "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.3.tgz", - "integrity": "sha512-k8JV2ECWNchD6ahkg2BR5wKVxY0OiKot7fuxiIpRK0frRqyOljcR2vKwgWSLw6YIeDcNNA4xybj7Og7NSxr2hA==", + "version": "2.22.15", + "resolved": "https://registry.npmjs.org/hardhat/-/hardhat-2.22.15.tgz", + "integrity": "sha512-BpTGa9PE/sKAaHi4s/S1e9WGv63DR1m7Lzfd60C8gSEchDPfAJssVRSq0MZ2v2k76ig9m0kHAwVLf5teYwu/Mw==", "dev": true, "dependencies": { "@ethersproject/abi": "^5.1.2", "@metamask/eth-sig-util": "^4.0.0", - "@nomicfoundation/edr": "^0.3.5", + "@nomicfoundation/edr": "^0.6.4", "@nomicfoundation/ethereumjs-common": "4.0.4", "@nomicfoundation/ethereumjs-tx": "5.0.4", "@nomicfoundation/ethereumjs-util": "9.0.4", @@ -15091,7 +15046,7 @@ "ansi-escapes": "^4.3.0", "boxen": "^5.1.2", "chalk": "^2.4.2", - "chokidar": "^3.4.0", + "chokidar": "^4.0.0", "ci-info": "^2.0.0", "debug": "^4.1.1", "enquirer": "^2.3.0", @@ -15104,6 +15059,7 @@ "glob": "7.2.0", "immutable": "^4.0.0-rc.12", "io-ts": "1.10.4", + "json-stream-stringify": "^3.1.4", "keccak": "^3.0.2", "lodash": "^4.17.11", "mnemonist": "^0.38.0", @@ -15112,7 +15068,7 @@ "raw-body": "^2.4.1", "resolve": "1.17.0", "semver": "^6.3.0", - "solc": "0.7.3", + "solc": "0.8.26", "source-map-support": "^0.5.13", "stacktrace-parser": "^0.1.10", "tsort": "0.0.1", @@ -15236,6 +15192,15 @@ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, + "node_modules/hardhat/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, "node_modules/hardhat/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", @@ -15266,15 +15231,6 @@ "node": ">=4" } }, - "node_modules/hardhat/node_modules/jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, "node_modules/hardhat/node_modules/resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -15287,18 +15243,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hardhat/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/hardhat/node_modules/semver": { "version": "6.3.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", @@ -15309,39 +15253,24 @@ } }, "node_modules/hardhat/node_modules/solc": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/solc/-/solc-0.7.3.tgz", - "integrity": "sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA==", + "version": "0.8.26", + "resolved": "https://registry.npmjs.org/solc/-/solc-0.8.26.tgz", + "integrity": "sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==", "dev": true, "dependencies": { "command-exists": "^1.2.8", - "commander": "3.0.2", + "commander": "^8.1.0", "follow-redirects": "^1.12.1", - "fs-extra": "^0.30.0", "js-sha3": "0.8.0", "memorystream": "^0.3.1", - "require-from-string": "^2.0.0", "semver": "^5.5.0", "tmp": "0.0.33" }, "bin": { - "solcjs": "solcjs" + "solcjs": "solc.js" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/hardhat/node_modules/solc/node_modules/fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" + "node": ">=10.0.0" } }, "node_modules/hardhat/node_modules/solc/node_modules/semver": { @@ -16162,6 +16091,15 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stream-stringify": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/json-stream-stringify/-/json-stream-stringify-3.1.6.tgz", + "integrity": "sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==", + "dev": true, + "engines": { + "node": ">=7.10.1" + } + }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", diff --git a/package.json b/package.json index 6933a56e..9b246c68 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "ethereum-waffle": "^3.4.4", "ethereumjs-util": "^7.0.8", "ethers": "^5.6.2", - "hardhat": "^2.12.2", + "hardhat": "^2.22.15", "hardhat-gas-reporter": "^1.0.8", "prettier": "^2.6.1", "prettier-plugin-solidity": "^1.0.0-beta.13", diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index 36d8d686..9c4c1001 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -111,11 +111,18 @@ async function main() { rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers }); + const deployResult = JSON.stringify({ - ethterum: l1DeployScript, + ethereum: l1DeployScript, optimism: l2DeployScript - }); - fs.writeFileSync('deployResult.json', JSON.stringify(deployResult, null, 2), 'utf-8'); + }, null, 2); + + const fileName = 'deployResult.json'; + try { + fs.writeFileSync(fileName, `${deployResult}\n`, { encoding: "utf8", flag: "w" }); + } catch (error) { + throw new Error(`Failed to write network state file ${fileName}: ${(error as Error).message}`); + } } main().catch((error) => { From 10d492f8ecbe9ddd0b797a7ec156d97663d0db24 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Thu, 31 Oct 2024 11:47:01 +0100 Subject: [PATCH 05/34] add test for op stack pusher --- ...er-pushing-token-rate.integration.test.ts} | 0 ...her-pushing-token-rate.integration.test.ts | 180 ++++++++++++++++++ utils/optimism/testing.ts | 11 +- utils/testing/env.ts | 3 + 4 files changed, 193 insertions(+), 1 deletion(-) rename test/integration/{pushingTokenRate.integration.test.ts => notifier-pushing-token-rate.integration.test.ts} (100%) create mode 100644 test/integration/op-pusher-pushing-token-rate.integration.test.ts diff --git a/test/integration/pushingTokenRate.integration.test.ts b/test/integration/notifier-pushing-token-rate.integration.test.ts similarity index 100% rename from test/integration/pushingTokenRate.integration.test.ts rename to test/integration/notifier-pushing-token-rate.integration.test.ts diff --git a/test/integration/op-pusher-pushing-token-rate.integration.test.ts b/test/integration/op-pusher-pushing-token-rate.integration.test.ts new file mode 100644 index 00000000..e653731c --- /dev/null +++ b/test/integration/op-pusher-pushing-token-rate.integration.test.ts @@ -0,0 +1,180 @@ +import { assert } from "chai"; +import { BigNumber } from "ethers"; +import env from "../../utils/env"; +import { wei } from "../../utils/wei"; +import optimism from "../../utils/optimism"; +import testing, { scenario } from "../../utils/testing"; +import { getExchangeRate, refSlotTimestamp } from "../../utils/testing/helpers"; + +scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) + + .step("Push Token Rate", async (ctx) => { + const { + tokenRateOracle, + opTokenRatePusher, + l1CrossDomainMessenger, + lido, + accountingOracle + } = ctx; + + const { + tokenRate, + } = ctx.constants; + + const tx = await opTokenRatePusher + .connect(lido) + .pushTokenRate(); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + const updateRateTime = await refSlotTimestamp(accountingOracle); + const l2Calldata = tokenRateOracle.interface.encodeFunctionData( + "updateRate", + [ + tokenRate, + updateRateTime + ] + ); + + await assert.emits(l1CrossDomainMessenger, tx, "SentMessage", [ + tokenRateOracle.address, + opTokenRatePusher.address, + l2Calldata, + messageNonce, + 300_000, + ]); + }) + + .step("Finalize pushing rate", async (ctx) => { + const { + opTokenRatePusher, + tokenRateOracle, + l1CrossDomainMessenger, + accountingOracle + } = ctx; + + const [ + , + tokenRateAnswerBefore, + startedAt_updatedRateBefore, + , + ] = await tokenRateOracle.latestRoundData(); + + console.log("tokenRateAnswerBefore=", tokenRateAnswerBefore); + console.log("startedAt_updatedRateBefore=",startedAt_updatedRateBefore); + + const { + tokenRate + } = ctx.constants; + + const account = ctx.accounts.accountA; + await l1CrossDomainMessenger + .connect(account.l1Signer) + .setXDomainMessageSender(opTokenRatePusher.address); + + const minTimeBetweenTokenRateUpdates = await tokenRateOracle.MIN_TIME_BETWEEN_TOKEN_RATE_UPDATES(); + const updateRateTime = (await refSlotTimestamp(accountingOracle)) + .add(minTimeBetweenTokenRateUpdates) + .add(1000); + + const messageNonce = await l1CrossDomainMessenger.messageNonce(); + + const tx = await ctx.l2CrossDomainMessenger + .connect(ctx.accounts.l1CrossDomainMessengerAliased) + .relayMessage( + messageNonce, + opTokenRatePusher.address, + tokenRateOracle.address, + 0, + 300_000, + tokenRateOracle.interface.encodeFunctionData("updateRate", [ + tokenRate, + updateRateTime + ]), + { gasLimit: 5_000_000 } + ); + + console.log("new tokenRate=",tokenRate); + console.log("new updateRateTime=",updateRateTime); + + if ((updateRateTime.sub(startedAt_updatedRateBefore)).gt(minTimeBetweenTokenRateUpdates)) { + await assert.emits(tokenRateOracle, tx, "RateUpdated", [ + tokenRate, + updateRateTime + ]); + } + + const answer = await tokenRateOracle.latestAnswer(); + assert.equalBN(answer, tokenRate); + + const [ + , + tokenRateAnswer, + startedAt_, + , + ] = await tokenRateOracle.latestRoundData(); + + assert.equalBN(tokenRateAnswer, tokenRate); + assert.equalBN(startedAt_, updateRateTime); + }) + + .run(); + +async function ctxFactory() { + const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); + + const { + totalPooledEther, + totalShares, + l1Provider, + l2Provider, + l1ERC20ExtendedTokensBridgeAdmin, + l2ERC20ExtendedTokensBridgeAdmin, + ...contracts + } = await optimism.testing(networkName).getIntegrationTestSetup(); + + const lidoAsEOA = await testing.impersonate(env.address("LIDO"), l1Provider); + + const tokenRateDecimals = BigNumber.from(27); + const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); + + const optContracts = optimism.contracts(networkName, { forking: true }); + const l2CrossDomainMessenger = optContracts.L2CrossDomainMessenger; + + await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + + const l1CrossDomainMessengerAliased = await testing.impersonate( + testing.accounts.applyL1ToL2Alias(optContracts.L1CrossDomainMessengerStub.address), + l2Provider + ); + await testing.setBalance( + await l1CrossDomainMessengerAliased.getAddress(), + wei.toBigNumber(wei`1 ether`), + l2Provider + ); + + const tokenRateOracle = contracts.tokenRateOracle; + const opTokenRatePusher = contracts.opStackTokenRatePusher; + const l1Token = contracts.l1Token; + const accountingOracle = contracts.accountingOracle; + + const accountA = testing.accounts.accountA(l1Provider, l2Provider); + const l1CrossDomainMessenger = optContracts.L1CrossDomainMessengerStub; + + return { + tokenRateOracle, + opTokenRatePusher, + l1CrossDomainMessenger, + l2CrossDomainMessenger, + l1Token, + accountingOracle, + l1Provider, + lido: lidoAsEOA, + accounts: { + accountA, + l1CrossDomainMessengerAliased + }, + constants: { + tokenRate + } + }; +} diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index 0e97bcd4..245e4d2a 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -16,7 +16,8 @@ import { ERC20RebasableBridgedPermit__factory, AccountingOracleStub__factory, TokenRateNotifier__factory, - StETHStub__factory + StETHStub__factory, + OpStackTokenRatePusher__factory } from "../../typechain"; import addresses from "./addresses"; import contracts from "./contracts"; @@ -166,6 +167,7 @@ async function loadDeployedBridges( ...connectBridgeContracts( { tokenRateNotifier: testingUtils.env.OPT_L1_TOKEN_RATE_NOTIFIER(), + opStackTokenRatePusher: testingUtils.env.OPT_L1_OP_STACK_TOKEN_RATE_PUSHER(), tokenRateOracle: testingUtils.env.OPT_L2_TOKEN_RATE_ORACLE(), l2Token: testingUtils.env.OPT_L2_NON_REBASABLE_TOKEN(), l2TokenRebasable: testingUtils.env.OPT_L2_REBASABLE_TOKEN(), @@ -334,6 +336,7 @@ async function deployTestBridge( ...connectBridgeContracts( { tokenRateNotifier: ethDeployScript.tokenRateNotifierImplAddress, + opStackTokenRatePusher: ethDeployScript.opStackTokenRatePusherImplAddress, tokenRateOracle: optDeployScript.tokenRateOracleProxyAddress, l2Token: optDeployScript.tokenProxyAddress, l2TokenRebasable: optDeployScript.tokenRebasableProxyAddress, @@ -349,6 +352,7 @@ async function deployTestBridge( function connectBridgeContracts( addresses: { tokenRateNotifier: string; + opStackTokenRatePusher: string; tokenRateOracle: string; l2Token: string; l2TokenRebasable: string; @@ -362,6 +366,10 @@ function connectBridgeContracts( addresses.tokenRateNotifier, ethSignerOrProvider ); + const opStackTokenRatePusher = OpStackTokenRatePusher__factory.connect( + addresses.opStackTokenRatePusher, + ethSignerOrProvider + ); const l1LidoTokensBridge = L1LidoTokensBridge__factory.connect( addresses.l1LidoTokensBridge, ethSignerOrProvider @@ -384,6 +392,7 @@ function connectBridgeContracts( ); return { tokenRateNotifier, + opStackTokenRatePusher, tokenRateOracle, l2Token, l2TokenRebasable, diff --git a/utils/testing/env.ts b/utils/testing/env.ts index 69dd135b..877f27e7 100644 --- a/utils/testing/env.ts +++ b/utils/testing/env.ts @@ -34,6 +34,9 @@ export default { OPT_L1_TOKEN_RATE_NOTIFIER() { return env.address("TESTING_OPT_L1_TOKEN_RATE_NOTIFIER"); }, + OPT_L1_OP_STACK_TOKEN_RATE_PUSHER() { + return env.address("TESTING_OPT_L1_OP_STACK_TOKEN_RATE_PUSHER"); + }, OPT_GOV_BRIDGE_EXECUTOR() { return env.address("TESTING_OPT_GOV_BRIDGE_EXECUTOR"); }, From be3b2026cd444bd2de91ac5b1718b3c1418df7dd Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 1 Nov 2024 15:23:48 +0100 Subject: [PATCH 06/34] fix deploy params --- scripts/optimism/deploy-automaton.ts | 8 +++- utils/deployment.ts | 64 ++++++++++------------------ 2 files changed, 29 insertions(+), 43 deletions(-) diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index 9c4c1001..e78bab7c 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -35,7 +35,7 @@ async function main() { deployer: ethDeployer, admins: { - proxy: deploymentConfig.ethereum.bridgeProxyAdmin, + proxy: deploymentConfig.ethereum.proxyAdmin, bridge: ethDeployer.address }, deployOffset: 0, @@ -52,15 +52,19 @@ async function main() { l1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp }, l2TokenNonRebasable: { + name: deploymentConfig.optimism.l2TokenNonRebasableName, + symbol: deploymentConfig.optimism.l2TokenNonRebasableSymbol, version: deploymentConfig.optimism.l2TokenNonRebasableDomainVersion }, l2TokenRebasable: { + name: deploymentConfig.optimism.l2TokenRebasableName, + symbol: deploymentConfig.optimism.l2TokenRebasableSymbol, version: deploymentConfig.optimism.l2TokenRebasableDomainVersion }, deployer: optDeployer, admins: { - proxy: deploymentConfig.optimism.bridgeProxyAdmin, + proxy: deploymentConfig.optimism.proxyAdmin, bridge: optDeployer.address, }, deployOffset: 0, diff --git a/utils/deployment.ts b/utils/deployment.ts index 6d2c5444..f593cbd1 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -5,33 +5,24 @@ import env from "./env"; import { DeployScript } from "./deployment/DeployScript"; import { BridgingManagerSetupConfig } from "./bridging-management"; -interface EthereumDeploymentConfig extends BridgingManagerSetupConfig { - bridgeProxyAdmin: string; - +interface EthereumAutomatonDeploymentConfig extends BridgingManagerSetupConfig { + accountingOracle: string; l1TokenNonRebasable: string; l1RebasableToken: string; - accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; - l1TokenBridge: string; - lido: string; - tokenRateNotifierOwner: string; + proxyAdmin: string; l1CrossDomainMessenger: string; } -interface OptimismDeploymentConfig extends BridgingManagerSetupConfig { - bridgeProxyAdmin: string; - +interface OptimismAutomatonDeploymentConfig extends BridgingManagerSetupConfig { govBridgeExecutor: string; - l2CrossDomainMessenger: string; /// Oracle - tokenRateOracleProxyAdmin: string; tokenRateOracleAdmin: string; tokenRateUpdateEnabled: boolean; tokenRateUpdateDisablers?: string[], tokenRateUpdateEnablers?: string[], - tokenRateOutdatedDelay: BigNumber; maxAllowedL2ToL1ClockLag: BigNumber; maxAllowedTokenRateDeviationPerDayBp: BigNumber; @@ -41,36 +32,35 @@ interface OptimismDeploymentConfig extends BridgingManagerSetupConfig { initialTokenRateL1Timestamp: BigNumber; /// L2 wstETH address to upgrade - l2TokenNonRebasableAddress: string; + l2TokenNonRebasableName?: string; + l2TokenNonRebasableSymbol?: string; l2TokenNonRebasableDomainVersion: string; /// L2 stETH + l2TokenRebasableName?: string; + l2TokenRebasableSymbol?: string; l2TokenRebasableDomainVersion: string; - l2TokenRebasableProxyAdmin: string; /// bridge - l2TokenBridge: string; + proxyAdmin: string; } interface MultiChainDeploymentConfig { - ethereum: EthereumDeploymentConfig; - optimism: OptimismDeploymentConfig; + ethereum: EthereumAutomatonDeploymentConfig; + optimism: OptimismAutomatonDeploymentConfig; } export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { return { ethereum: { - l1CrossDomainMessenger: env.address("L1_CROSSDOMAIN_MESSENGER", "0x0000000000000000000000000000000000000000"), + l1CrossDomainMessenger: env.address("L1_CROSSDOMAIN_MESSENGER"), l1TokenNonRebasable: env.address("L1_NON_REBASABLE_TOKEN"), l1RebasableToken: env.address("L1_REBASABLE_TOKEN"), accountingOracle: env.address("ACCOUNTING_ORACLE"), l2GasLimitForPushingTokenRate: BigNumber.from(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), - l1TokenBridge: env.address("L1_TOKEN_BRIDGE", "0x0000000000000000000000000000000000000000"), - lido: env.address("LIDO"), - tokenRateNotifierOwner: env.address("TOKEN_RATE_NOTIFIER_OWNER"), // Bridge - bridgeProxyAdmin: env.address("L1_PROXY_ADMIN"), + proxyAdmin: env.address("L1_PROXY_ADMIN"), bridgeAdmin: env.address("L1_BRIDGE_ADMIN"), depositsEnabled: env.bool("L1_DEPOSITS_ENABLED", false), withdrawalsEnabled: env.bool("L1_WITHDRAWALS_ENABLED", false), @@ -80,11 +70,10 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { withdrawalsDisablers: env.addresses("L1_WITHDRAWALS_DISABLERS", []), }, optimism: { - l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER", "0x0000000000000000000000000000000000000000"), + l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER"), govBridgeExecutor: env.address("GOV_BRIDGE_EXECUTOR"), /// TokenRateOracle - tokenRateOracleProxyAdmin: env.address("TOKEN_RATE_ORACLE_PROXY_ADMIN"), tokenRateOracleAdmin: env.address("TOKEN_RATE_ORACLE_ADMIN"), tokenRateUpdateEnabled: env.bool("TOKEN_RATE_UPDATE_ENABLED", true), tokenRateUpdateDisablers: env.addresses("TOKEN_RATE_UPDATE_DISABLERS", []), @@ -99,17 +88,17 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { initialTokenRateL1Timestamp: BigNumber.from(env.string("INITIAL_TOKEN_RATE_L1_TIMESTAMP")), // wstETH - l2TokenNonRebasableAddress: env.address("L2_TOKEN_NON_REBASABLE", "0x0000000000000000000000000000000000000000"), + l2TokenNonRebasableName: env.string("L2_TOKEN_NON_REBASABLE_NAME"), + l2TokenNonRebasableSymbol: env.string("L2_TOKEN_NON_REBASABLE_SYMBOL"), l2TokenNonRebasableDomainVersion: env.string("L2_TOKEN_NON_REBASABLE_SIGNING_DOMAIN_VERSION"), // stETH + l2TokenRebasableName: env.string("L2_TOKEN_REBASABLE_NAME"), + l2TokenRebasableSymbol: env.string("L2_TOKEN_REBASABLE_SYMBOL"), l2TokenRebasableDomainVersion: env.string("L2_TOKEN_REBASABLE_SIGNING_DOMAIN_VERSION"), - l2TokenRebasableProxyAdmin: env.string("L2_TOKEN_REBASABLE_PROXY_ADMIN"), // Bridge - l2TokenBridge: env.address("L2_TOKEN_BRIDGE", "0x0000000000000000000000000000000000000000"), - - bridgeProxyAdmin: env.address("L2_PROXY_ADMIN"), + proxyAdmin: env.address("L2_PROXY_ADMIN"), bridgeAdmin: env.address("L2_BRIDGE_ADMIN"), depositsEnabled: env.bool("L2_DEPOSITS_ENABLED", false), withdrawalsEnabled: env.bool("L2_WITHDRAWALS_ENABLED", false), @@ -159,7 +148,7 @@ export async function printMultiChainDeploymentConfig( async function printEthereumDeploymentConfig( deployer: Wallet, - params: EthereumDeploymentConfig, + params: EthereumAutomatonDeploymentConfig, scratchDeploy: boolean ) { const pad = " ".repeat(4); @@ -167,17 +156,14 @@ async function printEthereumDeploymentConfig( console.log(`${pad}· Chain ID: ${chainId}`); console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); + console.log(`${pad}·· Proxy Admin: ${chalk.underline(params.proxyAdmin)}`); console.log(`${pad}· l1TokenNonRebasable: ${chalk.underline(params.l1TokenNonRebasable)}`); console.log(`${pad}· l1RebasableToken: ${chalk.underline(params.l1RebasableToken)}`); console.log(`${pad}· accountingOracle: ${chalk.underline(params.accountingOracle)}`); console.log(`${pad}· l2GasLimitForPushingTokenRate: ${chalk.underline(params.l2GasLimitForPushingTokenRate)}`); - console.log(`${pad}· l1TokenBridge: ${chalk.underline(params.l1TokenBridge)}`); - console.log(`${pad}· lido: ${chalk.underline(params.lido)}`); - console.log(`${pad}· tokenRateNotifierOwner: ${chalk.underline(params.tokenRateNotifierOwner)}`); if(scratchDeploy) { console.log(`${pad}· Ethereum Bridge`); - console.log(`${pad}·· Proxy Admin: ${chalk.underline(params.bridgeProxyAdmin)}`); console.log(`${pad}·· Bridge Admin: ${chalk.underline(params.bridgeAdmin)}`); console.log(`${pad}·· Deposits Enabled: ${params.depositsEnabled}`); console.log( @@ -204,15 +190,15 @@ async function printEthereumDeploymentConfig( async function printOptimismDeploymentConfig( deployer: Wallet, - params: OptimismDeploymentConfig, + params: OptimismAutomatonDeploymentConfig, scratchDeploy: boolean ) { const pad = " ".repeat(4); const chainId = await deployer.getChainId(); console.log(`${pad}· Chain ID: ${chainId}`); console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); + console.log(`${pad}·· Proxy Admin: ${chalk.underline(params.proxyAdmin)}`); console.log(`${pad}· govBridgeExecutor: ${chalk.underline(params.govBridgeExecutor)}`); - console.log(`${pad}· tokenRateOracleProxyAdmin: ${chalk.underline(params.tokenRateOracleProxyAdmin)}`); console.log(`${pad}· tokenRateOracleAdmin: ${chalk.underline(params.tokenRateOracleAdmin)}`); console.log(`${pad}· tokenRateUpdateEnabled: ${chalk.underline(params.tokenRateUpdateEnabled)}`); console.log(`${pad}· tokenRateUpdateDisablers: ${chalk.underline(params.tokenRateUpdateDisablers)}`); @@ -224,15 +210,11 @@ async function printOptimismDeploymentConfig( console.log(`${pad}· minTimeBetweenTokenRateUpdates: ${chalk.underline(params.minTimeBetweenTokenRateUpdates)}`); console.log(`${pad}· initialTokenRateValue: ${chalk.underline(params.initialTokenRateValue)}`); console.log(`${pad}· initialTokenRateL1Timestamp: ${chalk.underline(params.initialTokenRateL1Timestamp)}`); - console.log(`${pad}· l2TokenNonRebasableAddress: ${chalk.underline(params.l2TokenNonRebasableAddress)}`); console.log(`${pad}· l2TokenNonRebasableDomainVersion: ${chalk.underline(params.l2TokenNonRebasableDomainVersion)}`); - console.log(`${pad}· l2TokenRebasableProxyAdmin: ${chalk.underline(params.l2TokenRebasableProxyAdmin)}`); console.log(`${pad}· l2TokenRebasableDomainVersion: ${chalk.underline(params.l2TokenRebasableDomainVersion)}`); - console.log(`${pad}· l2TokenBridge: ${chalk.underline(params.l2TokenBridge)}`); if (scratchDeploy) { console.log(`${pad}· Optimism Bridge`); - console.log(`${pad}·· Proxy Admin: ${chalk.underline(params.bridgeProxyAdmin)}`); console.log(`${pad}·· Admin: ${chalk.underline(params.bridgeAdmin)}`); console.log(`${pad}·· Deposits Enabled: ${params.depositsEnabled}`); console.log( From 88cd010d7b7a88215a9f866b66227c1ec0bd15a9 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 1 Nov 2024 15:32:07 +0100 Subject: [PATCH 07/34] remove gov executor config --- utils/deployment.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/utils/deployment.ts b/utils/deployment.ts index f593cbd1..5f8a722d 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -15,7 +15,6 @@ interface EthereumAutomatonDeploymentConfig extends BridgingManagerSetupConfig { } interface OptimismAutomatonDeploymentConfig extends BridgingManagerSetupConfig { - govBridgeExecutor: string; l2CrossDomainMessenger: string; /// Oracle @@ -71,7 +70,6 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { }, optimism: { l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER"), - govBridgeExecutor: env.address("GOV_BRIDGE_EXECUTOR"), /// TokenRateOracle tokenRateOracleAdmin: env.address("TOKEN_RATE_ORACLE_ADMIN"), @@ -198,7 +196,6 @@ async function printOptimismDeploymentConfig( console.log(`${pad}· Chain ID: ${chainId}`); console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); console.log(`${pad}·· Proxy Admin: ${chalk.underline(params.proxyAdmin)}`); - console.log(`${pad}· govBridgeExecutor: ${chalk.underline(params.govBridgeExecutor)}`); console.log(`${pad}· tokenRateOracleAdmin: ${chalk.underline(params.tokenRateOracleAdmin)}`); console.log(`${pad}· tokenRateUpdateEnabled: ${chalk.underline(params.tokenRateUpdateEnabled)}`); console.log(`${pad}· tokenRateUpdateDisablers: ${chalk.underline(params.tokenRateUpdateDisablers)}`); From 80f8344ef450d81aee8e52f5f603c5cd12558480 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 1 Nov 2024 17:26:29 +0100 Subject: [PATCH 08/34] remove lido from test --- .../op-pusher-pushing-token-rate.integration.test.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/integration/op-pusher-pushing-token-rate.integration.test.ts b/test/integration/op-pusher-pushing-token-rate.integration.test.ts index e653731c..e3dfdada 100644 --- a/test/integration/op-pusher-pushing-token-rate.integration.test.ts +++ b/test/integration/op-pusher-pushing-token-rate.integration.test.ts @@ -13,7 +13,6 @@ scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) tokenRateOracle, opTokenRatePusher, l1CrossDomainMessenger, - lido, accountingOracle } = ctx; @@ -21,8 +20,10 @@ scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) tokenRate, } = ctx.constants; + const account = ctx.accounts.accountA; + const tx = await opTokenRatePusher - .connect(lido) + .connect(account.l1Signer) .pushTokenRate(); const messageNonce = await l1CrossDomainMessenger.messageNonce(); @@ -132,8 +133,6 @@ async function ctxFactory() { ...contracts } = await optimism.testing(networkName).getIntegrationTestSetup(); - const lidoAsEOA = await testing.impersonate(env.address("LIDO"), l1Provider); - const tokenRateDecimals = BigNumber.from(27); const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); @@ -168,7 +167,6 @@ async function ctxFactory() { l1Token, accountingOracle, l1Provider, - lido: lidoAsEOA, accounts: { accountA, l1CrossDomainMessengerAliased From 871369f7a870fb082353866a20fedb4ad4a7e32c Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Thu, 7 Nov 2024 11:26:08 +0700 Subject: [PATCH 09/34] fix test for anvil --- utils/optimism/testing.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index 245e4d2a..6fe34818 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -136,6 +136,7 @@ export default function testing(networkName: NetworkName) { ).deploy(); const stubBytecode = await ethProvider.send("eth_getCode", [ stub.address, + "latest" ]); await ethProvider.send("hardhat_setCode", [ From e97eb49307859dafe7e552da3ddb7cbbcc217582 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 8 Nov 2024 11:46:53 +0700 Subject: [PATCH 10/34] use unichain messenger --- utils/optimism/addresses.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/optimism/addresses.ts b/utils/optimism/addresses.ts index 762cdb82..fd6dd18f 100644 --- a/utils/optimism/addresses.ts +++ b/utils/optimism/addresses.ts @@ -7,11 +7,11 @@ const OptimismMainnetAddresses: OptContractAddresses = { }; const OptimismSepoliaAddresses: OptContractAddresses = { - L1CrossDomainMessenger: "0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef", + L1CrossDomainMessenger: "0x448A37330A60494E666F6DD60aD48d930AEbA381", L2CrossDomainMessenger: "0x4200000000000000000000000000000000000007", }; -export default function addresses( +export default function addresses( networkName: NetworkName, options: CommonOptions = {} ) { From 1047114d039fb7cb9fa31495a8e2c99427179182 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 8 Nov 2024 17:58:35 +0700 Subject: [PATCH 11/34] add unichain in config --- hardhat.config.ts | 37 ++++++++++++++++++++++++++------ utils/deployment/DeployScript.ts | 2 ++ utils/network.ts | 8 +++++++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index d5704e34..ab239c7b 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -69,6 +69,22 @@ const config: HardhatUserConfig = { opt_sepolia_fork: { url: "http://localhost:9545", }, + + // Unichain Public Chains + uni_mainnet: { + url: env.string("RPC_UNI_MAINNET", ""), + }, + uni_sepolia: { + url: env.string("RPC_UNI_SEPOLIA", ""), + }, + + // Unichain Fork Chains + uni_mainnet_fork: { + url: "http://localhost:9545", + }, + uni_sepolia_fork: { + url: "http://localhost:9545", + }, }, gasReporter: { enabled: env.string("REPORT_GAS", "false") !== "false", @@ -80,6 +96,7 @@ const config: HardhatUserConfig = { sepolia: env.string("ETHERSCAN_API_KEY_ETH", ""), optimisticEthereum: env.string("ETHERSCAN_API_KEY_OPT", ""), "opt_sepolia": env.string("ETHERSCAN_API_KEY_OPT", ""), + "uni_sepolia": env.string("ETHERSCAN_API_KEY_OPT", ""), }, customChains: [ @@ -92,13 +109,21 @@ const config: HardhatUserConfig = { }, }, { - network: 'opt_sepolia', - chainId: 11155420, - urls: { - apiURL: 'https://api-sepolia-optimism.etherscan.io/api', - browserURL: 'https://sepolia-optimism.etherscan.io', - }, + network: 'opt_sepolia', + chainId: 11155420, + urls: { + apiURL: 'https://api-sepolia-optimism.etherscan.io/api', + browserURL: 'https://sepolia-optimism.etherscan.io', }, + }, + { + network: 'uni_sepolia', + chainId: 1301, + urls: { + apiURL: 'https://api-sepolia.uniscan.xyz/api', + browserURL: 'https://api-sepolia.uniscan.xyz', + }, + }, ], }, typechain: { diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index 3e9f7b8c..62ff36be 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -169,6 +169,8 @@ export class DeployScript { 11155111: "eth_sepolia", 10: "opt_mainnet", 11155420: "opt_sepolia", + 130: "uni_mainnet", + 1301: "uni_sepolia", 31337: "hardhat", }; const networkName = networkNameByChainId[chainId] || ""; diff --git a/utils/network.ts b/utils/network.ts index 30603cda..9b7a2af1 100644 --- a/utils/network.ts +++ b/utils/network.ts @@ -19,6 +19,10 @@ const HARDHAT_NETWORK_NAMES = { sepolia: "opt_sepolia", mainnet: "opt_mainnet", }, + uni: { + sepolia: "uni_sepolia", + mainnet: "uni_mainnet", + } }; const HARDHAT_NETWORK_NAMES_FORK = { @@ -30,6 +34,10 @@ const HARDHAT_NETWORK_NAMES_FORK = { sepolia: "opt_sepolia_fork", mainnet: "opt_mainnet_fork", }, + uni: { + sepolia: "uni_sepolia_fork", + mainnet: "uni_mainnet_fork", + }, }; export function getConfig(networkName: string, hre: HardhatRuntimeEnvironment) { From c21e667a98ecfd51c7d2bb983f9bf6082fa4b6c3 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 8 Nov 2024 18:21:18 +0700 Subject: [PATCH 12/34] save deploy args --- scripts/optimism/deploy-automaton.ts | 2 ++ utils/deployment/DeployScript.ts | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index e78bab7c..47e2107f 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -115,6 +115,8 @@ async function main() { rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers }); + l1DeployScript.saveResultToFile("l1DeployArgs.json"); + l2DeployScript.saveResultToFile("l2DeployArgs.json"); const deployResult = JSON.stringify({ ethereum: l1DeployScript, diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index 62ff36be..9471301b 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -8,6 +8,7 @@ import { Wallet, } from "ethers"; import network from "../network"; +import * as fs from 'fs'; interface TypechainFactoryConstructor< T extends ContractFactory = ContractFactory @@ -56,6 +57,7 @@ export class DeployScript { private readonly steps: DeployStep[] = []; private contracts: Contract[] = []; public readonly deployer: Wallet; + private resultJson: any; constructor(deployer: Wallet, logger?: Logger) { this.deployer = deployer; @@ -79,6 +81,14 @@ export class DeployScript { return res; } + saveResultToFile(fileName: string) { + try { + fs.writeFileSync(fileName, `${this.resultJson}\n`, { encoding: "utf8", flag: "w" }); + } catch (error) { + throw new Error(`Failed to write network state file ${fileName}: ${(error as Error).message}`); + } + } + print(printOptions?: PrintOptions) { for (let i = 0; i < this.steps.length; ++i) { this._printStepInfo(this._getStepInfo(i), { @@ -113,6 +123,7 @@ export class DeployScript { contract.address, this._getStepInfo(index) ); + this.resultJson[contract.address] = this._getStepInfo(index).args; return contract; } From f7a150280436017ebc8b65827155f7c0704c0ee6 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 8 Nov 2024 18:48:40 +0700 Subject: [PATCH 13/34] fix saving args --- scripts/optimism/deploy-automaton.ts | 4 ++-- utils/deployment/DeployScript.ts | 22 +++++++++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index 47e2107f..98a4e2d7 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -115,8 +115,8 @@ async function main() { rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers }); - l1DeployScript.saveResultToFile("l1DeployArgs.json"); - l2DeployScript.saveResultToFile("l2DeployArgs.json"); + await l1DeployScript.saveResultToFile("l1DeployArgs.json"); + await l2DeployScript.saveResultToFile("l2DeployArgs.json"); const deployResult = JSON.stringify({ ethereum: l1DeployScript, diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index 9471301b..f45f2099 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -57,7 +57,7 @@ export class DeployScript { private readonly steps: DeployStep[] = []; private contracts: Contract[] = []; public readonly deployer: Wallet; - private resultJson: any; + private resultJson: { [key: string]: any } = {}; constructor(deployer: Wallet, logger?: Logger) { this.deployer = deployer; @@ -81,12 +81,14 @@ export class DeployScript { return res; } - saveResultToFile(fileName: string) { - try { - fs.writeFileSync(fileName, `${this.resultJson}\n`, { encoding: "utf8", flag: "w" }); - } catch (error) { - throw new Error(`Failed to write network state file ${fileName}: ${(error as Error).message}`); - } + async saveResultToFile(fileName: string) { + console.log("this.resultJson=",this.resultJson); + fs.writeFile(fileName, JSON.stringify(this.resultJson, null, 2), { encoding: "utf8", flag: "w" }, function(err) { + if (err) { + return console.error(err); + } + console.log("File created!"); + }); } print(printOptions?: PrintOptions) { @@ -119,11 +121,13 @@ export class DeployScript { if (step.afterDeploy) { step.afterDeploy(contract); } + const stepInfo = this._getStepInfo(index); await this._printVerificationCommand( contract.address, - this._getStepInfo(index) + stepInfo ); - this.resultJson[contract.address] = this._getStepInfo(index).args; + const arsString = stepInfo.args.map((a) => `"${a.value}"`).join(" "); + this.resultJson[contract.address] = arsString; return contract; } From c35f7c8410229940c24a65c47c4394ad71263eba Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Sun, 10 Nov 2024 12:02:52 +0700 Subject: [PATCH 14/34] update verifier --- hardhat.config.ts | 6 +- package-lock.json | 220 ++++++++++++++++++++++++---------------------- package.json | 2 +- 3 files changed, 121 insertions(+), 107 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index ab239c7b..0082ad41 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -1,7 +1,7 @@ import * as dotenv from "dotenv"; import { HardhatUserConfig } from "hardhat/config"; -import "@nomiclabs/hardhat-etherscan"; +import "@nomicfoundation/hardhat-verify"; import "@nomiclabs/hardhat-waffle"; import "@typechain/hardhat"; import "hardhat-gas-reporter"; @@ -120,8 +120,8 @@ const config: HardhatUserConfig = { network: 'uni_sepolia', chainId: 1301, urls: { - apiURL: 'https://api-sepolia.uniscan.xyz/api', - browserURL: 'https://api-sepolia.uniscan.xyz', + apiURL: 'https://unichain-sepolia.blockscout.com/api', + browserURL: 'https://unichain-sepolia.blockscout.com/', }, }, ], diff --git a/package-lock.json b/package-lock.json index c15d351a..314c0e65 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,8 @@ "p-limit": "3.1.0" }, "devDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.11", "@nomiclabs/hardhat-ethers": "^2.0.6", - "@nomiclabs/hardhat-etherscan": "^3.1.8", "@nomiclabs/hardhat-waffle": "^2.0.3", "@typechain/ethers-v5": "^7.2.0", "@typechain/hardhat": "^2.3.1", @@ -1677,6 +1677,115 @@ } } }, + "node_modules/@nomicfoundation/hardhat-verify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-verify/-/hardhat-verify-2.0.11.tgz", + "integrity": "sha512-lGIo4dNjVQFdsiEgZp3KP6ntLiF7xJEJsbNHfSyIiFCyI0Yv0518ElsFtMC5uCuHEChiBBMrib9jWQvHHT+X3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ethersproject/abi": "^5.1.2", + "@ethersproject/address": "^5.0.2", + "cbor": "^8.1.0", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "lodash.clonedeep": "^4.5.0", + "semver": "^6.3.0", + "table": "^6.8.0", + "undici": "^5.14.0" + }, + "peerDependencies": { + "hardhat": "^2.0.4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@nomicfoundation/hardhat-verify/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@nomicfoundation/solidity-analyzer": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.1.tgz", @@ -1868,108 +1977,6 @@ "hardhat": "^2.0.0" } }, - "node_modules/@nomiclabs/hardhat-etherscan": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.8.tgz", - "integrity": "sha512-v5F6IzQhrsjHh6kQz4uNrym49brK9K5bYCq2zQZ729RYRaifI9hHbtmK+KkIVevfhut7huQFEQ77JLRMAzWYjQ==", - "deprecated": "The @nomiclabs/hardhat-etherscan package is deprecated, please use @nomicfoundation/hardhat-verify instead", - "dev": true, - "dependencies": { - "@ethersproject/abi": "^5.1.2", - "@ethersproject/address": "^5.0.2", - "cbor": "^8.1.0", - "chalk": "^2.4.2", - "debug": "^4.1.1", - "fs-extra": "^7.0.1", - "lodash": "^4.17.11", - "semver": "^6.3.0", - "table": "^6.8.0", - "undici": "^5.14.0" - }, - "peerDependencies": { - "hardhat": "^2.0.4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@nomiclabs/hardhat-etherscan/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/@nomiclabs/hardhat-waffle": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@nomiclabs/hardhat-waffle/-/hardhat-waffle-2.0.6.tgz", @@ -16315,6 +16322,13 @@ "integrity": "sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==", "dev": true }, + "node_modules/lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", diff --git a/package.json b/package.json index 9b246c68..6e8bb324 100644 --- a/package.json +++ b/package.json @@ -24,8 +24,8 @@ "author": "", "license": "ISC", "devDependencies": { + "@nomicfoundation/hardhat-verify": "^2.0.11", "@nomiclabs/hardhat-ethers": "^2.0.6", - "@nomiclabs/hardhat-etherscan": "^3.1.8", "@nomiclabs/hardhat-waffle": "^2.0.3", "@typechain/ethers-v5": "^7.2.0", "@typechain/hardhat": "^2.3.1", From cfa89ae5c5ea535c266e89ce0415b47833459926 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Mon, 11 Nov 2024 07:45:57 +0700 Subject: [PATCH 15/34] save array of args for verification --- utils/deployment/DeployScript.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index f45f2099..d5dc9394 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -126,7 +126,7 @@ export class DeployScript { contract.address, stepInfo ); - const arsString = stepInfo.args.map((a) => `"${a.value}"`).join(" "); + const arsString = stepInfo.args.map((a) => `${a.value}`); this.resultJson[contract.address] = arsString; return contract; } From 822d0c0a6d448b911e85f7b673b86160cc97abc6 Mon Sep 17 00:00:00 2001 From: Artyom Veremeenko Date: Thu, 14 Nov 2024 17:43:32 +0400 Subject: [PATCH 16/34] feat: burn nonces on L2 deployer if L1 and L2 clash --- utils/optimism/deploymentForAutomaton.ts | 142 ++++++++++++++--------- 1 file changed, 87 insertions(+), 55 deletions(-) diff --git a/utils/optimism/deploymentForAutomaton.ts b/utils/optimism/deploymentForAutomaton.ts index bf7aec3f..edf7b606 100644 --- a/utils/optimism/deploymentForAutomaton.ts +++ b/utils/optimism/deploymentForAutomaton.ts @@ -102,6 +102,39 @@ export class L2DeployAllScript extends DeployScript { public tokenRateOracleProxyAddress: string; } +async function predictAllAddresses(l1Params: OptL1DeployScriptParams, l2Params: OptL2DeployScriptParams) { + const [ + l1TokenBridgeImpl, + l1TokenBridgeProxy, + l1OpStackTokenRatePusherImpl, + ] = await network.predictAddresses(l1Params.deployer, l1Params.deployOffset + 3); + + const [ + l2TokenRateOracleImpl, + l2TokenRateOracleProxy, + l2TokenImpl, + l2TokenProxy, + l2TokenRebasableImpl, + l2TokenRebasableProxy, + l2TokenBridgeImpl, + l2TokenBridgeProxy + ] = await network.predictAddresses(l2Params.deployer, l2Params.deployOffset + 8); + + return { + l1TokenBridgeImpl, + l1TokenBridgeProxy, + l1OpStackTokenRatePusherImpl, + l2TokenRateOracleImpl, + l2TokenRateOracleProxy, + l2TokenImpl, + l2TokenProxy, + l2TokenRebasableImpl, + l2TokenRebasableProxy, + l2TokenBridgeImpl, + l2TokenBridgeProxy + }; +} + /// Deploy all from scratch except Notifier. Uses for automaton script. /// L1 part /// L1LidoTokensBridge + Proxy @@ -119,50 +152,49 @@ export default function deploymentAll( l1Params: OptL1DeployScriptParams, l2Params: OptL2DeployScriptParams, ): Promise<[L1DeployAllScript, L2DeployAllScript]> { + let predictedAddresses = await predictAllAddresses(l1Params, l2Params); + let numClashedAddresses = Object.keys(predictedAddresses).length - new Set(Object.values(predictedAddresses)).size; - const [ - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1OpStackTokenRatePusherImplAddress, - ] = await network.predictAddresses(l1Params.deployer, l1Params.deployOffset + 3); - - const [ - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress, - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableImplAddress, - expectedL2TokenRebasableProxyAddress, - expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress - ] = await network.predictAddresses(l2Params.deployer, l2Params.deployOffset + 8); + // Burning enough nonces on L2 side + while (numClashedAddresses > 0) { + console.log(`NB: Num of clashed predicted addresses on L1 and L2: ${numClashedAddresses}. Burning ${numClashedAddresses} nonces on L2 side...`); + for (let i = 0; i < numClashedAddresses; i++) { + const tx = await l2Params.deployer.sendTransaction({ + to: l2Params.deployer.address, + value: 0 + }); + await tx.wait() + } + predictedAddresses = await predictAllAddresses(l1Params, l2Params); + numClashedAddresses = Object.keys(predictedAddresses).length - new Set(Object.values(predictedAddresses)).size; + } const l1DeployScript = new L1DeployAllScript( l1Params.deployer, - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1OpStackTokenRatePusherImplAddress, + predictedAddresses.l1TokenBridgeImpl, + predictedAddresses.l1TokenBridgeProxy, + predictedAddresses.l1OpStackTokenRatePusherImpl, options?.logger ) .addStep({ factory: L1LidoTokensBridge__factory, args: [ l1Params.l1CrossDomainMessenger, - expectedL2TokenBridgeProxyAddress, + predictedAddresses.l2TokenBridgeProxy, l1Params.l1TokenNonRebasable, l1Params.l1TokenRebasable, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableProxyAddress, + predictedAddresses.l2TokenProxy, + predictedAddresses.l2TokenRebasableProxy, l1Params.accountingOracle, options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenBridgeImplAddress), + assert.equal(c.address, predictedAddresses.l1TokenBridgeImpl), }) .addStep({ factory: OssifiableProxy__factory, args: [ - expectedL1TokenBridgeImplAddress, + predictedAddresses.l1TokenBridgeImpl, l1Params.admins.proxy, L1LidoTokensBridge__factory.createInterface().encodeFunctionData( "initialize", @@ -171,7 +203,7 @@ export default function deploymentAll( options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenBridgeProxyAddress), + assert.equal(c.address, predictedAddresses.l1TokenBridgeProxy), }) .addStep({ factory: OpStackTokenRatePusher__factory, @@ -179,12 +211,12 @@ export default function deploymentAll( l1Params.l1CrossDomainMessenger, l1Params.l1TokenNonRebasable, l1Params.accountingOracle, - expectedL2TokenRateOracleProxyAddress, + predictedAddresses.l2TokenRateOracleProxy, l1Params.l2GasLimitForPushingTokenRate, options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), + assert.equal(c.address, predictedAddresses.l1OpStackTokenRatePusherImpl), }); const l1TokenNonRebasableInfo = IERC20Metadata__factory.connect( @@ -211,22 +243,22 @@ export default function deploymentAll( const l2DeployScript = new L2DeployAllScript( l2Params.deployer, - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableImplAddress, - expectedL2TokenRebasableProxyAddress, - expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress, - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress, + predictedAddresses.l2TokenImpl, + predictedAddresses.l2TokenProxy, + predictedAddresses.l2TokenRebasableImpl, + predictedAddresses.l2TokenRebasableProxy, + predictedAddresses.l2TokenBridgeImpl, + predictedAddresses.l2TokenBridgeProxy, + predictedAddresses.l2TokenRateOracleImpl, + predictedAddresses.l2TokenRateOracleProxy, options?.logger ) .addStep({ factory: TokenRateOracle__factory, args: [ l2Params.l2CrossDomainMessenger, - expectedL2TokenBridgeProxyAddress, - expectedL1OpStackTokenRatePusherImplAddress, + predictedAddresses.l2TokenBridgeProxy, + predictedAddresses.l1OpStackTokenRatePusherImpl, l2Params.tokenRateOracle.tokenRateOutdatedDelay, l2Params.tokenRateOracle.maxAllowedL2ToL1ClockLag, l2Params.tokenRateOracle.maxAllowedTokenRateDeviationPerDayBp, @@ -235,12 +267,12 @@ export default function deploymentAll( options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + assert.equal(c.address, predictedAddresses.l2TokenRateOracleImpl), }) .addStep({ factory: OssifiableProxy__factory, args: [ - expectedL2TokenRateOracleImplAddress, + predictedAddresses.l2TokenRateOracleImpl, l2Params.admins.proxy, TokenRateOracle__factory.createInterface().encodeFunctionData( "initialize", @@ -253,7 +285,7 @@ export default function deploymentAll( options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + assert.equal(c.address, predictedAddresses.l2TokenRateOracleProxy), }) .addStep({ factory: ERC20BridgedPermit__factory, @@ -262,16 +294,16 @@ export default function deploymentAll( l2TokenNonRebasableSymbol, l2Params.l2TokenNonRebasable.version, l2TokenNonRebasableDecimals, - expectedL2TokenBridgeProxyAddress, + predictedAddresses.l2TokenBridgeProxy, options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenImplAddress), + assert.equal(c.address, predictedAddresses.l2TokenImpl), }) .addStep({ factory: OssifiableProxy__factory, args: [ - expectedL2TokenImplAddress, + predictedAddresses.l2TokenImpl, l2Params.admins.proxy, ERC20BridgedPermit__factory.createInterface().encodeFunctionData( "initialize", @@ -284,7 +316,7 @@ export default function deploymentAll( options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenProxyAddress), + assert.equal(c.address, predictedAddresses.l2TokenProxy), }) .addStep({ factory: ERC20RebasableBridgedPermit__factory, @@ -293,18 +325,18 @@ export default function deploymentAll( l2TokenRebasableSymbol, l2Params.l2TokenRebasable.version, l2TokenRebasableDecimals, - expectedL2TokenProxyAddress, - expectedL2TokenRateOracleProxyAddress, - expectedL2TokenBridgeProxyAddress, + predictedAddresses.l2TokenProxy, + predictedAddresses.l2TokenRateOracleProxy, + predictedAddresses.l2TokenBridgeProxy, options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableImplAddress), + assert.equal(c.address, predictedAddresses.l2TokenRebasableImpl), }) .addStep({ factory: OssifiableProxy__factory, args: [ - expectedL2TokenRebasableImplAddress, + predictedAddresses.l2TokenRebasableImpl, l2Params.admins.proxy, ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData( "initialize", @@ -317,26 +349,26 @@ export default function deploymentAll( options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableProxyAddress), + assert.equal(c.address, predictedAddresses.l2TokenRebasableProxy), }) .addStep({ factory: L2ERC20ExtendedTokensBridge__factory, args: [ l2Params.l2CrossDomainMessenger, - expectedL1TokenBridgeProxyAddress, + predictedAddresses.l1TokenBridgeProxy, l1Params.l1TokenNonRebasable, l1Params.l1TokenRebasable, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableProxyAddress, + predictedAddresses.l2TokenProxy, + predictedAddresses.l2TokenRebasableProxy, options?.overrides, ], afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenBridgeImplAddress), + assert.equal(c.address, predictedAddresses.l2TokenBridgeImpl), }) .addStep({ factory: OssifiableProxy__factory, args: [ - expectedL2TokenBridgeImplAddress, + predictedAddresses.l2TokenBridgeImpl, l2Params.admins.proxy, L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( "initialize", From 45e6772f0ef8943bb906902b7feab23484df07f0 Mon Sep 17 00:00:00 2001 From: Artyom Veremeenko Date: Thu, 14 Nov 2024 17:43:51 +0400 Subject: [PATCH 17/34] feat: add env var L2_DEPLOY_SKIP_PROMPTS --- utils/prompt.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/utils/prompt.ts b/utils/prompt.ts index 90ce0868..cfaa4af2 100644 --- a/utils/prompt.ts +++ b/utils/prompt.ts @@ -17,6 +17,10 @@ function prompt(question: string, availableAnswers?: string[]) { } async function promptProceed() { + if (process.env.L2_DEPLOY_SKIP_PROMPTS) { + return; + } + const positiveAnswers = ["y", "yes"]; const negativeAnswers = ["n", "no"]; const answer = await prompt("Do you want to proceed? [yes/no]", [ From 77f745aa40120eca0d00337bb4280d3b329be6b1 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 6 Dec 2024 14:01:59 +0100 Subject: [PATCH 18/34] remove network name from --- .env.example | 17 ++-- .env.steth.opt_mainnet | 17 ++-- .env.steth.opt_sepolia | 16 +-- README.md | 23 +---- hardhat.config.ts | 53 ++-------- package.json | 6 +- scripts/optimism/check-deposits-concurrent.ts | 7 +- scripts/optimism/cross-chain-relayer.ts | 8 +- scripts/optimism/deploy-automaton.ts | 6 +- .../optimism/deploy-new-steth-contracts.ts | 10 +- scripts/optimism/deploy-scratch.ts | 10 +- .../optimism/execute-gov-bridge-executor.ts | 4 +- scripts/optimism/finalize-message.ts | 6 +- scripts/optimism/prove-message.ts | 6 +- scripts/optimism/update-ethereum-executor.ts | 19 ++-- test/e2e/bridging-rebasable-to.e2e.test.ts | 9 +- test/e2e/bridging-rebasable.e2e.test.ts | 9 +- test/e2e/bridging-to.e2e.test.ts | 9 +- test/e2e/bridging.e2e.test.ts | 8 +- test/e2e/pushingTokenRate.e2e.test.ts | 12 +-- test/integration/_bridging-non-rebasable.ts | 6 +- test/integration/_launch.test.ts | 4 +- .../bridging-rebasable.integration.test.ts | 6 +- .../deposit-gas-estimation.test.ts | 10 +- ...ier-pushing-token-rate.integration.test.ts | 8 +- ...her-pushing-token-rate.integration.test.ts | 9 +- test/integration/optimism.integration.test.ts | 14 +-- .../managing-deposits.e2e.test.ts | 12 +-- .../managing-executor.e2e.test.ts | 12 +-- test/managing-e2e/managing-proxy.e2e.test.ts | 14 ++- utils/deployment.ts | 2 +- utils/env.ts | 11 +-- utils/network.ts | 97 ++++--------------- utils/optimism/addresses.ts | 31 ++---- utils/optimism/contracts.ts | 6 +- utils/optimism/deployment.ts | 5 +- utils/optimism/deploymentOracle.ts | 8 +- utils/optimism/deploymentStETH.ts | 5 +- utils/optimism/messaging.ts | 10 +- utils/optimism/testing.ts | 35 +++---- 40 files changed, 169 insertions(+), 391 deletions(-) diff --git a/.env.example b/.env.example index c15c2be2..6e13865f 100644 --- a/.env.example +++ b/.env.example @@ -4,11 +4,14 @@ # RPCs # ############################ -RPC_ETH_MAINNET= -RPC_ETH_SEPOLIA= +L1_CHAIN_ID=10 +L2_CHAIN_ID=11155420 -RPC_OPT_MAINNET=https://mainnet.optimism.io -RPC_OPT_SEPOLIA=https://sepolia.optimism.io +L1_PRC=https://sepolia.infura.io/v3/ +L2_PRC=https://optimism-sepolia.infura.io/v3/ + +L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 +L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # ############################ # Etherscan @@ -21,10 +24,6 @@ ETHERSCAN_API_KEY_OPT= # Bridge/Gateway Deployment # ############################ -# Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "sepolia". -NETWORK=mainnet - # Run deployment in the forking network instead of public ones FORKING=true @@ -148,8 +147,6 @@ L2_WITHDRAWALS_DISABLERS=[] # Integration Acceptance & E2E Testing # ############################ -TESTING_OPT_NETWORK= - TESTING_OPT_L1_LIDO= TESTING_OPT_L1_REBASABLE_TOKEN= TESTING_OPT_L1_NON_REBASABLE_TOKEN= diff --git a/.env.steth.opt_mainnet b/.env.steth.opt_mainnet index f4462cf5..ff52e699 100644 --- a/.env.steth.opt_mainnet +++ b/.env.steth.opt_mainnet @@ -4,11 +4,14 @@ # RPCs # ############################ -RPC_ETH_SEPOLIA=https://sepolia.infura.io/v3/ -RPC_OPT_SEPOLIA=https://optimism-sepolia.infura.io/v3/ +L1_CHAIN_ID=10 +L2_CHAIN_ID=11155420 -RPC_ETH_MAINNET=https://mainnet.infura.io/v3/ -RPC_OPT_MAINNET=https://optimism-mainnet.infura.io/v3/ +L1_PRC=https://sepolia.infura.io/v3/ +L2_PRC=https://optimism-sepolia.infura.io/v3/ + +L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 +L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # ############################ # Etherscan @@ -21,10 +24,6 @@ ETHERSCAN_API_KEY_OPT= # Bridge/Gateway Deployment # ############################ -# Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "sepolia". -NETWORK=mainnet - # Run deployment in the forking network instead of public ones FORKING=false @@ -150,8 +149,6 @@ L2_WITHDRAWALS_DISABLERS=["0xEfa0dB536d2c8089685630fafe88CF7805966FC3","0x4Cf8fE # Integration & E2E Testing # ############################ -TESTING_OPT_NETWORK=sepolia - TESTING_OPT_L1_LIDO= TESTING_OPT_L1_REBASABLE_TOKEN= TESTING_OPT_L1_NON_REBASABLE_TOKEN= diff --git a/.env.steth.opt_sepolia b/.env.steth.opt_sepolia index 7ab45379..54935ad2 100644 --- a/.env.steth.opt_sepolia +++ b/.env.steth.opt_sepolia @@ -4,8 +4,14 @@ # RPCs # ############################ -RPC_ETH_SEPOLIA=https://sepolia.infura.io/v3/ -RPC_OPT_SEPOLIA=https://optimism-sepolia.infura.io/v3/ +L1_CHAIN_ID=10 +L2_CHAIN_ID=11155420 + +L1_PRC=https://sepolia.infura.io/v3/ +L2_PRC=https://optimism-sepolia.infura.io/v3/ + +L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 +L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # ############################ # Etherscan @@ -18,10 +24,6 @@ ETHERSCAN_API_KEY_OPT= # Bridge/Gateway Deployment # ############################ -# Name of the network environments used by deployment scripts. -# Might be one of: "mainnet", "sepolia". -NETWORK=sepolia - # Run deployment in the forking network instead of public ones FORKING=false @@ -145,8 +147,6 @@ L2_WITHDRAWALS_DISABLERS="["0xf695357C66bA514150Da95b189acb37b46DDe602", "0xa5F1 # Integration & E2E Testing # ############################ -TESTING_OPT_NETWORK=sepolia - TESTING_OPT_L1_LIDO=0x3e3FE7dBc6B4C189E7128855dD526361c49b40Af TESTING_OPT_L1_REBASABLE_TOKEN=0x3e3FE7dBc6B4C189E7128855dD526361c49b40Af TESTING_OPT_L1_NON_REBASABLE_TOKEN=0xB82381A3fBD3FaFA77B3a7bE693342618240067b diff --git a/README.md b/README.md index bb834dc3..d665533f 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,6 @@ The configuration of the deployment scripts happens via the ENV variables. The f - [`L2_TOKEN`](#L2_TOKEN) - address of the non-rebasable token on L2. - [`L2_TOKEN_RATE_ORACLE`](#L2_TOKEN_RATE_ORACLE) - address of token rate oracle on L2. - [`GOV_BRIDGE_EXECUTOR`](#GOV_BRIDGE_EXECUTOR) - address of bridge executor. -- [`NETWORK`](#NETWORK) - name of the network environments used by deployment scripts. Allowed values: `mainnet`, `sepolia`. - [`FORKING`](#FORKING) - run deployment in the forking network instead of real ones - [`ETH_DEPLOYER_PRIVATE_KEY`](#ETH_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Ethereum network is used during the deployment process. - [`OPT_DEPLOYER_PRIVATE_KEY`](#OPT_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Optimism network is used during the deployment process. @@ -101,14 +100,14 @@ npm run optimism:test:unit ### Integration tests -Before running integration tests, run the hardhat forked nodes in the standalone tabs corresponding to `TESTING_OPT_NETWORK` env variable or if it's not set use `mainnet` network. Example of the commands for the `mainnet` network: +Before running integration tests, run the hardhat forked nodes in the standalone tabs. Example of the commands: ```bash -# Required to run Optimism integraton tests -npm run fork:eth:mainnet +# Required to run integration tests +npm run fork:l1 -# Required to run Optimism integration tests -npm run fork:opt:mainnet +# Required to run integration tests +npm run fork:l2 The integration tests might be run via the following commands: @@ -129,7 +128,6 @@ TESTING_USE_DEPLOYED_CONTRACTS=true TESTING_L1_TOKENS_HOLDER= # Addresses of the Optimism bridge -TESTING_OPT_NETWORK= TESTING_OPT_L1_TOKEN= TESTING_OPT_L2_TOKEN= TESTING_OPT_L1_ERC20_TOKEN_BRIDGE= @@ -160,7 +158,6 @@ Additionally, tests might be run on the deployed contracts. To do it, set the fo TESTING_PRIVATE_KEY= # Addresses of the Optimism bridge -TESTING_OPT_NETWORK= TESTING_OPT_L1_TOKEN= TESTING_OPT_L2_TOKEN= TESTING_OPT_L1_ERC20_TOKEN_BRIDGE= @@ -229,12 +226,6 @@ Address of the existing non-rebasable token to deploy a new bridge for on the Et Address of the existing rebasable token to deploy new bridge for on the Ethereum chain. -#### `NETWORK` - -> Default value: `mainnet` - -Name of the network environments used by deployment scripts. Might be one of: `mainnet`, `sepolia`. - #### `FORKING` Run deployment in the forking network instead of public ones @@ -349,10 +340,6 @@ The array of addresses to grant `WITHDRAWALS_DISABLER_ROLE` on L2 bridge/gateway The following variables are used in the process of the Integration & E2E testing. -#### `TESTING_OPT_NETWORK` - -Name of the network environments used for Optimism Integration & E2E testing. Might be one of: `mainnet`, `sepolia`. - #### `TESTING_OPT_L1_TOKEN` Address of the token to use in the Acceptance Integration & E2E (when `TESTING_USE_DEPLOYED_CONTRACTS` is set to true) testing of the bridging between Ethereum and Optimism networks. diff --git a/hardhat.config.ts b/hardhat.config.ts index 0082ad41..878493d1 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -38,53 +38,18 @@ const config: HardhatUserConfig = { } } }, - // Ethereum Public Chains - eth_mainnet: { - url: env.string("RPC_ETH_MAINNET", ""), + l1: { + url: env.string("L1_PRC", ""), }, - eth_sepolia: { - url: env.string("RPC_ETH_SEPOLIA", ""), + l2: { + url: env.string("L2_PRC", ""), }, - - // Ethereum Fork Chains - eth_mainnet_fork: { - url: "http://localhost:8545", - }, - eth_sepolia_fork: { - url: "http://localhost:8545", - }, - - // Optimism Public Chains - opt_mainnet: { - url: env.string("RPC_OPT_MAINNET", ""), - }, - opt_sepolia: { - url: env.string("RPC_OPT_SEPOLIA", ""), - }, - - // Optimism Fork Chains - opt_mainnet_fork: { - url: "http://localhost:9545", - }, - opt_sepolia_fork: { - url: "http://localhost:9545", - }, - - // Unichain Public Chains - uni_mainnet: { - url: env.string("RPC_UNI_MAINNET", ""), - }, - uni_sepolia: { - url: env.string("RPC_UNI_SEPOLIA", ""), - }, - - // Unichain Fork Chains - uni_mainnet_fork: { - url: "http://localhost:9545", - }, - uni_sepolia_fork: { - url: "http://localhost:9545", + l1_fork: { + url: "http://localhost:8545" }, + l2_fork: { + url: "http://localhost:9545" + } }, gasReporter: { enabled: env.string("REPORT_GAS", "false") !== "false", diff --git a/package.json b/package.json index 6e8bb324..c1db7d52 100644 --- a/package.json +++ b/package.json @@ -7,10 +7,8 @@ "compile": "hardhat compile", "compile:force": "hardhat compile --force", "coverage": "hardhat coverage --testfiles './test/**/*.unit.test.ts'", - "fork:eth:mainnet": "hardhat node:fork eth_mainnet 8545", - "fork:eth:sepolia": "hardhat node:fork eth_sepolia 8545", - "fork:opt:sepolia": "hardhat node:fork opt_sepolia 9545", - "fork:opt:mainnet": "hardhat node:fork opt_mainnet 9545", + "fork:l1": "hardhat node:fork l1 8545", + "fork:l2": "hardhat node:fork l2 9545", "deploy": "ts-node --files ./scripts/optimism/deploy-scratch.ts", "deploy-new-steth-contracts": "ts-node --files ./scripts/optimism/deploy-new-steth-contracts.ts", "finalize-message": "ts-node --files ./scripts/optimism/finalize-message.ts", diff --git a/scripts/optimism/check-deposits-concurrent.ts b/scripts/optimism/check-deposits-concurrent.ts index 6c7b1bcf..33e2be30 100644 --- a/scripts/optimism/check-deposits-concurrent.ts +++ b/scripts/optimism/check-deposits-concurrent.ts @@ -4,12 +4,7 @@ import network from "../../utils/network"; import pLimit from "p-limit"; async function main() { - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - - const [ethereumProvider, optimismProvider] = ethOptNetwork.getProviders({ - forking: env.forking() - }); + const [ethereumProvider, optimismProvider] = network.getProviders({ forking: env.forking() }); // Mainnet const ethBridgeAddress = process.env["L1_TOKEN_BRIDGE"] ?? "0x76943C0D61395d8F2edF9060e1533529cAe05dE6" diff --git a/scripts/optimism/cross-chain-relayer.ts b/scripts/optimism/cross-chain-relayer.ts index d3768059..0d521183 100644 --- a/scripts/optimism/cross-chain-relayer.ts +++ b/scripts/optimism/cross-chain-relayer.ts @@ -13,10 +13,8 @@ import { L2CrossDomainMessenger__factory } from "../../typechain"; async function main() { console.log("Run Relayer"); - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - const [, optProvider] = ethOptNetwork.getProviders({ forking: true }); - const optAddresses = addresses(networkName); + const [, optProvider] = network.getProviders({ forking: true }); + const optAddresses = addresses(); const ethProviderUrl = 'ws://localhost:8545'; const wsEthProvider = new ethers.providers.WebSocketProvider(ethProviderUrl); @@ -34,7 +32,7 @@ async function main() { ); // 1. Catch Event - const optimismPortalAddress = networkName == "mainnet" ? "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" : "0x16Fc5058F25648194471939df75CF27A2fdC48BC"; + const optimismPortalAddress = env.address("L1_L2_PORTAL", "0x16Fc5058F25648194471939df75CF27A2fdC48BC"); const l1MessngerAbi = [ "event SentMessage(address indexed target, address sender, bytes message, uint256 messageNonce, uint256 gasLimit)" diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index 98a4e2d7..4fd89713 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -8,14 +8,12 @@ import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-managemen import * as fs from 'fs'; async function main() { - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + const [ethDeployer] = network.getSigners(env.privateKey(), { forking: env.forking() }); - const [, optDeployer] = ethOptNetwork.getSigners( + const [, optDeployer] = network.getSigners( env.string("OPT_DEPLOYER_PRIVATE_KEY"), { forking: env.forking() diff --git a/scripts/optimism/deploy-new-steth-contracts.ts b/scripts/optimism/deploy-new-steth-contracts.ts index a61224c8..ad58590e 100644 --- a/scripts/optimism/deploy-new-steth-contracts.ts +++ b/scripts/optimism/deploy-new-steth-contracts.ts @@ -7,17 +7,15 @@ import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-managemen import deploy from "../../utils/optimism/deploymentStETH"; async function main() { - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + const [ethDeployer] = network.getSigners(env.privateKey(), { forking: env.forking(), }); - const [ethProvider] = ethOptNetwork.getProviders({ + const [ethProvider] = network.getProviders({ forking: env.forking() }); - const [, optDeployer] = ethOptNetwork.getSigners( + const [, optDeployer] = network.getSigners( env.string("OPT_DEPLOYER_PRIVATE_KEY"), { forking: env.forking(), @@ -26,7 +24,7 @@ async function main() { const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deploy(networkName, { logger: console }) + const [l1DeployScript, l2DeployScript] = await deploy({ logger: console }) .deployScript( { l1TokenNonRebasable: deploymentConfig.ethereum.l1TokenNonRebasable, diff --git a/scripts/optimism/deploy-scratch.ts b/scripts/optimism/deploy-scratch.ts index 5e38d22b..b33f64a8 100644 --- a/scripts/optimism/deploy-scratch.ts +++ b/scripts/optimism/deploy-scratch.ts @@ -7,18 +7,16 @@ import deploymentAll from "../../utils/optimism/deployment"; import { TokenRateNotifierManagement } from "../../utils/tokenRateNotifier-management"; async function main() { - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - const [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + const [ethDeployer] = network.getSigners(env.privateKey(), { forking: env.forking() }); - const [ethProvider] = ethOptNetwork.getProviders({ + const [ethProvider] = network.getProviders({ forking: env.forking() }); - const [, optDeployer] = ethOptNetwork.getSigners( + const [, optDeployer] = network.getSigners( env.string("OPT_DEPLOYER_PRIVATE_KEY"), { forking: env.forking() @@ -27,7 +25,7 @@ async function main() { const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deploymentAll(networkName, { logger: console }) + const [l1DeployScript, l2DeployScript] = await deploymentAll({ logger: console }) .deployAllScript( { l1TokenNonRebasable: deploymentConfig.ethereum.l1TokenNonRebasable, diff --git a/scripts/optimism/execute-gov-bridge-executor.ts b/scripts/optimism/execute-gov-bridge-executor.ts index a9634813..ff0ddf60 100644 --- a/scripts/optimism/execute-gov-bridge-executor.ts +++ b/scripts/optimism/execute-gov-bridge-executor.ts @@ -6,12 +6,10 @@ import testing from "../../utils/testing"; async function main() { const isForking = true; - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); const GOV_BRIDGE_EXECUTOR = testing.env.OPT_GOV_BRIDGE_EXECUTOR(); - const [, optRunner] = ethOptNetwork.getSigners(env.privateKey(), { + const [, optRunner] = network.getSigners(env.privateKey(), { forking: isForking, }); diff --git a/scripts/optimism/finalize-message.ts b/scripts/optimism/finalize-message.ts index ac6c9b5b..f9121c9d 100644 --- a/scripts/optimism/finalize-message.ts +++ b/scripts/optimism/finalize-message.ts @@ -3,16 +3,14 @@ import env from "../../utils/env"; import network from "../../utils/network"; async function main() { - const networkName = env.network(); const [l1Signer, l2Signer] = network - .multichain(["eth", "opt"], networkName) .getSigners(env.privateKey(), { forking: false }); const txHash = env.string("TX_HASH"); const crossDomainMessenger = new CrossChainMessenger({ - l1ChainId: network.chainId("eth", networkName), - l2ChainId: network.chainId("opt", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: l1Signer, l2SignerOrProvider: l2Signer, }); diff --git a/scripts/optimism/prove-message.ts b/scripts/optimism/prove-message.ts index e0c2ee5e..e7563e31 100644 --- a/scripts/optimism/prove-message.ts +++ b/scripts/optimism/prove-message.ts @@ -3,16 +3,14 @@ import env from "../../utils/env"; import network from "../../utils/network"; async function main() { - const networkName = env.network(); const [l1Signer, l2Signer] = network - .multichain(["eth", "opt"], networkName) .getSigners(env.privateKey(), { forking: false }); const txHash = env.string("TX_HASH"); const crossChainMessenger = new CrossChainMessenger({ - l1ChainId: network.chainId("eth", networkName), - l2ChainId: network.chainId("opt", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: l1Signer, l2SignerOrProvider: l2Signer, bedrock: true, diff --git a/scripts/optimism/update-ethereum-executor.ts b/scripts/optimism/update-ethereum-executor.ts index aec4314b..35f67965 100644 --- a/scripts/optimism/update-ethereum-executor.ts +++ b/scripts/optimism/update-ethereum-executor.ts @@ -12,14 +12,12 @@ const GOV_BRIDGE_EXECUTOR = ""; async function main() { const isForking = env.forking(); - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); - const [l1LDOHolder] = ethOptNetwork.getSigners( + const [l1LDOHolder] = network.getSigners( env.string("TESTING_OPT_LDO_HOLDER_PRIVATE_KEY"), { forking: isForking } ); - const [, optRunner] = ethOptNetwork.getSigners(env.privateKey(), { + const [, optRunner] = network.getSigners(env.privateKey(), { forking: isForking, }); @@ -27,12 +25,9 @@ async function main() { GOV_BRIDGE_EXECUTOR, optRunner ); - + const networkName = "sepolia"; const newEthExecutorLidoDAO = lido(networkName, l1LDOHolder); - const oldEthExecutorLidoDAO = lido( - networkName === "mainnet" ? "mainnet_test" : networkName, - l1LDOHolder - ); + const oldEthExecutorLidoDAO = lido(networkName, l1LDOHolder); const prevEthGovExecutorAddress = await govBridgeExecutor.getEthereumGovernanceExecutor(); @@ -59,7 +54,7 @@ async function main() { console.log(`Preparing the voting tx...`); - const optAddresses = optimism.addresses(networkName); + const optAddresses = optimism.addresses(); // Prepare data for Governance Bridge Executor const executorCalldata = await govBridgeExecutor.interface.encodeFunctionData( @@ -79,7 +74,7 @@ async function main() { ); const { callvalue, calldata } = await optimism - .messaging(networkName, { forking: isForking }) + .messaging({ forking: isForking }) .prepareL2Message({ calldata: executorCalldata, recipient: GOV_BRIDGE_EXECUTOR, @@ -121,7 +116,7 @@ async function main() { console.log(`Waiting for L2 transaction...`); await optimism - .messaging(networkName, { forking: isForking }) + .messaging({ forking: isForking }) .waitForL2Message(executeTxReceipt.transactionHash); console.log(`Message delivered to L2`); diff --git a/test/e2e/bridging-rebasable-to.e2e.test.ts b/test/e2e/bridging-rebasable-to.e2e.test.ts index 9652dc00..b7ab41a2 100644 --- a/test/e2e/bridging-rebasable-to.e2e.test.ts +++ b/test/e2e/bridging-rebasable-to.e2e.test.ts @@ -4,8 +4,6 @@ import { } from "@eth-optimism/sdk"; import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; - - import env from "../../utils/env"; import { wei } from "../../utils/wei"; import network from "../../utils/network"; import optimism from "../../utils/optimism"; @@ -88,8 +86,7 @@ import { .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); - const testingSetup = await optimism.testing(networkName).getE2ETestSetup(); + const testingSetup = await optimism.testing().getE2ETestSetup(); return { depositAmount: wei`0.0001 ether`, @@ -101,8 +98,8 @@ import { l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, l2ERC20ExtendedTokensBridge: testingSetup.l2ERC20ExtendedTokensBridge, crossChainMessenger: new CrossChainMessenger({ - l2ChainId: network.chainId("opt", networkName), - l1ChainId: network.chainId("eth", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: testingSetup.l1Tester, l2SignerOrProvider: testingSetup.l2Tester, bridges: { diff --git a/test/e2e/bridging-rebasable.e2e.test.ts b/test/e2e/bridging-rebasable.e2e.test.ts index 173b90b5..e13d220b 100644 --- a/test/e2e/bridging-rebasable.e2e.test.ts +++ b/test/e2e/bridging-rebasable.e2e.test.ts @@ -4,8 +4,6 @@ import { } from "@eth-optimism/sdk"; import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; - - import env from "../../utils/env"; import { wei } from "../../utils/wei"; import network from "../../utils/network"; import optimism from "../../utils/optimism"; @@ -78,8 +76,7 @@ import { .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); - const testingSetup = await optimism.testing(networkName).getE2ETestSetup(); + const testingSetup = await optimism.testing().getE2ETestSetup(); return { depositAmount: wei`0.0001 ether`, @@ -89,8 +86,8 @@ import { l2TokenRebasable: testingSetup.l2TokenRebasable, l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, crossChainMessenger: new CrossChainMessenger({ - l2ChainId: network.chainId("opt", networkName), - l1ChainId: network.chainId("eth", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: testingSetup.l1Tester, l2SignerOrProvider: testingSetup.l2Tester, bridges: { diff --git a/test/e2e/bridging-to.e2e.test.ts b/test/e2e/bridging-to.e2e.test.ts index 72820b82..d4ed140e 100644 --- a/test/e2e/bridging-to.e2e.test.ts +++ b/test/e2e/bridging-to.e2e.test.ts @@ -1,13 +1,11 @@ import { CrossChainMessenger, - DAIBridgeAdapter, MessageStatus, } from "@eth-optimism/sdk"; import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; import { LidoBridgeAdapter } from "../../utils/optimism/LidoBridgeAdapter"; -import env from "../../utils/env"; import { wei } from "../../utils/wei"; import network from "../../utils/network"; import optimism from "../../utils/optimism"; @@ -90,8 +88,7 @@ scenario("Optimism :: Bridging non-rebasable via depositTo/withdrawTo E2E test", .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); - const testingSetup = await optimism.testing(networkName).getE2ETestSetup(); + const testingSetup = await optimism.testing().getE2ETestSetup(); return { depositAmount: wei`0.0001 ether`, @@ -103,8 +100,8 @@ async function ctxFactory() { l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, l2ERC20ExtendedTokensBridge: testingSetup.l2ERC20ExtendedTokensBridge, crossChainMessenger: new CrossChainMessenger({ - l2ChainId: network.chainId("opt", networkName), - l1ChainId: network.chainId("eth", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: testingSetup.l1Tester, l2SignerOrProvider: testingSetup.l2Tester, bridges: { diff --git a/test/e2e/bridging.e2e.test.ts b/test/e2e/bridging.e2e.test.ts index c3829e42..292424b8 100644 --- a/test/e2e/bridging.e2e.test.ts +++ b/test/e2e/bridging.e2e.test.ts @@ -5,7 +5,6 @@ import { import { assert } from "chai"; import { TransactionResponse } from "@ethersproject/providers"; import chalk from "chalk"; -import env from "../../utils/env"; import { wei } from "../../utils/wei"; import network from "../../utils/network"; import optimism from "../../utils/optimism"; @@ -77,8 +76,7 @@ scenario("Optimism :: Bridging non-rebasable token via deposit/withdraw E2E test .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); - const testingSetup = await optimism.testing(networkName).getE2ETestSetup(); + const testingSetup = await optimism.testing().getE2ETestSetup(); return { depositAmount: wei`0.0001 ether`, @@ -88,8 +86,8 @@ async function ctxFactory() { l2Token: testingSetup.l2Token, l1LidoTokensBridge: testingSetup.l1LidoTokensBridge, crossChainMessenger: new CrossChainMessenger({ - l2ChainId: network.chainId("opt", networkName), - l1ChainId: network.chainId("eth", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: testingSetup.l1Tester, l2SignerOrProvider: testingSetup.l2Tester, bridges: { diff --git a/test/e2e/pushingTokenRate.e2e.test.ts b/test/e2e/pushingTokenRate.e2e.test.ts index fa4495f5..e03e7abc 100644 --- a/test/e2e/pushingTokenRate.e2e.test.ts +++ b/test/e2e/pushingTokenRate.e2e.test.ts @@ -1,5 +1,4 @@ import { assert } from "chai"; -import env from "../../utils/env"; import network, { SignerOrProvider } from "../../utils/network"; import testingUtils, { scenario } from "../../utils/testing"; import { BigNumber } from 'ethers' @@ -50,16 +49,9 @@ async function ctxFactory() { async function getE2ETestSetup() { const testerPrivateKey = testingUtils.env.TESTING_PRIVATE_KEY(); - const networkName = env.network("TESTING_OPT_NETWORK", "sepolia"); - const ethOptNetworks = network.multichain(["eth", "opt"], networkName); - - const [ethProvider, optProvider] = ethOptNetworks.getProviders({ - forking: false, - }); - const [l1Tester, l2Tester] = ethOptNetworks.getSigners(testerPrivateKey, { - forking: false, - }); + const [ethProvider, optProvider] = network.getProviders({ forking: false }); + const [l1Tester, l2Tester] = network.getSigners(testerPrivateKey, { forking: false }); const contracts = await loadDeployedContracts(l1Tester, l2Tester); return { diff --git a/test/integration/_bridging-non-rebasable.ts b/test/integration/_bridging-non-rebasable.ts index e1a4dc4d..fd54dcc8 100644 --- a/test/integration/_bridging-non-rebasable.ts +++ b/test/integration/_bridging-non-rebasable.ts @@ -1,6 +1,5 @@ import { assert } from "chai"; import { BigNumber } from 'ethers' -import env from "../../utils/env"; import { wei } from "../../utils/wei"; import optimism from "../../utils/optimism"; import testing from "../../utils/testing"; @@ -543,7 +542,6 @@ export function ctxFactory(options: { withdrawalAmount, } = options; - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); const tokenRateDecimals = BigNumber.from(27); const { @@ -554,14 +552,14 @@ export function ctxFactory(options: { l1ERC20ExtendedTokensBridgeAdmin, l2ERC20ExtendedTokensBridgeAdmin, ...contracts - } = await optimism.testing(networkName).getIntegrationTestSetup(); + } = await optimism.testing().getIntegrationTestSetup(); const l1Snapshot = await l1Provider.send("evm_snapshot", []); const l2Snapshot = await l2Provider.send("evm_snapshot", []); const tokenRate = await contracts.l1Token.getStETHByWstETH(BigNumber.from(10).pow(tokenRateDecimals)); - await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + await optimism.testing().stubL1CrossChainMessengerContract(); const accountA = testing.accounts.accountA(l1Provider, l2Provider); const accountB = testing.accounts.accountB(l1Provider, l2Provider); diff --git a/test/integration/_launch.test.ts b/test/integration/_launch.test.ts index 13b63f89..840b91df 100644 --- a/test/integration/_launch.test.ts +++ b/test/integration/_launch.test.ts @@ -6,7 +6,6 @@ import optimism from "../../utils/optimism"; import testing, { scenario } from "../../utils/testing"; import { BridgingManagerRole } from "../../utils/bridging-management"; import { L1LidoTokensBridge__factory } from "../../typechain"; -import { BigNumber } from 'ethers' const REVERT = env.bool("REVERT", true); @@ -54,10 +53,9 @@ scenario("Optimism :: Launch integration test", ctxFactory) .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); const { l1Provider, l2Provider, l1LidoTokensBridge } = await optimism - .testing(networkName) + .testing() .getIntegrationTestSetup(); const hasDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); diff --git a/test/integration/bridging-rebasable.integration.test.ts b/test/integration/bridging-rebasable.integration.test.ts index 68397e6c..ca2ca334 100644 --- a/test/integration/bridging-rebasable.integration.test.ts +++ b/test/integration/bridging-rebasable.integration.test.ts @@ -1,6 +1,5 @@ import { assert } from "chai"; import { BigNumber, ethers } from 'ethers' -import env from "../../utils/env"; import { wei } from "../../utils/wei"; import optimism from "../../utils/optimism"; import testing, { scenario, ScenarioTest } from "../../utils/testing"; @@ -744,7 +743,6 @@ function ctxFactory( ) { return async () => { const hasDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); const { totalPooledEther, @@ -754,12 +752,12 @@ function ctxFactory( l1ERC20ExtendedTokensBridgeAdmin, l2ERC20ExtendedTokensBridgeAdmin, ...contracts - } = await optimism.testing(networkName).getIntegrationTestSetup(); + } = await optimism.testing().getIntegrationTestSetup(); const l1Snapshot = await l1Provider.send("evm_snapshot", []); const l2Snapshot = await l2Provider.send("evm_snapshot", []); - await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + await optimism.testing().stubL1CrossChainMessengerContract(); const accountA = testing.accounts.accountA(l1Provider, l2Provider); const accountB = testing.accounts.accountB(l1Provider, l2Provider); diff --git a/test/integration/deposit-gas-estimation.test.ts b/test/integration/deposit-gas-estimation.test.ts index 91258b44..36362e5a 100644 --- a/test/integration/deposit-gas-estimation.test.ts +++ b/test/integration/deposit-gas-estimation.test.ts @@ -1,6 +1,4 @@ import { assert } from "chai"; - -import env from "../../utils/env"; import { wei } from "../../utils/wei"; import optimism from "../../utils/optimism"; import testing, { scenario } from "../../utils/testing"; @@ -128,22 +126,16 @@ scenario("Optimism :: Bridging integration test", ctxFactory) const gasDifference = receipt1.gasUsed.sub(receipt0.gasUsed); console.log("gasUsed difference=", gasDifference); }) - - - .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); - console.log("networkName=", networkName); - const { l1Provider, l2Provider, l1ERC20ExtendedTokensBridgeAdmin, l2ERC20ExtendedTokensBridgeAdmin, ...contracts - } = await optimism.testing(networkName).getIntegrationTestSetup(); + } = await optimism.testing().getIntegrationTestSetup(); const l1Snapshot = await l1Provider.send("evm_snapshot", []); const l2Snapshot = await l2Provider.send("evm_snapshot", []); diff --git a/test/integration/notifier-pushing-token-rate.integration.test.ts b/test/integration/notifier-pushing-token-rate.integration.test.ts index 66b61aa6..97e3eaa8 100644 --- a/test/integration/notifier-pushing-token-rate.integration.test.ts +++ b/test/integration/notifier-pushing-token-rate.integration.test.ts @@ -121,8 +121,6 @@ scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); - const { totalPooledEther, totalShares, @@ -131,17 +129,17 @@ async function ctxFactory() { l1ERC20ExtendedTokensBridgeAdmin, l2ERC20ExtendedTokensBridgeAdmin, ...contracts - } = await optimism.testing(networkName).getIntegrationTestSetup(); + } = await optimism.testing().getIntegrationTestSetup(); const lidoAsEOA = await testing.impersonate(env.address("LIDO"), l1Provider); const tokenRateDecimals = BigNumber.from(27); const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); - const optContracts = optimism.contracts(networkName, { forking: true }); + const optContracts = optimism.contracts({ forking: true }); const l2CrossDomainMessenger = optContracts.L2CrossDomainMessenger; - await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + await optimism.testing().stubL1CrossChainMessengerContract(); const l1CrossDomainMessengerAliased = await testing.impersonate( testing.accounts.applyL1ToL2Alias(optContracts.L1CrossDomainMessengerStub.address), diff --git a/test/integration/op-pusher-pushing-token-rate.integration.test.ts b/test/integration/op-pusher-pushing-token-rate.integration.test.ts index e3dfdada..b4020138 100644 --- a/test/integration/op-pusher-pushing-token-rate.integration.test.ts +++ b/test/integration/op-pusher-pushing-token-rate.integration.test.ts @@ -1,6 +1,5 @@ import { assert } from "chai"; import { BigNumber } from "ethers"; -import env from "../../utils/env"; import { wei } from "../../utils/wei"; import optimism from "../../utils/optimism"; import testing, { scenario } from "../../utils/testing"; @@ -121,8 +120,6 @@ scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); - const { totalPooledEther, totalShares, @@ -131,15 +128,15 @@ async function ctxFactory() { l1ERC20ExtendedTokensBridgeAdmin, l2ERC20ExtendedTokensBridgeAdmin, ...contracts - } = await optimism.testing(networkName).getIntegrationTestSetup(); + } = await optimism.testing().getIntegrationTestSetup(); const tokenRateDecimals = BigNumber.from(27); const tokenRate = getExchangeRate(tokenRateDecimals, totalPooledEther, totalShares); - const optContracts = optimism.contracts(networkName, { forking: true }); + const optContracts = optimism.contracts({ forking: true }); const l2CrossDomainMessenger = optContracts.L2CrossDomainMessenger; - await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + await optimism.testing().stubL1CrossChainMessengerContract(); const l1CrossDomainMessengerAliased = await testing.impersonate( testing.accounts.applyL1ToL2Alias(optContracts.L1CrossDomainMessengerStub.address), diff --git a/test/integration/optimism.integration.test.ts b/test/integration/optimism.integration.test.ts index 509b7226..34838fea 100644 --- a/test/integration/optimism.integration.test.ts +++ b/test/integration/optimism.integration.test.ts @@ -1,7 +1,6 @@ import { assert } from "chai"; import { BigNumber } from 'ethers' import { wei } from "../../utils/wei"; -import env from "../../utils/env"; import optimism from "../../utils/optimism"; import testing, { scenario } from "../../utils/testing"; import { BridgingManagerRole } from "../../utils/bridging-management"; @@ -200,9 +199,7 @@ scenario("Optimism :: Bridge Executor integration test", ctxFactory) .run(); async function ctxFactory() { - const networkName = env.network("TESTING_OPT_NETWORK", "mainnet"); const [l1Provider, l2Provider] = network - .multichain(["eth", "opt"], networkName) .getProviders({ forking: true }); const l1Deployer = testing.accounts.deployer(l1Provider); @@ -255,7 +252,7 @@ async function ctxFactory() { decimals: 18 }; - await optimism.testing(networkName).stubL1CrossChainMessengerContract(); + await optimism.testing().stubL1CrossChainMessengerContract(); const l1TokenRebasable = await new StETHStub__factory(l1Deployer).deploy( l1TokenRebasableName, @@ -276,7 +273,7 @@ async function ctxFactory() { lastProcessingRefSlot ); - const optAddresses = optimism.addresses(networkName); + const optAddresses = optimism.addresses(); const testingOnDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); const govBridgeExecutor = testingOnDeployedContracts @@ -294,9 +291,8 @@ async function ctxFactory() { const l1EthGovExecutorAddress = await govBridgeExecutor.getEthereumGovernanceExecutor(); - const [, optDeployScript] = await deploymentAll( - networkName - ).deployAllScript( + const [, optDeployScript] = await deploymentAll() + .deployAllScript( { l1TokenNonRebasable: l1TokenNonRebasable.address, l1TokenRebasable: l1TokenRebasable.address, @@ -358,7 +354,7 @@ async function ctxFactory() { l2Deployer ); - const optContracts = optimism.contracts(networkName, { forking: true }); + const optContracts = optimism.contracts({ forking: true }); const l1CrossDomainMessengerAliased = await testing.impersonate( testing.accounts.applyL1ToL2Alias( diff --git a/test/managing-e2e/managing-deposits.e2e.test.ts b/test/managing-e2e/managing-deposits.e2e.test.ts index 36712d50..4893e4a6 100644 --- a/test/managing-e2e/managing-deposits.e2e.test.ts +++ b/test/managing-e2e/managing-deposits.e2e.test.ts @@ -63,7 +63,7 @@ const scenarioTest = scenario( [false, false], ]); - const optAddresses = optimism.addresses("sepolia"); + const optAddresses = optimism.addresses(); const { calldata, callvalue } = await ctx.messaging.prepareL2Message({ sender: ctx.lidoAragonDAO.agent.address, @@ -138,22 +138,20 @@ scenarioTest.run(); scenarioTest.run(); async function ctxFactory() { - const ethOptNetwork = network.multichain(["eth", "opt"], "sepolia"); - - const [l1Provider] = ethOptNetwork.getProviders({ forking: false }); - const [l1Tester, l2Tester] = ethOptNetwork.getSigners( + const [l1Provider] = network.getProviders({ forking: false }); + const [l1Tester, l2Tester] = network.getSigners( env.string("TESTING_PRIVATE_KEY"), { forking: false } ); - const [l1LDOHolder] = ethOptNetwork.getSigners( + const [l1LDOHolder] = network.getSigners( env.string("TESTING_OPT_LDO_HOLDER_PRIVATE_KEY"), { forking: false } ); return { lidoAragonDAO: lido("sepolia", l1Provider), - messaging: optimism.messaging("sepolia", { forking: false }), + messaging: optimism.messaging({ forking: false }), gasAmount: wei`0.1 ether`, l1Tester, l2Tester, diff --git a/test/managing-e2e/managing-executor.e2e.test.ts b/test/managing-e2e/managing-executor.e2e.test.ts index f48112e9..82326ff9 100644 --- a/test/managing-e2e/managing-executor.e2e.test.ts +++ b/test/managing-e2e/managing-executor.e2e.test.ts @@ -47,7 +47,7 @@ scenario("Optimism :: AAVE governance crosschain bridge management", ctxFactory) [false], ]); - const optAddresses = optimism.addresses("sepolia"); + const optAddresses = optimism.addresses(); const { calldata, callvalue } = await ctx.messaging.prepareL2Message({ sender: ctx.lidoAragonDAO.agent.address, @@ -115,22 +115,20 @@ scenario("Optimism :: AAVE governance crosschain bridge management", ctxFactory) .run(); async function ctxFactory() { - const ethOptNetwork = network.multichain(["eth", "opt"], "sepolia"); - - const [l1Provider] = ethOptNetwork.getProviders({ forking: false }); - const [, l2Tester] = ethOptNetwork.getSigners( + const [l1Provider] = network.getProviders({ forking: false }); + const [, l2Tester] = network.getSigners( env.string("TESTING_PRIVATE_KEY"), { forking: false } ); - const [l1LDOHolder] = ethOptNetwork.getSigners( + const [l1LDOHolder] = network.getSigners( env.string("TESTING_OPT_LDO_HOLDER_PRIVATE_KEY"), { forking: false } ); return { lidoAragonDAO: lido("sepolia", l1Provider), - messaging: optimism.messaging("sepolia", { forking: false }), + messaging: optimism.messaging({ forking: false }), gasAmount: wei`0.1 ether`, l2Tester, l1LDOHolder, diff --git a/test/managing-e2e/managing-proxy.e2e.test.ts b/test/managing-e2e/managing-proxy.e2e.test.ts index 8c5ddcc2..03165a74 100644 --- a/test/managing-e2e/managing-proxy.e2e.test.ts +++ b/test/managing-e2e/managing-proxy.e2e.test.ts @@ -47,7 +47,7 @@ scenario( [false], ]); - const optAddresses = optimism.addresses("sepolia"); + const optAddresses = optimism.addresses(); const { calldata, callvalue } = await ctx.messaging.prepareL2Message({ sender: ctx.lidoAragonDAO.agent.address, @@ -118,7 +118,7 @@ scenario( [false], ]); - const optAddresses = optimism.addresses("sepolia"); + const optAddresses = optimism.addresses(); const { calldata, callvalue } = await ctx.messaging.prepareL2Message({ sender: ctx.lidoAragonDAO.agent.address, @@ -180,22 +180,20 @@ scenario( .run(); async function ctxFactory() { - const ethOptNetwork = network.multichain(["eth", "opt"], "sepolia"); - - const [l1Provider] = ethOptNetwork.getProviders({ forking: false }); - const [l1Tester, l2Tester] = ethOptNetwork.getSigners( + const [l1Provider] = network.getProviders({ forking: false }); + const [l1Tester, l2Tester] = network.getSigners( env.string("TESTING_PRIVATE_KEY"), { forking: false } ); - const [l1LDOHolder] = ethOptNetwork.getSigners( + const [l1LDOHolder] = network.getSigners( env.string("TESTING_OPT_LDO_HOLDER_PRIVATE_KEY"), { forking: false } ); return { lidoAragonDAO: lido("sepolia", l1Provider), - messaging: optimism.messaging("sepolia", { forking: false }), + messaging: optimism.messaging({ forking: false }), gasAmount: wei`0.1 ether`, l1Tester, l2Tester, diff --git a/utils/deployment.ts b/utils/deployment.ts index 5f8a722d..26c22891 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -110,7 +110,7 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { export async function printDeploymentConfig() { const pad = " ".repeat(4); - console.log(`${pad}· Network: ${env.string("NETWORK")}`); +// console.log(`${pad}· Network: ${env.string("NETWORK")}`); console.log(`${pad}· Forking: ${env.bool("FORKING")}`); } diff --git a/utils/env.ts b/utils/env.ts index 543af0b6..5803abe1 100644 --- a/utils/env.ts +++ b/utils/env.ts @@ -1,5 +1,4 @@ import { toAddress } from "@eth-optimism/sdk"; -import { NetworkName } from "./network"; function getString(variableName: string, defaultValue?: string) { const value = process.env[variableName]; @@ -47,10 +46,6 @@ function getAddressList(variableName: string, defaultValue?: string[]) { return getList(variableName, defaultValue).map(toAddress); } -function getNetwork(name: string = "NETWORK", defaultNetwork?: NetworkName) { - return getEnum(name, ["mainnet", "sepolia"], defaultNetwork); -} - function getPrivateKey() { return getString("ETH_DEPLOYER_PRIVATE_KEY"); } @@ -59,14 +54,18 @@ function getForking() { return getBool("FORKING", false); } +function getNumber(variableName: string, defaultValue?: string) { + return Number(getString(variableName, defaultValue)); +} + export default { string: getString, + number: getNumber, list: getList, enum: getEnum, bool: getBool, address: getAddress, addresses: getAddressList, - network: getNetwork, privateKey: getPrivateKey, forking: getForking, }; diff --git a/utils/network.ts b/utils/network.ts index 9b7a2af1..b1a6c674 100644 --- a/utils/network.ts +++ b/utils/network.ts @@ -6,40 +6,9 @@ import { HardhatRuntimeEnvironment, HttpNetworkConfig } from "hardhat/types"; import env from "./env"; -type ChainNameShort = "opt" | "eth"; -export type NetworkName = "sepolia" | "mainnet"; +type ChainNameShort = "l1" | "l2"; export type SignerOrProvider = Signer | Provider; -const HARDHAT_NETWORK_NAMES = { - eth: { - sepolia: "eth_sepolia", - mainnet: "eth_mainnet", - }, - opt: { - sepolia: "opt_sepolia", - mainnet: "opt_mainnet", - }, - uni: { - sepolia: "uni_sepolia", - mainnet: "uni_mainnet", - } -}; - -const HARDHAT_NETWORK_NAMES_FORK = { - eth: { - sepolia: "eth_sepolia_fork", - mainnet: "eth_mainnet_fork", - }, - opt: { - sepolia: "opt_sepolia_fork", - mainnet: "opt_mainnet_fork", - }, - uni: { - sepolia: "uni_sepolia_fork", - mainnet: "uni_mainnet_fork", - }, -}; - export function getConfig(networkName: string, hre: HardhatRuntimeEnvironment) { const config = hre.config.networks[networkName]; if (!config) { @@ -80,57 +49,24 @@ function loadAccount(rpcURL: string, accountPrivateKeyName: string) { return new Wallet(privateKey, getProvider(rpcURL)); } -export function multichain( - chainNames: ChainNameShort[], - networkName: NetworkName -) { - return { - getNetworks(options: { forking: boolean }) { - const hardhatNetworkNames = options.forking - ? HARDHAT_NETWORK_NAMES_FORK - : HARDHAT_NETWORK_NAMES; +export function getProviders(options: { forking: boolean }) { + if (options.forking) { + return [getProvider(getConfig("l1_fork", hre).url), getProvider(getConfig("l2_fork", hre).url)]; + } + return [getProvider(getConfig("l1", hre).url), getProvider(getConfig("l2", hre).url)]; +} - const res: HttpNetworkConfig[] = []; - for (const chainName of chainNames) { - const hardhatNetworkName = hardhatNetworkNames[chainName][networkName]; - if (hardhatNetworkName === "NOT_DEPLOYED") { - throw new Error( - `Chain "${chainName}" doesn't support "${hardhatNetworkName}" network` - ); - } - res.push(getConfig(hardhatNetworkName, hre)); - } - return res; - }, - getProviders(options: { forking: boolean }) { - return this.getNetworks(options).map((network) => - getProvider(network.url) - ); - }, - getSigners(privateKey: string, options: { forking: boolean }) { - return this.getProviders(options).map( - (provider) => new Wallet(privateKey, provider) - ); - }, - }; +export function getSigners(privateKey: string, options: { forking: boolean }) { + return getProviders(options).map( + (provider) => new Wallet(privateKey, provider) + ); } -function getChainId(protocol: ChainNameShort, networkName: NetworkName) { - const chainIds = { - eth: { - mainnet: 1, - sepolia: 11155111, - }, - opt: { - mainnet: 10, - sepolia: 11155420, - }, - }; - const chainId = chainIds[protocol][networkName]; - if (!chainId) { - throw new Error(`Network for ${protocol} ${networkName} doesn't declared`); +function getChainId(protocol: ChainNameShort) { + if (protocol == "l1") { + return env.number("L1_CHAIN_ID"); } - return chainId; + return env.number("L2_CHAIN_ID"); } function getBlockExplorerBaseUrlByChainId(chainId: number) { @@ -150,7 +86,8 @@ function getBlockExplorerBaseUrlByChainId(chainId: number) { export default { blockExplorerBaseUrl: getBlockExplorerBaseUrlByChainId, chainId: getChainId, - multichain, + getProviders, + getSigners, getConfig, getProvider, loadAccount, diff --git a/utils/optimism/addresses.ts b/utils/optimism/addresses.ts index fd6dd18f..c5c565dc 100644 --- a/utils/optimism/addresses.ts +++ b/utils/optimism/addresses.ts @@ -1,26 +1,9 @@ -import { NetworkName } from "../network"; -import { OptContractAddresses, CommonOptions } from "./types"; +import env from "../env"; -const OptimismMainnetAddresses: OptContractAddresses = { - L1CrossDomainMessenger: "0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1", - L2CrossDomainMessenger: "0x4200000000000000000000000000000000000007" -}; - -const OptimismSepoliaAddresses: OptContractAddresses = { - L1CrossDomainMessenger: "0x448A37330A60494E666F6DD60aD48d930AEbA381", - L2CrossDomainMessenger: "0x4200000000000000000000000000000000000007", -}; - -export default function addresses( - networkName: NetworkName, - options: CommonOptions = {} -) { - switch (networkName) { - case "mainnet": - return { ...OptimismMainnetAddresses, ...options.customAddresses }; - case "sepolia": - return { ...OptimismSepoliaAddresses, ...options.customAddresses }; - default: - throw new Error(`Network "${networkName}" is not supported`); - } +export default function addresses() { + return { + L1CrossDomainMessenger: env.string("L1_CROSSDOMAIN_MESSENGER", ""), + L2CrossDomainMessenger: env.string("L2_CROSSDOMAIN_MESSENGER", "") + }; } + diff --git a/utils/optimism/contracts.ts b/utils/optimism/contracts.ts index 4a7014db..6db61cb9 100644 --- a/utils/optimism/contracts.ts +++ b/utils/optimism/contracts.ts @@ -5,21 +5,19 @@ import { } from "../../typechain"; import addresses from "./addresses"; import { CommonOptions } from "./types"; -import network, { NetworkName } from "../network"; +import network from "../network"; interface ContractsOptions extends CommonOptions { forking: boolean; } export default function contracts( - networkName: NetworkName, options: ContractsOptions ) { const [l1Provider, l2Provider] = network - .multichain(["eth", "opt"], networkName) .getProviders(options); - const optAddresses = addresses(networkName, options); + const optAddresses = addresses(); return { L1CrossDomainMessenger: L1CrossDomainMessenger__factory.connect( diff --git a/utils/optimism/deployment.ts b/utils/optimism/deployment.ts index b10add25..2952d536 100644 --- a/utils/optimism/deployment.ts +++ b/utils/optimism/deployment.ts @@ -2,7 +2,7 @@ import { assert } from "chai"; import { BigNumber, Wallet } from "ethers"; import addresses from "./addresses"; import { OptDeploymentOptions, DeployScriptParams } from "./types"; -import network, { NetworkName } from "../network"; +import network from "../network"; import { DeployScript, Logger } from "../deployment/DeployScript"; import { ERC20BridgedPermit__factory, @@ -117,10 +117,9 @@ export class L2DeployAllScript extends DeployScript { /// ERC20RebasableBridgedPermit + Proxy /// L2ERC20ExtendedTokensBridge + Proxy export default function deploymentAll( - networkName: NetworkName, options: OptDeploymentOptions = {} ) { - const optAddresses = addresses(networkName, options); + const optAddresses = addresses(); return { async deployAllScript( l1Params: OptL1DeployScriptParams, diff --git a/utils/optimism/deploymentOracle.ts b/utils/optimism/deploymentOracle.ts index ffec038e..09f8fc89 100644 --- a/utils/optimism/deploymentOracle.ts +++ b/utils/optimism/deploymentOracle.ts @@ -1,9 +1,8 @@ import { assert } from "chai"; import { BigNumber, Wallet } from "ethers"; -import { ethers } from "hardhat"; -import addresses from "./addresses"; import { DeployScriptParams, OptDeploymentOptions } from "./types"; -import network, { NetworkName } from "../network"; +import addresses from "./addresses"; +import network from "../network"; import { DeployScript, Logger } from "../deployment/DeployScript"; import { OssifiableProxy__factory, @@ -71,10 +70,9 @@ export class OracleL2DeployScript extends DeployScript { /// L2 part /// TokenRateOracle + proxy export default function deploymentOracle( - networkName: NetworkName, options: OptDeploymentOptions = {} ) { - const optAddresses = addresses(networkName, options); + const optAddresses = addresses(); return { async oracleDeployScript( l1Params: OptL1DeployScriptParams, diff --git a/utils/optimism/deploymentStETH.ts b/utils/optimism/deploymentStETH.ts index e7e6fc2e..42d4b366 100644 --- a/utils/optimism/deploymentStETH.ts +++ b/utils/optimism/deploymentStETH.ts @@ -2,7 +2,7 @@ import { assert } from "chai"; import { BigNumber, Wallet } from "ethers"; import addresses from "./addresses"; import { OptDeploymentOptions, DeployScriptParams } from "./types"; -import network, { NetworkName } from "../network"; +import network from "../network"; import { DeployScript, Logger } from "../deployment/DeployScript"; import { ERC20BridgedPermit__factory, @@ -125,10 +125,9 @@ export class L2UpgradeScript extends DeployScript { /// Non-rebasable token (wstETH) new Impl with Permissions export default function deploy( - networkName: NetworkName, options: OptDeploymentOptions = {} ) { - const optAddresses = addresses(networkName, options); + const optAddresses = addresses(); return { async deployScript( l1Params: OptL1UpgradeScriptParams, diff --git a/utils/optimism/messaging.ts b/utils/optimism/messaging.ts index 6724d447..0586dab8 100644 --- a/utils/optimism/messaging.ts +++ b/utils/optimism/messaging.ts @@ -1,5 +1,5 @@ import contracts from "./contracts"; -import network, { NetworkName } from "../network"; +import network from "../network"; import { CommonOptions } from "./types"; import { CrossChainMessenger, MessageStatus } from "@eth-optimism/sdk"; @@ -15,19 +15,17 @@ interface MessageData { } export default function messaging( - networkName: NetworkName, options: ContractsOptions ) { const [ethProvider, optProvider] = network - .multichain(["eth", "opt"], networkName) .getProviders(options); - const optContracts = contracts(networkName, options); + const optContracts = contracts(options); const crossChainMessenger = new CrossChainMessenger({ - l2ChainId: network.chainId("opt", networkName), + l1ChainId: network.chainId("l1"), + l2ChainId: network.chainId("l2"), l1SignerOrProvider: ethProvider, l2SignerOrProvider: optProvider, - l1ChainId: network.chainId("eth", networkName), }); return { prepareL2Message(msg: MessageData) { diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index 6fe34818..03dfda05 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -24,15 +24,14 @@ import contracts from "./contracts"; import deploymentAll from "./deployment"; import testingUtils from "../testing"; import { BridgingManagement } from "../bridging-management"; -import network, { NetworkName, SignerOrProvider } from "../network"; +import network, { SignerOrProvider } from "../network"; -export default function testing(networkName: NetworkName) { - const optAddresses = addresses(networkName); - const ethOptNetworks = network.multichain(["eth", "opt"], networkName); +export default function testing() { + const optAddresses = addresses(); return { async getAcceptanceTestSetup() { - const [ethProvider, optProvider] = ethOptNetworks.getProviders({ + const [ethProvider, optProvider] = network.getProviders({ forking: true, }); @@ -41,7 +40,7 @@ export default function testing(networkName: NetworkName) { optProvider ); - await printLoadedTestConfig(networkName, bridgeContracts); + await printLoadedTestConfig(bridgeContracts); return { l1Provider: ethProvider, @@ -51,14 +50,14 @@ export default function testing(networkName: NetworkName) { }, async getIntegrationTestSetup() { const hasDeployedContracts = testingUtils.env.USE_DEPLOYED_CONTRACTS(false); - const [ethProvider, optProvider] = ethOptNetworks.getProviders({ forking: true }); + const [ethProvider, optProvider] = network.getProviders({ forking: true }); var totalPooledEther = BigNumber.from('9309904612343950493629678'); var totalShares = BigNumber.from('7975822843597609202337218'); const bridgeContracts = hasDeployedContracts ? await loadDeployedBridges(ethProvider, optProvider) - : await deployTestBridge(networkName, totalPooledEther, totalShares, ethProvider, optProvider); + : await deployTestBridge(totalPooledEther, totalShares, ethProvider, optProvider); if (hasDeployedContracts) { totalPooledEther = await bridgeContracts.l1TokenRebasable.getTotalPooledEther(); @@ -80,13 +79,12 @@ export default function testing(networkName: NetworkName) { if (hasDeployedContracts) { await printLoadedTestConfig( - networkName, bridgeContracts, l1TokensHolder ); } - const optContracts = contracts(networkName, { forking: true }); + const optContracts = contracts({ forking: true }); return { totalPooledEther: totalPooledEther, @@ -109,16 +107,16 @@ export default function testing(networkName: NetworkName) { }, async getE2ETestSetup() { const testerPrivateKey = testingUtils.env.TESTING_PRIVATE_KEY(); - const [ethProvider, optProvider] = ethOptNetworks.getProviders({ + const [ethProvider, optProvider] = network.getProviders({ forking: false, }); - const [l1Tester, l2Tester] = ethOptNetworks.getSigners(testerPrivateKey, { + const [l1Tester, l2Tester] = network.getSigners(testerPrivateKey, { forking: false, }); const bridgeContracts = await loadDeployedBridges(l1Tester, l2Tester); - await printLoadedTestConfig(networkName, bridgeContracts, l1Tester); + await printLoadedTestConfig(bridgeContracts, l1Tester); return { l1Tester, @@ -129,7 +127,7 @@ export default function testing(networkName: NetworkName) { }; }, async stubL1CrossChainMessengerContract() { - const [ethProvider] = ethOptNetworks.getProviders({ forking: true }); + const [ethProvider] = network.getProviders({ forking: true }); const deployer = testingUtils.accounts.deployer(ethProvider); const stub = await new CrossDomainMessengerStub__factory( deployer @@ -182,7 +180,6 @@ async function loadDeployedBridges( } async function deployTestBridge( - networkName: NetworkName, totalPooledEther: BigNumber, totalShares: BigNumber, ethProvider: JsonRpcProvider, @@ -254,9 +251,8 @@ async function deployTestBridge( lastProcessingRefSlot ); - const [ethDeployScript, optDeployScript] = await deploymentAll( - networkName - ).deployAllScript( + const [ethDeployScript, optDeployScript] = await deploymentAll() + .deployAllScript( { l1TokenNonRebasable: l1TokenNonRebasable.address, l1TokenRebasable: l1TokenRebasable.address, @@ -403,7 +399,6 @@ function connectBridgeContracts( } async function printLoadedTestConfig( - networkName: NetworkName, bridgeContracts: { l1Token: IERC20; l1TokenRebasable: IERC20; @@ -417,7 +412,7 @@ async function printLoadedTestConfig( console.log( "In case of unexpected fails, please, make sure that you are forking correct Ethereum/Optimism networks" ); - console.log(` · Network Name: ${networkName}`); + //console.log(` · Network Id: ${networkName}`); console.log(` · L1 Token: ${bridgeContracts.l1Token.address}`); console.log(` · L2 Token: ${bridgeContracts.l2Token.address}`); if (l1TokensHolder) { From 03881342922cb86bd0baa1f5ed96c0dccf2a504e Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Mon, 9 Dec 2024 09:42:00 +0100 Subject: [PATCH 19/34] refactor deployment paramteres --- scripts/optimism/deploy-automaton.ts | 83 +++---- .../optimism/deploy-new-steth-contracts.ts | 94 ++++---- scripts/optimism/deploy-scratch.ts | 78 +++--- utils/deployment.ts | 222 ++++++++++++------ utils/optimism/deployment.ts | 6 +- utils/optimism/deploymentForAutomaton.ts | 3 +- utils/optimism/deploymentStETH.ts | 44 ++-- utils/optimism/types.ts | 2 +- 8 files changed, 317 insertions(+), 215 deletions(-) diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index 4fd89713..d9d62e8b 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -9,61 +9,62 @@ import * as fs from 'fs'; async function main() { - const [ethDeployer] = network.getSigners(env.privateKey(), { + const [l1Deployer] = network.getSigners(env.privateKey(), { forking: env.forking() }); - const [, optDeployer] = network.getSigners( + const [, l2Deployer] = network.getSigners( env.string("OPT_DEPLOYER_PRIVATE_KEY"), { forking: env.forking() } ); - const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); + const deploymentConfig = deployment.loadMultiChainAutomatonDeploymentConfig(); const [l1DeployScript, l2DeployScript] = await deploymentAll({ logger: console }) .deployAllScript( { - l1CrossDomainMessenger: deploymentConfig.ethereum.l1CrossDomainMessenger, - l1TokenNonRebasable: deploymentConfig.ethereum.l1TokenNonRebasable, - l1TokenRebasable: deploymentConfig.ethereum.l1RebasableToken, - accountingOracle: deploymentConfig.ethereum.accountingOracle, - l2GasLimitForPushingTokenRate: deploymentConfig.ethereum.l2GasLimitForPushingTokenRate, + l1CrossDomainMessenger: deploymentConfig.l1.l1CrossDomainMessenger, + l1TokenNonRebasable: deploymentConfig.l1.l1TokenNonRebasable, + l1TokenRebasable: deploymentConfig.l1.l1RebasableToken, + accountingOracle: deploymentConfig.l1.accountingOracle, + l2GasLimitForPushingTokenRate: deploymentConfig.l1.l2GasLimitForPushingTokenRate, - deployer: ethDeployer, + deployer: l1Deployer, admins: { - proxy: deploymentConfig.ethereum.proxyAdmin, - bridge: ethDeployer.address + proxy: deploymentConfig.l1.proxyAdmin, + bridge: l1Deployer.address, }, deployOffset: 0, }, { - l2CrossDomainMessenger: deploymentConfig.optimism.l2CrossDomainMessenger, + l2CrossDomainMessenger: deploymentConfig.l2.l2CrossDomainMessenger, tokenRateOracle: { - tokenRateOutdatedDelay: deploymentConfig.optimism.tokenRateOutdatedDelay, - maxAllowedL2ToL1ClockLag: deploymentConfig.optimism.maxAllowedL2ToL1ClockLag, - maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.optimism.maxAllowedTokenRateDeviationPerDayBp, - oldestRateAllowedInPauseTimeSpan: deploymentConfig.optimism.oldestRateAllowedInPauseTimeSpan, - minTimeBetweenTokenRateUpdates: deploymentConfig.optimism.minTimeBetweenTokenRateUpdates, - tokenRate: deploymentConfig.optimism.initialTokenRateValue, - l1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp + admin: l2Deployer.address, + tokenRateOutdatedDelay: deploymentConfig.l2.tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: deploymentConfig.l2.maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.l2.maxAllowedTokenRateDeviationPerDayBp, + oldestRateAllowedInPauseTimeSpan: deploymentConfig.l2.oldestRateAllowedInPauseTimeSpan, + minTimeBetweenTokenRateUpdates: deploymentConfig.l2.minTimeBetweenTokenRateUpdates, + tokenRate: deploymentConfig.l2.initialTokenRateValue, + l1Timestamp: deploymentConfig.l2.initialTokenRateL1Timestamp }, l2TokenNonRebasable: { - name: deploymentConfig.optimism.l2TokenNonRebasableName, - symbol: deploymentConfig.optimism.l2TokenNonRebasableSymbol, - version: deploymentConfig.optimism.l2TokenNonRebasableDomainVersion + name: deploymentConfig.l2.l2TokenNonRebasableName, + symbol: deploymentConfig.l2.l2TokenNonRebasableSymbol, + version: deploymentConfig.l2.l2TokenNonRebasableDomainVersion }, l2TokenRebasable: { - name: deploymentConfig.optimism.l2TokenRebasableName, - symbol: deploymentConfig.optimism.l2TokenRebasableSymbol, - version: deploymentConfig.optimism.l2TokenRebasableDomainVersion + name: deploymentConfig.l2.l2TokenRebasableName, + symbol: deploymentConfig.l2.l2TokenRebasableSymbol, + version: deploymentConfig.l2.l2TokenRebasableDomainVersion }, - deployer: optDeployer, + deployer: l2Deployer, admins: { - proxy: deploymentConfig.optimism.proxyAdmin, - bridge: optDeployer.address, + proxy: deploymentConfig.l2.proxyAdmin, + bridge: l2Deployer.address, }, deployOffset: 0, } @@ -71,8 +72,8 @@ async function main() { await deployment.printMultiChainDeploymentConfig( "Deploy Optimism Bridge", - ethDeployer, - optDeployer, + l1Deployer, + l2Deployer, deploymentConfig, l1DeployScript, l2DeployScript, @@ -86,31 +87,31 @@ async function main() { const l1BridgingManagement = new BridgingManagement( l1DeployScript.bridgeProxyAddress, - ethDeployer, + l1Deployer, { logger: console } ); const l2BridgingManagement = new BridgingManagement( l2DeployScript.tokenBridgeProxyAddress, - optDeployer, + l2Deployer, { logger: console } ); const tokenRateOracleManagement = new TokenRateOracleManagement( l2DeployScript.tokenRateOracleProxyAddress, - optDeployer, + l2Deployer, { logger: console } ); - await l1BridgingManagement.setup(deploymentConfig.ethereum); - await l2BridgingManagement.setup(deploymentConfig.optimism); + await l1BridgingManagement.setup(deploymentConfig.l1); + await l2BridgingManagement.setup(deploymentConfig.l2); await tokenRateOracleManagement.setup({ - tokenRateOracleAdmin: deploymentConfig.optimism.tokenRateOracleAdmin, - initialTokenRateValue: deploymentConfig.optimism.initialTokenRateValue, - initialTokenRateL1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp, - rateUpdatesEnabled: deploymentConfig.optimism.tokenRateUpdateEnabled, - rateUpdatesDisablers: deploymentConfig.optimism.tokenRateUpdateDisablers, - rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers + tokenRateOracleAdmin: deploymentConfig.l2.tokenRateOracleAdmin, + initialTokenRateValue: deploymentConfig.l2.initialTokenRateValue, + initialTokenRateL1Timestamp: deploymentConfig.l2.initialTokenRateL1Timestamp, + rateUpdatesEnabled: deploymentConfig.l2.tokenRateUpdateEnabled, + rateUpdatesDisablers: deploymentConfig.l2.tokenRateUpdateDisablers, + rateUpdatesEnablers: deploymentConfig.l2.tokenRateUpdateEnablers }); await l1DeployScript.saveResultToFile("l1DeployArgs.json"); diff --git a/scripts/optimism/deploy-new-steth-contracts.ts b/scripts/optimism/deploy-new-steth-contracts.ts index ad58590e..7e363eb9 100644 --- a/scripts/optimism/deploy-new-steth-contracts.ts +++ b/scripts/optimism/deploy-new-steth-contracts.ts @@ -8,69 +8,73 @@ import deploy from "../../utils/optimism/deploymentStETH"; async function main() { - const [ethDeployer] = network.getSigners(env.privateKey(), { + const [l1Deployer] = network.getSigners(env.privateKey(), { forking: env.forking(), }); const [ethProvider] = network.getProviders({ forking: env.forking() }); - const [, optDeployer] = network.getSigners( + const [, l2Deployer] = network.getSigners( env.string("OPT_DEPLOYER_PRIVATE_KEY"), { forking: env.forking(), } ); - const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); + const deploymentConfig = deployment.loadMultiChainStETHDeploymentConfig(); const [l1DeployScript, l2DeployScript] = await deploy({ logger: console }) .deployScript( { - l1TokenNonRebasable: deploymentConfig.ethereum.l1TokenNonRebasable, - l1TokenRebasable: deploymentConfig.ethereum.l1RebasableToken, - accountingOracle: deploymentConfig.ethereum.accountingOracle, - l2GasLimitForPushingTokenRate: deploymentConfig.ethereum.l2GasLimitForPushingTokenRate, - l1TokenBridge: deploymentConfig.ethereum.l1TokenBridge, - lido: deploymentConfig.ethereum.lido, + l1CrossDomainMessenger: deploymentConfig.l1.l1CrossDomainMessenger, + l1TokenNonRebasable: deploymentConfig.l1.l1TokenNonRebasable, + l1TokenRebasable: deploymentConfig.l1.l1RebasableToken, + accountingOracle: deploymentConfig.l1.accountingOracle, + l2GasLimitForPushingTokenRate: deploymentConfig.l1.l2GasLimitForPushingTokenRate, - deployer: ethDeployer, + l1TokenBridge: deploymentConfig.l1.l1TokenBridge, + lido: deploymentConfig.l1.lido, + tokenRateNotifierOwner: l1Deployer.address, + + deployer: l1Deployer, admins: { - proxy: deploymentConfig.ethereum.bridgeProxyAdmin, - bridge: ethDeployer.address + proxy: deploymentConfig.l1.proxyAdmin, + bridge: l1Deployer.address }, deployOffset: 0, }, { + l2CrossDomainMessenger: deploymentConfig.l2.l2CrossDomainMessenger, + l2TokenBridge: deploymentConfig.l2.l2TokenBridge, + tokenRateOracle: { - proxyAdmin: deploymentConfig.optimism.tokenRateOracleProxyAdmin, - admin: optDeployer.address, - constructor: { - tokenRateOutdatedDelay: deploymentConfig.optimism.tokenRateOutdatedDelay, - maxAllowedL2ToL1ClockLag: deploymentConfig.optimism.maxAllowedL2ToL1ClockLag, - maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.optimism.maxAllowedTokenRateDeviationPerDayBp, - oldestRateAllowedInPauseTimeSpan: deploymentConfig.optimism.oldestRateAllowedInPauseTimeSpan, - minTimeBetweenTokenRateUpdates: deploymentConfig.optimism.minTimeBetweenTokenRateUpdates - }, - initialize: { - tokenRate: deploymentConfig.optimism.initialTokenRateValue, - l1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp - } + admin: l2Deployer.address, + tokenRateOutdatedDelay: deploymentConfig.l2.tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: deploymentConfig.l2.maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.l2.maxAllowedTokenRateDeviationPerDayBp, + oldestRateAllowedInPauseTimeSpan: deploymentConfig.l2.oldestRateAllowedInPauseTimeSpan, + minTimeBetweenTokenRateUpdates: deploymentConfig.l2.minTimeBetweenTokenRateUpdates, + tokenRate: deploymentConfig.l2.initialTokenRateValue, + l1Timestamp: deploymentConfig.l2.initialTokenRateL1Timestamp }, - l2TokenBridge: deploymentConfig.optimism.l2TokenBridge, l2TokenNonRebasable: { - address: deploymentConfig.optimism.l2TokenNonRebasableAddress, - version: deploymentConfig.optimism.l2TokenNonRebasableDomainVersion + address: deploymentConfig.l2.l2TokenNonRebasableAddress, + name: deploymentConfig.l2.l2TokenNonRebasableName, + symbol: deploymentConfig.l2.l2TokenRebasableSymbol, + version: deploymentConfig.l2.l2TokenNonRebasableDomainVersion }, l2TokenRebasable: { - proxyAdmin: deploymentConfig.optimism.l2TokenRebasableProxyAdmin, - version: deploymentConfig.optimism.l2TokenRebasableDomainVersion + proxyAdmin: deploymentConfig.l2.l2TokenRebasableProxyAdmin, + name: deploymentConfig.l2.l2TokenRebasableName, + symbol: deploymentConfig.l2.l2TokenRebasableSymbol, + version: deploymentConfig.l2.l2TokenRebasableDomainVersion }, - deployer: optDeployer, + deployer: l2Deployer, admins: { - proxy: deploymentConfig.optimism.bridgeProxyAdmin, - bridge: optDeployer.address, + proxy: deploymentConfig.l2.proxyAdmin, + bridge: l2Deployer.address, }, deployOffset: 0, } @@ -78,8 +82,8 @@ async function main() { await deployment.printMultiChainDeploymentConfig( "Deploy new contracts for Optimism Bridge", - ethDeployer, - optDeployer, + l1Deployer, + l2Deployer, deploymentConfig, l1DeployScript, l2DeployScript, @@ -94,30 +98,30 @@ async function main() { /// Setup TokenRateNotifier const tokenRateNotifierManagement = new TokenRateNotifierManagement( l1DeployScript.tokenRateNotifierImplAddress, - ethDeployer, + l1Deployer, { logger: console } ); await tokenRateNotifierManagement.setup({ tokenRateNotifier: l1DeployScript.tokenRateNotifierImplAddress, opStackTokenRatePusher: l1DeployScript.opStackTokenRatePusherImplAddress, - ethDeployer: ethDeployer, + ethDeployer: l1Deployer, ethProvider: ethProvider, - notifierOwner: deploymentConfig.ethereum.tokenRateNotifierOwner + notifierOwner: deploymentConfig.l1.tokenRateNotifierOwner }); /// Setup TokenRateOracle const tokenRateOracleManagement = new TokenRateOracleManagement( l2DeployScript.tokenRateOracleProxyAddress, - optDeployer, + l2Deployer, { logger: console } ); await tokenRateOracleManagement.setup({ - tokenRateOracleAdmin: deploymentConfig.optimism.tokenRateOracleAdmin, - initialTokenRateValue: deploymentConfig.optimism.initialTokenRateValue, - initialTokenRateL1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp, - rateUpdatesEnabled: deploymentConfig.optimism.tokenRateUpdateEnabled, - rateUpdatesDisablers: deploymentConfig.optimism.tokenRateUpdateDisablers, - rateUpdatesEnablers: deploymentConfig.optimism.tokenRateUpdateEnablers + tokenRateOracleAdmin: deploymentConfig.l2.tokenRateOracleAdmin, + initialTokenRateValue: deploymentConfig.l2.initialTokenRateValue, + initialTokenRateL1Timestamp: deploymentConfig.l2.initialTokenRateL1Timestamp, + rateUpdatesEnabled: deploymentConfig.l2.tokenRateUpdateEnabled, + rateUpdatesDisablers: deploymentConfig.l2.tokenRateUpdateDisablers, + rateUpdatesEnablers: deploymentConfig.l2.tokenRateUpdateEnablers }); } diff --git a/scripts/optimism/deploy-scratch.ts b/scripts/optimism/deploy-scratch.ts index b33f64a8..7f321a32 100644 --- a/scripts/optimism/deploy-scratch.ts +++ b/scripts/optimism/deploy-scratch.ts @@ -8,60 +8,70 @@ import { TokenRateNotifierManagement } from "../../utils/tokenRateNotifier-manag async function main() { - const [ethDeployer] = network.getSigners(env.privateKey(), { + const [l1Deployer] = network.getSigners(env.privateKey(), { forking: env.forking() }); - const [ethProvider] = network.getProviders({ + const [l1Provider] = network.getProviders({ forking: env.forking() }); - const [, optDeployer] = network.getSigners( + const [, l2Deployer] = network.getSigners( env.string("OPT_DEPLOYER_PRIVATE_KEY"), { forking: env.forking() } ); - const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); + const deploymentConfig = deployment.loadMultiChainScratchDeploymentConfig(); const [l1DeployScript, l2DeployScript] = await deploymentAll({ logger: console }) .deployAllScript( { - l1TokenNonRebasable: deploymentConfig.ethereum.l1TokenNonRebasable, - l1TokenRebasable: deploymentConfig.ethereum.l1RebasableToken, - accountingOracle: deploymentConfig.ethereum.accountingOracle, - l2GasLimitForPushingTokenRate: deploymentConfig.ethereum.l2GasLimitForPushingTokenRate, - lido: deploymentConfig.ethereum.lido, + lido: deploymentConfig.l1.lido, + tokenRateNotifierOwner: deploymentConfig.l1.tokenRateNotifierOwner, - deployer: ethDeployer, + l1CrossDomainMessenger: deploymentConfig.l1.l1CrossDomainMessenger, + l1TokenNonRebasable: deploymentConfig.l1.l1TokenNonRebasable, + l1TokenRebasable: deploymentConfig.l1.l1RebasableToken, + accountingOracle: deploymentConfig.l1.accountingOracle, + l2GasLimitForPushingTokenRate: deploymentConfig.l1.l2GasLimitForPushingTokenRate, + + deployer: l1Deployer, admins: { - proxy: deploymentConfig.ethereum.bridgeProxyAdmin, - bridge: ethDeployer.address + proxy: deploymentConfig.l1.proxyAdmin, + bridge: l1Deployer.address, }, deployOffset: 0, }, { + l2CrossDomainMessenger: deploymentConfig.l2.l2CrossDomainMessenger, + tokenRateOracle: { - tokenRateOutdatedDelay: deploymentConfig.optimism.tokenRateOutdatedDelay, - maxAllowedL2ToL1ClockLag: deploymentConfig.optimism.maxAllowedL2ToL1ClockLag, - maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.optimism.maxAllowedTokenRateDeviationPerDayBp, - oldestRateAllowedInPauseTimeSpan: deploymentConfig.optimism.oldestRateAllowedInPauseTimeSpan, - minTimeBetweenTokenRateUpdates: deploymentConfig.optimism.minTimeBetweenTokenRateUpdates, - tokenRate: deploymentConfig.optimism.initialTokenRateValue, - l1Timestamp: deploymentConfig.optimism.initialTokenRateL1Timestamp + admin: l2Deployer.address, + tokenRateOutdatedDelay: deploymentConfig.l2.tokenRateOutdatedDelay, + maxAllowedL2ToL1ClockLag: deploymentConfig.l2.maxAllowedL2ToL1ClockLag, + maxAllowedTokenRateDeviationPerDayBp: deploymentConfig.l2.maxAllowedTokenRateDeviationPerDayBp, + oldestRateAllowedInPauseTimeSpan: deploymentConfig.l2.oldestRateAllowedInPauseTimeSpan, + minTimeBetweenTokenRateUpdates: deploymentConfig.l2.minTimeBetweenTokenRateUpdates, + tokenRate: deploymentConfig.l2.initialTokenRateValue, + l1Timestamp: deploymentConfig.l2.initialTokenRateL1Timestamp }, l2TokenNonRebasable: { - version: deploymentConfig.optimism.l2TokenNonRebasableDomainVersion + name: deploymentConfig.l2.l2TokenNonRebasableName, + symbol: deploymentConfig.l2.l2TokenNonRebasableSymbol, + version: deploymentConfig.l2.l2TokenNonRebasableDomainVersion }, l2TokenRebasable: { - version: deploymentConfig.optimism.l2TokenRebasableDomainVersion + name: deploymentConfig.l2.l2TokenRebasableName, + symbol: deploymentConfig.l2.l2TokenRebasableSymbol, + version: deploymentConfig.l2.l2TokenRebasableDomainVersion }, - deployer: optDeployer, + deployer: l2Deployer, admins: { - proxy: deploymentConfig.optimism.bridgeProxyAdmin, - bridge: optDeployer.address, + proxy: deploymentConfig.l2.proxyAdmin, + bridge: l2Deployer.address, }, deployOffset: 0, } @@ -69,8 +79,8 @@ async function main() { await deployment.printMultiChainDeploymentConfig( "Deploy Optimism Bridge", - ethDeployer, - optDeployer, + l1Deployer, + l2Deployer, deploymentConfig, l1DeployScript, l2DeployScript, @@ -84,30 +94,30 @@ async function main() { const tokenRateNotifierManagement = new TokenRateNotifierManagement( l1DeployScript.tokenRateNotifierImplAddress, - ethDeployer + l1Deployer ); await tokenRateNotifierManagement.setup({ tokenRateNotifier: l1DeployScript.tokenRateNotifierImplAddress, opStackTokenRatePusher: l1DeployScript.opStackTokenRatePusherImplAddress, - ethDeployer: ethDeployer, - ethProvider: ethProvider, - notifierOwner: deploymentConfig.ethereum.tokenRateNotifierOwner + ethDeployer: l1Deployer, + ethProvider: l1Provider, + notifierOwner: deploymentConfig.l1.lido }); const l1BridgingManagement = new BridgingManagement( l1DeployScript.bridgeProxyAddress, - ethDeployer, + l1Deployer, { logger: console } ); const l2BridgingManagement = new BridgingManagement( l2DeployScript.tokenBridgeProxyAddress, - optDeployer, + l2Deployer, { logger: console } ); - await l1BridgingManagement.setup(deploymentConfig.ethereum); - await l2BridgingManagement.setup(deploymentConfig.optimism); + await l1BridgingManagement.setup(deploymentConfig.l1); + await l2BridgingManagement.setup(deploymentConfig.l2); } main().catch((error) => { diff --git a/utils/deployment.ts b/utils/deployment.ts index 26c22891..bd2d792e 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -5,16 +5,35 @@ import env from "./env"; import { DeployScript } from "./deployment/DeployScript"; import { BridgingManagerSetupConfig } from "./bridging-management"; -interface EthereumAutomatonDeploymentConfig extends BridgingManagerSetupConfig { + +interface L1StETHDeploymentConfig extends L1ScratchDeploymentConfig { + l1TokenBridge: string; +} + +interface L1ScratchDeploymentConfig extends L1AutomatonDeploymentConfig { + lido: string; + tokenRateNotifierOwner: string; +} + +interface L1AutomatonDeploymentConfig extends BridgingManagerSetupConfig { + l1CrossDomainMessenger: string; + proxyAdmin: string; accountingOracle: string; l1TokenNonRebasable: string; l1RebasableToken: string; l2GasLimitForPushingTokenRate: BigNumber; - proxyAdmin: string; - l1CrossDomainMessenger: string; } -interface OptimismAutomatonDeploymentConfig extends BridgingManagerSetupConfig { +interface L2StETHDeploymentConfig extends L2ScratchDeploymentConfig { + l2TokenBridge: string; + l2TokenNonRebasableAddress: string; + l2TokenRebasableProxyAdmin: string; +} + +interface L2ScratchDeploymentConfig extends L2AutomatonDeploymentConfig { +} + +interface L2AutomatonDeploymentConfig extends BridgingManagerSetupConfig { l2CrossDomainMessenger: string; /// Oracle @@ -44,67 +63,130 @@ interface OptimismAutomatonDeploymentConfig extends BridgingManagerSetupConfig { proxyAdmin: string; } -interface MultiChainDeploymentConfig { - ethereum: EthereumAutomatonDeploymentConfig; - optimism: OptimismAutomatonDeploymentConfig; +interface MultiChainStETHDeploymentConfig { + l1: L1StETHDeploymentConfig; + l2: L2StETHDeploymentConfig; +} + +interface MultiChainScratchDeploymentConfig { + l1: L1ScratchDeploymentConfig; + l2: L2ScratchDeploymentConfig; +} + +interface MultiChainAutomatonDeploymentConfig { + l1: L1AutomatonDeploymentConfig; + l2: L2AutomatonDeploymentConfig; +} + +export function loadL1StETHDeploymentConfig(): L1StETHDeploymentConfig { + return { + ...loadL1ScratchDeploymentConfig(), + l1TokenBridge: env.address(""), + } +} + +export function loadL2StETHDeploymentConfig(): L2StETHDeploymentConfig { + return { + ...loadL2ScratchDeploymentConfig(), + l2TokenBridge: env.address(""), + l2TokenNonRebasableAddress: env.address(""), + l2TokenRebasableProxyAdmin: env.address(""), + } +} + +export function loadL1ScratchDeploymentConfig(): L1ScratchDeploymentConfig { + return { + ...loadL1AutomatonDeploymentConfig(), + lido: env.address("LIDO"), + tokenRateNotifierOwner: env.address("LIDO"), + }; +} + +export function loadL2ScratchDeploymentConfig(): L2ScratchDeploymentConfig { + return { + ...loadL2ScratchDeploymentConfig() + }; +} + +export function loadL1AutomatonDeploymentConfig(): L1AutomatonDeploymentConfig { + return { + l1CrossDomainMessenger: env.address("L1_CROSSDOMAIN_MESSENGER"), + proxyAdmin: env.address("L1_PROXY_ADMIN"), + + l1TokenNonRebasable: env.address("L1_NON_REBASABLE_TOKEN"), + l1RebasableToken: env.address("L1_REBASABLE_TOKEN"), + accountingOracle: env.address("ACCOUNTING_ORACLE"), + l2GasLimitForPushingTokenRate: BigNumber.from(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), + + // Bridge + bridgeAdmin: env.address("L1_BRIDGE_ADMIN"), + depositsEnabled: env.bool("L1_DEPOSITS_ENABLED", false), + withdrawalsEnabled: env.bool("L1_WITHDRAWALS_ENABLED", false), + depositsEnablers: env.addresses("L1_DEPOSITS_ENABLERS", []), + depositsDisablers: env.addresses("L1_DEPOSITS_DISABLERS", []), + withdrawalsEnablers: env.addresses("L1_WITHDRAWALS_ENABLERS", []), + withdrawalsDisablers: env.addresses("L1_WITHDRAWALS_DISABLERS", []), + }; +} + +export function loadL2AutomatonDeploymentConfig(): L2AutomatonDeploymentConfig { + return { + l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER"), + proxyAdmin: env.address("L2_PROXY_ADMIN"), + + /// TokenRateOracle + tokenRateOracleAdmin: env.address("TOKEN_RATE_ORACLE_ADMIN"), + tokenRateUpdateEnabled: env.bool("TOKEN_RATE_UPDATE_ENABLED", true), + tokenRateUpdateDisablers: env.addresses("TOKEN_RATE_UPDATE_DISABLERS", []), + tokenRateUpdateEnablers: env.addresses("TOKEN_RATE_UPDATE_ENABLERS", []), + + tokenRateOutdatedDelay: BigNumber.from(env.string("TOKEN_RATE_OUTDATED_DELAY")), + maxAllowedL2ToL1ClockLag: BigNumber.from(env.string("MAX_ALLOWED_L2_TO_L1_CLOCK_LAG")), + maxAllowedTokenRateDeviationPerDayBp: BigNumber.from(env.string("MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP")), + oldestRateAllowedInPauseTimeSpan: BigNumber.from(env.string("OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN")), + minTimeBetweenTokenRateUpdates: BigNumber.from(env.string("MIN_TIME_BETWEEN_TOKEN_RATE_UPDATES")), + initialTokenRateValue: BigNumber.from(env.string("INITIAL_TOKEN_RATE_VALUE")), + initialTokenRateL1Timestamp: BigNumber.from(env.string("INITIAL_TOKEN_RATE_L1_TIMESTAMP")), + + // wstETH + l2TokenNonRebasableName: env.string("L2_TOKEN_NON_REBASABLE_NAME"), + l2TokenNonRebasableSymbol: env.string("L2_TOKEN_NON_REBASABLE_SYMBOL"), + l2TokenNonRebasableDomainVersion: env.string("L2_TOKEN_NON_REBASABLE_SIGNING_DOMAIN_VERSION"), + + // stETH + l2TokenRebasableName: env.string("L2_TOKEN_REBASABLE_NAME"), + l2TokenRebasableSymbol: env.string("L2_TOKEN_REBASABLE_SYMBOL"), + l2TokenRebasableDomainVersion: env.string("L2_TOKEN_REBASABLE_SIGNING_DOMAIN_VERSION"), + + // Bridge + bridgeAdmin: env.address("L2_BRIDGE_ADMIN"), + depositsEnabled: env.bool("L2_DEPOSITS_ENABLED", false), + withdrawalsEnabled: env.bool("L2_WITHDRAWALS_ENABLED", false), + depositsEnablers: env.addresses("L2_DEPOSITS_ENABLERS", []), + depositsDisablers: env.addresses("L2_DEPOSITS_DISABLERS", []), + withdrawalsEnablers: env.addresses("L2_WITHDRAWALS_ENABLERS", []), + withdrawalsDisablers: env.addresses("L2_WITHDRAWALS_DISABLERS", []), + }; +} + +export function loadMultiChainStETHDeploymentConfig(): MultiChainStETHDeploymentConfig { + return { + l1: loadL1StETHDeploymentConfig(), + l2: loadL2StETHDeploymentConfig() + }; +} + +export function loadMultiChainAutomatonDeploymentConfig(): MultiChainAutomatonDeploymentConfig { + return { + l1: loadL1AutomatonDeploymentConfig(), + l2: loadL2AutomatonDeploymentConfig() + }; } -export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { +export function loadMultiChainScratchDeploymentConfig(): MultiChainScratchDeploymentConfig { return { - ethereum: { - l1CrossDomainMessenger: env.address("L1_CROSSDOMAIN_MESSENGER"), - l1TokenNonRebasable: env.address("L1_NON_REBASABLE_TOKEN"), - l1RebasableToken: env.address("L1_REBASABLE_TOKEN"), - accountingOracle: env.address("ACCOUNTING_ORACLE"), - l2GasLimitForPushingTokenRate: BigNumber.from(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), - - // Bridge - proxyAdmin: env.address("L1_PROXY_ADMIN"), - bridgeAdmin: env.address("L1_BRIDGE_ADMIN"), - depositsEnabled: env.bool("L1_DEPOSITS_ENABLED", false), - withdrawalsEnabled: env.bool("L1_WITHDRAWALS_ENABLED", false), - depositsEnablers: env.addresses("L1_DEPOSITS_ENABLERS", []), - depositsDisablers: env.addresses("L1_DEPOSITS_DISABLERS", []), - withdrawalsEnablers: env.addresses("L1_WITHDRAWALS_ENABLERS", []), - withdrawalsDisablers: env.addresses("L1_WITHDRAWALS_DISABLERS", []), - }, - optimism: { - l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER"), - - /// TokenRateOracle - tokenRateOracleAdmin: env.address("TOKEN_RATE_ORACLE_ADMIN"), - tokenRateUpdateEnabled: env.bool("TOKEN_RATE_UPDATE_ENABLED", true), - tokenRateUpdateDisablers: env.addresses("TOKEN_RATE_UPDATE_DISABLERS", []), - tokenRateUpdateEnablers: env.addresses("TOKEN_RATE_UPDATE_ENABLERS", []), - - tokenRateOutdatedDelay: BigNumber.from(env.string("TOKEN_RATE_OUTDATED_DELAY")), - maxAllowedL2ToL1ClockLag: BigNumber.from(env.string("MAX_ALLOWED_L2_TO_L1_CLOCK_LAG")), - maxAllowedTokenRateDeviationPerDayBp: BigNumber.from(env.string("MAX_ALLOWED_TOKEN_RATE_DEVIATION_PER_DAY_BP")), - oldestRateAllowedInPauseTimeSpan: BigNumber.from(env.string("OLDEST_RATE_ALLOWED_IN_PAUSE_TIME_SPAN")), - minTimeBetweenTokenRateUpdates: BigNumber.from(env.string("MIN_TIME_BETWEEN_TOKEN_RATE_UPDATES")), - initialTokenRateValue: BigNumber.from(env.string("INITIAL_TOKEN_RATE_VALUE")), - initialTokenRateL1Timestamp: BigNumber.from(env.string("INITIAL_TOKEN_RATE_L1_TIMESTAMP")), - - // wstETH - l2TokenNonRebasableName: env.string("L2_TOKEN_NON_REBASABLE_NAME"), - l2TokenNonRebasableSymbol: env.string("L2_TOKEN_NON_REBASABLE_SYMBOL"), - l2TokenNonRebasableDomainVersion: env.string("L2_TOKEN_NON_REBASABLE_SIGNING_DOMAIN_VERSION"), - - // stETH - l2TokenRebasableName: env.string("L2_TOKEN_REBASABLE_NAME"), - l2TokenRebasableSymbol: env.string("L2_TOKEN_REBASABLE_SYMBOL"), - l2TokenRebasableDomainVersion: env.string("L2_TOKEN_REBASABLE_SIGNING_DOMAIN_VERSION"), - - // Bridge - proxyAdmin: env.address("L2_PROXY_ADMIN"), - bridgeAdmin: env.address("L2_BRIDGE_ADMIN"), - depositsEnabled: env.bool("L2_DEPOSITS_ENABLED", false), - withdrawalsEnabled: env.bool("L2_WITHDRAWALS_ENABLED", false), - depositsEnablers: env.addresses("L2_DEPOSITS_ENABLERS", []), - depositsDisablers: env.addresses("L2_DEPOSITS_DISABLERS", []), - withdrawalsEnablers: env.addresses("L2_WITHDRAWALS_ENABLERS", []), - withdrawalsDisablers: env.addresses("L2_WITHDRAWALS_DISABLERS", []), - }, + l1: loadL1ScratchDeploymentConfig(), + l2: loadL2ScratchDeploymentConfig() }; } @@ -118,12 +200,12 @@ export async function printMultiChainDeploymentConfig( title: string, l1Deployer: Wallet, l2Deployer: Wallet, - deploymentParams: MultiChainDeploymentConfig, + deploymentParams: MultiChainAutomatonDeploymentConfig, l1DeployScript: DeployScript, l2DeployScript: DeployScript, scratchDeploy: boolean ) { - const { ethereum, optimism } = deploymentParams; + const { l1, l2 } = deploymentParams; console.log(chalk.bold(`${title}\n`)); console.log(chalk.bold(" · Deployment Params:")); @@ -131,13 +213,13 @@ export async function printMultiChainDeploymentConfig( console.log(); console.log(chalk.bold(" · L1 Deployment Params:")); - await printEthereumDeploymentConfig(l1Deployer, ethereum, scratchDeploy); + await printEthereumDeploymentConfig(l1Deployer, l1, scratchDeploy); console.log(); console.log(chalk.bold(" · L1 Deployment Actions:")); l1DeployScript.print({ padding: 6 }); console.log(chalk.bold(" · L2 Deployment Params:")); - await printOptimismDeploymentConfig(l2Deployer, optimism, scratchDeploy); + await printOptimismDeploymentConfig(l2Deployer, l2, scratchDeploy); console.log(); console.log(chalk.bold(" · L2 Deployment Actions:")); l2DeployScript.print({ padding: 6 }); @@ -146,7 +228,7 @@ export async function printMultiChainDeploymentConfig( async function printEthereumDeploymentConfig( deployer: Wallet, - params: EthereumAutomatonDeploymentConfig, + params: L1AutomatonDeploymentConfig, scratchDeploy: boolean ) { const pad = " ".repeat(4); @@ -188,7 +270,7 @@ async function printEthereumDeploymentConfig( async function printOptimismDeploymentConfig( deployer: Wallet, - params: OptimismAutomatonDeploymentConfig, + params: L2AutomatonDeploymentConfig, scratchDeploy: boolean ) { const pad = " ".repeat(4); @@ -237,6 +319,8 @@ async function printOptimismDeploymentConfig( } export default { - loadMultiChainDeploymentConfig, + loadMultiChainAutomatonDeploymentConfig, + loadMultiChainStETHDeploymentConfig, + loadMultiChainScratchDeploymentConfig, printMultiChainDeploymentConfig, }; diff --git a/utils/optimism/deployment.ts b/utils/optimism/deployment.ts index 2952d536..aa8a19f6 100644 --- a/utils/optimism/deployment.ts +++ b/utils/optimism/deployment.ts @@ -17,14 +17,17 @@ import { } from "../../typechain"; interface OptL1DeployScriptParams extends DeployScriptParams { + l1CrossDomainMessenger: string; l1TokenNonRebasable: string; l1TokenRebasable: string; accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; lido: string; + tokenRateNotifierOwner: string; } interface OptL2DeployScriptParams extends DeployScriptParams { + l2CrossDomainMessenger: string; l2TokenNonRebasable: { name?: string; symbol?: string; @@ -38,6 +41,7 @@ interface OptL2DeployScriptParams extends DeployScriptParams { decimals?: number; }; tokenRateOracle: { + admin: string; tokenRateOutdatedDelay: BigNumber; maxAllowedL2ToL1ClockLag: BigNumber; maxAllowedTokenRateDeviationPerDayBp: BigNumber; @@ -184,7 +188,7 @@ export default function deploymentAll( .addStep({ factory: TokenRateNotifier__factory, args: [ - l1Params.deployer.address, + l1Params.tokenRateNotifierOwner, l1Params.lido, options?.overrides, ], diff --git a/utils/optimism/deploymentForAutomaton.ts b/utils/optimism/deploymentForAutomaton.ts index edf7b606..c0cf135f 100644 --- a/utils/optimism/deploymentForAutomaton.ts +++ b/utils/optimism/deploymentForAutomaton.ts @@ -36,6 +36,7 @@ interface OptL2DeployScriptParams extends DeployScriptParams { decimals?: number; }; tokenRateOracle: { + admin: string; tokenRateOutdatedDelay: BigNumber; maxAllowedL2ToL1ClockLag: BigNumber; maxAllowedTokenRateDeviationPerDayBp: BigNumber; @@ -277,7 +278,7 @@ export default function deploymentAll( TokenRateOracle__factory.createInterface().encodeFunctionData( "initialize", [ - l2Params.admins.bridge, + l2Params.tokenRateOracle.admin, l2Params.tokenRateOracle.tokenRate, l2Params.tokenRateOracle.l1Timestamp ] diff --git a/utils/optimism/deploymentStETH.ts b/utils/optimism/deploymentStETH.ts index 42d4b366..9b1e09b0 100644 --- a/utils/optimism/deploymentStETH.ts +++ b/utils/optimism/deploymentStETH.ts @@ -17,44 +17,42 @@ import { } from "../../typechain"; interface OptL1UpgradeScriptParams extends DeployScriptParams { + l1CrossDomainMessenger: string; l1TokenNonRebasable: string; l1TokenRebasable: string; accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; l1TokenBridge: string; lido: string; + tokenRateNotifierOwner: string; } interface OptL2UpgradeScriptParams extends DeployScriptParams { + l2CrossDomainMessenger: string; l2TokenBridge: string; l2TokenNonRebasable: { address: string; + version: string; name?: string; symbol?: string; - version: string; decimals?: BigNumber; }; l2TokenRebasable: { proxyAdmin: string; + version: string; name?: string; symbol?: string; - version: string; decimals?: BigNumber; }; tokenRateOracle: { - proxyAdmin: string; admin: string; - constructor: { - tokenRateOutdatedDelay: BigNumber; - maxAllowedL2ToL1ClockLag: BigNumber; - maxAllowedTokenRateDeviationPerDayBp: BigNumber; - oldestRateAllowedInPauseTimeSpan: BigNumber; - minTimeBetweenTokenRateUpdates: BigNumber; - } - initialize: { - tokenRate: BigNumber; - l1Timestamp: BigNumber; - } + tokenRateOutdatedDelay: BigNumber; + maxAllowedL2ToL1ClockLag: BigNumber; + maxAllowedTokenRateDeviationPerDayBp: BigNumber; + oldestRateAllowedInPauseTimeSpan: BigNumber; + minTimeBetweenTokenRateUpdates: BigNumber; + tokenRate: BigNumber; + l1Timestamp: BigNumber; } } @@ -179,7 +177,7 @@ export default function deploy( .addStep({ factory: TokenRateNotifier__factory, args: [ - l1Params.deployer.address, + l1Params.tokenRateNotifierOwner, l1Params.lido, options?.overrides, ], @@ -238,11 +236,11 @@ export default function deploy( optAddresses.L2CrossDomainMessenger, l2Params.l2TokenBridge, expectedL1OpStackTokenRatePusherImplAddress, - l2Params.tokenRateOracle.constructor.tokenRateOutdatedDelay, - l2Params.tokenRateOracle.constructor.maxAllowedL2ToL1ClockLag, - l2Params.tokenRateOracle.constructor.maxAllowedTokenRateDeviationPerDayBp, - l2Params.tokenRateOracle.constructor.oldestRateAllowedInPauseTimeSpan, - l2Params.tokenRateOracle.constructor.minTimeBetweenTokenRateUpdates, + l2Params.tokenRateOracle.tokenRateOutdatedDelay, + l2Params.tokenRateOracle.maxAllowedL2ToL1ClockLag, + l2Params.tokenRateOracle.maxAllowedTokenRateDeviationPerDayBp, + l2Params.tokenRateOracle.oldestRateAllowedInPauseTimeSpan, + l2Params.tokenRateOracle.minTimeBetweenTokenRateUpdates, options?.overrides, ], afterDeploy: (c) => @@ -252,13 +250,13 @@ export default function deploy( factory: OssifiableProxy__factory, args: [ expectedL2TokenRateOracleImplAddress, - l2Params.tokenRateOracle.proxyAdmin, + l2Params.admins.proxy, TokenRateOracle__factory.createInterface().encodeFunctionData( "initialize", [ l2Params.tokenRateOracle.admin, - l2Params.tokenRateOracle.initialize.tokenRate, - l2Params.tokenRateOracle.initialize.l1Timestamp + l2Params.tokenRateOracle.tokenRate, + l2Params.tokenRateOracle.l1Timestamp ] ), options?.overrides, diff --git a/utils/optimism/types.ts b/utils/optimism/types.ts index af736ad9..37a5cafe 100644 --- a/utils/optimism/types.ts +++ b/utils/optimism/types.ts @@ -15,7 +15,7 @@ export interface DeployScriptParams { deployer: Wallet; admins: { proxy: string; - bridge: string + bridge: string; }; deployOffset: number; } From c2f506fb040c1b59837bf33f0c627f4d8860cc12 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Mon, 9 Dec 2024 10:39:38 +0100 Subject: [PATCH 20/34] fix env names --- scripts/optimism/deploy-new-steth-contracts.ts | 4 ++-- utils/deployment.ts | 12 +++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/scripts/optimism/deploy-new-steth-contracts.ts b/scripts/optimism/deploy-new-steth-contracts.ts index 7e363eb9..1cc90888 100644 --- a/scripts/optimism/deploy-new-steth-contracts.ts +++ b/scripts/optimism/deploy-new-steth-contracts.ts @@ -59,13 +59,13 @@ async function main() { l1Timestamp: deploymentConfig.l2.initialTokenRateL1Timestamp }, l2TokenNonRebasable: { - address: deploymentConfig.l2.l2TokenNonRebasableAddress, + address: deploymentConfig.l2.l2TokenNonRebasable, name: deploymentConfig.l2.l2TokenNonRebasableName, symbol: deploymentConfig.l2.l2TokenRebasableSymbol, version: deploymentConfig.l2.l2TokenNonRebasableDomainVersion }, l2TokenRebasable: { - proxyAdmin: deploymentConfig.l2.l2TokenRebasableProxyAdmin, + proxyAdmin: deploymentConfig.l2.proxyAdmin, name: deploymentConfig.l2.l2TokenRebasableName, symbol: deploymentConfig.l2.l2TokenRebasableSymbol, version: deploymentConfig.l2.l2TokenRebasableDomainVersion diff --git a/utils/deployment.ts b/utils/deployment.ts index bd2d792e..853cef77 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -26,8 +26,7 @@ interface L1AutomatonDeploymentConfig extends BridgingManagerSetupConfig { interface L2StETHDeploymentConfig extends L2ScratchDeploymentConfig { l2TokenBridge: string; - l2TokenNonRebasableAddress: string; - l2TokenRebasableProxyAdmin: string; + l2TokenNonRebasable: string; } interface L2ScratchDeploymentConfig extends L2AutomatonDeploymentConfig { @@ -81,16 +80,15 @@ interface MultiChainAutomatonDeploymentConfig { export function loadL1StETHDeploymentConfig(): L1StETHDeploymentConfig { return { ...loadL1ScratchDeploymentConfig(), - l1TokenBridge: env.address(""), + l1TokenBridge: env.address("L1_TOKEN_BRIDGE"), } } export function loadL2StETHDeploymentConfig(): L2StETHDeploymentConfig { return { ...loadL2ScratchDeploymentConfig(), - l2TokenBridge: env.address(""), - l2TokenNonRebasableAddress: env.address(""), - l2TokenRebasableProxyAdmin: env.address(""), + l2TokenBridge: env.address("L2_TOKEN_BRIDGE"), + l2TokenNonRebasable: env.address("L2_TOKEN_NON_REBASABLE"), } } @@ -98,7 +96,7 @@ export function loadL1ScratchDeploymentConfig(): L1ScratchDeploymentConfig { return { ...loadL1AutomatonDeploymentConfig(), lido: env.address("LIDO"), - tokenRateNotifierOwner: env.address("LIDO"), + tokenRateNotifierOwner: env.address("TOKEN_RATE_NOTIFIER_OWNER"), }; } From 939d270c7fe61e96ebded6773dec31bba39f993d Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 10 Dec 2024 17:27:10 +0100 Subject: [PATCH 21/34] remove unichain dependency from verifier --- .env.example | 12 +++---- .env.steth.opt_mainnet | 12 +++---- .env.steth.opt_sepolia | 12 +++---- README.md | 35 ++++++------------ hardhat.config.ts | 36 +++++++------------ package.json | 5 +-- scripts/optimism/deploy-automaton.ts | 2 +- .../optimism/deploy-new-steth-contracts.ts | 2 +- scripts/optimism/deploy-scratch.ts | 2 +- utils/deployment/DeployScript.ts | 25 ++++++------- utils/env.ts | 2 +- utils/network.ts | 33 ++++++++--------- 12 files changed, 77 insertions(+), 101 deletions(-) diff --git a/.env.example b/.env.example index 6e13865f..51331bf8 100644 --- a/.env.example +++ b/.env.example @@ -7,8 +7,8 @@ L1_CHAIN_ID=10 L2_CHAIN_ID=11155420 -L1_PRC=https://sepolia.infura.io/v3/ -L2_PRC=https://optimism-sepolia.infura.io/v3/ +L1_PRC_URL=https://sepolia.infura.io/v3/ +L2_PRC_URL=https://optimism-sepolia.infura.io/v3/ L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 @@ -17,8 +17,8 @@ L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # Etherscan # ############################ -ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_OPT= +L1_ETHERSCAN_API_KEY= +L2_ETHERSCAN_API_KEY= # ############################ # Bridge/Gateway Deployment @@ -28,8 +28,8 @@ ETHERSCAN_API_KEY_OPT= FORKING=true # Private key of the deployer account used for deployment process -ETH_DEPLOYER_PRIVATE_KEY= -OPT_DEPLOYER_PRIVATE_KEY= +L1_DEPLOYER_PRIVATE_KEY= +L2_DEPLOYER_PRIVATE_KEY= # Address of bridge executor. GOV_BRIDGE_EXECUTOR= diff --git a/.env.steth.opt_mainnet b/.env.steth.opt_mainnet index ff52e699..c0990bf3 100644 --- a/.env.steth.opt_mainnet +++ b/.env.steth.opt_mainnet @@ -7,8 +7,8 @@ L1_CHAIN_ID=10 L2_CHAIN_ID=11155420 -L1_PRC=https://sepolia.infura.io/v3/ -L2_PRC=https://optimism-sepolia.infura.io/v3/ +L1_PRC_URL=https://sepolia.infura.io/v3/ +L2_PRC_URL=https://optimism-sepolia.infura.io/v3/ L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 @@ -17,8 +17,8 @@ L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # Etherscan # ############################ -ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_OPT= +L1_ETHERSCAN_API_KEY= +L2_ETHERSCAN_API_KEY= # ############################ # Bridge/Gateway Deployment @@ -28,8 +28,8 @@ ETHERSCAN_API_KEY_OPT= FORKING=false # Private key of the deployer account used for deployment process -ETH_DEPLOYER_PRIVATE_KEY= -OPT_DEPLOYER_PRIVATE_KEY= +L1_DEPLOYER_PRIVATE_KEY= +L2_DEPLOYER_PRIVATE_KEY= # Address of bridge executor. GOV_BRIDGE_EXECUTOR=0xefa0db536d2c8089685630fafe88cf7805966fc3 diff --git a/.env.steth.opt_sepolia b/.env.steth.opt_sepolia index 54935ad2..1aff4bcc 100644 --- a/.env.steth.opt_sepolia +++ b/.env.steth.opt_sepolia @@ -7,8 +7,8 @@ L1_CHAIN_ID=10 L2_CHAIN_ID=11155420 -L1_PRC=https://sepolia.infura.io/v3/ -L2_PRC=https://optimism-sepolia.infura.io/v3/ +L1_PRC_URL=https://sepolia.infura.io/v3/ +L2_PRC_URL=https://optimism-sepolia.infura.io/v3/ L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 @@ -17,8 +17,8 @@ L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # Etherscan # ############################ -ETHERSCAN_API_KEY_ETH= -ETHERSCAN_API_KEY_OPT= +L1_ETHERSCAN_API_KEY= +L2_ETHERSCAN_API_KEY= # ############################ # Bridge/Gateway Deployment @@ -28,8 +28,8 @@ ETHERSCAN_API_KEY_OPT= FORKING=false # Private key of the deployer account used for deployment process -ETH_DEPLOYER_PRIVATE_KEY= -OPT_DEPLOYER_PRIVATE_KEY= +L1_DEPLOYER_PRIVATE_KEY= +L2_DEPLOYER_PRIVATE_KEY= # Address of bridge executor. GOV_BRIDGE_EXECUTOR= diff --git a/README.md b/README.md index d665533f..9fd57d2e 100644 --- a/README.md +++ b/README.md @@ -53,8 +53,8 @@ The configuration of the deployment scripts happens via the ENV variables. The f - [`L2_TOKEN_RATE_ORACLE`](#L2_TOKEN_RATE_ORACLE) - address of token rate oracle on L2. - [`GOV_BRIDGE_EXECUTOR`](#GOV_BRIDGE_EXECUTOR) - address of bridge executor. - [`FORKING`](#FORKING) - run deployment in the forking network instead of real ones -- [`ETH_DEPLOYER_PRIVATE_KEY`](#ETH_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Ethereum network is used during the deployment process. -- [`OPT_DEPLOYER_PRIVATE_KEY`](#OPT_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Optimism network is used during the deployment process. +- [`L1_DEPLOYER_PRIVATE_KEY`](#L1_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Ethereum network is used during the deployment process. +- [`L2_DEPLOYER_PRIVATE_KEY`](#L2_DEPLOYER_PRIVATE_KEY) - The private key of the deployer account in the Optimism network is used during the deployment process. - [`L1_PROXY_ADMIN`](#L1_PROXY_ADMIN) - The address to grant admin rights of the `OssifiableProxy` on the L1 bridge - [`L1_BRIDGE_ADMIN`](#L1_BRIDGE_ADMIN) - Address to grant the `DEFAULT_ADMIN_ROLE` on the L1 bridge - [`L2_PROXY_ADMIN`](#L2_PROXY_ADMIN) - The address to grant admin rights of the `OssifiableProxy` on the L2 bridge @@ -178,39 +178,24 @@ The configuration of the project happens via set of ENV variables. The full list ### RPCs -#### `RPC_URL_ETH_MAINNET` +#### `L1_PRC_URL` -Address of the RPC node for **Mainnet** Ethereum network. +Address of the RPC node for **L1** Ethereum network. -#### `RPC_ETH_SEPOLIA` - -Address of the RPC node for **Sepolia** Ethereum network. - -#### `RPC_OPT_SEPOLIA` - -Address of the RPC node for **Sepolia** Optimism network. - -#### `RPC_OPT_MAINNET` - -> **Warning** -> -> Please, don't use the default value for production deployments! The default RPC node might not be available or fail suddenly during the request. - -Address of the RPC node for **Mainnet** Optimism network. - -> Default value: `https://mainnet.optimism.io` +#### `L2_PRC_URL` +Address of the RPC node for **L2** Ethereum network. ### Etherscan Below variables are required for successfull verification of the contracts on block explorer for certain networks. -#### `ETHERSCAN_API_KEY_ETH` +#### `L1_ETHERSCAN_API_KEY` API key from the [Etherscan](https://etherscan.io/) block explorer. See details here: https://info.etherscan.com/api-keys/ -#### `ETHERSCAN_API_KEY_OPT` +#### `L2_ETHERSCAN_API_KEY` API key from the [Optimistic Ethereum](https://optimistic.etherscan.io/) block explorer. @@ -232,11 +217,11 @@ Run deployment in the forking network instead of public ones > Default value: `true` -#### `ETH_DEPLOYER_PRIVATE_KEY` +#### `L1_DEPLOYER_PRIVATE_KEY` The private key of the deployer account in the Ethereum network is used during the deployment process. -#### `OPT_DEPLOYER_PRIVATE_KEY` +#### `L2_DEPLOYER_PRIVATE_KEY` The private key of the deployer account in the Optimism network is used during the deployment process. diff --git a/hardhat.config.ts b/hardhat.config.ts index 878493d1..1e6f55ae 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -39,10 +39,10 @@ const config: HardhatUserConfig = { } }, l1: { - url: env.string("L1_PRC", ""), + url: env.string("L1_PRC", "") }, l2: { - url: env.string("L2_PRC", ""), + url: env.string("L2_PRC", "") }, l1_fork: { url: "http://localhost:8545" @@ -57,36 +57,24 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: { - mainnet: env.string("ETHERSCAN_API_KEY_ETH", ""), - sepolia: env.string("ETHERSCAN_API_KEY_ETH", ""), - optimisticEthereum: env.string("ETHERSCAN_API_KEY_OPT", ""), - "opt_sepolia": env.string("ETHERSCAN_API_KEY_OPT", ""), - "uni_sepolia": env.string("ETHERSCAN_API_KEY_OPT", ""), + "l1": env.string("L1_ETHERSCAN_API_KEY", ""), + "l2": env.string("L2_ETHERSCAN_API_KEY", ""), }, - customChains: [ { - network: 'sepolia', - chainId: 11155111, - urls: { - apiURL: 'https://api-sepolia.etherscan.io/api', - browserURL: 'https://sepolia.etherscan.io', - }, - }, - { - network: 'opt_sepolia', - chainId: 11155420, + network: 'l1', + chainId: env.number("L1_CHAIN_ID"), urls: { - apiURL: 'https://api-sepolia-optimism.etherscan.io/api', - browserURL: 'https://sepolia-optimism.etherscan.io', + apiURL: `${env.string("L1_BLOCK_EXPLORER_URL")}/api`, + browserURL: env.string("L1_BLOCK_EXPLORER_URL"), }, }, { - network: 'uni_sepolia', - chainId: 1301, + network: 'l2', + chainId: env.number("L2_CHAIN_ID"), urls: { - apiURL: 'https://unichain-sepolia.blockscout.com/api', - browserURL: 'https://unichain-sepolia.blockscout.com/', + apiURL: `${env.string("L2_BLOCK_EXPLORER_URL")}/api`, + browserURL: env.string("L2_BLOCK_EXPLORER_URL"), }, }, ], diff --git a/package.json b/package.json index c1db7d52..f73a2fa8 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,9 @@ "coverage": "hardhat coverage --testfiles './test/**/*.unit.test.ts'", "fork:l1": "hardhat node:fork l1 8545", "fork:l2": "hardhat node:fork l2 9545", - "deploy": "ts-node --files ./scripts/optimism/deploy-scratch.ts", - "deploy-new-steth-contracts": "ts-node --files ./scripts/optimism/deploy-new-steth-contracts.ts", + "deploy-automaton": "ts-node --files ./scripts/optimism/deploy-automaton.ts", + "deploy-scratch": "ts-node --files ./scripts/optimism/deploy-scratch.ts", + "deploy-steth": "ts-node --files ./scripts/optimism/deploy-new-steth-contracts.ts", "finalize-message": "ts-node --files ./scripts/optimism/finalize-message.ts", "test:e2e": "hardhat test ./test/e2e/*.e2e.test.ts", "test:managing-e2e": "hardhat test ./test/managing-e2e/*.e2e.test.ts", diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-automaton.ts index d9d62e8b..efa688fb 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-automaton.ts @@ -14,7 +14,7 @@ async function main() { }); const [, l2Deployer] = network.getSigners( - env.string("OPT_DEPLOYER_PRIVATE_KEY"), + env.string("L2_DEPLOYER_PRIVATE_KEY"), { forking: env.forking() } diff --git a/scripts/optimism/deploy-new-steth-contracts.ts b/scripts/optimism/deploy-new-steth-contracts.ts index 1cc90888..e4a879a2 100644 --- a/scripts/optimism/deploy-new-steth-contracts.ts +++ b/scripts/optimism/deploy-new-steth-contracts.ts @@ -16,7 +16,7 @@ async function main() { }); const [, l2Deployer] = network.getSigners( - env.string("OPT_DEPLOYER_PRIVATE_KEY"), + env.string("L2_DEPLOYER_PRIVATE_KEY"), { forking: env.forking(), } diff --git a/scripts/optimism/deploy-scratch.ts b/scripts/optimism/deploy-scratch.ts index 7f321a32..0126bec9 100644 --- a/scripts/optimism/deploy-scratch.ts +++ b/scripts/optimism/deploy-scratch.ts @@ -17,7 +17,7 @@ async function main() { }); const [, l2Deployer] = network.getSigners( - env.string("OPT_DEPLOYER_PRIVATE_KEY"), + env.string("L2_DEPLOYER_PRIVATE_KEY"), { forking: env.forking() } diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index d5dc9394..cda10275 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -9,6 +9,7 @@ import { } from "ethers"; import network from "../network"; import * as fs from 'fs'; +import env from "../../utils/env"; interface TypechainFactoryConstructor< T extends ContractFactory = ContractFactory @@ -82,12 +83,10 @@ export class DeployScript { } async saveResultToFile(fileName: string) { - console.log("this.resultJson=",this.resultJson); fs.writeFile(fileName, JSON.stringify(this.resultJson, null, 2), { encoding: "utf8", flag: "w" }, function(err) { if (err) { return console.error(err); } - console.log("File created!"); }); } @@ -179,16 +178,7 @@ export class DeployScript { stepInfo: DeployStepInfo ) { const chainId = await this.deployer.getChainId(); - const networkNameByChainId: Record = { - 1: "eth_mainnet", - 11155111: "eth_sepolia", - 10: "opt_mainnet", - 11155420: "opt_sepolia", - 130: "uni_mainnet", - 1301: "uni_sepolia", - 31337: "hardhat", - }; - const networkName = networkNameByChainId[chainId] || ""; + const networkName = this._networkNameByChainId(chainId); const arsString = stepInfo.args.map((a) => `"${a.value}"`).join(" "); this._log("To verify the contract on Etherscan, use command:"); this._log( @@ -199,6 +189,17 @@ export class DeployScript { private _log(message: string = "") { this.logger?.log(message); } + + private _networkNameByChainId(chainId: number): string { + switch (chainId) { + case env.number("L1_CHAIN_ID"): + return "l1"; + case env.number("L2_CHAIN_ID"): + return "l2"; + default: + throw new Error(`Unsupported chainId ${chainId}`) + } + } } function formatValue(value: string | number) { diff --git a/utils/env.ts b/utils/env.ts index 5803abe1..acbeb751 100644 --- a/utils/env.ts +++ b/utils/env.ts @@ -47,7 +47,7 @@ function getAddressList(variableName: string, defaultValue?: string[]) { } function getPrivateKey() { - return getString("ETH_DEPLOYER_PRIVATE_KEY"); + return getString("L1_DEPLOYER_PRIVATE_KEY"); } function getForking() { diff --git a/utils/network.ts b/utils/network.ts index b1a6c674..b6fd7b5c 100644 --- a/utils/network.ts +++ b/utils/network.ts @@ -62,25 +62,26 @@ export function getSigners(privateKey: string, options: { forking: boolean }) { ); } -function getChainId(protocol: ChainNameShort) { - if (protocol == "l1") { - return env.number("L1_CHAIN_ID"); +function getChainId(protocol: ChainNameShort): number { + switch (protocol) { + case "l1": + return env.number("L1_CHAIN_ID"); + case "l2": + return env.number("L2_CHAIN_ID"); + default: + throw new Error(`Unsupported protocol ${protocol}`); } - return env.number("L2_CHAIN_ID"); } -function getBlockExplorerBaseUrlByChainId(chainId: number) { - const baseUrlByChainId: Record = { - // ethereum - 1: "https://etherscan.io", - 11155111: "https://sepolia.etherscan.io", - // optimism - 10: "https://optimistic.etherscan.io", - 11155420: "https://blockscout.com/optimism/sepolia", - // forked node - 31337: "https://etherscan.io", - }; - return baseUrlByChainId[chainId]; +function getBlockExplorerBaseUrlByChainId(chainId: number): string { + switch (chainId) { + case env.number("L1_CHAIN_ID"): + return env.string("L1_BLOCK_EXPLORER_URL"); + case env.number("L2_CHAIN_ID"): + return env.string("L2_BLOCK_EXPLORER_URL"); + default: + throw new Error(`Unsupported chainId ${chainId}`); + } } export default { From 7e1c9552bc4db923e15312496122960ac3906f2d Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 10 Dec 2024 17:28:37 +0100 Subject: [PATCH 22/34] rename envs in hardhat config --- hardhat.config.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 1e6f55ae..0a34f189 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -39,10 +39,10 @@ const config: HardhatUserConfig = { } }, l1: { - url: env.string("L1_PRC", "") + url: env.string("L1_PRC_URL", "") }, l2: { - url: env.string("L2_PRC", "") + url: env.string("L2_PRC_URL", "") }, l1_fork: { url: "http://localhost:8545" From 34839bbcf37c05aa9a6363e7b748d5d489c9a40d Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 10 Dec 2024 17:33:01 +0100 Subject: [PATCH 23/34] rename etherscan var --- .env.example | 4 ++-- .env.steth.opt_mainnet | 4 ++-- .env.steth.opt_sepolia | 4 ++-- README.md | 4 ++-- hardhat.config.ts | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index 51331bf8..b102bacf 100644 --- a/.env.example +++ b/.env.example @@ -17,8 +17,8 @@ L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # Etherscan # ############################ -L1_ETHERSCAN_API_KEY= -L2_ETHERSCAN_API_KEY= +L1_BLOCK_EXPLORER_API_KEY= +L2_BLOCK_EXPLORER_API_KEY= # ############################ # Bridge/Gateway Deployment diff --git a/.env.steth.opt_mainnet b/.env.steth.opt_mainnet index c0990bf3..359f3267 100644 --- a/.env.steth.opt_mainnet +++ b/.env.steth.opt_mainnet @@ -17,8 +17,8 @@ L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # Etherscan # ############################ -L1_ETHERSCAN_API_KEY= -L2_ETHERSCAN_API_KEY= +L1_BLOCK_EXPLORER_API_KEY= +L2_BLOCK_EXPLORER_API_KEY= # ############################ # Bridge/Gateway Deployment diff --git a/.env.steth.opt_sepolia b/.env.steth.opt_sepolia index 1aff4bcc..48c78f00 100644 --- a/.env.steth.opt_sepolia +++ b/.env.steth.opt_sepolia @@ -17,8 +17,8 @@ L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 # Etherscan # ############################ -L1_ETHERSCAN_API_KEY= -L2_ETHERSCAN_API_KEY= +L1_BLOCK_EXPLORER_API_KEY= +L2_BLOCK_EXPLORER_API_KEY= # ############################ # Bridge/Gateway Deployment diff --git a/README.md b/README.md index 9fd57d2e..9593d59c 100644 --- a/README.md +++ b/README.md @@ -190,12 +190,12 @@ Address of the RPC node for **L2** Ethereum network. Below variables are required for successfull verification of the contracts on block explorer for certain networks. -#### `L1_ETHERSCAN_API_KEY` +#### `L1_BLOCK_EXPLORER_API_KEY` API key from the [Etherscan](https://etherscan.io/) block explorer. See details here: https://info.etherscan.com/api-keys/ -#### `L2_ETHERSCAN_API_KEY` +#### `L2_BLOCK_EXPLORER_API_KEY` API key from the [Optimistic Ethereum](https://optimistic.etherscan.io/) block explorer. diff --git a/hardhat.config.ts b/hardhat.config.ts index 0a34f189..c9c2b74b 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -57,8 +57,8 @@ const config: HardhatUserConfig = { }, etherscan: { apiKey: { - "l1": env.string("L1_ETHERSCAN_API_KEY", ""), - "l2": env.string("L2_ETHERSCAN_API_KEY", ""), + "l1": env.string("L1_BLOCK_EXPLORER_API_KEY", ""), + "l2": env.string("L2_BLOCK_EXPLORER_API_KEY", ""), }, customChains: [ { From 9a204ef41d478e511b43e262a246391e18f2b0a3 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 10 Dec 2024 21:59:32 +0100 Subject: [PATCH 24/34] add block explorer api url envs --- hardhat.config.ts | 8 ++++---- utils/network.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index c9c2b74b..53a15e9f 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -65,16 +65,16 @@ const config: HardhatUserConfig = { network: 'l1', chainId: env.number("L1_CHAIN_ID"), urls: { - apiURL: `${env.string("L1_BLOCK_EXPLORER_URL")}/api`, - browserURL: env.string("L1_BLOCK_EXPLORER_URL"), + apiURL: env.string("L1_BLOCK_EXPLORER_API_URL"), + browserURL: env.string("L1_BLOCK_EXPLORER_BROWSER_URL"), }, }, { network: 'l2', chainId: env.number("L2_CHAIN_ID"), urls: { - apiURL: `${env.string("L2_BLOCK_EXPLORER_URL")}/api`, - browserURL: env.string("L2_BLOCK_EXPLORER_URL"), + apiURL: env.string("L2_BLOCK_EXPLORER_API_URL"), + browserURL: env.string("L2_BLOCK_EXPLORER_BROWSER_URL"), }, }, ], diff --git a/utils/network.ts b/utils/network.ts index b6fd7b5c..495296a5 100644 --- a/utils/network.ts +++ b/utils/network.ts @@ -76,9 +76,9 @@ function getChainId(protocol: ChainNameShort): number { function getBlockExplorerBaseUrlByChainId(chainId: number): string { switch (chainId) { case env.number("L1_CHAIN_ID"): - return env.string("L1_BLOCK_EXPLORER_URL"); + return env.string("L1_BLOCK_EXPLORER_BROWSER_URL"); case env.number("L2_CHAIN_ID"): - return env.string("L2_BLOCK_EXPLORER_URL"); + return env.string("L2_BLOCK_EXPLORER_BROWSER_URL"); default: throw new Error(`Unsupported chainId ${chainId}`); } From 3517a572c28c0a43359e1d7ccb37be58cac64cab Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Thu, 19 Dec 2024 09:15:32 +0100 Subject: [PATCH 25/34] add empty default values to config in order to compile --- hardhat.config.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hardhat.config.ts b/hardhat.config.ts index 53a15e9f..866158a3 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -63,18 +63,18 @@ const config: HardhatUserConfig = { customChains: [ { network: 'l1', - chainId: env.number("L1_CHAIN_ID"), + chainId: env.number("L1_CHAIN_ID", ""), urls: { - apiURL: env.string("L1_BLOCK_EXPLORER_API_URL"), - browserURL: env.string("L1_BLOCK_EXPLORER_BROWSER_URL"), + apiURL: env.string("L1_BLOCK_EXPLORER_API_URL", ""), + browserURL: env.string("L1_BLOCK_EXPLORER_BROWSER_URL", ""), }, }, { network: 'l2', - chainId: env.number("L2_CHAIN_ID"), + chainId: env.number("L2_CHAIN_ID", ""), urls: { - apiURL: env.string("L2_BLOCK_EXPLORER_API_URL"), - browserURL: env.string("L2_BLOCK_EXPLORER_BROWSER_URL"), + apiURL: env.string("L2_BLOCK_EXPLORER_API_URL", ""), + browserURL: env.string("L2_BLOCK_EXPLORER_BROWSER_URL", ""), }, }, ], From 2c52c10807746017d66c36c9558f455c2df4c949 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 14 Jan 2025 19:13:51 +0100 Subject: [PATCH 26/34] get rid of automaton word --- package.json | 6 +- ...n.ts => deploy-bridge-without-notifier.ts} | 6 +- .../{deploy-scratch.ts => deploy-bridge.ts} | 8 +- ...new-steth-contracts.ts => deploy-steth.ts} | 4 +- utils/deployment.ts | 36 +- ...deploymentForAutomaton.ts => deployAll.ts} | 48 ++- .../{deploymentOracle.ts => deployOracle.ts} | 0 .../{deploymentStETH.ts => deployStETH.ts} | 0 utils/optimism/deployment.ts | 374 ------------------ 9 files changed, 62 insertions(+), 420 deletions(-) rename scripts/optimism/{deploy-automaton.ts => deploy-bridge-without-notifier.ts} (94%) rename scripts/optimism/{deploy-scratch.ts => deploy-bridge.ts} (91%) rename scripts/optimism/{deploy-new-steth-contracts.ts => deploy-steth.ts} (97%) rename utils/optimism/{deploymentForAutomaton.ts => deployAll.ts} (92%) rename utils/optimism/{deploymentOracle.ts => deployOracle.ts} (100%) rename utils/optimism/{deploymentStETH.ts => deployStETH.ts} (100%) delete mode 100644 utils/optimism/deployment.ts diff --git a/package.json b/package.json index f73a2fa8..d74f2e0f 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "coverage": "hardhat coverage --testfiles './test/**/*.unit.test.ts'", "fork:l1": "hardhat node:fork l1 8545", "fork:l2": "hardhat node:fork l2 9545", - "deploy-automaton": "ts-node --files ./scripts/optimism/deploy-automaton.ts", - "deploy-scratch": "ts-node --files ./scripts/optimism/deploy-scratch.ts", - "deploy-steth": "ts-node --files ./scripts/optimism/deploy-new-steth-contracts.ts", + "deploy-bridge-without-notifier": "ts-node --files ./scripts/optimism/deploy-bridge-without-notifier.ts", + "deploy-bridge": "ts-node --files ./scripts/optimism/deploy-bridge.ts", + "deploy-steth": "ts-node --files ./scripts/optimism/deploy-steth.ts", "finalize-message": "ts-node --files ./scripts/optimism/finalize-message.ts", "test:e2e": "hardhat test ./test/e2e/*.e2e.test.ts", "test:managing-e2e": "hardhat test ./test/managing-e2e/*.e2e.test.ts", diff --git a/scripts/optimism/deploy-automaton.ts b/scripts/optimism/deploy-bridge-without-notifier.ts similarity index 94% rename from scripts/optimism/deploy-automaton.ts rename to scripts/optimism/deploy-bridge-without-notifier.ts index efa688fb..ee980df5 100644 --- a/scripts/optimism/deploy-automaton.ts +++ b/scripts/optimism/deploy-bridge-without-notifier.ts @@ -3,7 +3,7 @@ import prompt from "../../utils/prompt"; import network from "../../utils/network"; import deployment from "../../utils/deployment"; import { BridgingManagement } from "../../utils/bridging-management"; -import deploymentAll from "../../utils/optimism/deploymentForAutomaton"; +import deployLidoOPStackBridge from "../../utils/optimism/deployAll"; import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-management"; import * as fs from 'fs'; @@ -20,9 +20,9 @@ async function main() { } ); - const deploymentConfig = deployment.loadMultiChainAutomatonDeploymentConfig(); + const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deploymentAll({ logger: console }) + const [l1DeployScript, l2DeployScript] = await deployLidoOPStackBridge(false, { logger: console }) .deployAllScript( { l1CrossDomainMessenger: deploymentConfig.l1.l1CrossDomainMessenger, diff --git a/scripts/optimism/deploy-scratch.ts b/scripts/optimism/deploy-bridge.ts similarity index 91% rename from scripts/optimism/deploy-scratch.ts rename to scripts/optimism/deploy-bridge.ts index 0126bec9..d51c2eda 100644 --- a/scripts/optimism/deploy-scratch.ts +++ b/scripts/optimism/deploy-bridge.ts @@ -3,7 +3,7 @@ import prompt from "../../utils/prompt"; import network from "../../utils/network"; import deployment from "../../utils/deployment"; import { BridgingManagement } from "../../utils/bridging-management"; -import deploymentAll from "../../utils/optimism/deployment"; +import deployLidoOPStackBridge from "../../utils/optimism/deployAll"; import { TokenRateNotifierManagement } from "../../utils/tokenRateNotifier-management"; async function main() { @@ -25,7 +25,7 @@ async function main() { const deploymentConfig = deployment.loadMultiChainScratchDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deploymentAll({ logger: console }) + const [l1DeployScript, l2DeployScript] = await deployLidoOPStackBridge(true, { logger: console }) .deployAllScript( { lido: deploymentConfig.l1.lido, @@ -92,6 +92,10 @@ async function main() { await l1DeployScript.run(); await l2DeployScript.run(); + if (!l1DeployScript.tokenRateNotifierImplAddress || !l1DeployScript.opStackTokenRatePusherImplAddress) { + throw new Error('Token rate notifier addresses are not defined'); + } + const tokenRateNotifierManagement = new TokenRateNotifierManagement( l1DeployScript.tokenRateNotifierImplAddress, l1Deployer diff --git a/scripts/optimism/deploy-new-steth-contracts.ts b/scripts/optimism/deploy-steth.ts similarity index 97% rename from scripts/optimism/deploy-new-steth-contracts.ts rename to scripts/optimism/deploy-steth.ts index e4a879a2..699b8885 100644 --- a/scripts/optimism/deploy-new-steth-contracts.ts +++ b/scripts/optimism/deploy-steth.ts @@ -4,7 +4,7 @@ import network from "../../utils/network"; import deployment from "../../utils/deployment"; import { TokenRateNotifierManagement } from "../../utils/tokenRateNotifier-management"; import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-management"; -import deploy from "../../utils/optimism/deploymentStETH"; +import deployStETH from "../../utils/optimism/deployStETH"; async function main() { @@ -24,7 +24,7 @@ async function main() { const deploymentConfig = deployment.loadMultiChainStETHDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deploy({ logger: console }) + const [l1DeployScript, l2DeployScript] = await deployStETH({ logger: console }) .deployScript( { l1CrossDomainMessenger: deploymentConfig.l1.l1CrossDomainMessenger, diff --git a/utils/deployment.ts b/utils/deployment.ts index 853cef77..4fec0989 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -10,12 +10,12 @@ interface L1StETHDeploymentConfig extends L1ScratchDeploymentConfig { l1TokenBridge: string; } -interface L1ScratchDeploymentConfig extends L1AutomatonDeploymentConfig { +interface L1ScratchDeploymentConfig extends L1DeploymentConfig { lido: string; tokenRateNotifierOwner: string; } -interface L1AutomatonDeploymentConfig extends BridgingManagerSetupConfig { +interface L1DeploymentConfig extends BridgingManagerSetupConfig { l1CrossDomainMessenger: string; proxyAdmin: string; accountingOracle: string; @@ -29,10 +29,10 @@ interface L2StETHDeploymentConfig extends L2ScratchDeploymentConfig { l2TokenNonRebasable: string; } -interface L2ScratchDeploymentConfig extends L2AutomatonDeploymentConfig { +interface L2ScratchDeploymentConfig extends L2DeploymentConfig { } -interface L2AutomatonDeploymentConfig extends BridgingManagerSetupConfig { +interface L2DeploymentConfig extends BridgingManagerSetupConfig { l2CrossDomainMessenger: string; /// Oracle @@ -72,9 +72,9 @@ interface MultiChainScratchDeploymentConfig { l2: L2ScratchDeploymentConfig; } -interface MultiChainAutomatonDeploymentConfig { - l1: L1AutomatonDeploymentConfig; - l2: L2AutomatonDeploymentConfig; +interface MultiChainDeploymentConfig { + l1: L1DeploymentConfig; + l2: L2DeploymentConfig; } export function loadL1StETHDeploymentConfig(): L1StETHDeploymentConfig { @@ -94,7 +94,7 @@ export function loadL2StETHDeploymentConfig(): L2StETHDeploymentConfig { export function loadL1ScratchDeploymentConfig(): L1ScratchDeploymentConfig { return { - ...loadL1AutomatonDeploymentConfig(), + ...loadL1DeploymentConfig(), lido: env.address("LIDO"), tokenRateNotifierOwner: env.address("TOKEN_RATE_NOTIFIER_OWNER"), }; @@ -106,7 +106,7 @@ export function loadL2ScratchDeploymentConfig(): L2ScratchDeploymentConfig { }; } -export function loadL1AutomatonDeploymentConfig(): L1AutomatonDeploymentConfig { +export function loadL1DeploymentConfig(): L1DeploymentConfig { return { l1CrossDomainMessenger: env.address("L1_CROSSDOMAIN_MESSENGER"), proxyAdmin: env.address("L1_PROXY_ADMIN"), @@ -127,7 +127,7 @@ export function loadL1AutomatonDeploymentConfig(): L1AutomatonDeploymentConfig { }; } -export function loadL2AutomatonDeploymentConfig(): L2AutomatonDeploymentConfig { +export function loadL2DeploymentConfig(): L2DeploymentConfig { return { l2CrossDomainMessenger: env.address("L2_CROSSDOMAIN_MESSENGER"), proxyAdmin: env.address("L2_PROXY_ADMIN"), @@ -174,10 +174,10 @@ export function loadMultiChainStETHDeploymentConfig(): MultiChainStETHDeployment }; } -export function loadMultiChainAutomatonDeploymentConfig(): MultiChainAutomatonDeploymentConfig { +export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { return { - l1: loadL1AutomatonDeploymentConfig(), - l2: loadL2AutomatonDeploymentConfig() + l1: loadL1DeploymentConfig(), + l2: loadL2DeploymentConfig() }; } @@ -190,7 +190,6 @@ export function loadMultiChainScratchDeploymentConfig(): MultiChainScratchDeploy export async function printDeploymentConfig() { const pad = " ".repeat(4); -// console.log(`${pad}· Network: ${env.string("NETWORK")}`); console.log(`${pad}· Forking: ${env.bool("FORKING")}`); } @@ -198,7 +197,7 @@ export async function printMultiChainDeploymentConfig( title: string, l1Deployer: Wallet, l2Deployer: Wallet, - deploymentParams: MultiChainAutomatonDeploymentConfig, + deploymentParams: MultiChainDeploymentConfig, l1DeployScript: DeployScript, l2DeployScript: DeployScript, scratchDeploy: boolean @@ -223,10 +222,9 @@ export async function printMultiChainDeploymentConfig( l2DeployScript.print({ padding: 6 }); } - async function printEthereumDeploymentConfig( deployer: Wallet, - params: L1AutomatonDeploymentConfig, + params: L1DeploymentConfig, scratchDeploy: boolean ) { const pad = " ".repeat(4); @@ -268,7 +266,7 @@ async function printEthereumDeploymentConfig( async function printOptimismDeploymentConfig( deployer: Wallet, - params: L2AutomatonDeploymentConfig, + params: L2DeploymentConfig, scratchDeploy: boolean ) { const pad = " ".repeat(4); @@ -317,7 +315,7 @@ async function printOptimismDeploymentConfig( } export default { - loadMultiChainAutomatonDeploymentConfig, + loadMultiChainDeploymentConfig, loadMultiChainStETHDeploymentConfig, loadMultiChainScratchDeploymentConfig, printMultiChainDeploymentConfig, diff --git a/utils/optimism/deploymentForAutomaton.ts b/utils/optimism/deployAll.ts similarity index 92% rename from utils/optimism/deploymentForAutomaton.ts rename to utils/optimism/deployAll.ts index c0cf135f..449d7bb5 100644 --- a/utils/optimism/deploymentForAutomaton.ts +++ b/utils/optimism/deployAll.ts @@ -11,18 +11,22 @@ import { OssifiableProxy__factory, TokenRateOracle__factory, OpStackTokenRatePusher__factory, + TokenRateNotifier__factory, IERC20Metadata__factory } from "../../typechain"; interface OptL1DeployScriptParams extends DeployScriptParams { l1CrossDomainMessenger: string; - accountingOracle: string; l1TokenNonRebasable: string; l1TokenRebasable: string; + accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; + lido?: string; + tokenRateNotifierOwner?: string; } interface OptL2DeployScriptParams extends DeployScriptParams { + l2CrossDomainMessenger: string; l2TokenNonRebasable: { name?: string; symbol?: string; @@ -45,26 +49,27 @@ interface OptL2DeployScriptParams extends DeployScriptParams { tokenRate: BigNumber; l1Timestamp: BigNumber; }, - l2CrossDomainMessenger: string; } export class L1DeployAllScript extends DeployScript { - constructor( deployer: Wallet, bridgeImplAddress: string, bridgeProxyAddress: string, opStackTokenRatePusherImplAddress: string, + tokenRateNotifierImplAddress?: string, logger?: Logger ) { super(deployer, logger); this.bridgeImplAddress = bridgeImplAddress; this.bridgeProxyAddress = bridgeProxyAddress; + this.tokenRateNotifierImplAddress = tokenRateNotifierImplAddress; this.opStackTokenRatePusherImplAddress = opStackTokenRatePusherImplAddress; } public bridgeImplAddress: string; public bridgeProxyAddress: string; + public tokenRateNotifierImplAddress?: string; public opStackTokenRatePusherImplAddress: string; } @@ -103,12 +108,13 @@ export class L2DeployAllScript extends DeployScript { public tokenRateOracleProxyAddress: string; } -async function predictAllAddresses(l1Params: OptL1DeployScriptParams, l2Params: OptL2DeployScriptParams) { +async function predictAllAddresses(l1Params: OptL1DeployScriptParams, l2Params: OptL2DeployScriptParams, deployNotifier: boolean) { const [ l1TokenBridgeImpl, l1TokenBridgeProxy, l1OpStackTokenRatePusherImpl, - ] = await network.predictAddresses(l1Params.deployer, l1Params.deployOffset + 3); + l1TokenRateNotifierImpl + ] = await network.predictAddresses(l1Params.deployer, l1Params.deployOffset + 3 + (deployNotifier ? 1 : 0)); const [ l2TokenRateOracleImpl, @@ -125,6 +131,7 @@ async function predictAllAddresses(l1Params: OptL1DeployScriptParams, l2Params: l1TokenBridgeImpl, l1TokenBridgeProxy, l1OpStackTokenRatePusherImpl, + l1TokenRateNotifierImpl, l2TokenRateOracleImpl, l2TokenRateOracleProxy, l2TokenImpl, @@ -136,16 +143,9 @@ async function predictAllAddresses(l1Params: OptL1DeployScriptParams, l2Params: }; } -/// Deploy all from scratch except Notifier. Uses for automaton script. -/// L1 part -/// L1LidoTokensBridge + Proxy -/// OpStackTokenRatePusher -/// L2 part -/// TokenRateOracle + Proxy -/// ERC20BridgedPermit + Proxy -/// ERC20RebasableBridgedPermit + Proxy -/// L2ERC20ExtendedTokensBridge + Proxy -export default function deploymentAll( +/// Deploy all contracts on new network from scratch. +export default function deployLidoOPStackBridge( + deployNotifier: boolean, options: OptDeploymentOptions = {} ) { return { @@ -153,7 +153,7 @@ export default function deploymentAll( l1Params: OptL1DeployScriptParams, l2Params: OptL2DeployScriptParams, ): Promise<[L1DeployAllScript, L2DeployAllScript]> { - let predictedAddresses = await predictAllAddresses(l1Params, l2Params); + let predictedAddresses = await predictAllAddresses(l1Params, l2Params, deployNotifier); let numClashedAddresses = Object.keys(predictedAddresses).length - new Set(Object.values(predictedAddresses)).size; // Burning enough nonces on L2 side @@ -166,7 +166,7 @@ export default function deploymentAll( }); await tx.wait() } - predictedAddresses = await predictAllAddresses(l1Params, l2Params); + predictedAddresses = await predictAllAddresses(l1Params, l2Params, deployNotifier); numClashedAddresses = Object.keys(predictedAddresses).length - new Set(Object.values(predictedAddresses)).size; } @@ -175,6 +175,7 @@ export default function deploymentAll( predictedAddresses.l1TokenBridgeImpl, predictedAddresses.l1TokenBridgeProxy, predictedAddresses.l1OpStackTokenRatePusherImpl, + predictedAddresses.l1TokenRateNotifierImpl, options?.logger ) .addStep({ @@ -220,6 +221,19 @@ export default function deploymentAll( assert.equal(c.address, predictedAddresses.l1OpStackTokenRatePusherImpl), }); + if (deployNotifier && l1Params.tokenRateNotifierOwner && l1Params.lido) { + l1DeployScript.addStep({ + factory: TokenRateNotifier__factory, + args: [ + l1Params.tokenRateNotifierOwner, + l1Params.lido, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, predictedAddresses.l1TokenRateNotifierImpl), + }) + } + const l1TokenNonRebasableInfo = IERC20Metadata__factory.connect( l1Params.l1TokenNonRebasable, l1Params.deployer diff --git a/utils/optimism/deploymentOracle.ts b/utils/optimism/deployOracle.ts similarity index 100% rename from utils/optimism/deploymentOracle.ts rename to utils/optimism/deployOracle.ts diff --git a/utils/optimism/deploymentStETH.ts b/utils/optimism/deployStETH.ts similarity index 100% rename from utils/optimism/deploymentStETH.ts rename to utils/optimism/deployStETH.ts diff --git a/utils/optimism/deployment.ts b/utils/optimism/deployment.ts deleted file mode 100644 index aa8a19f6..00000000 --- a/utils/optimism/deployment.ts +++ /dev/null @@ -1,374 +0,0 @@ -import { assert } from "chai"; -import { BigNumber, Wallet } from "ethers"; -import addresses from "./addresses"; -import { OptDeploymentOptions, DeployScriptParams } from "./types"; -import network from "../network"; -import { DeployScript, Logger } from "../deployment/DeployScript"; -import { - ERC20BridgedPermit__factory, - ERC20RebasableBridgedPermit__factory, - L1LidoTokensBridge__factory, - L2ERC20ExtendedTokensBridge__factory, - OssifiableProxy__factory, - TokenRateOracle__factory, - TokenRateNotifier__factory, - OpStackTokenRatePusher__factory, - IERC20Metadata__factory -} from "../../typechain"; - -interface OptL1DeployScriptParams extends DeployScriptParams { - l1CrossDomainMessenger: string; - l1TokenNonRebasable: string; - l1TokenRebasable: string; - accountingOracle: string; - l2GasLimitForPushingTokenRate: BigNumber; - lido: string; - tokenRateNotifierOwner: string; -} - -interface OptL2DeployScriptParams extends DeployScriptParams { - l2CrossDomainMessenger: string; - l2TokenNonRebasable: { - name?: string; - symbol?: string; - version: string; - decimals?: number; - }; - l2TokenRebasable: { - name?: string; - symbol?: string; - version: string; - decimals?: number; - }; - tokenRateOracle: { - admin: string; - tokenRateOutdatedDelay: BigNumber; - maxAllowedL2ToL1ClockLag: BigNumber; - maxAllowedTokenRateDeviationPerDayBp: BigNumber; - oldestRateAllowedInPauseTimeSpan: BigNumber; - minTimeBetweenTokenRateUpdates: BigNumber; - tokenRate: BigNumber; - l1Timestamp: BigNumber; - } -} - -export class L1DeployAllScript extends DeployScript { - - constructor( - deployer: Wallet, - bridgeImplAddress: string, - bridgeProxyAddress: string, - tokenRateNotifierImplAddress: string, - opStackTokenRatePusherImplAddress: string, - logger?: Logger - ) { - super(deployer, logger); - this.bridgeImplAddress = bridgeImplAddress; - this.bridgeProxyAddress = bridgeProxyAddress; - this.tokenRateNotifierImplAddress = tokenRateNotifierImplAddress; - this.opStackTokenRatePusherImplAddress = opStackTokenRatePusherImplAddress; - } - - public bridgeImplAddress: string; - public bridgeProxyAddress: string; - public tokenRateNotifierImplAddress: string; - public opStackTokenRatePusherImplAddress: string; -} - -export class L2DeployAllScript extends DeployScript { - - constructor( - deployer: Wallet, - tokenImplAddress: string, - tokenProxyAddress: string, - tokenRebasableImplAddress: string, - tokenRebasableProxyAddress: string, - tokenBridgeImplAddress: string, - tokenBridgeProxyAddress: string, - tokenRateOracleImplAddress: string, - tokenRateOracleProxyAddress: string, - logger?: Logger - ) { - super(deployer, logger); - this.tokenImplAddress = tokenImplAddress; - this.tokenProxyAddress = tokenProxyAddress; - this.tokenRebasableImplAddress = tokenRebasableImplAddress; - this.tokenRebasableProxyAddress = tokenRebasableProxyAddress; - this.tokenBridgeImplAddress = tokenBridgeImplAddress; - this.tokenBridgeProxyAddress = tokenBridgeProxyAddress; - this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; - this.tokenRateOracleProxyAddress = tokenRateOracleProxyAddress; - } - - public tokenImplAddress: string; - public tokenProxyAddress: string; - public tokenRebasableImplAddress: string; - public tokenRebasableProxyAddress: string; - public tokenBridgeImplAddress: string; - public tokenBridgeProxyAddress: string; - public tokenRateOracleImplAddress: string; - public tokenRateOracleProxyAddress: string; -} - -/// Deploy all from scratch -/// L1 part -/// L1LidoTokensBridge + Proxy -/// TokenRateNotifier -/// OpStackTokenRatePusher -/// L2 part -/// TokenRateOracle + Proxy -/// ERC20BridgedPermit + Proxy -/// ERC20RebasableBridgedPermit + Proxy -/// L2ERC20ExtendedTokensBridge + Proxy -export default function deploymentAll( - options: OptDeploymentOptions = {} -) { - const optAddresses = addresses(); - return { - async deployAllScript( - l1Params: OptL1DeployScriptParams, - l2Params: OptL2DeployScriptParams, - ): Promise<[L1DeployAllScript, L2DeployAllScript]> { - - const [ - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - ] = await network.predictAddresses(l1Params.deployer, l1Params.deployOffset + 4); - - const [ - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress, - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableImplAddress, - expectedL2TokenRebasableProxyAddress, - expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress - ] = await network.predictAddresses(l2Params.deployer, l2Params.deployOffset + 8); - - const l1DeployScript = new L1DeployAllScript( - l1Params.deployer, - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - options?.logger - ) - .addStep({ - factory: L1LidoTokensBridge__factory, - args: [ - optAddresses.L1CrossDomainMessenger, - expectedL2TokenBridgeProxyAddress, - l1Params.l1TokenNonRebasable, - l1Params.l1TokenRebasable, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableProxyAddress, - l1Params.accountingOracle, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenBridgeImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL1TokenBridgeImplAddress, - l1Params.admins.proxy, - L1LidoTokensBridge__factory.createInterface().encodeFunctionData( - "initialize", - [l1Params.admins.bridge] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenBridgeProxyAddress), - }) - .addStep({ - factory: TokenRateNotifier__factory, - args: [ - l1Params.tokenRateNotifierOwner, - l1Params.lido, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), - }) - .addStep({ - factory: OpStackTokenRatePusher__factory, - args: [ - optAddresses.L1CrossDomainMessenger, - l1Params.l1TokenNonRebasable, - l1Params.accountingOracle, - expectedL2TokenRateOracleProxyAddress, - l1Params.l2GasLimitForPushingTokenRate, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), - }); - - const l1TokenNonRebasableInfo = IERC20Metadata__factory.connect( - l1Params.l1TokenNonRebasable, - l1Params.deployer - ); - - const l1TokenRebasableInfo = IERC20Metadata__factory.connect( - l1Params.l1TokenRebasable, - l1Params.deployer - ); - - const [ - l2TokenNonRebasableDecimals, l2TokenNonRebasableName, l2TokenNonRebasableSymbol, - l2TokenRebasableDecimals, l2TokenRebasableName, l2TokenRebasableSymbol - ] = await Promise.all([ - l1TokenNonRebasableInfo.decimals(), - l2Params.l2TokenNonRebasable?.name ?? l1TokenNonRebasableInfo.name(), - l2Params.l2TokenNonRebasable?.symbol ?? l1TokenNonRebasableInfo.symbol(), - l1TokenRebasableInfo.decimals(), - l2Params.l2TokenRebasable?.name ?? l1TokenRebasableInfo.name(), - l2Params.l2TokenRebasable?.symbol ?? l1TokenRebasableInfo.symbol(), - ]); - - const l2DeployScript = new L2DeployAllScript( - l2Params.deployer, - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableImplAddress, - expectedL2TokenRebasableProxyAddress, - expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress, - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress, - options?.logger - ) - .addStep({ - factory: TokenRateOracle__factory, - args: [ - optAddresses.L2CrossDomainMessenger, - expectedL2TokenBridgeProxyAddress, - expectedL1OpStackTokenRatePusherImplAddress, - l2Params.tokenRateOracle.tokenRateOutdatedDelay, - l2Params.tokenRateOracle.maxAllowedL2ToL1ClockLag, - l2Params.tokenRateOracle.maxAllowedTokenRateDeviationPerDayBp, - l2Params.tokenRateOracle.oldestRateAllowedInPauseTimeSpan, - l2Params.tokenRateOracle.minTimeBetweenTokenRateUpdates, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenRateOracleImplAddress, - l2Params.admins.proxy, - TokenRateOracle__factory.createInterface().encodeFunctionData( - "initialize", - [ - l2Params.admins.bridge, - l2Params.tokenRateOracle.tokenRate, - l2Params.tokenRateOracle.l1Timestamp - ] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), - }) - .addStep({ - factory: ERC20BridgedPermit__factory, - args: [ - l2TokenNonRebasableName, - l2TokenNonRebasableSymbol, - l2Params.l2TokenNonRebasable.version, - l2TokenNonRebasableDecimals, - expectedL2TokenBridgeProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenImplAddress, - l2Params.admins.proxy, - ERC20BridgedPermit__factory.createInterface().encodeFunctionData( - "initialize", - [ - l2TokenNonRebasableName, - l2TokenNonRebasableSymbol, - l2Params.l2TokenNonRebasable.version - ] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenProxyAddress), - }) - .addStep({ - factory: ERC20RebasableBridgedPermit__factory, - args: [ - l2TokenRebasableName, - l2TokenRebasableSymbol, - l2Params.l2TokenRebasable.version, - l2TokenRebasableDecimals, - expectedL2TokenProxyAddress, - expectedL2TokenRateOracleProxyAddress, - expectedL2TokenBridgeProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenRebasableImplAddress, - l2Params.admins.proxy, - ERC20RebasableBridgedPermit__factory.createInterface().encodeFunctionData( - "initialize", - [ - l2TokenRebasableName, - l2TokenRebasableSymbol, - l2Params.l2TokenRebasable.version - ] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableProxyAddress), - }) - .addStep({ - factory: L2ERC20ExtendedTokensBridge__factory, - args: [ - optAddresses.L2CrossDomainMessenger, - expectedL1TokenBridgeProxyAddress, - l1Params.l1TokenNonRebasable, - l1Params.l1TokenRebasable, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenBridgeImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenBridgeImplAddress, - l2Params.admins.proxy, - L2ERC20ExtendedTokensBridge__factory.createInterface().encodeFunctionData( - "initialize", - [l2Params.admins.bridge] - ), - options?.overrides, - ], - }); - - return [l1DeployScript as L1DeployAllScript, l2DeployScript as L2DeployAllScript]; - }, - }; -} From 26615fae41fb135930f25a46380a13669358ec3d Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 14 Jan 2025 19:24:46 +0100 Subject: [PATCH 27/34] add comments for two envs --- .env.example | 6 ++++++ README.md | 11 +++++++++++ utils/deployment/DeployScript.ts | 2 +- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/.env.example b/.env.example index b102bacf..ba18d7f9 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,12 @@ L2_PRC_URL=https://optimism-sepolia.infura.io/v3/ L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 +# Portal for relayer +L1_L2_PORTAL=0x16Fc5058F25648194471939df75CF27A2fdC48BC + +# Skip interactive prompts during L2 deployment if set to true +L2_DEPLOY_SKIP_PROMPTS=false + # ############################ # Etherscan # ############################ diff --git a/README.md b/README.md index 9593d59c..6a918475 100644 --- a/README.md +++ b/README.md @@ -321,6 +321,10 @@ The array of addresses to grant `WITHDRAWALS_ENABLER_ROLE` on L2 bridge/gateway. The array of addresses to grant `WITHDRAWALS_DISABLER_ROLE` on L2 bridge/gateway. The value must be in the form of JSON array of strings. For example: `["0x00000000219ab540356cbb839cbe05303d7705fa","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]` +#### `L2_DEPLOY_SKIP_PROMPTS` + +Skip interactive prompts during L2 deployment if set to true. + ### Acceptance Integration & E2E Testing The following variables are used in the process of the Integration & E2E testing. @@ -377,3 +381,10 @@ The test Ether might be retrived via [Paradigm Faucet](https://faucet.paradigm.x The private key from the address which holds 50+% TLDO +### Cross-Chain Relayer + +Utility that relays messages to L2. + +#### `L1_L2_PORTAL` + +An address of portal that relays messages. diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index cda10275..f9389385 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -85,7 +85,7 @@ export class DeployScript { async saveResultToFile(fileName: string) { fs.writeFile(fileName, JSON.stringify(this.resultJson, null, 2), { encoding: "utf8", flag: "w" }, function(err) { if (err) { - return console.error(err); + return console.error(err); } }); } From 9c9f3d70efda5b1a195f6a7e5bc502f250e3f15b Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 14 Jan 2025 19:41:03 +0100 Subject: [PATCH 28/34] fix tests --- utils/optimism/testing.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index 03dfda05..b08b4cd9 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -21,7 +21,7 @@ import { } from "../../typechain"; import addresses from "./addresses"; import contracts from "./contracts"; -import deploymentAll from "./deployment"; +import deployLidoOPStackBridge from "./deployAll"; import testingUtils from "../testing"; import { BridgingManagement } from "../bridging-management"; import network, { SignerOrProvider } from "../network"; @@ -232,6 +232,11 @@ async function deployTestBridge( const ethDeployer = testingUtils.accounts.deployer(ethProvider); const optDeployer = testingUtils.accounts.deployer(optProvider); + const crossDomainAddresses = addresses(); + if (!crossDomainAddresses.L1CrossDomainMessenger || !crossDomainAddresses.L2CrossDomainMessenger) { + throw new Error('CrossDomainMessenger addresses are not defined'); + } + const l1TokenRebasable = await new StETHStub__factory(ethDeployer).deploy( l1TokenRebasableName, l1TokenRebasableSymbol @@ -251,7 +256,7 @@ async function deployTestBridge( lastProcessingRefSlot ); - const [ethDeployScript, optDeployScript] = await deploymentAll() + const [ethDeployScript, optDeployScript] = await deployLidoOPStackBridge(true) .deployAllScript( { l1TokenNonRebasable: l1TokenNonRebasable.address, @@ -259,6 +264,7 @@ async function deployTestBridge( accountingOracle: accountingOracle.address, l2GasLimitForPushingTokenRate: l2GasLimitForPushingTokenRate, lido: lido, + l1CrossDomainMessenger: crossDomainAddresses.L1CrossDomainMessenger, deployer: ethDeployer, admins: { proxy: ethDeployer.address, bridge: ethDeployer.address }, @@ -266,6 +272,7 @@ async function deployTestBridge( }, { tokenRateOracle: { + admin: optDeployer.address, tokenRateOutdatedDelay: tokenRateOutdatedDelay, maxAllowedL2ToL1ClockLag: maxAllowedL2ToL1ClockLag, maxAllowedTokenRateDeviationPerDayBp: maxAllowedTokenRateDeviationPerDay, @@ -274,6 +281,7 @@ async function deployTestBridge( tokenRate: tokenRate, l1Timestamp: l1TokenRateUpdate }, + l2CrossDomainMessenger: crossDomainAddresses.L2CrossDomainMessenger, l2TokenNonRebasable: { name: l2TokenNonRebasable.name, symbol: l2TokenNonRebasable.symbol, @@ -296,6 +304,10 @@ async function deployTestBridge( await ethDeployScript.run(); await optDeployScript.run(); + if (!ethDeployScript.tokenRateNotifierImplAddress || !ethDeployScript.opStackTokenRatePusherImplAddress) { + throw new Error('Token rate notifier addresses are not defined'); + } + const tokenRateNotifier = TokenRateNotifier__factory.connect( ethDeployScript.tokenRateNotifierImplAddress, ethProvider From 0ddc2b1e6d70ae78d811a1afbd7019c4a202ef8c Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Tue, 14 Jan 2025 22:02:26 +0100 Subject: [PATCH 29/34] fix tests2 --- scripts/optimism/deploy-bridge-without-notifier.ts | 4 ++-- scripts/optimism/deploy-bridge.ts | 4 ++-- test/integration/optimism.integration.test.ts | 7 +++++-- utils/optimism/deployAll.ts | 2 +- utils/optimism/testing.ts | 4 ++-- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/optimism/deploy-bridge-without-notifier.ts b/scripts/optimism/deploy-bridge-without-notifier.ts index ee980df5..ea90ee1e 100644 --- a/scripts/optimism/deploy-bridge-without-notifier.ts +++ b/scripts/optimism/deploy-bridge-without-notifier.ts @@ -3,7 +3,7 @@ import prompt from "../../utils/prompt"; import network from "../../utils/network"; import deployment from "../../utils/deployment"; import { BridgingManagement } from "../../utils/bridging-management"; -import deployLidoOPStackBridge from "../../utils/optimism/deployAll"; +import deployAll from "../../utils/optimism/deployAll"; import { TokenRateOracleManagement } from "../../utils/tokenRateOracle-management"; import * as fs from 'fs'; @@ -22,7 +22,7 @@ async function main() { const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deployLidoOPStackBridge(false, { logger: console }) + const [l1DeployScript, l2DeployScript] = await deployAll(false, { logger: console }) .deployAllScript( { l1CrossDomainMessenger: deploymentConfig.l1.l1CrossDomainMessenger, diff --git a/scripts/optimism/deploy-bridge.ts b/scripts/optimism/deploy-bridge.ts index d51c2eda..63dc4714 100644 --- a/scripts/optimism/deploy-bridge.ts +++ b/scripts/optimism/deploy-bridge.ts @@ -3,7 +3,7 @@ import prompt from "../../utils/prompt"; import network from "../../utils/network"; import deployment from "../../utils/deployment"; import { BridgingManagement } from "../../utils/bridging-management"; -import deployLidoOPStackBridge from "../../utils/optimism/deployAll"; +import deployAll from "../../utils/optimism/deployAll"; import { TokenRateNotifierManagement } from "../../utils/tokenRateNotifier-management"; async function main() { @@ -25,7 +25,7 @@ async function main() { const deploymentConfig = deployment.loadMultiChainScratchDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deployLidoOPStackBridge(true, { logger: console }) + const [l1DeployScript, l2DeployScript] = await deployAll(true, { logger: console }) .deployAllScript( { lido: deploymentConfig.l1.lido, diff --git a/test/integration/optimism.integration.test.ts b/test/integration/optimism.integration.test.ts index 34838fea..679aeff3 100644 --- a/test/integration/optimism.integration.test.ts +++ b/test/integration/optimism.integration.test.ts @@ -6,7 +6,7 @@ import testing, { scenario } from "../../utils/testing"; import { BridgingManagerRole } from "../../utils/bridging-management"; import { getExchangeRate } from "../../utils/testing/helpers"; import { getBridgeExecutorParams } from "../../utils/bridge-executor"; -import deploymentAll from "../../utils/optimism/deployment"; +import deployAll from "../../utils/optimism/deployAll"; import network from "../../utils/network"; import { StETHStub__factory, @@ -291,7 +291,7 @@ async function ctxFactory() { const l1EthGovExecutorAddress = await govBridgeExecutor.getEthereumGovernanceExecutor(); - const [, optDeployScript] = await deploymentAll() + const [, optDeployScript] = await deployAll(true) .deployAllScript( { l1TokenNonRebasable: l1TokenNonRebasable.address, @@ -299,6 +299,7 @@ async function ctxFactory() { accountingOracle: accountingOracle.address, l2GasLimitForPushingTokenRate: l2GasLimitForPushingTokenRate, lido: lido.address, + l1CrossDomainMessenger: optAddresses.L1CrossDomainMessenger, deployer: l1Deployer, admins: { @@ -309,6 +310,7 @@ async function ctxFactory() { }, { tokenRateOracle: { + admin: l2Deployer.address, tokenRateOutdatedDelay: tokenRateOutdatedDelay, maxAllowedL2ToL1ClockLag: maxAllowedL2ToL1ClockLag, maxAllowedTokenRateDeviationPerDayBp: maxAllowedTokenRateDeviationPerDay, @@ -317,6 +319,7 @@ async function ctxFactory() { tokenRate: exchangeRate, l1Timestamp: l1Timestamp }, + l2CrossDomainMessenger: optAddresses.L2CrossDomainMessenger, l2TokenNonRebasable: { name: l2TokenNonRebasable.name, symbol: l2TokenNonRebasable.symbol, diff --git a/utils/optimism/deployAll.ts b/utils/optimism/deployAll.ts index 449d7bb5..f5981ebd 100644 --- a/utils/optimism/deployAll.ts +++ b/utils/optimism/deployAll.ts @@ -144,7 +144,7 @@ async function predictAllAddresses(l1Params: OptL1DeployScriptParams, l2Params: } /// Deploy all contracts on new network from scratch. -export default function deployLidoOPStackBridge( +export default function deployAll( deployNotifier: boolean, options: OptDeploymentOptions = {} ) { diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index b08b4cd9..d64b3760 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -21,7 +21,7 @@ import { } from "../../typechain"; import addresses from "./addresses"; import contracts from "./contracts"; -import deployLidoOPStackBridge from "./deployAll"; +import deployAll from "./deployAll"; import testingUtils from "../testing"; import { BridgingManagement } from "../bridging-management"; import network, { SignerOrProvider } from "../network"; @@ -256,7 +256,7 @@ async function deployTestBridge( lastProcessingRefSlot ); - const [ethDeployScript, optDeployScript] = await deployLidoOPStackBridge(true) + const [ethDeployScript, optDeployScript] = await deployAll(true) .deployAllScript( { l1TokenNonRebasable: l1TokenNonRebasable.address, From 17a98dbe1747f60bf2f0dc292acdb8c64dda174b Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Sun, 19 Jan 2025 23:12:49 +0100 Subject: [PATCH 30/34] save deploy block number to file --- utils/deployment/DeployScript.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/utils/deployment/DeployScript.ts b/utils/deployment/DeployScript.ts index f9389385..0baa9e7e 100644 --- a/utils/deployment/DeployScript.ts +++ b/utils/deployment/DeployScript.ts @@ -59,6 +59,7 @@ export class DeployScript { private contracts: Contract[] = []; public readonly deployer: Wallet; private resultJson: { [key: string]: any } = {}; + public lastBlockNumber: number = 0; constructor(deployer: Wallet, logger?: Logger) { this.deployer = deployer; @@ -108,7 +109,8 @@ export class DeployScript { const contract = await new Factory(deployer).deploy(...step.args); const deployTx = contract.deployTransaction; this._log(`Waiting for tx: ${getBlockExplorerTxLinkByChainId(deployTx)}`); - await deployTx.wait(); + const receipt = await deployTx.wait(); + this.lastBlockNumber = receipt.blockNumber; this._log( `Contract ${chalk.yellow( factoryName From d408ffe9740739f6525ae8a6663869036f28c1a1 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Mon, 20 Jan 2025 08:36:55 +0100 Subject: [PATCH 31/34] remove unused script, add pring functions for other deployemnt parameter configs --- scripts/optimism/update-ethereum-executor.ts | 144 ------------------- utils/deployment.ts | 131 ++++++++++++++++- 2 files changed, 127 insertions(+), 148 deletions(-) delete mode 100644 scripts/optimism/update-ethereum-executor.ts diff --git a/scripts/optimism/update-ethereum-executor.ts b/scripts/optimism/update-ethereum-executor.ts deleted file mode 100644 index 35f67965..00000000 --- a/scripts/optimism/update-ethereum-executor.ts +++ /dev/null @@ -1,144 +0,0 @@ -import { assert } from "chai"; -import { ethers } from "hardhat"; -import { GovBridgeExecutor__factory } from "../../typechain"; -import env from "../../utils/env"; -import lido from "../../utils/lido"; -import network from "../../utils/network"; -import optimism from "../../utils/optimism"; -import prompt from "../../utils/prompt"; - -// Set address of the bridge executor to run the script -const GOV_BRIDGE_EXECUTOR = ""; - -async function main() { - const isForking = env.forking(); - - const [l1LDOHolder] = network.getSigners( - env.string("TESTING_OPT_LDO_HOLDER_PRIVATE_KEY"), - { forking: isForking } - ); - const [, optRunner] = network.getSigners(env.privateKey(), { - forking: isForking, - }); - - const govBridgeExecutor = GovBridgeExecutor__factory.connect( - GOV_BRIDGE_EXECUTOR, - optRunner - ); - const networkName = "sepolia"; - const newEthExecutorLidoDAO = lido(networkName, l1LDOHolder); - const oldEthExecutorLidoDAO = lido(networkName, l1LDOHolder); - const prevEthGovExecutorAddress = - await govBridgeExecutor.getEthereumGovernanceExecutor(); - - assert.equal( - oldEthExecutorLidoDAO.agent.address.toLocaleLowerCase(), - prevEthGovExecutorAddress.toLowerCase(), - `${oldEthExecutorLidoDAO.agent.address} is not current ethereumGovernanceExecutor` - ); - - console.log(` · Is forking: ${isForking}`); - console.log(` · Network Name: ${networkName}`); - console.log( - ` · Prev Ethereum Governance Executor: ${prevEthGovExecutorAddress}` - ); - console.log( - ` · New Ethereum Governance Executor: ${newEthExecutorLidoDAO.agent.address}` - ); - console.log(` · LDO Holder: ${l1LDOHolder.address}`); - console.log(` · LDO Holder ETH balance: ${await l1LDOHolder.getBalance()}`); - console.log(` · L2 tx runner: ${optRunner.address}`); - console.log(` · L2 tx runner ETH balance: ${await optRunner.getBalance()}`); - - await prompt.proceed(); - - console.log(`Preparing the voting tx...`); - - const optAddresses = optimism.addresses(); - - // Prepare data for Governance Bridge Executor - const executorCalldata = await govBridgeExecutor.interface.encodeFunctionData( - "queue", - [ - [GOV_BRIDGE_EXECUTOR], - [0], - ["updateEthereumGovernanceExecutor(address)"], - [ - ethers.utils.defaultAbiCoder.encode( - ["address"], - [newEthExecutorLidoDAO.agent.address] - ), - ], - [false], - ] - ); - - const { callvalue, calldata } = await optimism - .messaging({ forking: isForking }) - .prepareL2Message({ - calldata: executorCalldata, - recipient: GOV_BRIDGE_EXECUTOR, - sender: oldEthExecutorLidoDAO.agent.address, - }); - - const createVoteTx = await oldEthExecutorLidoDAO.createVote( - l1LDOHolder, - "Update ethereumGovernanceExecutor on Optimism Governance Bridge Executor", - { - address: oldEthExecutorLidoDAO.agent.address, - signature: "execute(address,uint256,bytes)", - decodedCallData: [ - optAddresses.L1CrossDomainMessenger, - callvalue, - calldata, - ], - } - ); - - console.log("Creating voting to update ethereumGovernanceExecutor..."); - await createVoteTx.wait(); - console.log(`Vote was created!`); - - const votesCount = await oldEthExecutorLidoDAO.voting.votesLength(); - const voteId = votesCount.sub(1); - - console.log(`New vote id ${voteId.toString()}`); - console.log(`Voting for and executing the vote...`); - - const voteAndExecuteTx = await oldEthExecutorLidoDAO.voteAndExecute( - l1LDOHolder, - voteId, - true - ); - const executeTxReceipt = await voteAndExecuteTx.wait(); - - console.log(`Vote ${voteId.toString()} was executed!`); - - console.log(`Waiting for L2 transaction...`); - await optimism - .messaging({ forking: isForking }) - .waitForL2Message(executeTxReceipt.transactionHash); - - console.log(`Message delivered to L2`); - - console.log("Executing the queued task..."); - // execute task on L2 - const tasksCount = await govBridgeExecutor.getActionsSetCount(); - const targetTaskId = tasksCount.toNumber() - 1; - - const tx = await govBridgeExecutor.execute(targetTaskId); - await tx.wait(); - console.log(`Task executed on L2!`); - - const ethereumGovernanceExecutor = - await govBridgeExecutor.getEthereumGovernanceExecutor(); - - console.log( - `New ethereum governance executor is: ${ethereumGovernanceExecutor}` - ); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/utils/deployment.ts b/utils/deployment.ts index 4fec0989..ab8f359d 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -210,19 +210,19 @@ export async function printMultiChainDeploymentConfig( console.log(); console.log(chalk.bold(" · L1 Deployment Params:")); - await printEthereumDeploymentConfig(l1Deployer, l1, scratchDeploy); + await printL1DeploymentConfig(l1Deployer, l1, scratchDeploy); console.log(); console.log(chalk.bold(" · L1 Deployment Actions:")); l1DeployScript.print({ padding: 6 }); console.log(chalk.bold(" · L2 Deployment Params:")); - await printOptimismDeploymentConfig(l2Deployer, l2, scratchDeploy); + await printL2DeploymentConfig(l2Deployer, l2, scratchDeploy); console.log(); console.log(chalk.bold(" · L2 Deployment Actions:")); l2DeployScript.print({ padding: 6 }); } -async function printEthereumDeploymentConfig( +async function printL1DeploymentConfig( deployer: Wallet, params: L1DeploymentConfig, scratchDeploy: boolean @@ -264,7 +264,7 @@ async function printEthereumDeploymentConfig( } } -async function printOptimismDeploymentConfig( +async function printL2DeploymentConfig( deployer: Wallet, params: L2DeploymentConfig, scratchDeploy: boolean @@ -314,9 +314,132 @@ async function printOptimismDeploymentConfig( } } +export async function printMultiChainStETHDeploymentConfig( + title: string, + l1Deployer: Wallet, + l2Deployer: Wallet, + deploymentParams: MultiChainStETHDeploymentConfig, + l1DeployScript: DeployScript, + l2DeployScript: DeployScript, +) { + const { l1, l2 } = deploymentParams; + console.log(chalk.bold(`${title}\n`)); + + console.log(chalk.bold(" · Deployment Params:")); + await printDeploymentConfig(); + console.log(); + + console.log(chalk.bold(" · L1 StETH Deployment Params:")); + await printL1StETHConfig(l1Deployer, l1); + console.log(); + console.log(chalk.bold(" · L1 Deployment Actions:")); + l1DeployScript.print({ padding: 6 }); + + console.log(chalk.bold(" · L2 StETH Deployment Params:")); + await printL2StETHConfig(l2Deployer, l2); + console.log(); + console.log(chalk.bold(" · L2 Deployment Actions:")); + l2DeployScript.print({ padding: 6 }); +} + +async function printL1StETHConfig( + deployer: Wallet, + params: L1StETHDeploymentConfig +) { + const pad = " ".repeat(4); + const chainId = await deployer.getChainId(); + console.log(`${pad}· Chain ID: ${chainId}`); + console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); + + // Print base config + await printL1DeploymentConfig(deployer, params, false); + + // Print StETH specific fields + console.log(`${pad}· L1 Token Bridge: ${chalk.underline(params.l1TokenBridge)}`); + console.log(`${pad}· Lido: ${chalk.underline(params.lido)}`); + console.log(`${pad}· Token Rate Notifier Owner: ${chalk.underline(params.tokenRateNotifierOwner)}`); +} + +async function printL2StETHConfig( + deployer: Wallet, + params: L2StETHDeploymentConfig +) { + const pad = " ".repeat(4); + const chainId = await deployer.getChainId(); + console.log(`${pad}· Chain ID: ${chainId}`); + console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); + + // Print base config + await printL2DeploymentConfig(deployer, params, false); + + // Print StETH specific fields + console.log(`${pad}· L2 Token Bridge: ${chalk.underline(params.l2TokenBridge)}`); + console.log(`${pad}· L2 Token Non-Rebasable: ${chalk.underline(params.l2TokenNonRebasable)}`); +} + +export async function printMultiChainScratchDeploymentConfig( + title: string, + l1Deployer: Wallet, + l2Deployer: Wallet, + deploymentParams: MultiChainScratchDeploymentConfig, + l1DeployScript: DeployScript, + l2DeployScript: DeployScript, +) { + const { l1, l2 } = deploymentParams; + console.log(chalk.bold(`${title}\n`)); + + console.log(chalk.bold(" · Deployment Params:")); + await printDeploymentConfig(); + console.log(); + + console.log(chalk.bold(" · L1 Scratch Deployment Params:")); + await printL1ScratchConfig(l1Deployer, l1); + console.log(); + console.log(chalk.bold(" · L1 Deployment Actions:")); + l1DeployScript.print({ padding: 6 }); + + console.log(chalk.bold(" · L2 Scratch Deployment Params:")); + await printL2ScratchConfig(l2Deployer, l2); + console.log(); + console.log(chalk.bold(" · L2 Deployment Actions:")); + l2DeployScript.print({ padding: 6 }); +} + +async function printL1ScratchConfig( + deployer: Wallet, + params: L1ScratchDeploymentConfig +) { + const pad = " ".repeat(4); + const chainId = await deployer.getChainId(); + console.log(`${pad}· Chain ID: ${chainId}`); + console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); + + // Print base config with scratch deploy enabled + await printL1DeploymentConfig(deployer, params, true); + + // Print Scratch specific fields + console.log(`${pad}· Lido: ${chalk.underline(params.lido)}`); + console.log(`${pad}· Token Rate Notifier Owner: ${chalk.underline(params.tokenRateNotifierOwner)}`); +} + +async function printL2ScratchConfig( + deployer: Wallet, + params: L2ScratchDeploymentConfig +) { + const pad = " ".repeat(4); + const chainId = await deployer.getChainId(); + console.log(`${pad}· Chain ID: ${chainId}`); + console.log(`${pad}· Deployer: ${chalk.underline(deployer.address)}`); + + // Print base config with scratch deploy enabled + await printL2DeploymentConfig(deployer, params, true); +} + export default { loadMultiChainDeploymentConfig, loadMultiChainStETHDeploymentConfig, loadMultiChainScratchDeploymentConfig, printMultiChainDeploymentConfig, + printMultiChainStETHDeploymentConfig, + printMultiChainScratchDeploymentConfig, }; From 6a01c602f210aa713217c90da67e9887336cd183 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Wed, 22 Jan 2025 12:55:31 +0100 Subject: [PATCH 32/34] add comment to env example --- .env.example | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.env.example b/.env.example index ba18d7f9..0aec71b8 100644 --- a/.env.example +++ b/.env.example @@ -4,12 +4,19 @@ # RPCs # ############################ -L1_CHAIN_ID=10 -L2_CHAIN_ID=11155420 +# ID of the L1 chain. For example, 1 is the ID of the Ethereum Mainnet. +L1_CHAIN_ID=1 -L1_PRC_URL=https://sepolia.infura.io/v3/ -L2_PRC_URL=https://optimism-sepolia.infura.io/v3/ +# ID of the L2 chain. For example, 1 is the ID of the Seneium Mainnet. +L2_CHAIN_ID=1868 +# URL of the L1 RPC. For example, https://sepolia.infura.io/v3/ is the URL of the Sepolia testnet. +L1_PRC_URL=https://sepolia.infura.io/v3/ + +# URL of the L2 RPC. For example, https://optimism-sepolia.infura.io/v3/ is the URL of the Optimism testnet. +L2_PRC_URL=https://optimism-sepolia.infura.io/v3/ + +# Address of the rollup cross-domain messenger. Can be found in rollup docs. L1_CROSSDOMAIN_MESSENGER=0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1 L2_CROSSDOMAIN_MESSENGER=0x4200000000000000000000000000000000000007 From 78338b07131c585245a6914cb4117d8ddd811a02 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Thu, 23 Jan 2025 16:21:15 +0100 Subject: [PATCH 33/34] add permission to github action --- .github/workflows/storage-layout-update.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/storage-layout-update.yml b/.github/workflows/storage-layout-update.yml index 689c56b5..37300a9e 100644 --- a/.github/workflows/storage-layout-update.yml +++ b/.github/workflows/storage-layout-update.yml @@ -3,6 +3,11 @@ name: Update .storage-layout on: workflow_dispatch: +permissions: + contents: write + issues: write + pull-requests: write + jobs: assert: runs-on: ubuntu-latest From bc609797f5bcdefdc9fb4b01dbc63bf09abdb4c6 Mon Sep 17 00:00:00 2001 From: kovalgek Date: Thu, 23 Jan 2025 15:22:56 +0000 Subject: [PATCH 34/34] fix: Make storage-layout up to date --- .storage-layout | 103 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 87 insertions(+), 16 deletions(-) diff --git a/.storage-layout b/.storage-layout index a2b1b3e3..48103c0a 100644 --- a/.storage-layout +++ b/.storage-layout @@ -5,125 +5,196 @@ ➡ BridgingManager ======================= + +╭--------+---------------------------------------------------+------+--------+-------+-----------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|-----------------------------------------------| ++====================================================================================================================================+ | _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/BridgingManager.sol:BridgingManager | +╰--------+---------------------------------------------------+------+--------+-------+-----------------------------------------------╯ + ======================= ➡ CrossDomainEnabled ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ ERC20Bridged ======================= + +╭-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|-------------|-------------------------------------------------|------|--------|-------|-----------------------------------------------| ++=======================================================================================================================================+ | totalSupply | uint256 | 0 | 0 | 32 | contracts/token/ERC20Bridged.sol:ERC20Bridged | +|-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------| | balanceOf | mapping(address => uint256) | 1 | 0 | 32 | contracts/token/ERC20Bridged.sol:ERC20Bridged | +|-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------| | allowance | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | contracts/token/ERC20Bridged.sol:ERC20Bridged | +╰-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------╯ + ======================= ➡ ERC20BridgedPermit ======================= + +╭-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|-------------|-------------------------------------------------|------|--------|-------|-----------------------------------------------------------| ++===================================================================================================================================================+ | totalSupply | uint256 | 0 | 0 | 32 | contracts/token/ERC20BridgedPermit.sol:ERC20BridgedPermit | +|-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------| | balanceOf | mapping(address => uint256) | 1 | 0 | 32 | contracts/token/ERC20BridgedPermit.sol:ERC20BridgedPermit | +|-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------| | allowance | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | contracts/token/ERC20BridgedPermit.sol:ERC20BridgedPermit | +╰-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------------------------╯ + ======================= ➡ ERC20Core ======================= + +╭-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|-------------|-------------------------------------------------|------|--------|-------|-----------------------------------------| ++=================================================================================================================================+ | totalSupply | uint256 | 0 | 0 | 32 | contracts/token/ERC20Core.sol:ERC20Core | +|-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------| | balanceOf | mapping(address => uint256) | 1 | 0 | 32 | contracts/token/ERC20Core.sol:ERC20Core | +|-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------| | allowance | mapping(address => mapping(address => uint256)) | 2 | 0 | 32 | contracts/token/ERC20Core.sol:ERC20Core | +╰-------------+-------------------------------------------------+------+--------+-------+-----------------------------------------╯ + ======================= ➡ ERC20Metadata ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ ERC20RebasableBridged ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ ERC20RebasableBridgedPermit ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ L1LidoTokensBridge ======================= + +╭--------+---------------------------------------------------+------+--------+-------+--------------------------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------| ++===================================================================================================================================================+ | _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L1LidoTokensBridge.sol:L1LidoTokensBridge | +╰--------+---------------------------------------------------+------+--------+-------+--------------------------------------------------------------╯ + ======================= ➡ L2ERC20ExtendedTokensBridge ======================= + +╭--------+---------------------------------------------------+------+--------+-------+--------------------------------------------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------------------------------| ++=====================================================================================================================================================================+ | _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/L2ERC20ExtendedTokensBridge.sol:L2ERC20ExtendedTokensBridge | +╰--------+---------------------------------------------------+------+--------+-------+--------------------------------------------------------------------------------╯ + ======================= ➡ OpStackTokenRatePusher ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ OssifiableProxy ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ RebasableAndNonRebasableTokens ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ + ======================= ➡ TokenRateNotifier ======================= + +╭-----------+-----------+------+--------+-------+--------------------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|-----------|-----------|------|--------|-------|--------------------------------------------------------| ++========================================================================================================+ | _owner | address | 0 | 0 | 20 | contracts/lido/TokenRateNotifier.sol:TokenRateNotifier | +|-----------+-----------+------+--------+-------+--------------------------------------------------------| | observers | address[] | 1 | 0 | 32 | contracts/lido/TokenRateNotifier.sol:TokenRateNotifier | +╰-----------+-----------+------+--------+-------+--------------------------------------------------------╯ + ======================= ➡ TokenRateOracle ======================= + +╭--------+---------------------------------------------------+------+--------+-------+--------------------------------------------------------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|--------|---------------------------------------------------|------|--------|-------|--------------------------------------------------------| ++=============================================================================================================================================+ | _roles | mapping(bytes32 => struct AccessControl.RoleData) | 0 | 0 | 32 | contracts/optimism/TokenRateOracle.sol:TokenRateOracle | +╰--------+---------------------------------------------------+------+--------+-------+--------------------------------------------------------╯ + ======================= ➡ Versioned ======================= + +╭------+------+------+--------+-------+----------╮ | Name | Type | Slot | Offset | Bytes | Contract | -|------|------|------|--------|-------|----------| ++================================================+ +╰------+------+------+--------+-------+----------╯ +