From 12333ef11a9d374b62a49ecde0af3db3488a3162 Mon Sep 17 00:00:00 2001 From: Anton Kovalchuk Date: Fri, 14 Jun 2024 17:14:04 +0200 Subject: [PATCH] add permission to handle toekn rate report by token rate notifier --- contracts/lido/TokenRateNotifier.sol | 15 +- scripts/optimism/deploy-bridge.ts | 83 ----- scripts/optimism/deploy-scratch.ts | 5 +- test/optimism/TokenRateNotifier.unit.test.ts | 60 ++- .../pushingTokenRate.integration.test.ts | 16 +- utils/deployment.ts | 2 + utils/optimism/deployment.ts | 2 + utils/optimism/deploymentAllFromScratch.ts | 346 ------------------ utils/optimism/deploymentOracle.ts | 5 +- utils/optimism/testing.ts | 1 + utils/optimism/upgrade.ts | 2 + 11 files changed, 82 insertions(+), 455 deletions(-) delete mode 100644 scripts/optimism/deploy-bridge.ts delete mode 100644 utils/optimism/deploymentAllFromScratch.ts diff --git a/contracts/lido/TokenRateNotifier.sol b/contracts/lido/TokenRateNotifier.sol index 587bb45d..96f1c718 100644 --- a/contracts/lido/TokenRateNotifier.sol +++ b/contracts/lido/TokenRateNotifier.sol @@ -27,6 +27,9 @@ interface IPostTokenRebaseReceiver { contract TokenRateNotifier is Ownable, IPostTokenRebaseReceiver { using ERC165Checker for address; + /// @notice Address of the contract that is allowed to call handlePostTokenRebase. + address public immutable AUTHORIZED_REBASE_CALLER; + /// @notice Maximum amount of observers to be supported. uint256 public constant MAX_OBSERVERS_COUNT = 32; @@ -40,11 +43,16 @@ contract TokenRateNotifier is Ownable, IPostTokenRebaseReceiver { address[] public observers; /// @param initialOwner_ initial owner - constructor(address initialOwner_) { + /// @param authorizedRebaseCaller_ Address of the contract that is allowed to call handlePostTokenRebase. + constructor(address initialOwner_, address authorizedRebaseCaller_) { if (initialOwner_ == address(0)) { revert ErrorZeroAddressOwner(); } + if (authorizedRebaseCaller_ == address(0)) { + revert ErrorZeroAddressCaller(); + } _transferOwnership(initialOwner_); + AUTHORIZED_REBASE_CALLER = authorizedRebaseCaller_; } /// @notice Add a `observer_` to the back of array @@ -94,6 +102,9 @@ contract TokenRateNotifier is Ownable, IPostTokenRebaseReceiver { uint256, /* postTotalEther */ uint256 /* sharesMintedAsFees */ ) external { + if (msg.sender != AUTHORIZED_REBASE_CALLER) { + revert ErrorNotAuthorizedRebaseCaller(); + } uint256 cachedObserversLength = observers.length; for (uint256 obIndex = 0; obIndex < cachedObserversLength; obIndex++) { // solhint-disable-next-line no-empty-blocks @@ -141,5 +152,7 @@ contract TokenRateNotifier is Ownable, IPostTokenRebaseReceiver { error ErrorMaxObserversCountExceeded(); error ErrorNoObserverToRemove(); error ErrorZeroAddressOwner(); + error ErrorZeroAddressCaller(); + error ErrorNotAuthorizedRebaseCaller(); error ErrorAddExistedObserver(); } diff --git a/scripts/optimism/deploy-bridge.ts b/scripts/optimism/deploy-bridge.ts deleted file mode 100644 index 57538f49..00000000 --- a/scripts/optimism/deploy-bridge.ts +++ /dev/null @@ -1,83 +0,0 @@ -import env from "../../utils/env"; -import prompt from "../../utils/prompt"; -import network from "../../utils/network"; -import optimism from "../../utils/optimism"; -import deployment from "../../utils/deployment"; -import { BridgingManagement } from "../../utils/bridging-management"; - -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 optimism - .deployment(networkName, { logger: console }) - .erc20TokenBridgeDeployScript( - deploymentConfig.l1Token, - deploymentConfig.l1RebasableToken, - deploymentConfig.l2TokenRateOracle, - { - 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 deployment.printMultiChainDeploymentConfig( - "Deploy Optimism Bridge", - ethDeployer, - optDeployer, - deploymentConfig, - l1DeployScript, - l2DeployScript - ); - - await prompt.proceed(); - - await l1DeployScript.run(); - await l2DeployScript.run(); - - const l1ERC20ExtendedTokensBridgeProxyDeployStepIndex = 1; - const l1BridgingManagement = new BridgingManagement( - l1DeployScript.getContractAddress(l1ERC20ExtendedTokensBridgeProxyDeployStepIndex), - ethDeployer, - { logger: console } - ); - - const l2ERC20ExtendedTokensBridgeProxyDeployStepIndex = 5; - const l2BridgingManagement = new BridgingManagement( - l2DeployScript.getContractAddress(l2ERC20ExtendedTokensBridgeProxyDeployStepIndex), - optDeployer, - { logger: console } - ); - - await l1BridgingManagement.setup(deploymentConfig.l1); - await l2BridgingManagement.setup(deploymentConfig.l2); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/optimism/deploy-scratch.ts b/scripts/optimism/deploy-scratch.ts index 165155ec..3583379f 100644 --- a/scripts/optimism/deploy-scratch.ts +++ b/scripts/optimism/deploy-scratch.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 deploymentAllFromScratch from "../../utils/optimism/deployment"; +import deploymentAll from "../../utils/optimism/deployment"; async function main() { const networkName = env.network(); @@ -21,13 +21,14 @@ async function main() { const deploymentConfig = deployment.loadMultiChainDeploymentConfig(); - const [l1DeployScript, l2DeployScript] = await deploymentAllFromScratch (networkName, { logger: console }) + const [l1DeployScript, l2DeployScript] = await deploymentAll (networkName, { logger: console }) .deployAllScript( { l1TokenNonRebasable: deploymentConfig.l1TokenNonRebasable, l1TokenRebasable: deploymentConfig.l1RebasableToken, accountingOracle: deploymentConfig.accountingOracle, l2GasLimitForPushingTokenRate: deploymentConfig.l2GasLimitForPushingTokenRate, + l1AuthorizedRebaseCaller: deploymentConfig.l1AuthorizedRebaseCaller, deployer: ethDeployer, admins: { diff --git a/test/optimism/TokenRateNotifier.unit.test.ts b/test/optimism/TokenRateNotifier.unit.test.ts index cd19b9aa..e0d7b38b 100644 --- a/test/optimism/TokenRateNotifier.unit.test.ts +++ b/test/optimism/TokenRateNotifier.unit.test.ts @@ -21,14 +21,23 @@ import { unit("TokenRateNotifier", ctxFactory) .test("deploy with zero address owner", async (ctx) => { - const { deployer } = ctx.accounts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; await assert.revertsWith( - new TokenRateNotifier__factory(deployer).deploy(ethers.constants.AddressZero), + new TokenRateNotifier__factory(deployer).deploy(ethers.constants.AddressZero, l1AuthorizedRebaseCaller.address), "ErrorZeroAddressOwner()" ); }) + .test("deploy with zero address rebase caller", async (ctx) => { + const { deployer } = ctx.accounts; + + await assert.revertsWith( + new TokenRateNotifier__factory(deployer).deploy(deployer.address, ethers.constants.AddressZero), + "ErrorZeroAddressCaller()" + ); + }) + .test("initial state", async (ctx) => { const { tokenRateNotifier } = ctx.contracts; @@ -63,9 +72,9 @@ unit("TokenRateNotifier", ctxFactory) .test("addObserver() :: revert on adding observer with bad interface", async (ctx) => { const { tokenRateNotifier } = ctx.contracts; - const { deployer } = ctx.accounts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; - const observer = await new TokenRateNotifier__factory(deployer).deploy(deployer.address); + const observer = await new TokenRateNotifier__factory(deployer).deploy(deployer.address, l1AuthorizedRebaseCaller.address); await assert.revertsWith( tokenRateNotifier .connect(ctx.accounts.owner) @@ -76,7 +85,7 @@ unit("TokenRateNotifier", ctxFactory) .test("addObserver() :: revert on adding too many observers", async (ctx) => { const { tokenRateNotifier, opStackTokenRatePusher } = ctx.contracts; - const { deployer, owner, tokenRateOracle } = ctx.accounts; + const { deployer, owner, tokenRateOracle, l1AuthorizedRebaseCaller } = ctx.accounts; const { l2GasLimitForPushingTokenRate, tokenRate, totalPooledEther, totalShares, genesisTime, secondsPerSlot, lastProcessingRefSlot } = ctx.constants; assert.equalBN(await tokenRateNotifier.observersLength(), 0); @@ -95,7 +104,8 @@ unit("TokenRateNotifier", ctxFactory) deployer, owner, tokenRateOracle, - l2GasLimitForPushingTokenRate + l2GasLimitForPushingTokenRate, + l1AuthorizedRebaseCaller ); await tokenRateNotifier @@ -183,23 +193,33 @@ unit("TokenRateNotifier", ctxFactory) assert.equalBN(await tokenRateNotifier.observersLength(), 0); }) + .test("handlePostTokenRebase() :: unauthorized caller", async (ctx) => { + const { tokenRateNotifier } = ctx.contracts; + const { stranger } = ctx.accounts; + + await assert.revertsWith( + tokenRateNotifier.connect(stranger).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7), + "ErrorNotAuthorizedRebaseCaller()" + ); + }) + .test("handlePostTokenRebase() :: failed with some error", async (ctx) => { const { tokenRateNotifier } = ctx.contracts; - const { deployer } = ctx.accounts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; const observer = await new OpStackTokenRatePusherWithSomeErrorStub__factory(deployer).deploy(); await tokenRateNotifier .connect(ctx.accounts.owner) .addObserver(observer.address); - const tx = await tokenRateNotifier.handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); + const tx = await tokenRateNotifier.connect(l1AuthorizedRebaseCaller).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); await assert.emits(tokenRateNotifier, tx, "PushTokenRateFailed", [observer.address, "0x332e27d2"]); }) .test("handlePostTokenRebase() :: revert when observer has out of gas error", async (ctx) => { const { tokenRateNotifier } = ctx.contracts; - const { deployer } = ctx.accounts; + const { deployer, l1AuthorizedRebaseCaller } = ctx.accounts; const observer = await new OpStackTokenRatePusherWithOutOfGasErrorStub__factory(deployer).deploy(); await tokenRateNotifier @@ -207,7 +227,7 @@ unit("TokenRateNotifier", ctxFactory) .addObserver(observer.address); await assert.revertsWith( - tokenRateNotifier.handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7), + tokenRateNotifier.connect(l1AuthorizedRebaseCaller).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7), "ErrorTokenRateNotifierRevertedWithNoData()" ); }) @@ -218,7 +238,7 @@ unit("TokenRateNotifier", ctxFactory) l1MessengerStub, opStackTokenRatePusher } = ctx.contracts; - const { tokenRateOracle } = ctx.accounts; + const { tokenRateOracle, l1AuthorizedRebaseCaller } = ctx.accounts; const { l2GasLimitForPushingTokenRate, tokenRate, genesisTime, secondsPerSlot, lastProcessingRefSlot } = ctx.constants; const updateRateTime = genesisTime.add(secondsPerSlot.mul(lastProcessingRefSlot)); @@ -226,7 +246,7 @@ unit("TokenRateNotifier", ctxFactory) await tokenRateNotifier .connect(ctx.accounts.owner) .addObserver(opStackTokenRatePusher.address); - let tx = await tokenRateNotifier.handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); + let tx = await tokenRateNotifier.connect(l1AuthorizedRebaseCaller).handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); await assert.emits(l1MessengerStub, tx, "SentMessage", [ tokenRateOracle.address, @@ -246,7 +266,7 @@ unit("TokenRateNotifier", ctxFactory) .run(); async function ctxFactory() { - const [deployer, owner, stranger, tokenRateOracle] = await ethers.getSigners(); + const [deployer, owner, stranger, tokenRateOracle, l1AuthorizedRebaseCaller] = await ethers.getSigners(); const totalPooledEther = BigNumber.from('9309904612343950493629678'); const totalShares = BigNumber.from('7975822843597609202337218'); const tokenRateDecimals = BigNumber.from(27); @@ -270,7 +290,8 @@ async function ctxFactory() { deployer, owner, tokenRateOracle, - l2GasLimitForPushingTokenRate + l2GasLimitForPushingTokenRate, + l1AuthorizedRebaseCaller ); return { @@ -278,7 +299,8 @@ async function ctxFactory() { deployer, owner, stranger, - tokenRateOracle + tokenRateOracle, + l1AuthorizedRebaseCaller }, contracts: { tokenRateNotifier, @@ -307,9 +329,13 @@ async function createContracts( deployer: SignerWithAddress, owner: SignerWithAddress, tokenRateOracle: SignerWithAddress, - l2GasLimitForPushingTokenRate: number) { + l2GasLimitForPushingTokenRate: number, + l1AuthorizedRebaseCaller: SignerWithAddress) { - const tokenRateNotifier = await new TokenRateNotifier__factory(deployer).deploy(owner.address); + const tokenRateNotifier = await new TokenRateNotifier__factory(deployer).deploy( + owner.address, + l1AuthorizedRebaseCaller.address + ); const l1MessengerStub = await new CrossDomainMessengerStub__factory(deployer) .deploy({ value: wei.toBigNumber(wei`1 ether`) }); diff --git a/test/optimism/pushingTokenRate.integration.test.ts b/test/optimism/pushingTokenRate.integration.test.ts index cab7d3da..cf6fc902 100644 --- a/test/optimism/pushingTokenRate.integration.test.ts +++ b/test/optimism/pushingTokenRate.integration.test.ts @@ -16,7 +16,8 @@ import { OptimismBridgeExecutor__factory, TokenRateNotifier__factory, TokenRateOracle__factory, - AccountingOracleStub__factory + AccountingOracleStub__factory, + EmptyContractStub__factory } from "../../typechain"; scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) @@ -30,13 +31,12 @@ scenario("Optimism :: Token Rate Oracle integration test", ctxFactory) genesisTime, secondsPerSlot, lastProcessingRefSlot, - tokenRate + tokenRate, + l1AuthorizedRebaseCaller } = ctx; - const account = ctx.accounts.accountA; - const tx = await tokenRateNotifier - .connect(account.l1Signer) + .connect(l1AuthorizedRebaseCaller) .handlePostTokenRebase(1, 2, 3, 4, 5, 6, 7); const messageNonce = await l1CrossDomainMessenger.messageNonce(); @@ -169,6 +169,10 @@ async function ctxFactory() { const [l2ERC20TokenBridge] = await hre.ethers.getSigners(); + const l1AuthorizedRebaseCaller = await new EmptyContractStub__factory(l1Deployer).deploy({ value: 10000000 }); + const l1AuthorizedRebaseCallerAsEOA = await testing.impersonate(l1AuthorizedRebaseCaller.address); + await testing.setBalance(l1AuthorizedRebaseCaller.address, wei.toBigNumber(wei`1 ether`)); + const [ethDeployScript, optDeployScript] = await deploymentOracle( networkName ).oracleDeployScript( @@ -178,6 +182,7 @@ async function ctxFactory() { l2GasLimitForPushingTokenRate, tokenRateOutdatedDelay, { + l1AuthorizedRebaseCaller: l1AuthorizedRebaseCaller.address, deployer: l1Deployer, admins: { proxy: l1Deployer.address, @@ -245,6 +250,7 @@ async function ctxFactory() { blockTimestamp, tokenRate, genesisTime, secondsPerSlot, lastProcessingRefSlot, + l1AuthorizedRebaseCaller: l1AuthorizedRebaseCallerAsEOA, accounts: { accountA, l1CrossDomainMessengerAliased diff --git a/utils/deployment.ts b/utils/deployment.ts index d9fc7406..58021774 100644 --- a/utils/deployment.ts +++ b/utils/deployment.ts @@ -16,6 +16,7 @@ interface MultiChainDeploymentConfig { accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; l1TokenBridge: string; + l1AuthorizedRebaseCaller: string; /// L2 /// Oracle @@ -46,6 +47,7 @@ export function loadMultiChainDeploymentConfig(): MultiChainDeploymentConfig { accountingOracle: env.address("ACCOUNTING_ORACLE"), l2GasLimitForPushingTokenRate: BigNumber.from(env.string("L2_GAS_LIMIT_FOR_PUSHING_TOKEN_RATE")), l1TokenBridge: env.address("L1_TOKEN_BRIDGE"), + l1AuthorizedRebaseCaller: env.address("L1_AUTHORIZED_REBASE_CALLER"), /// L2 Part /// TokenRateOracle diff --git a/utils/optimism/deployment.ts b/utils/optimism/deployment.ts index 3464ed08..c652cdda 100644 --- a/utils/optimism/deployment.ts +++ b/utils/optimism/deployment.ts @@ -21,6 +21,7 @@ interface OptL1DeployScriptParams extends DeployScriptParams { l1TokenRebasable: string; accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; + l1AuthorizedRebaseCaller: string; } interface OptL2DeployScriptParams extends DeployScriptParams { @@ -185,6 +186,7 @@ export default function deploymentAll( factory: TokenRateNotifier__factory, args: [ l1Params.deployer.address, + l1Params.l1AuthorizedRebaseCaller, options?.overrides, ], afterDeploy: (c) => diff --git a/utils/optimism/deploymentAllFromScratch.ts b/utils/optimism/deploymentAllFromScratch.ts deleted file mode 100644 index 39457f3e..00000000 --- a/utils/optimism/deploymentAllFromScratch.ts +++ /dev/null @@ -1,346 +0,0 @@ -import { assert } from "chai"; -import { BigNumber, Wallet } from "ethers"; -import addresses from "./addresses"; -import { OptDeploymentOptions, DeployScriptParams } from "./types"; -import network, { NetworkName } from "../network"; -import { DeployScript, Logger } from "../deployment/DeployScript"; -import { - ERC20BridgedPermit__factory, - ERC20RebasableBridgedPermit__factory, - IERC20Metadata__factory, - L1LidoTokensBridge__factory, - L2ERC20ExtendedTokensBridge__factory, - OssifiableProxy__factory, - TokenRateOracle__factory, - TokenRateNotifier__factory, - OpStackTokenRatePusher__factory -} from "../../typechain"; - -interface OptL1DeployScriptParams extends DeployScriptParams { - l1Token: string; - l1TokenRebasable: string; - accountingOracle: string; - l2GasLimitForPushingTokenRate: number; -} -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; - maxAllowedTimeBetweenTokenRateUpdates: 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( - networkName: NetworkName, - options: OptDeploymentOptions = {} -) { - const optAddresses = addresses(networkName, options); - return { - async deployAllScript( - l1Params: OptL1DeployScriptParams, - l2Params: OptL2DeployScriptParams, - ): Promise<[L1DeployAllScript, L2DeployAllScript]> { - - const [ - expectedL1TokenBridgeImplAddress, - expectedL1TokenBridgeProxyAddress, - expectedL1TokenRateNotifierImplAddress, - expectedL1OpStackTokenRatePusherImplAddress, - ] = await network.predictAddresses(l1Params.deployer, l1Params.contractsShift + 4); - - const [ - expectedL2TokenRateOracleImplAddress, - expectedL2TokenRateOracleProxyAddress, - expectedL2TokenImplAddress, - expectedL2TokenProxyAddress, - expectedL2TokenRebasableImplAddress, - expectedL2TokenRebasableProxyAddress, - expectedL2TokenBridgeImplAddress, - expectedL2TokenBridgeProxyAddress - ] = 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, - l1Params.l1Token, - 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.deployer.address, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1TokenRateNotifierImplAddress), - }) - .addStep({ - factory: OpStackTokenRatePusher__factory, - args: [ - optAddresses.L1CrossDomainMessenger, - l1Params.l1Token, - l1Params.accountingOracle, - expectedL2TokenRateOracleProxyAddress, - l1Params.l2GasLimitForPushingTokenRate, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL1OpStackTokenRatePusherImplAddress), - }); - - 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.maxAllowedTimeBetweenTokenRateUpdates, - 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: [ - l2Params.l2TokenNonRebasable.name, - l2Params.l2TokenNonRebasable.symbol, - l2Params.l2TokenNonRebasable.version, - l2Params.l2TokenNonRebasable.decimals, - expectedL2TokenBridgeProxyAddress, - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenImplAddress), - }) - .addStep({ - factory: OssifiableProxy__factory, - args: [ - expectedL2TokenImplAddress, - l2Params.admins.proxy, - ERC20BridgedPermit__factory.createInterface().encodeFunctionData( - "initialize", - [ - l2Params.l2TokenNonRebasable.name, - l2Params.l2TokenNonRebasable.symbol, - l2Params.l2TokenNonRebasable.version - ] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenProxyAddress), - }) - .addStep({ - factory: ERC20RebasableBridgedPermit__factory, - args: [ - l2Params.l2TokenRebasable.name, - l2Params.l2TokenRebasable.symbol, - l2Params.l2TokenRebasable.version, - l2Params.l2TokenRebasable.decimals, - 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", - [ - l2Params.l2TokenRebasable.name, - l2Params.l2TokenRebasable.symbol, - l2Params.l2TokenRebasable.version - ] - ), - options?.overrides, - ], - afterDeploy: (c) => - assert.equal(c.address, expectedL2TokenRebasableProxyAddress), - }) - .addStep({ - factory: L2ERC20ExtendedTokensBridge__factory, - args: [ - optAddresses.L2CrossDomainMessenger, - expectedL1TokenBridgeProxyAddress, - l1Params.l1Token, - 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]; - }, - }; -} diff --git a/utils/optimism/deploymentOracle.ts b/utils/optimism/deploymentOracle.ts index d715ddfe..ad2fa31d 100644 --- a/utils/optimism/deploymentOracle.ts +++ b/utils/optimism/deploymentOracle.ts @@ -12,7 +12,9 @@ import { OpStackTokenRatePusher__factory } from "../../typechain"; -interface OptDeployScriptParams extends DeployScriptParams { } +interface OptDeployScriptParams extends DeployScriptParams { + l1AuthorizedRebaseCaller: string; +} interface OptL2DeployScriptParams extends DeployScriptParams { tokenRateOracle: { @@ -99,6 +101,7 @@ export default function deploymentOracle( factory: TokenRateNotifier__factory, args: [ l1Params.deployer.address, + l1Params.l1AuthorizedRebaseCaller, options?.overrides, ], afterDeploy: (c) => diff --git a/utils/optimism/testing.ts b/utils/optimism/testing.ts index f27e1f8b..6f38f783 100644 --- a/utils/optimism/testing.ts +++ b/utils/optimism/testing.ts @@ -236,6 +236,7 @@ async function deployTestBridge( l1TokenRebasable: l1TokenRebasable.address, accountingOracle: accountingOracle.address, l2GasLimitForPushingTokenRate: BigNumber.from(300_000), + l1AuthorizedRebaseCaller: ethDeployer.address, deployer: ethDeployer, admins: { proxy: ethDeployer.address, bridge: ethDeployer.address }, contractsShift: 0 diff --git a/utils/optimism/upgrade.ts b/utils/optimism/upgrade.ts index a01cb864..ceea1f87 100644 --- a/utils/optimism/upgrade.ts +++ b/utils/optimism/upgrade.ts @@ -22,6 +22,7 @@ interface OptL1UpgradeScriptParams extends DeployScriptParams { accountingOracle: string; l2GasLimitForPushingTokenRate: BigNumber; l1TokenBridge: string; + l1AuthorizedRebaseCaller: string; } interface OptL2UpgradeScriptParams extends DeployScriptParams { @@ -177,6 +178,7 @@ export default function upgrade( factory: TokenRateNotifier__factory, args: [ l1Params.deployer.address, + l1Params.l1AuthorizedRebaseCaller, options?.overrides, ], afterDeploy: (c) =>