diff --git a/.env.example b/.env.example index d3ecb36..db67351 100644 --- a/.env.example +++ b/.env.example @@ -31,6 +31,33 @@ TOKEN= # Address of the rebasable token to deploy the bridge/gateway for REBASABLE_TOKEN= +# Address of token rate notifier. Connects Lido core protocol. +TOKEN_RATE_NOTIFIER= + +# Address of token rate pusher +L1_OP_STACK_TOKEN_RATE_PUSHER= + +# Gas limit required to complete pushing token rate on L2. +L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE= + +# A time period when token rate can be considered outdated. +RATE_OUTDATED_DELAY= + +# Address of L1 token bridge proxy. +L1_TOKEN_BRIDGE= + +# Address of L2 token bridge proxy. +L2_TOKEN_BRIDGE= + +# Address of the non-rebasable token proxy on L2. +L2_TOKEN= + +# Address of token rate oracle on L2 +L2_TOKEN_RATE_ORACLE= + +# Address of bridge executor. +GOV_BRIDGE_EXECUTOR= + # Name of the network environments used by deployment scripts. # Might be one of: "mainnet", "goerli". NETWORK=mainnet diff --git a/scripts/optimism/deploy-bridge.ts b/scripts/optimism/deploy-bridge.ts index 682eeb4..2e4f272 100644 --- a/scripts/optimism/deploy-bridge.ts +++ b/scripts/optimism/deploy-bridge.ts @@ -24,8 +24,8 @@ async function main() { const [l1DeployScript, l2DeployScript] = await optimism .deployment(networkName, { logger: console }) .erc20TokenBridgeDeployScript( - deploymentConfig.token, - deploymentConfig.rebasableToken, + deploymentConfig.l1Token, + deploymentConfig.l1RebasableToken, deploymentConfig.l2TokenRateOracle, { deployer: ethDeployer, diff --git a/scripts/optimism/deploy-new-impls.ts b/scripts/optimism/deploy-new-impls.ts new file mode 100644 index 0000000..2026c9c --- /dev/null +++ b/scripts/optimism/deploy-new-impls.ts @@ -0,0 +1,73 @@ +import env from "../../utils/env"; +import prompt from "../../utils/prompt"; +import network from "../../utils/network"; +import deployment from "../../utils/deployment"; + +import deploymentNewImplementations from "../../utils/optimism/deploymentNewImplementations"; + +async function main() { + 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 deploymentNewImplementations( + networkName, + { logger: console } + ) + .deployScript( + { + deployer: ethDeployer, + admins: { + proxy: deploymentConfig.l1.proxyAdmin, + bridge: ethDeployer.address + }, + contractsShift: 0, + tokenProxyAddress: deploymentConfig.l1Token, + tokenRebasableProxyAddress: deploymentConfig.l1RebasableToken, + opStackTokenRatePusherImplAddress: deploymentConfig.l1OpStackTokenRatePusher, + tokenBridgeProxyAddress: deploymentConfig.l1TokenBridge, + }, + { + deployer: optDeployer, + admins: { + proxy: deploymentConfig.l2.proxyAdmin, + bridge: optDeployer.address, + }, + contractsShift: 0, + tokenBridgeProxyAddress: deploymentConfig.l2TokenBridge, + tokenProxyAddress: deploymentConfig.l2Token, + tokenRateOracleProxyAddress: deploymentConfig.l2TokenRateOracle, + tokenRateOracleRateOutdatedDelay: deploymentConfig.rateOutdatedDelay, + } + ); + + await deployment.printMultiChainDeploymentConfig( + "Deploy new implementations: bridges, wstETH, stETH", + ethDeployer, + optDeployer, + deploymentConfig, + l1DeployScript, + l2DeployScript + ); + + await prompt.proceed(); + + await l1DeployScript.run(); + await l2DeployScript.run(); +} + +main().catch((error) => { + console.error(error); + process.exitCode = 1; +}); diff --git a/scripts/optimism/deploy-oracle.ts b/scripts/optimism/deploy-oracle.ts index bf5e38f..7d75e0f 100644 --- a/scripts/optimism/deploy-oracle.ts +++ b/scripts/optimism/deploy-oracle.ts @@ -2,72 +2,74 @@ import env from "../../utils/env"; import prompt from "../../utils/prompt"; import network from "../../utils/network"; import optimism from "../../utils/optimism"; -import deploymentOracle from "../../utils/deployment"; +import deployment from "../../utils/deployment"; import { TokenRateNotifier__factory } from "../../typechain"; async function main() { - const networkName = env.network(); - const ethOptNetwork = network.multichain(["eth", "opt"], networkName); + 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 [ethDeployer] = ethOptNetwork.getSigners(env.privateKey(), { + forking: env.forking(), + }); + const [, optDeployer] = ethOptNetwork.getSigners( + env.string("OPT_DEPLOYER_PRIVATE_KEY"), + { + forking: env.forking(), + } + ); - const l1Token = env.address("TOKEN") - const l1Admin = env.address("L1_PROXY_ADMIN"); - const l2Admin = env.address("L2_PROXY_ADMIN"); + const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await optimism - .deploymentOracle(networkName, { logger: console }) - .oracleDeployScript( - l1Token, - { - deployer: ethDeployer, - admins: { - proxy: l1Admin, - bridge: ethDeployer.address, - }, - }, - { - deployer: optDeployer, - admins: { - proxy: l2Admin, - bridge: optDeployer.address, - }, - } - ); + const [l1DeployScript, l2DeployScript] = await optimism + .deploymentOracle(networkName, { logger: console }) + .oracleDeployScript( + deploymentConfig.l1Token, + deploymentConfig.l2GasLimitForPushingTokenRate, + deploymentConfig.rateOutdatedDelay, + { + deployer: ethDeployer, + admins: { + proxy: deploymentConfig.l1.proxyAdmin, + bridge: ethDeployer.address, + }, + contractsShift: 0 + }, + { + deployer: optDeployer, + admins: { + proxy: deploymentConfig.l2.proxyAdmin, + bridge: optDeployer.address, + }, + contractsShift: 0 + } + ); -// await deploymentOracle.printMultiChainDeploymentConfig( -// "Deploy Token Rate Oracle", -// ethDeployer, -// optDeployer, -// deploymentConfig, -// l1DeployScript, -// l2DeployScript -// ); + await deployment.printMultiChainDeploymentConfig( + "Deploy Token Rate Oracle", + ethDeployer, + optDeployer, + deploymentConfig, + l1DeployScript, + l2DeployScript + ); - await prompt.proceed(); + await prompt.proceed(); - await l1DeployScript.run(); - await l2DeployScript.run(); + await l1DeployScript.run(); + await l2DeployScript.run(); - /// setup, add observer - const tokenRateNotifier = TokenRateNotifier__factory.connect( - l1DeployScript.tokenRateNotifierImplAddress, - ethDeployer - ); - await tokenRateNotifier - .connect(ethDeployer) - .addObserver(l1DeployScript.opStackTokenRatePusherImplAddress); + /// setup by adding observer + const tokenRateNotifier = TokenRateNotifier__factory.connect( + l1DeployScript.tokenRateNotifierImplAddress, + ethDeployer + ); + await tokenRateNotifier + .connect(ethDeployer) + .addObserver(l1DeployScript.opStackTokenRatePusherImplAddress); } main().catch((error) => { - console.error(error); - process.exitCode = 1; + console.error(error); + process.exitCode = 1; }); diff --git a/test/bridge-executor/optimism.integration.test.ts b/test/bridge-executor/optimism.integration.test.ts index 1cf1db4..bc8fcc1 100644 --- a/test/bridge-executor/optimism.integration.test.ts +++ b/test/bridge-executor/optimism.integration.test.ts @@ -15,7 +15,7 @@ import { BridgingManagerRole } from "../../utils/bridging-management"; import env from "../../utils/env"; import network from "../../utils/network"; import { getBridgeExecutorParams } from "../../utils/bridge-executor"; -import deploymentAll from "../../utils/optimism/deploymentAll"; +import deploymentAll from "../../utils/optimism/deploymentAllFromScratch"; scenario("Optimism :: Bridge Executor integration test", ctxFactory) .step("Activate L2 bridge", async (ctx) => { @@ -239,7 +239,7 @@ async function ctxFactory() { const [, optDeployScript] = await deploymentAll( networkName - ).erc20TokenBridgeDeployScript( + ).deployAllScript( l1Token.address, l1TokenRebasable.address, { diff --git a/utils/deployment.ts b/utils/deployment.ts index eba5c07..e820bd8 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -10,18 +10,32 @@ interface ChainDeploymentConfig extends BridgingManagerSetupConfig { } interface MultiChainDeploymentConfig { - token: string; - rebasableToken: string; + l1Token: string; + l1RebasableToken: string; + l1OpStackTokenRatePusher: string; + l2GasLimitForPushingTokenRate: number; + rateOutdatedDelay: number; + l1TokenBridge: string; + l2TokenBridge: string; + l2Token: string; l2TokenRateOracle: string; + govBridgeExecutor: string; l1: ChainDeploymentConfig; l2: ChainDeploymentConfig; } export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { return { - token: env.address("TOKEN"), - rebasableToken: env.address("REBASABLE_TOKEN"), - l2TokenRateOracle: env.address("TOKEN_RATE_ORACLE"), + l1Token: env.address("TOKEN"), + l1RebasableToken: env.address("REBASABLE_TOKEN"), + l1OpStackTokenRatePusher: env.address("L1_OP_STACK_TOKEN_RATE_PUSHER"), + l2GasLimitForPushingTokenRate: Number(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), + rateOutdatedDelay: Number(env.string("RATE_OUTDATED_DELAY")), + l1TokenBridge: env.address("L1_TOKEN_BRIDGE"), + l2TokenBridge: env.address("L2_TOKEN_BRIDGE"), + l2Token: env.address("L2_TOKEN"), + l2TokenRateOracle: env.address("L2_TOKEN_RATE_ORACLE"), + govBridgeExecutor: env.address("GOV_BRIDGE_EXECUTOR"), l1: { proxyAdmin: env.address("L1_PROXY_ADMIN"), bridgeAdmin: env.address("L1_BRIDGE_ADMIN"), @@ -53,8 +67,8 @@ export async function printMultiChainDeploymentConfig( l1DeployScript: DeployScript, l2DeployScript: DeployScript ) { - const { token, stETHToken, l1, l2 } = deploymentParams; - console.log(chalk.bold(`${title} :: ${chalk.underline(token)} :: ${chalk.underline(stETHToken)}\n`)); + const { l1Token, l1RebasableToken, l1, l2 } = deploymentParams; + console.log(chalk.bold(`${title} :: ${chalk.underline(l1Token)} :: ${chalk.underline(l1RebasableToken)}\n`)); console.log(chalk.bold(" ยท L1 Deployment Params:")); await printChainDeploymentConfig(l1Deployer, l1); console.log(); diff --git a/utils/optimism/deploymentAll.ts b/utils/optimism/deploymentAll.ts deleted file mode 100644 index 993b7a2..0000000 --- a/utils/optimism/deploymentAll.ts +++ /dev/null @@ -1,318 +0,0 @@ -import { assert } from "chai"; -import { Overrides, Wallet } from "ethers"; -import addresses from "./addresses"; -import { CommonOptions } from "./types"; -import network, { NetworkName } from "../network"; -import { DeployScript, Logger } from "../deployment/DeployScript"; -import { - ERC20Bridged__factory, - ERC20Rebasable__factory, - IERC20Metadata__factory, - L1LidoTokensBridge__factory, - L2ERC20TokenBridge__factory, - OssifiableProxy__factory, - TokenRateOracle__factory, - TokenRateNotifier__factory, - OpStackTokenRatePusher__factory - } from "../../typechain"; - -interface OptL1DeployScriptParams { - deployer: Wallet; - admins: { proxy: string; bridge: string }; - contractsShift: number; -} - -interface OptL2DeployScriptParams extends OptL1DeployScriptParams { - l2Token?: { name?: string; symbol?: string }; - l2TokenRebasable?: { name?: string; symbol?: string }; -} - -interface OptDeploymentOptions extends CommonOptions { - logger?: Logger; - overrides?: Overrides; -} - -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; -} - -/// deploys from scratch wstETH on L2, stETH on L2, bridgeL1, bridgeL2 and Oracle -export default function deploymentAll( - networkName: NetworkName, - options: OptDeploymentOptions = {} -) { - const optAddresses = addresses(networkName, options); - return { - async erc20TokenBridgeDeployScript( - l1Token: string, - l1TokenRebasable: string, - l1Params: OptL1DeployScriptParams, - l2Params: OptL2DeployScriptParams, - ): Promise<[L1DeployAllScript, L2DeployAllScript]> { - - const [ - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - ] = await network.predictAddresses(l1Params.deployer, l1Params.contractsShift + 4); - - const [ - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableImplAddress, - expectedL2TokenRebasableProxyAddress, - expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress, - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress - ] = await network.predictAddresses(l2Params.deployer, l2Params.contractsShift + 8); - - const l1DeployScript = new L1DeployAllScript( - l1Params.deployer, - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - options?.logger - ) - .addStep({ - factory: L1LidoTokensBridge__factory, - args: [ - optAddresses.L1CrossDomainMessenger, - expectedL2TokenBridgeProxyAddress, - l1Token, - l1TokenRebasable, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableProxyAddress, - 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: [ - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), - }) - .addStep({ - factory: OpStackTokenRatePusher__factory, - args: [ - optAddresses.L1CrossDomainMessenger, - l1Token, - expectedL2TokenRateOracleProxyAddress, - 1000, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), - }); - - const l1TokenInfo = IERC20Metadata__factory.connect( - l1Token, - l1Params.deployer - ); - - const l1TokenRebasableInfo = IERC20Metadata__factory.connect( - l1TokenRebasable, - l1Params.deployer - ); - const [decimals, l2TokenName, l2TokenSymbol, l2TokenRebasableName, l2TokenRebasableSymbol] = await Promise.all([ - l1TokenInfo.decimals(), - l2Params.l2Token?.name ?? l1TokenInfo.name(), - l2Params.l2Token?.symbol ?? l1TokenInfo.symbol(), - 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: ERC20Bridged__factory, - args: [ - l2TokenName, - l2TokenSymbol, - decimals, - expectedL2TokenBridgeProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenImplAddress, - l2Params.admins.proxy, - ERC20Bridged__factory.createInterface().encodeFunctionData( - "initialize", - [l2TokenName, l2TokenSymbol] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenProxyAddress), - }) - .addStep({ - factory: ERC20Rebasable__factory, - args: [ - l2TokenRebasableName, - l2TokenRebasableSymbol, - decimals, - expectedL2TokenProxyAddress, - expectedL2TokenRateOracleProxyAddress, - expectedL2TokenBridgeProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenRebasableImplAddress, - l2Params.admins.proxy, - ERC20Rebasable__factory.createInterface().encodeFunctionData( - "initialize", - [l2TokenRebasableName, l2TokenRebasableSymbol] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableProxyAddress), - }) - .addStep({ - factory: L2ERC20TokenBridge__factory, - args: [ - optAddresses.L2CrossDomainMessenger, - expectedL1TokenBridgeProxyAddress, - l1Token, - l1TokenRebasable, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenBridgeImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenBridgeImplAddress, - l2Params.admins.proxy, - L2ERC20TokenBridge__factory.createInterface().encodeFunctionData( - "initialize", - [l2Params.admins.bridge] - ), - options?.overrides, - ], - }) - .addStep({ - factory: TokenRateOracle__factory, - args: [ - optAddresses.L2CrossDomainMessenger, - expectedL2TokenBridgeProxyAddress, - expectedL1OpStackTokenRatePusherImplAddress, - 86400, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenRateOracleImplAddress, - l2Params.admins.proxy, - [], - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), - }); - - return [l1DeployScript as L1DeployAllScript, l2DeployScript as L2DeployAllScript]; - }, - }; -} diff --git a/utils/optimism/deploymentAllFromScratch.ts b/utils/optimism/deploymentAllFromScratch.ts new file mode 100644 index 0000000..6b95f1b --- /dev/null +++ b/utils/optimism/deploymentAllFromScratch.ts @@ -0,0 +1,320 @@ +import { assert } from "chai"; +import { Wallet } from "ethers"; +import addresses from "./addresses"; +import { OptDeploymentOptions, DeployScriptParams } from "./types"; +import network, { NetworkName } from "../network"; +import { DeployScript, Logger } from "../deployment/DeployScript"; +import { + ERC20Bridged__factory, + ERC20Rebasable__factory, + IERC20Metadata__factory, + L1LidoTokensBridge__factory, + L2ERC20TokenBridge__factory, + OssifiableProxy__factory, + TokenRateOracle__factory, + TokenRateNotifier__factory, + OpStackTokenRatePusher__factory +} from "../../typechain"; + +interface OptL1DeployScriptParams extends DeployScriptParams { +} +interface OptL2DeployScriptParams extends DeployScriptParams { + l2Token?: { + name?: string; + symbol?: string + }; + l2TokenRebasable?: { + name?: string; + symbol?: string + }; +} + +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; +} + +/// deploys from scratch +/// - wstETH on L2 +/// - stETH on L2 +/// - bridgeL1 +/// - bridgeL2 +/// - Oracle +export default function deploymentAll( + networkName: NetworkName, + options: OptDeploymentOptions = {} +) { + const optAddresses = addresses(networkName, options); + return { + async deployAllScript( + l1Token: string, + l1TokenRebasable: string, + l1Params: OptL1DeployScriptParams, + l2Params: OptL2DeployScriptParams, + ): Promise<[L1DeployAllScript, L2DeployAllScript]> { + + const [ + expectedL1TokenBridgeImplAddress, + expectedL1TokenBridgeProxyAddress, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + ] = await network.predictAddresses(l1Params.deployer, l1Params.contractsShift + 4); + + const [ + expectedL2TokenImplAddress, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + expectedL2TokenBridgeImplAddress, + expectedL2TokenBridgeProxyAddress, + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress + ] = await network.predictAddresses(l2Params.deployer, l2Params.contractsShift + 8); + + const l1DeployScript = new L1DeployAllScript( + l1Params.deployer, + expectedL1TokenBridgeImplAddress, + expectedL1TokenBridgeProxyAddress, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + options?.logger + ) + .addStep({ + factory: L1LidoTokensBridge__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + expectedL2TokenBridgeProxyAddress, + l1Token, + l1TokenRebasable, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + 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: [ + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), + }) + .addStep({ + factory: OpStackTokenRatePusher__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l1Token, + expectedL2TokenRateOracleProxyAddress, + 1000, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), + }); + + const l1TokenInfo = IERC20Metadata__factory.connect( + l1Token, + l1Params.deployer + ); + + const l1TokenRebasableInfo = IERC20Metadata__factory.connect( + l1TokenRebasable, + l1Params.deployer + ); + const [decimals, l2TokenName, l2TokenSymbol, l2TokenRebasableName, l2TokenRebasableSymbol] = await Promise.all([ + l1TokenInfo.decimals(), + l2Params.l2Token?.name ?? l1TokenInfo.name(), + l2Params.l2Token?.symbol ?? l1TokenInfo.symbol(), + 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: ERC20Bridged__factory, + args: [ + l2TokenName, + l2TokenSymbol, + decimals, + expectedL2TokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenImplAddress, + l2Params.admins.proxy, + ERC20Bridged__factory.createInterface().encodeFunctionData( + "initialize", + [l2TokenName, l2TokenSymbol] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenProxyAddress), + }) + .addStep({ + factory: ERC20Rebasable__factory, + args: [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + decimals, + expectedL2TokenProxyAddress, + expectedL2TokenRateOracleProxyAddress, + expectedL2TokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRebasableImplAddress, + l2Params.admins.proxy, + ERC20Rebasable__factory.createInterface().encodeFunctionData( + "initialize", + [l2TokenRebasableName, l2TokenRebasableSymbol] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableProxyAddress), + }) + .addStep({ + factory: L2ERC20TokenBridge__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + expectedL1TokenBridgeProxyAddress, + l1Token, + l1TokenRebasable, + expectedL2TokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenBridgeImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenBridgeImplAddress, + l2Params.admins.proxy, + L2ERC20TokenBridge__factory.createInterface().encodeFunctionData( + "initialize", + [l2Params.admins.bridge] + ), + options?.overrides, + ], + }) + .addStep({ + factory: TokenRateOracle__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + expectedL2TokenBridgeProxyAddress, + expectedL1OpStackTokenRatePusherImplAddress, + 86400, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRateOracleImplAddress, + l2Params.admins.proxy, + [], + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + }); + + return [l1DeployScript as L1DeployAllScript, l2DeployScript as L2DeployAllScript]; + }, + }; +} diff --git a/utils/optimism/deploymentNewImplementations.ts b/utils/optimism/deploymentNewImplementations.ts new file mode 100644 index 0000000..706dbf4 --- /dev/null +++ b/utils/optimism/deploymentNewImplementations.ts @@ -0,0 +1,229 @@ +import { assert } from "chai"; +import { Wallet } from "ethers"; +import addresses from "./addresses"; +import { OptDeploymentOptions, DeployScriptParams } from "./types"; +import network, { NetworkName } from "../network"; +import { DeployScript, Logger } from "../deployment/DeployScript"; +import { + ERC20Bridged__factory, + ERC20Rebasable__factory, + IERC20Metadata__factory, + L1LidoTokensBridge__factory, + L2ERC20TokenBridge__factory, + OssifiableProxy__factory, + TokenRateOracle__factory +} from "../../typechain"; + +interface OptL1DeployScriptParams extends DeployScriptParams { + tokenProxyAddress: string; + tokenRebasableProxyAddress: string; + opStackTokenRatePusherImplAddress: string; + tokenBridgeProxyAddress: string; + deployer: Wallet; + admins: { + proxy: string; + bridge: string + }; + contractsShift: number; +} + +interface OptL2DeployScriptParams extends DeployScriptParams { + tokenBridgeProxyAddress: string; + tokenProxyAddress: string; + tokenRateOracleProxyAddress: string; + tokenRateOracleRateOutdatedDelay: number; + token?: { + name?: string; + symbol?: string + }; + tokenRebasable?: { + name?: string; + symbol?: string + }; +} + +export class BridgeL1DeployScript extends DeployScript { + + constructor( + deployer: Wallet, + bridgeImplAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.bridgeImplAddress = bridgeImplAddress; + } + + public bridgeImplAddress: string; +} + +export class BridgeL2DeployScript extends DeployScript { + + constructor( + deployer: Wallet, + tokenImplAddress: string, + tokenRebasableImplAddress: string, + tokenRebasableProxyAddress: string, + tokenBridgeImplAddress: string, + tokenRateOracleImplAddress: string, + logger?: Logger + ) { + super(deployer, logger); + this.tokenImplAddress = tokenImplAddress; + this.tokenRebasableImplAddress = tokenRebasableImplAddress; + this.tokenRebasableProxyAddress = tokenRebasableProxyAddress; + this.tokenBridgeImplAddress = tokenBridgeImplAddress; + this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; + } + + public tokenImplAddress: string; + public tokenRebasableImplAddress: string; + public tokenRebasableProxyAddress: string; + public tokenBridgeImplAddress: string; + public tokenRateOracleImplAddress: string; +} + +/// deploys +/// - new L1Bridge Impl +/// - new L2Bridge Impl +/// - RebasableToken(stETH) Impl and Proxy (because it was never deployed before) +/// - Non-rebasable token (wstETH) new Impl with Permissions +export default function deploymentNewImplementations( + networkName: NetworkName, + options: OptDeploymentOptions = {} +) { + const optAddresses = addresses(networkName, options); + return { + async deployScript( + l1Params: OptL1DeployScriptParams, + l2Params: OptL2DeployScriptParams, + ): Promise<[BridgeL1DeployScript, BridgeL2DeployScript]> { + + const [ + expectedL1TokenBridgeImplAddress, + ] = await network.predictAddresses(l1Params.deployer, l1Params.contractsShift + 1); + + const [ + expectedL2TokenImplAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + expectedL2TokenBridgeImplAddress, + expectedL2TokenRateOracleImplAddress + ] = await network.predictAddresses(l2Params.deployer, l2Params.contractsShift + 5); + + const l1DeployScript = new BridgeL1DeployScript( + l1Params.deployer, + expectedL1TokenBridgeImplAddress, + options?.logger + ) + .addStep({ + factory: L1LidoTokensBridge__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l2Params.tokenBridgeProxyAddress, + l1Params.tokenProxyAddress, + l1Params.tokenRebasableProxyAddress, + l2Params.tokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenBridgeImplAddress), + }); + + const l1TokenInfo = IERC20Metadata__factory.connect( + l1Params.tokenProxyAddress, + l1Params.deployer + ); + + const l1TokenRebasableInfo = IERC20Metadata__factory.connect( + l1Params.tokenRebasableProxyAddress, + l1Params.deployer + ); + const [decimals, l2TokenName, l2TokenSymbol, l2TokenRebasableName, l2TokenRebasableSymbol] = await Promise.all([ + l1TokenInfo.decimals(), + l2Params.token?.name ?? l1TokenInfo.name(), + l2Params.token?.symbol ?? l1TokenInfo.symbol(), + l2Params.tokenRebasable?.name ?? l1TokenRebasableInfo.name(), + l2Params.tokenRebasable?.symbol ?? l1TokenRebasableInfo.symbol(), + ]); + + const l2DeployScript = new BridgeL2DeployScript( + l2Params.deployer, + expectedL2TokenImplAddress, + expectedL2TokenRebasableImplAddress, + expectedL2TokenRebasableProxyAddress, + expectedL2TokenBridgeImplAddress, + expectedL2TokenRateOracleImplAddress, + options?.logger + ) + .addStep({ + factory: ERC20Bridged__factory, + args: [ + l2TokenName, + l2TokenSymbol, + decimals, + l2Params.tokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenImplAddress), + }) + .addStep({ + factory: ERC20Rebasable__factory, + args: [ + l2TokenRebasableName, + l2TokenRebasableSymbol, + decimals, + l2Params.tokenProxyAddress, + l2Params.tokenRateOracleProxyAddress, + l2Params.tokenBridgeProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRebasableImplAddress, + l2Params.admins.proxy, + ERC20Rebasable__factory.createInterface().encodeFunctionData( + "initialize", + [l2TokenRebasableName, l2TokenRebasableSymbol] + ), + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRebasableProxyAddress), + }) + .addStep({ + factory: L2ERC20TokenBridge__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + l1Params.tokenBridgeProxyAddress, + l1Params.tokenProxyAddress, + l1Params.tokenRebasableProxyAddress, + l2Params.tokenProxyAddress, + expectedL2TokenRebasableProxyAddress, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenBridgeImplAddress), + }) + .addStep({ + factory: TokenRateOracle__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + l2Params.tokenBridgeProxyAddress, + l1Params.opStackTokenRatePusherImplAddress, + l2Params.tokenRateOracleRateOutdatedDelay, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }); + + return [l1DeployScript as BridgeL1DeployScript, l2DeployScript as BridgeL2DeployScript]; + }, + }; +} diff --git a/utils/optimism/deploymentOracle.ts b/utils/optimism/deploymentOracle.ts index ec28c82..002a923 100644 --- a/utils/optimism/deploymentOracle.ts +++ b/utils/optimism/deploymentOracle.ts @@ -1,8 +1,8 @@ import { assert } from "chai"; -import { Overrides, Wallet } from "ethers"; +import { Wallet } from "ethers"; import { ethers } from "hardhat"; import addresses from "./addresses"; -import { CommonOptions } from "./types"; +import { DeployScriptParams, OptDeploymentOptions } from "./types"; import network, { NetworkName } from "../network"; import { DeployScript, Logger } from "../deployment/DeployScript"; import { @@ -10,20 +10,10 @@ import { TokenRateOracle__factory, TokenRateNotifier__factory, OpStackTokenRatePusher__factory - } from "../../typechain"; - -interface OptDeployScriptParams { - deployer: Wallet; - admins: { proxy: string; bridge: string }; -} - -interface OptDeploymentOptions extends CommonOptions { - logger?: Logger; - overrides?: Overrides; -} +} from "../../typechain"; +interface OptDeployScriptParams extends DeployScriptParams {} export class OracleL1DeployScript extends DeployScript { - constructor( deployer: Wallet, tokenRateNotifierImplAddress: string, @@ -40,7 +30,6 @@ export class OracleL1DeployScript extends DeployScript { } export class OracleL2DeployScript extends DeployScript { - constructor( deployer: Wallet, tokenRateOracleImplAddress: string, @@ -50,7 +39,7 @@ export class OracleL2DeployScript extends DeployScript { super(deployer, logger); this.tokenRateOracleImplAddress = tokenRateOracleImplAddress; this.tokenRateOracleProxyAddress = tokenRateOracleProxyAddress; - } + } public tokenRateOracleImplAddress: string; public tokenRateOracleProxyAddress: string; @@ -59,83 +48,85 @@ export class OracleL2DeployScript extends DeployScript { export default function deploymentOracle( networkName: NetworkName, options: OptDeploymentOptions = {} - ) { +) { const optAddresses = addresses(networkName, options); return { - async oracleDeployScript( - l1Token: string, - l1Params: OptDeployScriptParams, - l2Params: OptDeployScriptParams, - ): Promise<[OracleL1DeployScript, OracleL2DeployScript]> { + async oracleDeployScript( + l1Token: string, + l2GasLimitForPushingTokenRate: number, + rateOutdatedDelay: number, + l1Params: OptDeployScriptParams, + l2Params: OptDeployScriptParams, + ): Promise<[OracleL1DeployScript, OracleL2DeployScript]> { - const [ - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - ] = await network.predictAddresses(l1Params.deployer, 2); + const [ + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + ] = await network.predictAddresses(l1Params.deployer, 2); - const [ - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress - ] = await network.predictAddresses(l2Params.deployer, 2); + const [ + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress + ] = await network.predictAddresses(l2Params.deployer, 2); - const l1DeployScript = new OracleL1DeployScript( - l1Params.deployer, - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - options?.logger - ) - .addStep({ - factory: TokenRateNotifier__factory, - args: [ - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), - }) - .addStep({ - factory: OpStackTokenRatePusher__factory, - args: [ - optAddresses.L1CrossDomainMessenger, - l1Token, - expectedL2TokenRateOracleProxyAddress, - 1000, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), - }); + const l1DeployScript = new OracleL1DeployScript( + l1Params.deployer, + expectedL1TokenRateNotifierImplAddress, + expectedL1OpStackTokenRatePusherImplAddress, + options?.logger + ) + .addStep({ + factory: TokenRateNotifier__factory, + args: [ + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), + }) + .addStep({ + factory: OpStackTokenRatePusher__factory, + args: [ + optAddresses.L1CrossDomainMessenger, + l1Token, + expectedL2TokenRateOracleProxyAddress, + l2GasLimitForPushingTokenRate, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), + }); - const l2DeployScript = new OracleL2DeployScript( - l2Params.deployer, - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress, - options?.logger - ) - .addStep({ - factory: TokenRateOracle__factory, - args: [ - optAddresses.L2CrossDomainMessenger, - ethers.constants.AddressZero, - expectedL1OpStackTokenRatePusherImplAddress, - 86400, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenRateOracleImplAddress, - l2Params.admins.proxy, - [], - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), - }); + const l2DeployScript = new OracleL2DeployScript( + l2Params.deployer, + expectedL2TokenRateOracleImplAddress, + expectedL2TokenRateOracleProxyAddress, + options?.logger + ) + .addStep({ + factory: TokenRateOracle__factory, + args: [ + optAddresses.L2CrossDomainMessenger, + ethers.constants.AddressZero, + expectedL1OpStackTokenRatePusherImplAddress, + rateOutdatedDelay, + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleImplAddress), + }) + .addStep({ + factory: OssifiableProxy__factory, + args: [ + expectedL2TokenRateOracleImplAddress, + l2Params.admins.proxy, + [], + options?.overrides, + ], + afterDeploy: (c) => + assert.equal(c.address, expectedL2TokenRateOracleProxyAddress), + }); - return [l1DeployScript as OracleL1DeployScript, l2DeployScript as OracleL2DeployScript]; - }, + return [l1DeployScript as OracleL1DeployScript, l2DeployScript as OracleL2DeployScript]; + }, }; - } +} diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index a0cd514..e7848ef 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -18,7 +18,7 @@ import { } from "../../typechain"; import addresses from "./addresses"; import contracts from "./contracts"; -import deploymentAll from "./deploymentAll"; +import deploymentAll from "./deploymentAllFromScratch"; import testingUtils from "../testing"; import { BridgingManagement } from "../bridging-management"; import network, { NetworkName, SignerOrProvider } from "../network"; @@ -199,7 +199,7 @@ async function deployTestBridge( const [ethDeployScript, optDeployScript] = await deploymentAll( networkName - ).erc20TokenBridgeDeployScript( + ).deployAllScript( l1Token.address, l1TokenRebasable.address, { diff --git a/utils/optimism/types.ts b/utils/optimism/types.ts index 38cea94..461be4c 100644 --- a/utils/optimism/types.ts +++ b/utils/optimism/types.ts @@ -1,3 +1,6 @@ +import { Overrides, Wallet } from "ethers"; +import { Logger } from "../deployment/DeployScript"; + export type OptContractNames = | "L1CrossDomainMessenger" | "L2CrossDomainMessenger"; @@ -7,3 +10,17 @@ export type CustomOptContractAddresses = Partial; export interface CommonOptions { customAddresses?: CustomOptContractAddresses; } + +export interface DeployScriptParams { + deployer: Wallet; + admins: { + proxy: string; + bridge: string + }; + contractsShift: number; +} + +export interface OptDeploymentOptions extends CommonOptions { + logger?: Logger; + overrides?: Overrides; +} diff --git a/utils/optimism/upgradeOracle.ts b/utils/optimism/upgradeOracle.ts deleted file mode 100644 index 17fd0b2..0000000 --- a/utils/optimism/upgradeOracle.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { - OssifiableProxy__factory, - OptimismBridgeExecutor__factory -} from "../../typechain"; - -import network, { NetworkName } from "../network"; -import testingUtils from "../testing"; -import contracts from "./contracts"; -import testing from "../../utils/testing"; -import optimism from "../../utils/optimism"; -import { getBridgeExecutorParams } from "../../utils/bridge-executor"; - -export async function upgradeOracle( - networkName: NetworkName, - oracleProxyAddress: string, - newOracleAddress: string - ) { - const ethOptNetworks = network.multichain(["eth", "opt"], networkName); - const [ - ethProvider, - optProvider - ] = ethOptNetworks.getProviders({ forking: true }); - const ethDeployer = testing.accounts.deployer(ethProvider); - const optDeployer = testing.accounts.deployer(optProvider); - - - const optContracts = contracts(networkName, { forking: true }); - const l1CrossDomainMessengerAliased = await testingUtils.impersonate( - testingUtils.accounts.applyL1ToL2Alias(optContracts.L1CrossDomainMessenger.address), - optProvider - ); - const l2CrossDomainMessenger = await optContracts.L2CrossDomainMessenger.connect( - l1CrossDomainMessengerAliased - ); - - - const testingOnDeployedContracts = testing.env.USE_DEPLOYED_CONTRACTS(false); - const optAddresses = optimism.addresses(networkName); - const govBridgeExecutor = testingOnDeployedContracts - ? OptimismBridgeExecutor__factory.connect( - testing.env.OPT_GOV_BRIDGE_EXECUTOR(), - optProvider - ) - : await new OptimismBridgeExecutor__factory(optDeployer).deploy( - optAddresses.L2CrossDomainMessenger, - ethDeployer.address, - ...getBridgeExecutorParams(), - optDeployer.address - ); - - - const l1EthGovExecutorAddress = await govBridgeExecutor.getEthereumGovernanceExecutor(); - const bridgeExecutor = govBridgeExecutor.connect(optDeployer); - const l2OracleProxy = OssifiableProxy__factory.connect( - oracleProxyAddress, - optDeployer - ); - - await l2CrossDomainMessenger.relayMessage( - 0, - l1EthGovExecutorAddress, - bridgeExecutor.address, - 0, - 300_000, - bridgeExecutor.interface.encodeFunctionData("queue", [ - [oracleProxyAddress], - [0], - ["proxy__upgradeTo(address)"], - [ - "0x" + - l2OracleProxy.interface - .encodeFunctionData("proxy__upgradeTo", [newOracleAddress]) - .substring(10), - ], - [false], - ]), - { gasLimit: 5_000_000 } - ); -}