diff --git a/src/libraries/RevShareGasLimits.sol b/src/libraries/RevShareGasLimits.sol new file mode 100644 index 0000000000..7fb692e4b0 --- /dev/null +++ b/src/libraries/RevShareGasLimits.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +/// @notice Library for storing the gas limits for the calls done in the Revenue Share templates +library RevShareGasLimits { + /// @notice Based on deployment tests, these are the average gas costs for each of the L2 operations: + /// - L1Withdrawer deployment: 497,812 + /// - SC Rev Share Calculator deployment: 518,168 + /// - Fee Vaults deployment: 757,214 + /// - Fee Splitter deployment: 1,027,359 + /// - upgradeAndCall: 73,015 + /// - upgrade: 6,202 + /// - setters: TODO: add this after simulating in tenderly + /// A buffer of ~20% is applied to each value to have enough margin. While leaving the upgrade call + /// to a fixed 150,000 gas limit. + + /// @notice The gas limit for the SC Rev Share Calculator deployment. + uint64 internal constant SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT = 625_000; + + /// @notice The gas limit for the L1 Withdrawer deployment. + uint64 internal constant L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT = 625_000; + + /// @notice The gas limit for the Fee Vaults deployment. + uint64 internal constant FEE_VAULTS_DEPLOYMENT_GAS_LIMIT = 910_000; + + /// @notice The gas limit for the Fee Splitter deployment. + uint64 internal constant FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT = 1_235_000; + + /// @notice The gas limit for the upgrade calls on L2. + uint64 internal constant UPGRADE_GAS_LIMIT = 150_000; + + /// @notice The gas limit for the Fee Vaults deployment. + uint64 internal constant SETTERS_GAS_LIMIT = 50_000; +} diff --git a/src/template/LateOptInRevenueShare.sol b/src/template/LateOptInRevenueShare.sol index c41fad67df..79e42aaaae 100644 --- a/src/template/LateOptInRevenueShare.sol +++ b/src/template/LateOptInRevenueShare.sol @@ -10,6 +10,7 @@ import {Action} from "src/libraries/MultisigTypes.sol"; import {RevShareCodeRepo} from "src/libraries/RevShareCodeRepo.sol"; import {Utils} from "src/libraries/Utils.sol"; import {MultisigTaskPrinter} from "src/libraries/MultisigTaskPrinter.sol"; +import {RevShareGasLimits} from "src/libraries/RevShareGasLimits.sol"; /// @notice Interface for the OptimismPortal2 in L1. This is the main interaction point for the template. interface IOptimismPortal2 { @@ -133,11 +134,6 @@ contract LateOptInRevenueShare is SimpleTaskBase { useOwnCalculator = _toml.readBool(".useOwnCalculator"); - uint256 _gasLimitRaw = _toml.readUint(".gasLimit"); - require(_gasLimitRaw > 0, "gasLimit must be set"); - require(_gasLimitRaw <= type(uint64).max, "gasLimit must be less than uint64.max"); - gasLimit = uint64(_gasLimitRaw); - if (useOwnCalculator) { calculator = _toml.readAddress(".calculator"); require( @@ -150,7 +146,7 @@ contract LateOptInRevenueShare is SimpleTaskBase { ( address(FEE_SPLITTER), 0, - gasLimit, + RevShareGasLimits.SETTERS_GAS_LIMIT, false, abi.encodeCall(IFeeSplitter.setSharesCalculator, (calculator)) ) @@ -183,7 +179,13 @@ contract LateOptInRevenueShare is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, gasLimit, false, _l1WithdrawerCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, + false, + _l1WithdrawerCalldata + ) ) ); @@ -205,7 +207,13 @@ contract LateOptInRevenueShare is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, gasLimit, false, _scRevShareCalculatorCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, + false, + _scRevShareCalculatorCalldata + ) ) ); } @@ -223,7 +231,7 @@ contract LateOptInRevenueShare is SimpleTaskBase { ( address(FEE_SPLITTER), 0, - gasLimit, + RevShareGasLimits.SETTERS_GAS_LIMIT, false, abi.encodeCall(IFeeSplitter.setSharesCalculator, (calculator)) ) @@ -235,12 +243,20 @@ contract LateOptInRevenueShare is SimpleTaskBase { if (!useOwnCalculator) { // Deploy L1 Withdrawer IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, gasLimit, false, _l1WithdrawerCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, + false, + _l1WithdrawerCalldata ); // Deploy SC Rev Share Calculator IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, gasLimit, false, _scRevShareCalculatorCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, + false, + _scRevShareCalculatorCalldata ); } @@ -265,7 +281,7 @@ contract LateOptInRevenueShare is SimpleTaskBase { bytes memory _feeSplitterSetCalculatorCalldata = abi.encodeCall(IFeeSplitter.setSharesCalculator, (calculator)); IOptimismPortal2(payable(portal)).depositTransaction( - address(FEE_SPLITTER), 0, gasLimit, false, _feeSplitterSetCalculatorCalldata + address(FEE_SPLITTER), 0, RevShareGasLimits.SETTERS_GAS_LIMIT, false, _feeSplitterSetCalculatorCalldata ); } @@ -306,19 +322,21 @@ contract LateOptInRevenueShare is SimpleTaskBase { abi.encodeCall(IFeeVault.setMinWithdrawalAmount, (_minWithdrawalAmount)); IOptimismPortal2(payable(portal)).depositTransaction( - _vaultAddress, 0, gasLimit, false, _minWithdrawalAmountCalldata + _vaultAddress, 0, RevShareGasLimits.SETTERS_GAS_LIMIT, false, _minWithdrawalAmountCalldata ); // Set the recipient calldata bytes memory _recipientCalldata = abi.encodeCall(IFeeVault.setRecipient, (_recipient)); - IOptimismPortal2(payable(portal)).depositTransaction(_vaultAddress, 0, gasLimit, false, _recipientCalldata); + IOptimismPortal2(payable(portal)).depositTransaction( + _vaultAddress, 0, RevShareGasLimits.SETTERS_GAS_LIMIT, false, _recipientCalldata + ); // Set the withdrawal network calldata bytes memory _withdrawalNetworkCalldata = abi.encodeCall(IFeeVault.setWithdrawalNetwork, (_withdrawalNetwork)); IOptimismPortal2(payable(portal)).depositTransaction( - _vaultAddress, 0, gasLimit, false, _withdrawalNetworkCalldata + _vaultAddress, 0, RevShareGasLimits.SETTERS_GAS_LIMIT, false, _withdrawalNetworkCalldata ); } @@ -331,7 +349,7 @@ contract LateOptInRevenueShare is SimpleTaskBase { ( _vaultAddress, 0, - gasLimit, + RevShareGasLimits.SETTERS_GAS_LIMIT, false, abi.encodeCall(IFeeVault.setMinWithdrawalAmount, (FEE_VAULT_MIN_WITHDRAWAL_AMOUNT)) ) @@ -340,7 +358,13 @@ contract LateOptInRevenueShare is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (_vaultAddress, 0, gasLimit, false, abi.encodeCall(IFeeVault.setRecipient, (FEE_VAULT_RECIPIENT))) + ( + _vaultAddress, + 0, + RevShareGasLimits.SETTERS_GAS_LIMIT, + false, + abi.encodeCall(IFeeVault.setRecipient, (FEE_VAULT_RECIPIENT)) + ) ) ); _incrementCallsToPortal( @@ -349,7 +373,7 @@ contract LateOptInRevenueShare is SimpleTaskBase { ( _vaultAddress, 0, - gasLimit, + RevShareGasLimits.SETTERS_GAS_LIMIT, false, abi.encodeCall(IFeeVault.setWithdrawalNetwork, (FEE_VAULT_WITHDRAWAL_NETWORK)) ) diff --git a/src/template/RevenueShareUpgradePath.sol b/src/template/RevenueShareUpgradePath.sol index e97bbd10ae..14709d6ce9 100644 --- a/src/template/RevenueShareUpgradePath.sol +++ b/src/template/RevenueShareUpgradePath.sol @@ -8,6 +8,7 @@ import {SimpleTaskBase} from "src/tasks/types/SimpleTaskBase.sol"; import {Action} from "src/libraries/MultisigTypes.sol"; import {MultisigTaskPrinter} from "src/libraries/MultisigTaskPrinter.sol"; import {RevShareCodeRepo} from "src/libraries/RevShareCodeRepo.sol"; +import {RevShareGasLimits} from "src/libraries/RevShareGasLimits.sol"; import {Utils} from "src/libraries/Utils.sol"; /// @notice Interface for the OptimismPortal2 in L1. This is the main interaction point for the template. @@ -58,27 +59,6 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { /// @notice Address of the ProxyAdmin predeploy on L2. address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018; - /// @notice Based on deployment tests, these are the average gas costs for each of the L2 operations: - /// - L1Withdrawer deployment: 497,812 - /// - SC Rev Share Calculator deployment: 518,168 - /// - Fee Vaults deployment: 757,214 - /// - Fee Splitter deployment: 1,027,359 - /// - upgradeAndCall: 73,015 - /// - upgrade: 6,202 - /// A buffer of ~20% is applied to each value to have enough margin. While leaving the upgrade call - /// to a fixed 150,000 gas limit. - - /// @notice The gas limit for the SC Rev Share Calculator deployment. - uint64 internal constant SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT = 625_000; - /// @notice The gas limit for the L1 Withdrawer deployment. - uint64 internal constant L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT = 625_000; - /// @notice The gas limit for the Fee Vaults deployment. - uint64 internal constant FEE_VAULTS_DEPLOYMENT_GAS_LIMIT = 910_000; - /// @notice The gas limit for the Fee Splitter deployment. - uint64 internal constant FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT = 1_235_000; - /// @notice The gas limit for the upgrade calls on L2. - uint64 internal constant UPGRADE_GAS_LIMIT = 150_000; - /// @notice Used to validate calls made to the OptimismPortal. mapping(bytes32 => uint8) internal _callsToPortal; @@ -288,7 +268,13 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, false, _l1WithdrawerCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, + false, + _l1WithdrawerCalldata + ) ) ); @@ -317,7 +303,7 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { ( address(CREATE2_DEPLOYER), 0, - SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, + RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, false, _scRevShareCalculatorCalldata ) @@ -334,12 +320,17 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { _operatorFeeVaultCalldata = abi.encodeCall( ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "OperatorFeeVault"), _operatorFeeVaultInitCode) ); - // Expected calls for OperatorFeeVault: 2 (deploy + upgradeAndCall) _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _operatorFeeVaultCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _operatorFeeVaultCalldata + ) ) ); _incrementCallsToPortal( @@ -348,7 +339,7 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { ( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -382,7 +373,13 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _sequencerFeeVaultCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _sequencerFeeVaultCalldata + ) ) ); _incrementCallsToPortal( @@ -391,7 +388,7 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { ( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -423,7 +420,13 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _baseFeeVaultCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _baseFeeVaultCalldata + ) ) ); _incrementCallsToPortal( @@ -432,7 +435,7 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { ( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -460,7 +463,13 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _l1FeeVaultCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _l1FeeVaultCalldata + ) ) ); _incrementCallsToPortal( @@ -469,7 +478,7 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { ( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -498,7 +507,13 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { _incrementCallsToPortal( abi.encodeCall( IOptimismPortal2.depositTransaction, - (address(CREATE2_DEPLOYER), 0, FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, false, _feeSplitterCalldata) + ( + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, + false, + _feeSplitterCalldata + ) ) ); _incrementCallsToPortal( @@ -507,7 +522,7 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { ( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -537,14 +552,18 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { if (optInRevenueShare) { // Deploy L1 Withdrawer IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, false, _l1WithdrawerCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, + false, + _l1WithdrawerCalldata ); // Deploy SC Rev Share Calculator IOptimismPortal2(payable(portal)).depositTransaction( address(CREATE2_DEPLOYER), 0, - SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, + RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, false, _scRevShareCalculatorCalldata ); @@ -580,12 +599,16 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { // Deploy the fee vaults // Deploy the operator fee vault IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _operatorFeeVaultCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _operatorFeeVaultCalldata ); IOptimismPortal2(payable(portal)).depositTransaction( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -606,12 +629,16 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { // Deploy the sequencer fee vault IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _sequencerFeeVaultCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _sequencerFeeVaultCalldata ); IOptimismPortal2(payable(portal)).depositTransaction( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -632,12 +659,16 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { // Deploy the base fee vault IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _baseFeeVaultCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + _baseFeeVaultCalldata ); IOptimismPortal2(payable(portal)).depositTransaction( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -654,12 +685,12 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { // Deploy the l1 fee vault IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _l1FeeVaultCalldata + address(CREATE2_DEPLOYER), 0, RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _l1FeeVaultCalldata ); IOptimismPortal2(payable(portal)).depositTransaction( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, @@ -679,13 +710,17 @@ contract RevenueShareV100UpgradePath is SimpleTaskBase { function _deployFeeSplitter() private { // Deploy Fee Splitter IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, false, _feeSplitterCalldata + address(CREATE2_DEPLOYER), + 0, + RevShareGasLimits.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, + false, + _feeSplitterCalldata ); IOptimismPortal2(payable(portal)).depositTransaction( address(PROXY_ADMIN), 0, - UPGRADE_GAS_LIMIT, + RevShareGasLimits.UPGRADE_GAS_LIMIT, false, abi.encodeCall( IProxyAdmin.upgradeAndCall, diff --git a/test/integration/RevenueShareIntegration.t.sol b/test/integration/RevenueShareIntegration.t.sol index e216402bf4..7a18b70aaf 100644 --- a/test/integration/RevenueShareIntegration.t.sol +++ b/test/integration/RevenueShareIntegration.t.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.15; import {RevenueShareV100UpgradePath} from "src/template/RevenueShareUpgradePath.sol"; +import {LateOptInRevenueShare} from "src/template/LateOptInRevenueShare.sol"; import {Action} from "src/libraries/MultisigTypes.sol"; import {IntegrationBase} from "./IntegrationBase.t.sol"; import {Test} from "forge-std/Test.sol"; @@ -36,7 +37,8 @@ interface ISuperchainRevSharesCalculator { } contract RevenueShareIntegrationTest is IntegrationBase { - RevenueShareV100UpgradePath public template; + RevenueShareV100UpgradePath public revenueShareTemplate; + LateOptInRevenueShare public lateOptInTemplate; // Fork IDs uint256 internal _mainnetForkId; @@ -59,12 +61,17 @@ contract RevenueShareIntegrationTest is IntegrationBase { address internal constant L1_WITHDRAWER = 0x65E05252dd7964dBb722a9fCa24c6a2D7AFbeF57; /// @notice Address of the Rev Share Calculator Predeploy on L2. address internal constant REV_SHARE_CALCULATOR = 0xa9C1d283Ab6f149853337395E18850B3fF6cf192; + /// @notice Address of the L1 Withdrawer Predeploy on L2 for late opt in. + address internal constant L1_WITHDRAWER_LATE_OPT_IN = 0x4427a644D44b1795655847ecB3795caEba83cf7C; + /// @notice Address of the Rev Share Calculator Predeploy on L2 for late opt in. + address internal constant REV_SHARE_CALCULATOR_LATE_OPT_IN = 0x28cC7ed36D4788B7248aE2a7a70efC7011DbA7c2; function setUp() public { _mainnetForkId = vm.createFork("http://127.0.0.1:8545"); _l2ForkId = vm.createFork("http://127.0.0.1:9545"); vm.selectFork(_mainnetForkId); - template = new RevenueShareV100UpgradePath(); + revenueShareTemplate = new RevenueShareV100UpgradePath(); + lateOptInTemplate = new LateOptInRevenueShare(); } /// @notice Test the integration of the revenue share system when the chain is opting in @@ -73,7 +80,7 @@ contract RevenueShareIntegrationTest is IntegrationBase { // Step 1: Execute L1 transaction recording logs vm.recordLogs(); - template.simulate(_configPath, new address[](0)); + revenueShareTemplate.simulate(_configPath, new address[](0)); // Step 2: Relay messages from L1 to L2 // Pass true for _isSimulate since simulate() emits events twice @@ -102,7 +109,7 @@ contract RevenueShareIntegrationTest is IntegrationBase { // Vaults: recipient should be fee splitter, withdrawal network should be L2, min withdrawal amount 0 // getters for legacy and the new values should be the same - _assertFeeVaultsState(true, _config); + _assertFeeVaultsState(true, ""); // No need to send the config since the chain is opting in } /// @notice Test the integration of the revenue share system when the chain is opting out @@ -111,7 +118,7 @@ contract RevenueShareIntegrationTest is IntegrationBase { // Step 1: Execute L1 transaction recording logs vm.recordLogs(); - template.simulate(_configPath, new address[](0)); + revenueShareTemplate.simulate(_configPath, new address[](0)); // Step 2: Relay messages from L1 to L2 // Pass true for _isSimulate since simulate() emits events twice @@ -128,6 +135,122 @@ contract RevenueShareIntegrationTest is IntegrationBase { _assertFeeVaultsState(false, _config); } + /// @notice Test the integration of the revenue share system when the chain is opting out, + /// then running the late opt in revenue share task with the custom calculator. + function test_lateOptInRevenueShareCustomCalculator_integration() public { + string memory _configPath = "test/tasks/example/eth/019-revenueshare-upgrade-opt-out/config.toml"; + + // Step 1: Execute L1 transaction recording logs + vm.recordLogs(); + revenueShareTemplate.simulate(_configPath, new address[](0)); + + // Step 2: Relay messages from L1 to L2 + // Pass true for _isSimulate since simulate() emits events twice + _relayAllMessages(_l2ForkId, true); + + // Step 3: Assert the state of the L2 contracts + string memory _config = vm.readFile(_configPath); + + // Fee Splitter: check calculator is set to address(0) + assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), address(0)); + + // Vaults: vaults configuration should be the same as the ones in the config provided + // getters for legacy and the new values should be the same + _assertFeeVaultsState(false, _config); + + string memory _configPathCustomCalc = + "test/tasks/example/eth/017-opt-in-revenue-share-late-custom-calc/config.toml"; + + vm.selectFork(_mainnetForkId); + + // Step 4: Execute the late opt in revenue share task + vm.recordLogs(); + lateOptInTemplate.simulate(_configPathCustomCalc, new address[](0)); + + // Step 5: Relay messages from L1 to L2 + // Pass true for _isSimulate since simulate() emits events twice + _relayAllMessages(_l2ForkId, true); + + // Step 6: Assert the state of the L2 contracts + string memory _configCustomCalc = vm.readFile(_configPathCustomCalc); + + // Fee Splitter: check calculator is set + assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), vm.parseTomlAddress(_configCustomCalc, ".calculator")); + + // Vaults: recipient should be fee splitter, withdrawal network should be L2, min withdrawal amount 0 + // getters for legacy and the new values should be the same + _assertFeeVaultsState(true, ""); // No need to send the config since the chain is opting in + } + + /// @notice Test the integration of the revenue share system when the chain is opting out, + /// then running the late opt in revenue share task with the default calculator. + function test_lateOptInRevenueShareDefaultCalculator_integration() public { + string memory _configPath = "test/tasks/example/eth/019-revenueshare-upgrade-opt-out/config.toml"; + + // Step 1: Execute L1 transaction recording logs + vm.recordLogs(); + revenueShareTemplate.simulate(_configPath, new address[](0)); + + // Step 2: Relay messages from L1 to L2 + // Pass true for _isSimulate since simulate() emits events twice + _relayAllMessages(_l2ForkId, true); + + // Step 3: Assert the state of the L2 contracts + string memory _config = vm.readFile(_configPath); + + // Fee Splitter: check calculator is set to address(0) + assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), address(0)); + + // Vaults: vaults configuration should be the same as the ones in the config provided + // getters for legacy and the new values should be the same + _assertFeeVaultsState(false, _config); + + string memory _configPathDefaultCalc = "test/tasks/example/eth/018-opt-in-revenue-share-late/config.toml"; + + vm.selectFork(_mainnetForkId); + + // Step 4: Execute the late opt in revenue share task + vm.recordLogs(); + lateOptInTemplate.simulate(_configPathDefaultCalc, new address[](0)); + + // Step 5: Relay messages from L1 to L2 + // Pass true for _isSimulate since simulate() emits events twice + _relayAllMessages(_l2ForkId, true); + + // Step 6: Assert the state of the L2 contracts + string memory _configDefaultCalc = vm.readFile(_configPathDefaultCalc); + + // L1Withdrawer: check withdrawal threshold and fees depositor + assertEq( + IL1Withdrawer(L1_WITHDRAWER_LATE_OPT_IN).minWithdrawalAmount(), + vm.parseTomlUint(_configDefaultCalc, ".l1WithdrawerMinWithdrawalAmount") + ); + assertEq( + IL1Withdrawer(L1_WITHDRAWER_LATE_OPT_IN).recipient(), + vm.parseTomlAddress(_configDefaultCalc, ".l1WithdrawerRecipient") + ); + assertEq( + IL1Withdrawer(L1_WITHDRAWER_LATE_OPT_IN).withdrawalGasLimit(), + vm.parseTomlUint(_configDefaultCalc, ".l1WithdrawerGasLimit") + ); + + // Rev Share Calculator: check chain fees recipient and remainder recipient + assertEq( + ISuperchainRevSharesCalculator(REV_SHARE_CALCULATOR_LATE_OPT_IN).shareRecipient(), L1_WITHDRAWER_LATE_OPT_IN + ); + assertEq( + ISuperchainRevSharesCalculator(REV_SHARE_CALCULATOR_LATE_OPT_IN).remainderRecipient(), + vm.parseTomlAddress(_configDefaultCalc, ".scRevShareCalcChainFeesRecipient") + ); + + // Fee Splitter: check calculator is set + assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), REV_SHARE_CALCULATOR_LATE_OPT_IN); + + // Vaults: recipient should be fee splitter, withdrawal network should be L2, min withdrawal amount 0 + // getters for legacy and the new values should be the same + _assertFeeVaultsState(true, ""); // No need to send the config since the chain is opting in + } + /// @notice Assert the configuration of the fee vaults /// @param _isOptIn Whether the chain is opting in to use the Fee Splitter /// @param _config The configuration of the fee vaults diff --git a/test/tasks/example/eth/018-opt-in-revenue-share-late/config.toml b/test/tasks/example/eth/018-opt-in-revenue-share-late/config.toml index 03df1773f6..d071dafdec 100644 --- a/test/tasks/example/eth/018-opt-in-revenue-share-late/config.toml +++ b/test/tasks/example/eth/018-opt-in-revenue-share-late/config.toml @@ -9,7 +9,6 @@ l1WithdrawerMinWithdrawalAmount = 1000000000000000000 l1WithdrawerRecipient = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" l1WithdrawerGasLimit = 300000 scRevShareCalcChainFeesRecipient = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" -gasLimit = 300000 # Gas limit for L2 calls through the portal [addresses] ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" # 2-of-2 between council and foundation diff --git a/test/template/late-opt-in-rev-share/LateOptInRevenueShare.t.sol b/test/template/late-opt-in-rev-share/LateOptInRevenueShare.t.sol index 5ae7211b52..ecc1d6760d 100644 --- a/test/template/late-opt-in-rev-share/LateOptInRevenueShare.t.sol +++ b/test/template/late-opt-in-rev-share/LateOptInRevenueShare.t.sol @@ -9,6 +9,7 @@ import {IGnosisSafe, Enum} from "@base-contracts/script/universal/IGnosisSafe.so import {IMulticall3} from "forge-std/interfaces/IMulticall3.sol"; import {Signatures} from "@base-contracts/script/universal/Signatures.sol"; import {RevShareCodeRepo} from "src/libraries/RevShareCodeRepo.sol"; +import {RevShareGasLimits} from "src/libraries/RevShareGasLimits.sol"; import {Utils} from "src/libraries/Utils.sol"; interface IOptimismPortal2 { @@ -54,7 +55,6 @@ contract LateOptInRevenueShareTest is Test { // L1 Withdrawer configuration string internal constant SALT_SEED = "DeploymentSalt"; - uint64 internal constant GAS_LIMIT = 300000; address internal constant L1_WITHDRAWER_RECIPIENT = 0xDeaDbeefdEAdbeefdEadbEEFdeadbeEFdEaDbeeF; uint256 internal constant L1_WITHDRAWER_MIN_WITHDRAWAL_AMOUNT = 1000000000000000000; uint32 internal constant L1_WITHDRAWER_GAS_LIMIT = 300000; @@ -198,11 +198,17 @@ contract LateOptInRevenueShareTest is Test { vaults[1] = SEQUENCER_FEE_VAULT; vaults[2] = L1_FEE_VAULT; vaults[3] = OPERATOR_FEE_VAULT; - _expectVaultSetOperations(vaults, GAS_LIMIT); + _expectVaultSetOperations(vaults, RevShareGasLimits.SETTERS_GAS_LIMIT); bytes memory setCalculatorCalldata = abi.encodeCall( IOptimismPortal2.depositTransaction, - (FEE_SPLITTER, 0, GAS_LIMIT, false, abi.encodeCall(IFeeSplitter.setSharesCalculator, (calculator))) + ( + FEE_SPLITTER, + 0, + RevShareGasLimits.SETTERS_GAS_LIMIT, + false, + abi.encodeCall(IFeeSplitter.setSharesCalculator, (calculator)) + ) ); vm.expectCall(PORTAL, setCalculatorCalldata); } @@ -332,20 +338,6 @@ contract LateOptInRevenueShareRequiredFieldsTest is Test { template = new LateOptInRevenueShare(); } - /// @notice Tests that the template reverts when the gasLimit is too low. - function test_lateOptInRevenueShare_too_low_gasLimit_reverts() public { - string memory configPath = "test/template/late-opt-in-rev-share/config/zero-gas-limit-config.toml"; - vm.expectRevert("gasLimit must be set"); - template.simulate(configPath); - } - - /// @notice Tests that the template reverts when the gasLimit is too high. - function test_lateOptInRevenueShare_too_high_gasLimit_reverts() public { - string memory configPath = "test/template/late-opt-in-rev-share/config/too-high-gas-limit-config.toml"; - vm.expectRevert("gasLimit must be less than uint64.max"); - template.simulate(configPath); - } - /// @notice Tests that the template reverts when using own calculator and the calculator address is zero. function test_lateOptInRevenueShare_calculator_zero_address_reverts() public { string memory configPath = "test/template/late-opt-in-rev-share/config/calculator-zero-address-config.toml"; diff --git a/test/template/late-opt-in-rev-share/config/too-high-gas-limit-config.toml b/test/template/late-opt-in-rev-share/config/too-high-gas-limit-config.toml deleted file mode 100644 index e4bb687b5c..0000000000 --- a/test/template/late-opt-in-rev-share/config/too-high-gas-limit-config.toml +++ /dev/null @@ -1,15 +0,0 @@ -templateName = "LateOptInRevenueShare" - -# Revenue Share Configuration -# When using custom calculator, only the calculator address and the gas limit are required -useOwnCalculator = false -saltSeed = "DeploymentSalt" -l1WithdrawerMinWithdrawalAmount = 1000000000000000000 -l1WithdrawerRecipient = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" -l1WithdrawerGasLimit = 300000 -scRevShareCalcChainFeesRecipient = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" -gasLimit = 1.9e64 # Greater than uint64.max - -[addresses] -ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" -OptimismPortal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" \ No newline at end of file diff --git a/test/template/late-opt-in-rev-share/config/zero-gas-limit-config.toml b/test/template/late-opt-in-rev-share/config/zero-gas-limit-config.toml deleted file mode 100644 index 16a49d0f78..0000000000 --- a/test/template/late-opt-in-rev-share/config/zero-gas-limit-config.toml +++ /dev/null @@ -1,15 +0,0 @@ -templateName = "LateOptInRevenueShare" - -# Revenue Share Configuration -# When using custom calculator, only the calculator address and the gas limit are required -useOwnCalculator = false -saltSeed = "DeploymentSalt" -l1WithdrawerMinWithdrawalAmount = 1000000000000000000 -l1WithdrawerRecipient = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" -l1WithdrawerGasLimit = 300000 -scRevShareCalcChainFeesRecipient = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef" -gasLimit = 0 # gasLimit must be set - -[addresses] -ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" -OptimismPortal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" \ No newline at end of file