diff --git a/src/RevShareContractsUpgrader.sol b/src/RevShareContractsUpgrader.sol new file mode 100644 index 0000000000..9dccd26703 --- /dev/null +++ b/src/RevShareContractsUpgrader.sol @@ -0,0 +1,302 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {RevShareLibrary} from "src/libraries/RevShareLibrary.sol"; +import {Utils} from "src/libraries/Utils.sol"; + +// Interfaces +import {IOptimismPortal2} from "@eth-optimism-bedrock/interfaces/L1/IOptimismPortal2.sol"; +import {IProxyAdmin} from "@eth-optimism-bedrock/interfaces/universal/IProxyAdmin.sol"; +import {ICreate2Deployer} from "src/interfaces/ICreate2Deployer.sol"; +import {IFeeSplitter} from "src/interfaces/IFeeSplitter.sol"; +import {IFeeVault} from "src/interfaces/IFeeVault.sol"; + +/// @title RevShareContractsUpgrader +/// @notice Upgrader contract that manages RevShare deployments and configuration via delegatecall. +/// @dev Supports two operations: +/// 1. setupRevShare() - Setup revenue sharing on already-upgraded contracts +/// 2. upgradeAndSetupRevShare() - Combined upgrade + setup (most efficient) +/// All operations use the default calculator (L1Withdrawer + SuperchainRevenueShareCalculator). +contract RevShareContractsUpgrader { + /// @notice Base salt seed for CREATE2 deployments + string private constant SALT_SEED = "RevShare"; + + /// @notice Thrown when portal address is zero + error PortalCannotBeZeroAddress(); + + /// @notice Thrown when L1Withdrawer recipient is zero address + error L1WithdrawerRecipientCannotBeZeroAddress(); + + /// @notice Thrown when chain fees recipient is zero address + error ChainFeesRecipientCannotBeZeroAddress(); + + /// @notice Thrown when gas limit is zero + error GasLimitCannotBeZero(); + + /// @notice Thrown when array is empty + error EmptyArray(); + + /// @notice Emitted when a chain's RevShare setup deposits are completed + /// @param portal The portal address for the chain + /// @param chainIndex The index of the chain in the configs array + event ChainProcessed(address portal, uint256 chainIndex); + + /// @notice Struct for L1Withdrawer configuration. + /// @param minWithdrawalAmount Minimum withdrawal amount + /// @param recipient Recipient address for withdrawals + /// @param gasLimit Gas limit for L1 withdrawals + struct L1WithdrawerConfig { + uint256 minWithdrawalAmount; + address recipient; + uint32 gasLimit; + } + + /// @notice Struct for RevShare setup configuration per chain. + /// @param portal OptimismPortal2 address for the target L2 + /// @param l1WithdrawerConfig L1Withdrawer configuration + /// @param chainFeesRecipient Chain fees recipient address for the calculator + struct RevShareConfig { + address portal; + L1WithdrawerConfig l1WithdrawerConfig; + address chainFeesRecipient; + } + + /// @notice Upgrades vault and splitter contracts and sets up revenue sharing in one transaction for multiple chains. + /// This is the most efficient path as vaults are initialized with RevShare config from the start. + /// @param _configs Array of RevShare configuration structs, one per chain. + function upgradeAndSetupRevShare(RevShareConfig[] calldata _configs) external { + if (_configs.length == 0) revert EmptyArray(); + + for (uint256 i; i < _configs.length; i++) { + RevShareConfig calldata config = _configs[i]; + if (config.portal == address(0)) revert PortalCannotBeZeroAddress(); + if (config.l1WithdrawerConfig.recipient == address(0)) revert L1WithdrawerRecipientCannotBeZeroAddress(); + if (config.chainFeesRecipient == address(0)) revert ChainFeesRecipientCannotBeZeroAddress(); + if (config.l1WithdrawerConfig.gasLimit == 0) revert GasLimitCannotBeZero(); + + // Deploy L1Withdrawer and SuperchainRevenueShareCalculator + address precalculatedCalculator = + _deployRevSharePeriphery(config.portal, config.l1WithdrawerConfig, config.chainFeesRecipient); + + // Upgrade fee splitter and initialize with calculator FIRST + // This prevents the edge case where fees could be sent to an uninitialized FeeSplitter + bytes32 feeSplitterSalt = _getSalt("FeeSplitter"); + address feeSplitterImpl = Utils.getCreate2Address( + feeSplitterSalt, RevShareLibrary.feeSplitterCreationCode, RevShareLibrary.CREATE2_DEPLOYER + ); + _depositCreate2( + config.portal, + RevShareLibrary.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, + feeSplitterSalt, + RevShareLibrary.feeSplitterCreationCode + ); + _depositCall( + config.portal, + address(RevShareLibrary.PROXY_ADMIN), + RevShareLibrary.UPGRADE_GAS_LIMIT, + abi.encodeCall( + IProxyAdmin.upgradeAndCall, + ( + payable(RevShareLibrary.FEE_SPLITTER), + feeSplitterImpl, + abi.encodeCall(IFeeSplitter.initialize, (precalculatedCalculator)) + ) + ) + ); + + // Upgrade all 4 vaults with RevShare configuration (recipient=FeeSplitter, minWithdrawal=0, network=L2) + _upgradeVaultsWithRevShareConfig(config.portal); + + emit ChainProcessed(config.portal, i); + } + } + + /// @notice Enables revenue sharing after vaults have been upgraded and `FeeSplitter` initialized. + /// Deploys L1Withdrawer and calculator, then configures vaults and splitter for multiple chains. + /// @param _configs Array of RevShare configuration structs, one per chain. + function setupRevShare(RevShareConfig[] calldata _configs) external { + if (_configs.length == 0) revert EmptyArray(); + + for (uint256 i; i < _configs.length; i++) { + RevShareConfig calldata config = _configs[i]; + if (config.portal == address(0)) revert PortalCannotBeZeroAddress(); + if (config.l1WithdrawerConfig.recipient == address(0)) revert L1WithdrawerRecipientCannotBeZeroAddress(); + if (config.chainFeesRecipient == address(0)) revert ChainFeesRecipientCannotBeZeroAddress(); + if (config.l1WithdrawerConfig.gasLimit == 0) revert GasLimitCannotBeZero(); + + // Deploy L1Withdrawer and SuperchainRevenueShareCalculator + address calculator = + _deployRevSharePeriphery(config.portal, config.l1WithdrawerConfig, config.chainFeesRecipient); + + // Set calculator on fee splitter + _depositCall( + config.portal, + RevShareLibrary.FEE_SPLITTER, + RevShareLibrary.SETTERS_GAS_LIMIT, + abi.encodeCall(IFeeSplitter.setSharesCalculator, (calculator)) + ); + + // Configure all 4 vaults for revenue sharing + _configureVaultsForRevShare(config.portal); + + emit ChainProcessed(config.portal, i); + } + } + + /// @notice Deploys L1Withdrawer and SuperchainRevenueShareCalculator to L2. + /// @param _portal The OptimismPortal2 address for the target L2 + /// @param _l1WithdrawerConfig L1Withdrawer configuration + /// @param _chainFeesRecipient Chain fees recipient address + /// @return calculator The deployed calculator address + function _deployRevSharePeriphery( + address _portal, + L1WithdrawerConfig calldata _l1WithdrawerConfig, + address _chainFeesRecipient + ) private returns (address calculator) { + // Deploy L1Withdrawer + bytes memory l1WithdrawerInitCode = bytes.concat( + RevShareLibrary.l1WithdrawerCreationCode, + abi.encode( + _l1WithdrawerConfig.minWithdrawalAmount, _l1WithdrawerConfig.recipient, _l1WithdrawerConfig.gasLimit + ) + ); + bytes32 l1WithdrawerSalt = _getSalt("L1Withdrawer"); + address precalculatedL1Withdrawer = + Utils.getCreate2Address(l1WithdrawerSalt, l1WithdrawerInitCode, RevShareLibrary.CREATE2_DEPLOYER); + _depositCreate2( + _portal, RevShareLibrary.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, l1WithdrawerSalt, l1WithdrawerInitCode + ); + + // Deploy SuperchainRevenueShareCalculator + bytes memory calculatorInitCode = bytes.concat( + RevShareLibrary.scRevShareCalculatorCreationCode, abi.encode(precalculatedL1Withdrawer, _chainFeesRecipient) + ); + bytes32 calculatorSalt = _getSalt("SCRevShareCalculator"); + calculator = Utils.getCreate2Address(calculatorSalt, calculatorInitCode, RevShareLibrary.CREATE2_DEPLOYER); + _depositCreate2( + _portal, RevShareLibrary.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, calculatorSalt, calculatorInitCode + ); + } + + /// @notice Configures all 4 vaults for revenue sharing (recipient=FeeSplitter, minWithdrawal=0, network=L2). + /// @param _portal The OptimismPortal2 address for the target L2 + function _configureVaultsForRevShare(address _portal) private { + address[4] memory vaults = [ + RevShareLibrary.OPERATOR_FEE_VAULT, + RevShareLibrary.SEQUENCER_FEE_WALLET, + RevShareLibrary.BASE_FEE_VAULT, + RevShareLibrary.L1_FEE_VAULT + ]; + + for (uint256 i; i < vaults.length; i++) { + _depositCall( + _portal, + vaults[i], + RevShareLibrary.SETTERS_GAS_LIMIT, + abi.encodeCall(IFeeVault.setRecipient, (RevShareLibrary.FEE_SPLITTER)) + ); + _depositCall( + _portal, + vaults[i], + RevShareLibrary.SETTERS_GAS_LIMIT, + abi.encodeCall(IFeeVault.setMinWithdrawalAmount, (0)) + ); + _depositCall( + _portal, + vaults[i], + RevShareLibrary.SETTERS_GAS_LIMIT, + abi.encodeCall(IFeeVault.setWithdrawalNetwork, (IFeeVault.WithdrawalNetwork.L2)) + ); + } + } + + /// @notice Upgrades all 4 vaults with RevShare configuration (recipient=FeeSplitter, minWithdrawal=0, network=L2). + /// Deploys only 3 implementations: OperatorFeeVault, SequencerFeeVault, and the same FeeVault implementation is used for both BaseFeeVault and L1FeeVault (we use the same one for both to avoid making the deployment size bigger). + /// @param _portal The OptimismPortal2 address for the target L2 + function _upgradeVaultsWithRevShareConfig(address _portal) private { + address[4] memory vaultProxies = [ + RevShareLibrary.OPERATOR_FEE_VAULT, + RevShareLibrary.SEQUENCER_FEE_WALLET, + RevShareLibrary.BASE_FEE_VAULT, + RevShareLibrary.L1_FEE_VAULT + ]; + bytes[4] memory creationCodes = [ + RevShareLibrary.operatorFeeVaultCreationCode, + RevShareLibrary.sequencerFeeVaultCreationCode, + RevShareLibrary.defaultFeeVaultCreationCode, + RevShareLibrary.defaultFeeVaultCreationCode + ]; + string[4] memory vaultNames = ["OperatorFeeVault", "SequencerFeeVault", "BaseFeeVault", "L1FeeVault"]; + + address defaultImpl; + for (uint256 i; i < vaultProxies.length; i++) { + bytes32 salt = _getSalt(vaultNames[i]); + address impl; + + // Check if this is the BaseFeeVault or L1FeeVault (both use default implementation) + bool isBaseFeeVault = keccak256(bytes(vaultNames[i])) == keccak256(bytes("BaseFeeVault")); + bool isL1FeeVault = keccak256(bytes(vaultNames[i])) == keccak256(bytes("L1FeeVault")); + + if (isBaseFeeVault) { + // Deploy default implementation for BaseFeeVault + impl = Utils.getCreate2Address(salt, creationCodes[i], RevShareLibrary.CREATE2_DEPLOYER); + defaultImpl = impl; + _depositCreate2(_portal, RevShareLibrary.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, salt, creationCodes[i]); + } else if (isL1FeeVault) { + // Reuse the default implementation for L1FeeVault + impl = defaultImpl; + } else { + // Deploy specific implementations for OperatorFeeVault and SequencerFeeVault + impl = Utils.getCreate2Address(salt, creationCodes[i], RevShareLibrary.CREATE2_DEPLOYER); + _depositCreate2(_portal, RevShareLibrary.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, salt, creationCodes[i]); + } + + _depositCall( + _portal, + address(RevShareLibrary.PROXY_ADMIN), + RevShareLibrary.UPGRADE_GAS_LIMIT, + abi.encodeCall( + IProxyAdmin.upgradeAndCall, + ( + payable(vaultProxies[i]), + impl, + abi.encodeCall( + IFeeVault.initialize, (RevShareLibrary.FEE_SPLITTER, 0, IFeeVault.WithdrawalNetwork.L2) + ) + ) + ) + ); + } + } + + /// @notice Helper for CREATE2 contract deployments via depositTransaction. + /// @param _portal The OptimismPortal2 address + /// @param _gasLimit Gas limit for the transaction + /// @param _salt CREATE2 salt + /// @param _initCode Contract creation code with constructor args + function _depositCreate2(address _portal, uint64 _gasLimit, bytes32 _salt, bytes memory _initCode) private { + IOptimismPortal2(payable(_portal)).depositTransaction( + address(RevShareLibrary.CREATE2_DEPLOYER), + 0, + _gasLimit, + false, + abi.encodeCall(ICreate2Deployer.deploy, (0, _salt, _initCode)) + ); + } + + /// @notice Helper for regular function calls via depositTransaction. + /// @param _portal The OptimismPortal2 address + /// @param _target Target contract address + /// @param _gasLimit Gas limit for the transaction + /// @param _data Encoded function call data + function _depositCall(address _portal, address _target, uint64 _gasLimit, bytes memory _data) private { + IOptimismPortal2(payable(_portal)).depositTransaction(_target, 0, _gasLimit, false, _data); + } + + /// @notice Generates a unique salt for CREATE2 deployments based on the contract suffix. + /// @param _suffix The suffix to append to the base salt seed + /// @return The generated salt as bytes32 + function _getSalt(string memory _suffix) private pure returns (bytes32) { + return keccak256(abi.encodePacked(SALT_SEED, ":", _suffix)); + } +} diff --git a/src/interfaces/ICreate2Deployer.sol b/src/interfaces/ICreate2Deployer.sol new file mode 100644 index 0000000000..23b37a16bd --- /dev/null +++ b/src/interfaces/ICreate2Deployer.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +/// @notice Interface of the Create2 Preinstall in L2. +interface ICreate2Deployer { + function deploy(uint256 _value, bytes32 _salt, bytes memory _code) external; +} diff --git a/src/interfaces/IFeeSplitter.sol b/src/interfaces/IFeeSplitter.sol new file mode 100644 index 0000000000..680ad671b1 --- /dev/null +++ b/src/interfaces/IFeeSplitter.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +/// @notice Interface for the FeeSplitter in L2. +interface IFeeSplitter { + function initialize(address _sharesCalculator) external; + function sharesCalculator() external view returns (address); + function setSharesCalculator(address _calculator) external; +} diff --git a/src/interfaces/IFeeVault.sol b/src/interfaces/IFeeVault.sol new file mode 100644 index 0000000000..c0a7206547 --- /dev/null +++ b/src/interfaces/IFeeVault.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +interface IFeeVault { + enum WithdrawalNetwork { + L1, + L2 + } + + function initialize(address _recipient, uint256 _minWithdrawalAmount, WithdrawalNetwork _withdrawalNetwork) external; + + function RECIPIENT() external view returns (address); + function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); + function WITHDRAWAL_NETWORK() external view returns (WithdrawalNetwork); + function minWithdrawalAmount() external view returns (uint256); + function recipient() external view returns (address); + function withdrawalNetwork() external view returns (WithdrawalNetwork); + + function setRecipient(address _recipient) external; + function setMinWithdrawalAmount(uint256 _minWithdrawalAmount) external; + function setWithdrawalNetwork(WithdrawalNetwork _withdrawalNetwork) external; +} diff --git a/src/interfaces/IL1Withdrawer.sol b/src/interfaces/IL1Withdrawer.sol new file mode 100644 index 0000000000..3a0e3b0490 --- /dev/null +++ b/src/interfaces/IL1Withdrawer.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +interface IL1Withdrawer { + function minWithdrawalAmount() external view returns (uint256); + function recipient() external view returns (address); + function withdrawalGasLimit() external view returns (uint32); +} \ No newline at end of file diff --git a/src/interfaces/IRevShareContractsUpgrader.sol b/src/interfaces/IRevShareContractsUpgrader.sol new file mode 100644 index 0000000000..4f5f04833f --- /dev/null +++ b/src/interfaces/IRevShareContractsUpgrader.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +interface IRevShareContractsUpgrader { + error PortalCannotBeZeroAddress(); + error L1WithdrawerRecipientCannotBeZeroAddress(); + error ChainFeesRecipientCannotBeZeroAddress(); + error GasLimitCannotBeZero(); + error EmptyArray(); + + event ChainProcessed(address portal, uint256 chainIndex); + + struct L1WithdrawerConfig { + uint256 minWithdrawalAmount; + address recipient; + uint32 gasLimit; + } + + struct RevShareConfig { + address portal; + L1WithdrawerConfig l1WithdrawerConfig; + address chainFeesRecipient; + } + + function upgradeAndSetupRevShare(RevShareConfig[] calldata _configs) external; + function setupRevShare(RevShareConfig[] calldata _configs) external; +} diff --git a/src/interfaces/ISuperchainRevSharesCalculator.sol b/src/interfaces/ISuperchainRevSharesCalculator.sol new file mode 100644 index 0000000000..37f855091c --- /dev/null +++ b/src/interfaces/ISuperchainRevSharesCalculator.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +interface ISuperchainRevSharesCalculator { + function shareRecipient() external view returns (address payable); + function remainderRecipient() external view returns (address payable); +} \ No newline at end of file diff --git a/src/libraries/RevShareCodeRepo.sol b/src/libraries/RevShareCodeRepo.sol deleted file mode 100644 index a7a14583ca..0000000000 --- a/src/libraries/RevShareCodeRepo.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -/// @notice Library for storing the creation code for the revenue share contracts. -library RevShareCodeRepo { - /// @notice The creation code for each fee vault, fee splitter, l1 withdrawer, FeesDepositor and sc rev share calculator. - /// Obtained from https://github.com/defi-wonderland/optimism at commit 989afa818dfee3ee1fba715584c2f7e8663268f8 - bytes public constant operatorFeeVaultCreationCode = - hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a"; - bytes public constant sequencerFeeVaultCreationCode = - hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610ec4806100d65f395ff3fe6080604052600436106100dc575f3560e01c80638312f1491161007c578063b49dc74111610057578063b49dc741146102a0578063d0e12f90146102bf578063d3e5792b146102ee578063d4ff9218146100e7575f80fd5b80638312f1491461025857806384411d651461026d57806385b5b14d14610281575f80fd5b80633ccfd60b116100b75780633ccfd60b1461017757806354fd4d501461019957806366d003ac146101ee57806382356d8a1461021a575f80fd5b80630d9019e1146100e7578063307f2962146101375780633bbed4a014610158575f80fd5b366100e357005b5f80fd5b3480156100f2575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610142575f80fd5b50610156610151366004610c91565b610302565b005b348015610163575f80fd5b50610156610172366004610cce565b610485565b348015610182575f80fd5b5061018b6105e9565b60405190815260200161012e565b3480156101a4575f80fd5b506101e16040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b60405161012e9190610ce9565b3480156101f9575f80fd5b5060025461010d9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610225575f80fd5b5060025461024b9074010000000000000000000000000000000000000000900460ff1681565b60405161012e9190610da2565b348015610263575f80fd5b5061018b60015481565b348015610278575f80fd5b5061018b5f5481565b34801561028c575f80fd5b5061015661029b366004610db6565b610923565b3480156102ab575f80fd5b506101566102ba366004610dcd565b610a46565b3480156102ca575f80fd5b5060025474010000000000000000000000000000000000000000900460ff1661024b565b3480156102f9575f80fd5b5060015461018b565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103839190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103e7576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561044357610443610d3c565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc88183604051610479929190610e23565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105069190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461056a576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e45939101610479565b5f6001544710156106a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106ba9190610e3e565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077f91849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e76565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107b8576107b8610d3c565b03610875576002545f906107e29073ffffffffffffffffffffffffffffffffffffffff1683610c5a565b905080610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e7400000000000000000000000000000000606482015260840161069e565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b158015610909575f80fd5b505af115801561091b573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610980573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a49190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a08576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e42039101610479565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a905750825b90505f8267ffffffffffffffff166001148015610aac5750303b155b905081158015610aba575080155b15610af1576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b525784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bea57610bea610d3c565b02179055508315610c505784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c66835a84610c6d565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c8c575f80fd5b919050565b5f60208284031215610ca1575f80fd5b610c6682610c7e565b73ffffffffffffffffffffffffffffffffffffffff81168114610ccb575f80fd5b50565b5f60208284031215610cde575f80fd5b8135610c6681610caa565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d9e577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610db08284610d69565b92915050565b5f60208284031215610dc6575f80fd5b5035919050565b5f805f60608486031215610ddf575f80fd5b8335610dea81610caa565b925060208401359150610dff60408501610c7e565b90509250925092565b5f60208284031215610e18575f80fd5b8151610c6681610caa565b60408101610e318285610d69565b610c666020830184610d69565b80820180821115610db0577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610eae6060830184610d69565b9594505050505056fea164736f6c6343000819000a"; - bytes public constant baseFeeVaultCreationCode = - hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a"; - bytes public constant l1FeeVaultCreationCode = - hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a"; - bytes public constant feeSplitterCreationCode = - hex"6080604052348015600e575f80fd5b5060156019565b60d4565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff908116101560d2575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6112f1806100e15f395ff3fe608060405260043610610096575f3560e01c80637dfbd04911610066578063b87ea8d41161004c578063b87ea8d414610313578063c4d66de814610327578063d61a398b14610346575f80fd5b80637dfbd049146102dd5780637fc81bb7146102f4575f80fd5b80630a7617b3146101dd5780630c0544a3146101fe578063394d27311461026057806354fd4d5014610288575f80fd5b366101d9577fe3007e9730850b5618eacb0537bef0cf0f1600267ae8549e472449d77b731e455c6100f3576040517f17617f6100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337342000000000000000000000000000000000000111480159061012b57503373420000000000000000000000000000000000001914155b801561014b57503373420000000000000000000000000000000000001a14155b801561016b57503373420000000000000000000000000000000000001b14155b156101a2576040517f9dcde10900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405134815233907f2ccfc58c2cef4ee590b5f16be0548cc54afc12e1c66a67b362b7d640fd16bb2d9060200160405180910390a2005b5f80fd5b3480156101e8575f80fd5b506101fc6101f7366004610f4b565b61039c565b005b348015610209575f80fd5b5060015461023a9070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561026b575f80fd5b5060015461023a906fffffffffffffffffffffffffffffffff1681565b348015610293575f80fd5b506102d06040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516102579190610f66565b3480156102e8575f80fd5b5061023a6301e1338081565b3480156102ff575f80fd5b506101fc61030e366004610fb9565b61055e565b34801561031e575f80fd5b506101fc610706565b348015610332575f80fd5b506101fc610341366004610f4b565b610aea565b348015610351575f80fd5b505f546103779062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610257565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061041d9190610fe8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166104ce576040517f99c6ec0800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff85161790945560408051949093049091168084526020840191909152917f16417cc372deec0caee5f52e2ad77a5f07b4591fd56b4ff31b6e20f817d4daeb91015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105bb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105df9190610fe8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610643576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6301e133806fffffffffffffffffffffffffffffffff82161115610693576040517f30b9f35e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546fffffffffffffffffffffffffffffffff8381167001000000000000000000000000000000008181028385161790945560408051949093049091168084526020840191909152917f4492086b630ed3846eec0979dd87a71c814ceb1c6dab80ab81e3450b21e4de289101610552565b60015461073b906fffffffffffffffffffffffffffffffff700100000000000000000000000000000000820481169116611030565b6fffffffffffffffffffffffffffffffff16421015610786576040517f1e4a9f3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016426fffffffffffffffffffffffffffffffff161781556107cb90610ce0565b5f6107e9734200000000000000000000000000000000000011610d06565b90505f610809734200000000000000000000000000000000000019610d06565b90505f61082973420000000000000000000000000000000000001a610d06565b90505f61084973420000000000000000000000000000000000001b610d06565b90506108545f610ce0565b5f82826108618688611060565b61086b9190611060565b6108759190611060565b9050805f036108b0576040517fc8972e5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546040517f54e7f42d000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260448101859052606481018690526201000090910473ffffffffffffffffffffffffffffffffffffffff16906354e7f42d906084015f60405180830381865afa158015610936573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261097b9190810190611118565b905080515f036109b7576040517f763970d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8251811015610a6e575f8382815181106109d6576109d66111e7565b60200260200101515f015190505f8483815181106109f6576109f66111e7565b6020026020010151602001519050805f03610a12575050610a66565b5f610a1d8383610f03565b905080610a56576040517fd68d1b1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a608286611060565b94505050505b6001016109ba565b50828114610aa8576040517f9c01eac000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f73f9a13241a1848ec157967f3a85601709353e616f1f2605d818c0f2d21774df8284604051610ad9929190611214565b60405180910390a150505050505050565b5f54610100900460ff1615808015610b0857505f54600160ff909116105b80610b215750303b158015610b2157505f5460ff166001145b610bb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610c0d575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f80547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff851602179055600180546fffffffffffffffffffffffffffffffff1672015180000000000000000000000000000000001790558015610cdc575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610552565b5050565b807fe3007e9730850b5618eacb0537bef0cf0f1600267ae8549e472449d77b731e455d50565b5f60018273ffffffffffffffffffffffffffffffffffffffff166382356d8a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7691906112af565b6001811115610d8757610d87611282565b14610dbe576040517fb4726cbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff166366d003ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e1e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e429190610fe8565b73ffffffffffffffffffffffffffffffffffffffff1614610e8f576040517fc3380cef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610ed9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610efd91906112cd565b92915050565b5f610f0f835a84610f16565b9392505050565b5f805f805f858888f1949350505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f48575f80fd5b50565b5f60208284031215610f5b575f80fd5b8135610f0f81610f27565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f60208284031215610fc9575f80fd5b81356fffffffffffffffffffffffffffffffff81168114610f0f575f80fd5b5f60208284031215610ff8575f80fd5b8151610f0f81610f27565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6fffffffffffffffffffffffffffffffff81811683821601908082111561105957611059611003565b5092915050565b80820180821115610efd57610efd611003565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156110c3576110c3611073565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561111057611110611073565b604052919050565b5f6020808385031215611129575f80fd5b825167ffffffffffffffff80821115611140575f80fd5b818501915085601f830112611153575f80fd5b81518181111561116557611165611073565b611173848260051b016110c9565b818152848101925060069190911b830184019087821115611192575f80fd5b928401925b818410156111dc57604084890312156111ae575f80fd5b6111b66110a0565b84516111c181610f27565b81528486015186820152835260409093019291840191611197565b979650505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b604080825283518282018190525f91906020906060850190828801855b8281101561126c578151805173ffffffffffffffffffffffffffffffffffffffff168552850151858501529285019290840190600101611231565b5050508093505050508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f602082840312156112bf575f80fd5b815160028110610f0f575f80fd5b5f602082840312156112dd575f80fd5b505191905056fea164736f6c6343000819000a"; - bytes public constant scRevShareCalculatorCreationCode = - hex"6080604052348015600e575f80fd5b50604051610955380380610955833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b6108a8806100ad5f395ff3fe608060405234801561000f575f80fd5b506004361061009f575f3560e01c80635b201d83116100725780637b42d6c2116100585780637b42d6c21461019157806396d842be1461019a5780639c662fdd146101b9575f80fd5b80635b201d831461016b578063712d7bb814610189575f80fd5b806329f33ec8146100a35780634b012e9a146100ed57806354e7f42d1461010257806354fd4d5014610122575b5f80fd5b6001546100c39073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101006100fb3660046106a3565b6101cc565b005b6101156101103660046106c5565b610325565b6040516100e491906106f4565b61015e6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100e49190610758565b61017461271081565b60405163ffffffff90911681526020016100e4565b61017460fa81565b6101746105dc81565b5f546100c39073ffffffffffffffffffffffffffffffffffffffff1681565b6101006101c73660046106a3565b610524565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906107ab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b1576040517f67102c4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917fc7b7459ad1ab31862524bf0c4a5e6a8518c60f27607a5c483a58ea27e30c214c9190a35050565b6040805160028082526060828101909352816020015b604080518082019091525f808252602082015281526020019060019003908161033b575050604080518082019091525f805473ffffffffffffffffffffffffffffffffffffffff16825260208201819052825192935090918391906103a2576103a26107c6565b6020026020010181905250604051806040016040528060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f8152508160018151811061040c5761040c6107c6565b60209081029190910101525f82846104248789610820565b61042e9190610820565b6104389190610820565b90505f61271061044960fa84610839565b6104539190610850565b9050805f0361048e576040517f0174e42600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6104998584610888565b90505f6127106104ab6105dc84610839565b6104b59190610850565b90505f8184116104c557816104c7565b835b905080865f815181106104dc576104dc6107c6565b60209081029190910181015101526104f48186610888565b86600181518110610507576105076107c6565b602002602001015160200181815250505050505050949350505050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610581573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a591906107ab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610609576040517f67102c4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f28c1e0a919cd3b91d6d516417dedc06a2bd7954ad8960315347250b1aee2a4f1905f90a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a0575f80fd5b50565b5f602082840312156106b3575f80fd5b81356106be8161067f565b9392505050565b5f805f80608085870312156106d8575f80fd5b5050823594602084013594506040840135936060013592509050565b602080825282518282018190525f919060409081850190868401855b8281101561074b578151805173ffffffffffffffffffffffffffffffffffffffff168552860151868501529284019290850190600101610710565b5091979650505050505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156107bb575f80fd5b81516106be8161067f565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610833576108336107f3565b92915050565b8082028115828204841417610833576108336107f3565b5f82610883577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610833576108336107f356fea164736f6c6343000819000a"; - bytes public constant l1WithdrawerCreationCode = - hex"6080604052348015600e575f80fd5b50604051610908380380610908833981016040819052602b916067565b5f929092556001805463ffffffff909316600160a01b026001600160c01b03199093166001600160a01b039092169190911791909117905560b8565b5f805f606084860312156078575f80fd5b835160208501519093506001600160a01b03811681146095575f80fd5b604085015190925063ffffffff8116811460ad575f80fd5b809150509250925092565b610843806100c55f395ff3fe608060405260043610610071575f3560e01c806366d003ac1161004c57806366d003ac146102995780638312f149146102ea57806385b5b14d1461030c5780639d7955b41461032b575f80fd5b80633bbed4a0146101d7578063500bf72f146101f657806354fd4d5014610244575f80fd5b366101d3576040805134815247602082018190529133917f363f315f930a17d1266b86a20d6dd34b1cfbc5a9db9f13a65d06a689c3a2af8a910160405180910390a25f5481106101d1576001546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152606060248201525f60648201527401000000000000000000000000000000000000000090910463ffffffff16604482015273420000000000000000000000000000000000000790633dbb202b9083906084015f604051808303818588803b158015610169575f80fd5b505af115801561017b573d5f803e3d5ffd5b505060015460405185815273ffffffffffffffffffffffffffffffffffffffff90911693507f6d92f7d3303f995bf21956bb0c51b388bae348eaf45c23debd2cfa3fcd9ec6469250602001905060405180910390a25b005b5f80fd5b3480156101e2575f80fd5b506101d16101f136600461076c565b61034a565b348015610201575f80fd5b5060015461022a9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b34801561024f575f80fd5b5061028c6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161023b919061078e565b3480156102a4575f80fd5b506001546102c59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023b565b3480156102f5575f80fd5b506102fe5f5481565b60405190815260200161023b565b348015610317575f80fd5b506101d16103263660046107e1565b6104b6565b348015610336575f80fd5b506101d16103453660046107f8565b6105d8565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103cb919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461042f576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e459391015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610513573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610537919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461059b576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e420391016104aa565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610635573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610659919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106bd576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805463ffffffff838116740100000000000000000000000000000000000000008181027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff85161790945560408051949093049091168084526020840191909152917fd00b9b2acb0059a20066ca19b541618141c03305a0a6644d43277758c539b5de91016104aa565b73ffffffffffffffffffffffffffffffffffffffff81168114610769575f80fd5b50565b5f6020828403121561077c575f80fd5b813561078781610748565b9392505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156107f1575f80fd5b5035919050565b5f60208284031215610808575f80fd5b813563ffffffff81168114610787575f80fd5b5f6020828403121561082b575f80fd5b81516107878161074856fea164736f6c6343000819000a"; - bytes public constant feesDepositorCreationCode = - hex"60a060405234801561001057600080fd5b50600160805261001e610023565b6100e3565b600054610100900460ff161561008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610d9161010560003960008181610274015261048e0152610d916000f3fe6080604052600436106100cb5760003560e01c8063645006ca11610074578063a2a956171161004e578063a2a9561714610425578063dad544e014610445578063f68016b71461045a57600080fd5b8063645006ca1461038657806366125607146103c85780637b11936e146103e857600080fd5b80633e47158c116100a55780633e47158c146102fb57806352d84c621461031057806354fd4d501461033057600080fd5b80630de2db4d1461024057806338d38c97146102605780633cb747bf146102a357600080fd5b3661023b576040805134815247602082018190529133917f363f315f930a17d1266b86a20d6dd34b1cfbc5a9db9f13a65d06a689c3a2af8a910160405180910390a26001546bffffffffffffffffffffffff16811061023957600154600080546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000090950485166004820181905260606024830152606482019490945263ffffffff90911660448201529192620100009091041690633dbb202b9084906084016000604051808303818588803b1580156101ce57600080fd5b505af11580156101e2573d6000803e3d6000fd5b50505050508073ffffffffffffffffffffffffffffffffffffffff167f2acaf92365a0b69fb3570802396f62d51aabccd684036b72c3ce78699425e7ee8360405161022f91815260200190565b60405180910390a2505b005b600080fd5b34801561024c57600080fd5b5061023961025b366004610bde565b61048c565b34801561026c57600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020015b60405180910390f35b3480156102af57600080fd5b506000546102d69062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161029a565b34801561030757600080fd5b506102d661069e565b34801561031c57600080fd5b5061023961032b366004610c36565b6108a9565b34801561033c57600080fd5b506103796040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161029a9190610c58565b34801561039257600080fd5b506001546103ab906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff909116815260200161029a565b3480156103d457600080fd5b506102396103e3366004610ccb565b610928565b3480156103f457600080fd5b506001546102d6906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561043157600080fd5b50610239610440366004610ce8565b6109af565b34801561045157600080fd5b506102d6610a2e565b34801561046657600080fd5b506002546104779063ffffffff1681565b60405163ffffffff909116815260200161029a565b7f0000000000000000000000000000000000000000000000000000000000000000600054610100900460ff161580156104cc575060005460ff8083169116105b61055c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100179055610595610aab565b6000805473ffffffffffffffffffffffffffffffffffffffff8681166c01000000000000000000000000026bffffffffffffffffffffffff8916176001556002805463ffffffff87167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9086166201000002167fffffffffffffffffffff000000000000000000000000000000000000000000ff9091161790556040517f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989061068f90839060ff91909116815260200190565b60405180910390a15050505050565b6000806106c97fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905073ffffffffffffffffffffffffffffffffffffffff8116156106ec57919050565b6040518060400160405280601a81526020017f4f564d5f4c3143726f7373446f6d61696e4d657373656e67657200000000000081525051600261072f9190610d03565b604080513060208201526000918101919091527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000919091179061078a906060015b604051602081830303815290604052805190602001205490565b146107c1576040517f54e433cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080513060208201526001918101919091526000906107e390606001610770565b905073ffffffffffffffffffffffffffffffffffffffff811615610877578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561084c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108709190610d67565b9250505090565b6040517f332144db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108b1610b2e565b6002805463ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000083168117909355604080519190921680825260208201939093527f84858bb3fb3ecf87e268ebef250ef9ad9cd53ef7973ef7a0ec9d89470bb00a8091015b60405180910390a15050565b610930610b2e565b6001805473ffffffffffffffffffffffffffffffffffffffff8381166c010000000000000000000000008181026bffffffffffffffffffffffff85161790945560408051949093049091168084526020840191909152917f158f04d12e0403fdd63fbced694e8f70d3b87d04d8e2dfad526f5fcf6e49bbcf910161091c565b6109b7610b2e565b600180546bffffffffffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083168117909355604080519190921680825260208201939093527f132832be4270c0d1573ca543c41517dd443fe9daf5f21a9c74940e6db282e229910161091c565b6000610a3861069e565b73ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190610d67565b905090565b33610ab461069e565b73ffffffffffffffffffffffffffffffffffffffff1614158015610af5575033610adc610a2e565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610b2c576040517fc4050a2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b33610b37610a2e565b73ffffffffffffffffffffffffffffffffffffffff1614610b2c576040517f7f12c64b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80356bffffffffffffffffffffffff81168114610ba057600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610bc757600080fd5b50565b803563ffffffff81168114610ba057600080fd5b60008060008060808587031215610bf457600080fd5b610bfd85610b84565b93506020850135610c0d81610ba5565b92506040850135610c1d81610ba5565b9150610c2b60608601610bca565b905092959194509250565b600060208284031215610c4857600080fd5b610c5182610bca565b9392505050565b600060208083528351808285015260005b81811015610c8557858101830151858201604001528201610c69565b81811115610c97576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cdd57600080fd5b8135610c5181610ba5565b600060208284031215610cfa57600080fd5b610c5182610b84565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610d62577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500290565b600060208284031215610d7957600080fd5b8151610c5181610ba556fea164736f6c634300080f000a"; -} diff --git a/src/libraries/RevShareGasLimits.sol b/src/libraries/RevShareGasLimits.sol deleted file mode 100644 index a8c3d248ec..0000000000 --- a/src/libraries/RevShareGasLimits.sol +++ /dev/null @@ -1,32 +0,0 @@ -// 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 Tenderly simulations, these are the actual gas costs for each of the L2 operations: - /// - L1Withdrawer deployment: 558,056 - /// - SC Rev Share Calculator deployment: 579,688 - /// - Fee Vaults deployment: ~831,000 - /// - Fee Splitter deployment: 1,121,747 - /// - upgrade: ~48,000 - /// - setters: ~50,000 - /// The gas limits below include a buffer to ensure successful execution. - - /// @notice The gas limit for the SC Rev Share Calculator deployment. - uint64 internal constant SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT = 681_986; - - /// @notice The gas limit for the L1 Withdrawer deployment. - uint64 internal constant L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT = 656_536; - - /// @notice The gas limit for the Fee Vaults deployment. - uint64 internal constant FEE_VAULTS_DEPLOYMENT_GAS_LIMIT = 1_200_000; - - /// @notice The gas limit for the Fee Splitter deployment. - uint64 internal constant FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT = 1_319_702; - - /// @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/libraries/RevShareLibrary.sol b/src/libraries/RevShareLibrary.sol new file mode 100644 index 0000000000..c91fdb3617 --- /dev/null +++ b/src/libraries/RevShareLibrary.sol @@ -0,0 +1,85 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +/// @notice Unified library for Revenue Share system containing creation code, gas limits, and predeploys. +/// @dev This library combines the functionality of RevShare, RevShare, and RevSharePredeploys. +library RevShareLibrary { + // ============================ + // Creation Code Repository + // ============================ + + /// @notice The creation code for each fee vault, fee splitter, l1 withdrawer, FeesDepositor and sc rev share calculator. + /// Obtained from https://github.com/defi-wonderland/optimism at commit 0f21af947798a94aa50e797c61f576ca18b1334d + bytes public constant operatorFeeVaultCreationCode = + hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610e8d806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c5a565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610c97565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cb2565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d6b565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610d7f565b6108ec565b3480156102a0575f80fd5b5061014b6102af366004610d96565b610a0f565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dd1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d05565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610dec565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dd1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e07565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff909216602083018190523383830152905190917fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba919081900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee916107649185918591339174010000000000000000000000000000000000000000900460ff1690610e3f565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff16600181111561079d5761079d610d05565b03610841575f6107ad8284610c23565b90508061083c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b505090565b6040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9084906084015f604051808303818588803b1580156108d1575f80fd5b505af11580156108e3573d5f803e3d5ffd5b50505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610949573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061096d9190610dd1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109d1576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a595750825b90505f8267ffffffffffffffff166001148015610a755750303b155b905081158015610a83575080155b15610aba576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b1b5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bb357610bb3610d05565b02179055508315610c195784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c2f835a84610c36565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c55575f80fd5b919050565b5f60208284031215610c6a575f80fd5b610c2f82610c47565b73ffffffffffffffffffffffffffffffffffffffff81168114610c94575f80fd5b50565b5f60208284031215610ca7575f80fd5b8135610c2f81610c73565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d67577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610d798284610d32565b92915050565b5f60208284031215610d8f575f80fd5b5035919050565b5f805f60608486031215610da8575f80fd5b8335610db381610c73565b925060208401359150610dc860408501610c47565b90509250925092565b5f60208284031215610de1575f80fd5b8151610c2f81610c73565b60408101610dfa8285610d32565b610c2f6020830184610d32565b80820180821115610d79577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610e776060830184610d32565b9594505050505056fea164736f6c6343000819000a"; + bytes public constant sequencerFeeVaultCreationCode = + hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610e98806100d65f395ff3fe6080604052600436106100dc575f3560e01c80638312f1491161007c578063b49dc74111610057578063b49dc741146102a0578063d0e12f90146102bf578063d3e5792b146102ee578063d4ff9218146100e7575f80fd5b80638312f1491461025857806384411d651461026d57806385b5b14d14610281575f80fd5b80633ccfd60b116100b75780633ccfd60b1461017757806354fd4d501461019957806366d003ac146101ee57806382356d8a1461021a575f80fd5b80630d9019e1146100e7578063307f2962146101375780633bbed4a014610158575f80fd5b366100e357005b5f80fd5b3480156100f2575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610142575f80fd5b50610156610151366004610c65565b610302565b005b348015610163575f80fd5b50610156610172366004610ca2565b610485565b348015610182575f80fd5b5061018b6105e9565b60405190815260200161012e565b3480156101a4575f80fd5b506101e16040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b60405161012e9190610cbd565b3480156101f9575f80fd5b5060025461010d9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610225575f80fd5b5060025461024b9074010000000000000000000000000000000000000000900460ff1681565b60405161012e9190610d76565b348015610263575f80fd5b5061018b60015481565b348015610278575f80fd5b5061018b5f5481565b34801561028c575f80fd5b5061015661029b366004610d8a565b6108f7565b3480156102ab575f80fd5b506101566102ba366004610da1565b610a1a565b3480156102ca575f80fd5b5060025474010000000000000000000000000000000000000000900460ff1661024b565b3480156102f9575f80fd5b5060015461018b565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103839190610ddc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103e7576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561044357610443610d10565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc88183604051610479929190610df7565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105069190610ddc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461056a576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e45939101610479565b5f6001544710156106a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106ba9190610e12565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff909216602083018190523383830152905190917fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba919081900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161076f9185918591339174010000000000000000000000000000000000000000900460ff1690610e4a565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107a8576107a8610d10565b0361084c575f6107b88284610c2e565b905080610847576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e7400000000000000000000000000000000606482015260840161069e565b505090565b6040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9084906084015f604051808303818588803b1580156108dc575f80fd5b505af11580156108ee573d5f803e3d5ffd5b50505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610954573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109789190610ddc565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e42039101610479565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a645750825b90505f8267ffffffffffffffff166001148015610a805750303b155b905081158015610a8e575080155b15610ac5576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b265784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bbe57610bbe610d10565b02179055508315610c245784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c3a835a84610c41565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c60575f80fd5b919050565b5f60208284031215610c75575f80fd5b610c3a82610c52565b73ffffffffffffffffffffffffffffffffffffffff81168114610c9f575f80fd5b50565b5f60208284031215610cb2575f80fd5b8135610c3a81610c7e565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d72577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610d848284610d3d565b92915050565b5f60208284031215610d9a575f80fd5b5035919050565b5f805f60608486031215610db3575f80fd5b8335610dbe81610c7e565b925060208401359150610dd360408501610c52565b90509250925092565b5f60208284031215610dec575f80fd5b8151610c3a81610c7e565b60408101610e058285610d3d565b610c3a6020830184610d3d565b80820180821115610d84577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610e826060830184610d3d565b9594505050505056fea164736f6c6343000819000a"; + /// @notice Both `L1FeeVault` and `BaseFeeVault` share the exact same creation code. + bytes public constant defaultFeeVaultCreationCode = + hex"6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610e8d806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c5a565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610c97565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cb2565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d6b565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610d7f565b6108ec565b3480156102a0575f80fd5b5061014b6102af366004610d96565b610a0f565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dd1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d05565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610dec565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dd1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e07565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff909216602083018190523383830152905190917fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba919081900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee916107649185918591339174010000000000000000000000000000000000000000900460ff1690610e3f565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff16600181111561079d5761079d610d05565b03610841575f6107ad8284610c23565b90508061083c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b505090565b6040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8216600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9084906084015f604051808303818588803b1580156108d1575f80fd5b505af11580156108e3573d5f803e3d5ffd5b50505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610949573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061096d9190610dd1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109d1576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a595750825b90505f8267ffffffffffffffff166001148015610a755750303b155b905081158015610a83575080155b15610aba576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b1b5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bb357610bb3610d05565b02179055508315610c195784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c2f835a84610c36565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c55575f80fd5b919050565b5f60208284031215610c6a575f80fd5b610c2f82610c47565b73ffffffffffffffffffffffffffffffffffffffff81168114610c94575f80fd5b50565b5f60208284031215610ca7575f80fd5b8135610c2f81610c73565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d67577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610d798284610d32565b92915050565b5f60208284031215610d8f575f80fd5b5035919050565b5f805f60608486031215610da8575f80fd5b8335610db381610c73565b925060208401359150610dc860408501610c47565b90509250925092565b5f60208284031215610de1575f80fd5b8151610c2f81610c73565b60408101610dfa8285610d32565b610c2f6020830184610d32565b80820180821115610d79577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610e776060830184610d32565b9594505050505056fea164736f6c6343000819000a"; + bytes public constant feeSplitterCreationCode = + hex"6080604052348015600e575f80fd5b5060156019565b60d4565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff908116101560d2575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611308806100e15f395ff3fe608060405260043610610096575f3560e01c80637dfbd04911610066578063b87ea8d41161004c578063b87ea8d414610284578063c4d66de814610298578063d61a398b146102b7575f80fd5b80637dfbd0491461024e5780637fc81bb714610265575f80fd5b80630a7617b31461014e5780630c0544a31461016f578063394d2731146101d157806354fd4d50146101f9575f80fd5b3661014a573373ffffffffffffffffffffffffffffffffffffffff7f21346dddac42cc163a6523eefc19df981df7352c870dc3b0b17a6a92fc6fe8135c161461010b576040517f14885cf900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805134815247602082018190529133917f213e72af0d3613bd643cff3059f872c1015e6541624e37872bf95eefbaf220a8910160405180910390a2005b5f80fd5b348015610159575f80fd5b5061016d610168366004610f49565b61030d565b005b34801561017a575f80fd5b506001546101ab9070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101dc575f80fd5b506001546101ab906fffffffffffffffffffffffffffffffff1681565b348015610204575f80fd5b506102416040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516101c89190610f64565b348015610259575f80fd5b506101ab6301e1338081565b348015610270575f80fd5b5061016d61027f366004610fb7565b6104cf565b34801561028f575f80fd5b5061016d6106c2565b3480156102a3575f80fd5b5061016d6102b2366004610f49565b610a9a565b3480156102c2575f80fd5b505f546102e89062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101c8565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561036a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038e9190610fe6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103f2576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff811661043f576040517f99c6ec0800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff85161790945560408051949093049091168084526020840191909152917f16417cc372deec0caee5f52e2ad77a5f07b4591fd56b4ff31b6e20f817d4daeb91015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561052c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105509190610fe6565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105b4576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806fffffffffffffffffffffffffffffffff165f036105ff576040517fcf85916100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6301e133806fffffffffffffffffffffffffffffffff8216111561064f576040517f30b9f35e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546fffffffffffffffffffffffffffffffff8381167001000000000000000000000000000000008181028385161790945560408051949093049091168084526020840191909152917f4492086b630ed3846eec0979dd87a71c814ceb1c6dab80ab81e3450b21e4de2891016104c3565b6001546106f7906fffffffffffffffffffffffffffffffff70010000000000000000000000000000000082048116911661102e565b6fffffffffffffffffffffffffffffffff16421015610742576040517f1e4a9f3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016426fffffffffffffffffffffffffffffffff161790555f61079c734200000000000000000000000000000000000011610c8e565b90505f6107bc734200000000000000000000000000000000000019610c8e565b90505f6107dc73420000000000000000000000000000000000001a610c8e565b90505f6107fc73420000000000000000000000000000000000001b610c8e565b90506108075f610edb565b5f8282610814868861105e565b61081e919061105e565b610828919061105e565b9050805f03610863576040517fc8972e5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546040517f54e7f42d000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260448101859052606481018690526201000090910473ffffffffffffffffffffffffffffffffffffffff16906354e7f42d906084015f60405180830381865afa1580156108e9573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261092e919081019061111c565b80519091505f81900361096d576040517f763970d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b82811015610a1d575f84828151811061098b5761098b6111eb565b6020026020010151602001519050805f036109a65750610a15565b5f6109cd8684815181106109bc576109bc6111eb565b60200260200101515f015183610f01565b905080610a06576040517fd68d1b1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a10828561105e565b935050505b600101610970565b50838114610a57576040517f9c01eac000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f73f9a13241a1848ec157967f3a85601709353e616f1f2605d818c0f2d21774df8385604051610a88929190611218565b60405180910390a15050505050505050565b5f54610100900460ff1615808015610ab857505f54600160ff909116105b80610ad15750303b158015610ad157505f5460ff166001145b610b61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610bbd575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f80547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff85160217905572015180000000000000000000000000000000006fffffffffffffffffffffffffffffffff4216176001558015610c8a575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016104c3565b5050565b5f60018273ffffffffffffffffffffffffffffffffffffffff166382356d8a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610cda573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cfe91906112b3565b6001811115610d0f57610d0f611286565b14610d46576040517fb4726cbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff166366d003ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610da6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dca9190610fe6565b73ffffffffffffffffffffffffffffffffffffffff1614610e17576040517fc3380cef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b47610e2183610edb565b8273ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610e6b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e8f91906112d1565b91504782610e9d83836112e8565b14610ed4576040517f87c91c5c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050919050565b807f21346dddac42cc163a6523eefc19df981df7352c870dc3b0b17a6a92fc6fe8135d50565b5f610f0d835a84610f14565b9392505050565b5f805f805f858888f1949350505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f46575f80fd5b50565b5f60208284031215610f59575f80fd5b8135610f0d81610f25565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f60208284031215610fc7575f80fd5b81356fffffffffffffffffffffffffffffffff81168114610f0d575f80fd5b5f60208284031215610ff6575f80fd5b8151610f0d81610f25565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6fffffffffffffffffffffffffffffffff81811683821601908082111561105757611057611001565b5092915050565b8082018082111561107157611071611001565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156110c7576110c7611077565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561111457611114611077565b604052919050565b5f602080838503121561112d575f80fd5b825167ffffffffffffffff80821115611144575f80fd5b818501915085601f830112611157575f80fd5b81518181111561116957611169611077565b611177848260051b016110cd565b818152848101925060069190911b830184019087821115611196575f80fd5b928401925b818410156111e057604084890312156111b2575f80fd5b6111ba6110a4565b84516111c581610f25565b8152848601518682015283526040909301929184019161119b565b979650505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b604080825283518282018190525f91906020906060850190828801855b82811015611270578151805173ffffffffffffffffffffffffffffffffffffffff168552850151858501529285019290840190600101611235565b5050508093505050508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f602082840312156112c3575f80fd5b815160028110610f0d575f80fd5b5f602082840312156112e1575f80fd5b5051919050565b818103818111156110715761107161100156fea164736f6c6343000819000a"; + bytes public constant scRevShareCalculatorCreationCode = + hex"6080604052348015600e575f80fd5b50604051610955380380610955833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b6108a8806100ad5f395ff3fe608060405234801561000f575f80fd5b506004361061009f575f3560e01c80635b201d83116100725780637b42d6c2116100585780637b42d6c21461019157806396d842be1461019a5780639c662fdd146101b9575f80fd5b80635b201d831461016b578063712d7bb814610189575f80fd5b806329f33ec8146100a35780634b012e9a146100ed57806354e7f42d1461010257806354fd4d5014610122575b5f80fd5b6001546100c39073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101006100fb3660046106a3565b6101cc565b005b6101156101103660046106c5565b610325565b6040516100e491906106f4565b61015e6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100e49190610758565b61017461271081565b60405163ffffffff90911681526020016100e4565b61017460fa81565b6101746105dc81565b5f546100c39073ffffffffffffffffffffffffffffffffffffffff1681565b6101006101c73660046106a3565b610524565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906107ab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b1576040517f67102c4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917fc7b7459ad1ab31862524bf0c4a5e6a8518c60f27607a5c483a58ea27e30c214c9190a35050565b6040805160028082526060828101909352816020015b604080518082019091525f808252602082015281526020019060019003908161033b575050604080518082019091525f805473ffffffffffffffffffffffffffffffffffffffff16825260208201819052825192935090918391906103a2576103a26107c6565b6020026020010181905250604051806040016040528060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f8152508160018151811061040c5761040c6107c6565b60209081029190910101525f82846104248789610820565b61042e9190610820565b6104389190610820565b90505f61271061044960fa84610839565b6104539190610850565b9050805f0361048e576040517f0174e42600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6104998584610888565b90505f6127106104ab6105dc84610839565b6104b59190610850565b90505f8184116104c557816104c7565b835b905080865f815181106104dc576104dc6107c6565b60209081029190910181015101526104f48186610888565b86600181518110610507576105076107c6565b602002602001015160200181815250505050505050949350505050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610581573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a591906107ab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610609576040517f67102c4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f28c1e0a919cd3b91d6d516417dedc06a2bd7954ad8960315347250b1aee2a4f1905f90a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a0575f80fd5b50565b5f602082840312156106b3575f80fd5b81356106be8161067f565b9392505050565b5f805f80608085870312156106d8575f80fd5b5050823594602084013594506040840135936060013592509050565b602080825282518282018190525f919060409081850190868401855b8281101561074b578151805173ffffffffffffffffffffffffffffffffffffffff168552860151868501529284019290850190600101610710565b5091979650505050505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156107bb575f80fd5b81516106be8161067f565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610833576108336107f3565b92915050565b8082028115828204841417610833576108336107f3565b5f82610883577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610833576108336107f356fea164736f6c6343000819000a"; + bytes public constant l1WithdrawerCreationCode = + hex"6080604052348015600e575f80fd5b50604051610908380380610908833981016040819052602b916067565b5f929092556001805463ffffffff909316600160a01b026001600160c01b03199093166001600160a01b039092169190911791909117905560b8565b5f805f606084860312156078575f80fd5b835160208501519093506001600160a01b03811681146095575f80fd5b604085015190925063ffffffff8116811460ad575f80fd5b809150509250925092565b610843806100c55f395ff3fe608060405260043610610071575f3560e01c806366d003ac1161004c57806366d003ac146102995780638312f149146102ea57806385b5b14d1461030c5780639d7955b41461032b575f80fd5b80633bbed4a0146101d7578063500bf72f146101f657806354fd4d5014610244575f80fd5b366101d3576040805134815247602082018190529133917f363f315f930a17d1266b86a20d6dd34b1cfbc5a9db9f13a65d06a689c3a2af8a910160405180910390a25f5481106101d1576001546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152606060248201525f60648201527401000000000000000000000000000000000000000090910463ffffffff16604482015273420000000000000000000000000000000000000790633dbb202b9083906084015f604051808303818588803b158015610169575f80fd5b505af115801561017b573d5f803e3d5ffd5b505060015460405185815273ffffffffffffffffffffffffffffffffffffffff90911693507f6d92f7d3303f995bf21956bb0c51b388bae348eaf45c23debd2cfa3fcd9ec6469250602001905060405180910390a25b005b5f80fd5b3480156101e2575f80fd5b506101d16101f136600461076c565b61034a565b348015610201575f80fd5b5060015461022a9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b34801561024f575f80fd5b5061028c6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161023b919061078e565b3480156102a4575f80fd5b506001546102c59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023b565b3480156102f5575f80fd5b506102fe5f5481565b60405190815260200161023b565b348015610317575f80fd5b506101d16103263660046107e1565b6104b6565b348015610336575f80fd5b506101d16103453660046107f8565b6105d8565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103cb919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461042f576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e459391015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610513573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610537919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461059b576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e420391016104aa565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610635573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610659919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106bd576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805463ffffffff838116740100000000000000000000000000000000000000008181027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff85161790945560408051949093049091168084526020840191909152917fd00b9b2acb0059a20066ca19b541618141c03305a0a6644d43277758c539b5de91016104aa565b73ffffffffffffffffffffffffffffffffffffffff81168114610769575f80fd5b50565b5f6020828403121561077c575f80fd5b813561078781610748565b9392505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156107f1575f80fd5b5035919050565b5f60208284031215610808575f80fd5b813563ffffffff81168114610787575f80fd5b5f6020828403121561082b575f80fd5b81516107878161074856fea164736f6c6343000819000a"; + + // ============================ + // Gas Limits + // ============================ + + /// @notice Based on Tenderly simulations, these are the actual gas costs for each of the L2 operations: + /// - L1Withdrawer deployment: 558,056 + /// - SC Rev Share Calculator deployment: 579,688 + /// - Fee Vaults deployment: ~831,000 + /// - Fee Splitter deployment: 1,121,747 + /// - Splitter upgrade: 72,913 + /// - Vaults upgrades: ~55,000 + /// The gas limits below include a buffer to ensure successful execution. + + /// @notice The gas limit for the SC Rev Share Calculator deployment. + uint64 internal constant SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT = 681_986; + + /// @notice The gas limit for the L1 Withdrawer deployment. + uint64 internal constant L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT = 656_536; + + /// @notice The gas limit for the Fee Vaults deployment. + uint64 internal constant FEE_VAULTS_DEPLOYMENT_GAS_LIMIT = 1_200_000; + + /// @notice The gas limit for the Fee Splitter deployment. + uint64 internal constant FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT = 1_319_702; + + /// @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; + + // ============================ + // Predeploy Addresses + // ============================ + + /// @notice Address of the Create2Deployer Preinstall on L2. + address internal constant CREATE2_DEPLOYER = 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2; + + /// @notice Address of the Operator Fee Vault Predeploy on L2. + address internal constant OPERATOR_FEE_VAULT = 0x420000000000000000000000000000000000001b; + + /// @notice Address of the FeeSplitter Predeploy on L2. + address internal constant FEE_SPLITTER = 0x420000000000000000000000000000000000002B; + + /// @notice Address of the Sequencer Fee Vault Predeploy on L2. + address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; + + /// @notice Address of the L1 Fee Vault Predeploy on L2. + address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A; + + /// @notice Address of the Base Fee Vault Predeploy on L2. + address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019; + + /// @notice The default recipient for the FeeVault once part of the Revenue Share system. + address public constant FEE_VAULT_RECIPIENT = FEE_SPLITTER; + + /// @notice Address of the ProxyAdmin predeploy on L2. + address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018; +} diff --git a/src/libraries/RevSharePredeploys.sol b/src/libraries/RevSharePredeploys.sol deleted file mode 100644 index 09d66d9cb4..0000000000 --- a/src/libraries/RevSharePredeploys.sol +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -// TODO: Import `FeeSplitter` and `OperatorFeeVault` from the Optimism contracts library once they are included. -/// @notice Library for storing the predeploys for the Revenue Share templates -abstract contract RevSharePredeploys { - /// @notice Address of the Create2Deployer Preinstall on L2. - address internal constant CREATE2_DEPLOYER = 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2; - /// @notice Address of the Operator Fee Vault Predeploy on L2. - address internal constant OPERATOR_FEE_VAULT = 0x420000000000000000000000000000000000001b; - /// @notice Address of the FeeSplitter Predeploy on L2. - address internal constant FEE_SPLITTER = 0x420000000000000000000000000000000000002B; - /// @notice Address of the Sequencer Fee Vault Predeploy on L2. - address internal constant SEQUENCER_FEE_WALLET = 0x4200000000000000000000000000000000000011; - /// @notice Address of the L1 Fee Vault Predeploy on L2. - address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A; - /// @notice Address of the Base Fee Vault Predeploy on L2. - address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019; - /// @notice The default recipient for the FeeVault once part of the Revenue Share system. - address public constant FEE_VAULT_RECIPIENT = FEE_SPLITTER; - /// @notice Address of the ProxyAdmin predeploy on L2. - address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018; -} diff --git a/src/template/DeployFeesDepositor.sol b/src/template/DeployFeesDepositor.sol deleted file mode 100644 index b69fbe5330..0000000000 --- a/src/template/DeployFeesDepositor.sol +++ /dev/null @@ -1,149 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {VmSafe} from "forge-std/Vm.sol"; -import {LibString} from "@solady/utils/LibString.sol"; -import {stdToml} from "lib/forge-std/src/StdToml.sol"; -import {SimpleTaskBase} from "src/tasks/types/SimpleTaskBase.sol"; -import {Action} from "src/libraries/MultisigTypes.sol"; -import {RevShareCodeRepo} from "src/libraries/RevShareCodeRepo.sol"; -import {Proxy} from "optimism/packages/contracts-bedrock/src/universal/Proxy.sol"; -import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; - -/// @notice Interface for the FeesDepositor contract on L1. -/// This is used to deposit fees into L2. -interface IFeesDepositor { - function initialize(uint96 _minDepositAmount, address _l2Recipient, address _messenger, uint32 _gasLimit) - external; - function minDepositAmount() external view returns (uint96); - function l2Recipient() external view returns (address); - function gasLimit() external view returns (uint32); -} - -/// @notice Interface for the CREATE2 deployer contract. -interface ICreate2Deployer { - function deploy(uint256 value, bytes32 salt, bytes memory code) external; -} - -/// @notice Interface for the ProxyAdmin contract. -interface IProxyAdmin { - function upgradeAndCall(address payable _proxy, address _implementation, bytes memory _data) external; -} - -/// @notice A template contract for deploying and initializing the FeesDepositor contract. -contract DeployFeesDepositor is SimpleTaskBase { - using LibString for string; - using stdToml for string; - - /// @notice The address of the CREATE2 deployer contract. - /// @notice This is present in OP Stack chains as a Preinstall and on L1. - address internal constant CREATE2_DEPLOYER = address(0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2); - - /// @notice The salt for the deployment of the FeesDepositor contract. - string public salt; - /// @notice The address of the L2 recipient of the fees. - address public l2Recipient; - /// @notice The minimum amount of fees the depositor needs before initiating a deposit. - uint96 public minDepositAmount; - /// @notice The address of the portal contract. - address public portal; - /// @notice The gas limit for the deposit. - uint32 public gasLimit; - /// @notice The address of the proxy admin. - address public proxyAdmin; - - /// @notice The initialization code for the proxy contract. Sent to the CREATE2 deployer. - bytes internal _proxyInitCode; - /// @notice The calculated address of the proxy contract. - address internal _proxyCalculatedAddress; - /// @notice The calculated address of the FeesDepositor implementation contract. - address internal _implCalculatedAddress; - - /// @notice Returns the safe address string identifier. - function safeAddressString() public pure override returns (string memory) { - return "ProxyAdminOwner"; - } - - /// @notice Returns the storage write permissions required for this task. This is an array of - /// contract names that are expected to be written to during the execution of the task. - function _taskStorageWrites() internal pure virtual override returns (string[] memory) {} - - /// @notice Returns an array of strings that refer to contract names in the address registry. - /// Contracts with these names are expected to have their balance changes during the task. - /// By default returns an empty array. Override this function if your task expects balance changes. - function _taskBalanceChanges() internal view virtual override returns (string[] memory) {} - - /// @notice Sets up the template with implementation configurations from a TOML file. - /// State overrides are not applied yet. Keep this in mind when performing various pre-simulation assertions in this function. - function _templateSetup(string memory _taskConfigFilePath, address) internal override { - string memory tomlContent = vm.readFile(_taskConfigFilePath); - salt = tomlContent.readString(".salt"); - require(bytes(salt).length > 0, "salt must be set"); - - // Default to 0 if not set - minDepositAmount = uint96(tomlContent.readUint(".minDepositAmount")); - - l2Recipient = tomlContent.readAddress(".l2Recipient"); - require(l2Recipient != address(0), "l2Recipient must be set"); - - portal = tomlContent.readAddress(".portal"); - require(portal != address(0), "portal must be set"); - - uint256 _gasLimitRaw = tomlContent.readUint(".gasLimit"); - require(_gasLimitRaw > 0, "gasLimit must be set"); - require(_gasLimitRaw <= type(uint32).max, "gasLimit must be less than uint32.max"); - gasLimit = uint32(_gasLimitRaw); - - proxyAdmin = tomlContent.readAddress(".proxyAdmin"); - require(proxyAdmin != address(0), "proxyAdmin must be set"); - - _proxyInitCode = bytes.concat(type(Proxy).creationCode, abi.encode(proxyAdmin)); - - _proxyCalculatedAddress = - Create2.computeAddress(bytes32(bytes(salt)), keccak256(_proxyInitCode), CREATE2_DEPLOYER); - vm.label(_proxyCalculatedAddress, "Proxy"); - - _implCalculatedAddress = Create2.computeAddress( - bytes32(bytes(salt)), keccak256(RevShareCodeRepo.feesDepositorCreationCode), CREATE2_DEPLOYER - ); - vm.label(_implCalculatedAddress, "FeesDepositorV100"); - } - - /// @notice Builds the deployment transactions for the FeesDepositor implementation and proxy. - /// @dev This function deploys both the implementation contract and the proxy contract using CREATE2, - /// then initializes the proxy with the implementation. The calculated addresses are validated - /// implicitly because if the calculated address of the Proxy would differ from the one we - /// calculated, the task would fail on the check for code to be present, since the changes - /// in build function revert and the parent contract validates that accessed accounts have code. - function _build(address) internal override { - // Deploy the FeesDepositor implementation contract using CREATE2 - ICreate2Deployer(CREATE2_DEPLOYER).deploy(0, bytes32(bytes(salt)), RevShareCodeRepo.feesDepositorCreationCode); - - // Deploy the proxy contract using CREATE2 with the calculated initialization code - ICreate2Deployer(CREATE2_DEPLOYER).deploy(0, bytes32(bytes(salt)), _proxyInitCode); - - // Initialize the proxy by upgrading to the implementation and calling initialize via ProxyAdmin - IProxyAdmin(proxyAdmin).upgradeAndCall( - payable(_proxyCalculatedAddress), - _implCalculatedAddress, - abi.encodeCall(IFeesDepositor.initialize, (minDepositAmount, l2Recipient, portal, gasLimit)) - ); - } - - /// @notice This method performs all validations and assertions that verify the calls executed as expected. - function _validate(VmSafe.AccountAccess[] memory, Action[] memory, address) internal view override { - require( - IFeesDepositor(payable(_proxyCalculatedAddress)).minDepositAmount() == minDepositAmount, - "minDepositAmount mismatch" - ); - require(IFeesDepositor(payable(_proxyCalculatedAddress)).l2Recipient() == l2Recipient, "l2Recipient mismatch"); - require(IFeesDepositor(payable(_proxyCalculatedAddress)).gasLimit() == gasLimit, "gasLimit mismatch"); - } - - /// @notice Override to return a list of addresses that should not be checked for code length. - function _getCodeExceptions() internal view virtual override returns (address[] memory) { - address[] memory codeExceptions = new address[](1); - codeExceptions[0] = _proxyCalculatedAddress; - return codeExceptions; - } -} diff --git a/src/template/RevShareUpgradeAndSetup.sol b/src/template/RevShareUpgradeAndSetup.sol new file mode 100644 index 0000000000..04f591f669 --- /dev/null +++ b/src/template/RevShareUpgradeAndSetup.sol @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {VmSafe} from "forge-std/Vm.sol"; +import {stdToml} from "forge-std/StdToml.sol"; +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; + +import {OPCMTaskBase} from "src/tasks/types/OPCMTaskBase.sol"; +import {Action} from "src/libraries/MultisigTypes.sol"; +import {MultisigTaskPrinter} from "src/libraries/MultisigTaskPrinter.sol"; +import {RevShareContractsUpgrader} from "src/RevShareContractsUpgrader.sol"; + +/// @notice Task for setting up revenue sharing on OP Stack chains. +contract RevShareUpgradeAndSetup is OPCMTaskBase { + using stdToml for string; + using EnumerableSet for EnumerableSet.AddressSet; + + /// @notice RevShareContractsUpgrader address + address public REV_SHARE_UPGRADER; + + /// @notice RevShare configurations + RevShareContractsUpgrader.RevShareConfig[] internal revShareConfigs; + + /// @notice Names in the SimpleAddressRegistry that are expected to be written during this task. + function _taskStorageWrites() internal pure virtual override returns (string[] memory) { + return new string[](0); + } + + /// @notice Returns an array of strings that refer to contract names in the address registry. + function _taskBalanceChanges() internal view virtual override returns (string[] memory) { + return new string[](0); + } + + /// @notice Sets the allowed storage accesses - override to add portal addresses + function _setAllowedStorageAccesses() internal virtual override { + super._setAllowedStorageAccesses(); + // Add portal addresses as they will have storage writes from depositTransaction calls + for (uint256 i; i < revShareConfigs.length; i++) { + _allowedStorageAccesses.add(revShareConfigs[i].portal); + } + } + + /// @notice Sets up the template with configurations from a TOML file. + function _templateSetup(string memory taskConfigFilePath, address) internal override { + string memory tomlContent = vm.readFile(taskConfigFilePath); + + // Load RevShareContractsUpgrader address from TOML + REV_SHARE_UPGRADER = tomlContent.readAddress(".revShareUpgrader"); + require(REV_SHARE_UPGRADER.code.length > 0, "RevShareContractsUpgrader has no code"); + vm.label(REV_SHARE_UPGRADER, "RevShareContractsUpgrader"); + + // Set RevShareContractsUpgrader as the allowed target for delegatecall + OPCM_TARGETS.push(REV_SHARE_UPGRADER); + + // Get the length of the configs array by parsing just the portal addresses + address[] memory portals = abi.decode(tomlContent.parseRaw(".configs[*].portal"), (address[])); + require(portals.length > 0, "No configs found"); + + // Load RevShare configs by reading each field individually + // Note: We can't use parseRaw + abi.decode directly because TOML inline tables + // sort keys alphabetically, which doesn't match the struct field order + // So we need to read each field separately and construct the struct manually + for (uint256 i; i < portals.length; i++) { + string memory basePath = string.concat(".configs[", vm.toString(i), "]"); + revShareConfigs.push(RevShareContractsUpgrader.RevShareConfig({ + portal: tomlContent.readAddress(string.concat(basePath, ".portal")), + l1WithdrawerConfig: RevShareContractsUpgrader.L1WithdrawerConfig({ + minWithdrawalAmount: tomlContent.readUint(string.concat(basePath, ".l1WithdrawerConfig.minWithdrawalAmount")), + recipient: tomlContent.readAddress(string.concat(basePath, ".l1WithdrawerConfig.recipient")), + gasLimit: uint32(tomlContent.readUint(string.concat(basePath, ".l1WithdrawerConfig.gasLimit"))) + }), + chainFeesRecipient: tomlContent.readAddress(string.concat(basePath, ".chainFeesRecipient")) + })); + } + } + + /// @notice Builds the actions for executing the operations. + function _build(address) internal override { + // Delegatecall into RevShareContractsUpgrader + // OPCMTaskBase uses Multicall3Delegatecall, so this delegatecall will be captured as an action + (bool success,) = REV_SHARE_UPGRADER.delegatecall( + abi.encodeCall(RevShareContractsUpgrader.upgradeAndSetupRevShare, (revShareConfigs)) + ); + require(success, "RevShareUpgradeAndSetup: Delegatecall failed"); + } + + /// @notice This method performs all validations and assertions that verify the calls executed as expected. + function _validate(VmSafe.AccountAccess[] memory, Action[] memory _actions, address) internal view override { + MultisigTaskPrinter.printTitle("Validating delegatecall to RevShareContractsUpgrader"); + + // For OPCM tasks using delegatecall, we validate that the delegatecall was made correctly. + // The actual portal calls happen inside the delegatecall and are validated by integration tests. + + require(_actions.length == 1, "Expected exactly one action"); + + Action memory action = _actions[0]; + require(action.target == REV_SHARE_UPGRADER, "Delegatecall to RevShareContractsUpgrader not found"); + require(action.value == 0, "Call value must be 0 for delegatecall"); + + // Verify it's calling upgradeAndSetupRevShare + bytes4 selector = bytes4(action.arguments); + require( + selector == RevShareContractsUpgrader.upgradeAndSetupRevShare.selector, + "Wrong function selector for delegatecall" + ); + + // Decode and validate the revShareConfigs argument + // Skip the first 4 bytes (function selector) and decode the rest + RevShareContractsUpgrader.RevShareConfig[] memory configs; + { + bytes memory args = action.arguments; + bytes memory argsWithoutSelector = new bytes(args.length - 4); + for (uint256 j = 4; j < args.length; j++) { + argsWithoutSelector[j - 4] = args[j]; + } + configs = abi.decode(argsWithoutSelector, (RevShareContractsUpgrader.RevShareConfig[])); + } + + // Validate each config + require(configs.length > 0, "No configs provided"); + require(configs.length == revShareConfigs.length, "Config length mismatch"); + + for (uint256 i; i < configs.length; i++) { + RevShareContractsUpgrader.RevShareConfig memory config = configs[i]; + + // Validate portal address is not zero + require(config.portal != address(0), "Portal address cannot be zero"); + + // Validate L1 withdrawer config + require( + config.l1WithdrawerConfig.recipient != address(0), + "L1 withdrawer recipient cannot be zero" + ); + require( + config.l1WithdrawerConfig.gasLimit > 0, + "Gas limit must be greater than 0" + ); + + // Validate chain fees recipient + require( + config.chainFeesRecipient != address(0), + "Chain fees recipient cannot be zero" + ); + + // Validate config matches the expected config from template setup + require(config.portal == revShareConfigs[i].portal, "Portal address mismatch"); + require( + config.l1WithdrawerConfig.minWithdrawalAmount == revShareConfigs[i].l1WithdrawerConfig.minWithdrawalAmount, + "Min withdrawal amount mismatch" + ); + require( + config.l1WithdrawerConfig.recipient == revShareConfigs[i].l1WithdrawerConfig.recipient, + "L1 withdrawer recipient mismatch" + ); + require( + config.l1WithdrawerConfig.gasLimit == revShareConfigs[i].l1WithdrawerConfig.gasLimit, + "Gas limit mismatch" + ); + require( + config.chainFeesRecipient == revShareConfigs[i].chainFeesRecipient, + "Chain fees recipient mismatch" + ); + } + } + + /// @notice Override to return a list of addresses that should not be checked for code length. + function _getCodeExceptions() internal view virtual override returns (address[] memory) { + return new address[](0); + } +} diff --git a/src/template/RevenueShareUpgradePath.sol b/src/template/RevenueShareUpgradePath.sol deleted file mode 100644 index 60048cf1ce..0000000000 --- a/src/template/RevenueShareUpgradePath.sol +++ /dev/null @@ -1,662 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {VmSafe} from "forge-std/Vm.sol"; -import {LibString} from "@solady/utils/LibString.sol"; -import {stdToml} from "lib/forge-std/src/StdToml.sol"; -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"; -import {RevSharePredeploys} from "src/libraries/RevSharePredeploys.sol"; - -/// @notice Interface for the OptimismPortal2 in L1. This is the main interaction point for the template. -interface IOptimismPortal2 { - function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes memory _data) - external - payable; -} - -/// @notice Interface of the Create2 Preinstall in L2. -interface ICreate2Deployer { - function deploy(uint256 _value, bytes32 _salt, bytes memory _code) external; -} - -/// @notice Interface for the FeeSplitter in L2. -interface IFeeSplitter { - function initialize(address _sharesCalculator) external; -} - -/// @notice Interface for the vaults in L2. -interface IFeeVault { - function initialize(address _recipient, uint256 _minWithdrawalAmount, uint8 _withdrawalNetwork) external; -} - -/// @notice Interface for ProxyAdmin. -interface IProxyAdmin { - function upgrade(address payable _proxy, address _implementation) external; - function upgradeAndCall(address payable _proxy, address _implementation, bytes memory _data) external; -} - -/// @notice A template contract for chains to upgrade to the Revenue Share v1.0.0 implementation. -contract RevenueShareV100UpgradePath is SimpleTaskBase, RevSharePredeploys { - using LibString for string; - using stdToml for string; - - /// @notice Used to validate calls made to the OptimismPortal. - mapping(bytes32 => uint8) internal _callsToPortal; - - /// @notice The withdrawal network configuration for the fee vaults. - uint8 public constant FEE_VAULT_WITHDRAWAL_NETWORK = 1; - - /// @notice The minimum withdrawal amount configuration for the fee vaults. - uint256 public constant FEE_VAULT_MIN_WITHDRAWAL_AMOUNT = 0; - - /// @notice The configuration for the l1 withdrawer - uint256 public l1WithdrawerMinWithdrawalAmount; - // TODO(17505): This address is expected to be set to the appropriate FeesDepositor address once deployed. - // The deployment is done by running the task at test/tasks/example/eth/016-deploy-fees-depositor - address public l1WithdrawerRecipient; - /// @notice The gas limit for the L1 Withdrawer. - uint32 public l1WithdrawerGasLimit; - - /// @notice The configuration for sc rev share calculator. - address public scRevShareCalcChainFeesRecipient; - - /// @notice Whether to use the default calculator. If true, deploy the default SC Rev Share Calculator and L1Withdrawer. - /// If false, use the custom calculator and skip deploying the default calculator and L1Withdrawer. - bool public useDefaultCalculator; - - /// @notice Custom calculator address. - address public customCalculator; - - /// @notice The address of the OptimismPortal through which we are making the deposit txns - address public portal; - - /// @notice The salt seed to be used for the L2 deployments - string public saltSeed; - - /// @notice The address the OperatorFeeVault implementation is deployed to. - address internal _operatorFeeVaultPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the OperatorFeeVault. - bytes internal _operatorFeeVaultCalldata; - - /// @notice The address the SequencerFeeVault implementation is deployed to. - address internal _sequencerFeeVaultPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the SequencerFeeVault. - bytes internal _sequencerFeeVaultCalldata; - - /// @notice The address the BaseFeeVault implementation is deployed to. - address internal _baseFeeVaultPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the BaseFeeVault. - bytes internal _baseFeeVaultCalldata; - - /// @notice The address the L1FeeVault implementation is deployed to. - address internal _l1FeeVaultPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the L1FeeVault. - bytes internal _l1FeeVaultCalldata; - - /// @notice The address the L1Withdrawer implementation is deployed to. - address internal _l1WithdrawerPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the L1Withdrawer. - bytes internal _l1WithdrawerCalldata; - - /// @notice The address the SuperchainRevenueShareCalculator implementation is deployed to. - address internal _scRevShareCalculatorPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the SuperchainRevenueShareCalculator. - bytes internal _scRevShareCalculatorCalldata; - - /// @notice The address the FeeSplitter implementation is deployed to. - address internal _feeSplitterPrecalculatedAddress; - /// @notice The calldata sent to the OptimismPortal to deploy the FeeSplitter. - bytes internal _feeSplitterCalldata; - - /// @notice Returns the safe address string identifier. - function safeAddressString() public pure override returns (string memory) { - return "ProxyAdminOwner"; - } - - /// @notice Returns the storage write permissions required for this task. This is an array of - /// contract names that are expected to be written to during the execution of the task. - function _taskStorageWrites() internal pure virtual override returns (string[] memory) { - string[] memory _storageWrites = new string[](1); - _storageWrites[0] = "OptimismPortal"; - return _storageWrites; - } - - /// @notice Returns an array of strings that refer to contract names in the address registry. - /// Contracts with these names are expected to have their balance changes during the task. - /// By default returns an empty array. Override this function if your task expects balance changes. - function _taskBalanceChanges() internal view virtual override returns (string[] memory) { - string[] memory _balanceChanges = new string[](1); - _balanceChanges[0] = "OptimismPortal"; - return _balanceChanges; - } - - /// @notice Sets up the template with implementation configurations from a TOML file. - /// State overrides are not applied yet. Keep this in mind when performing various pre-simulation assertions in this function. - function _templateSetup(string memory _taskConfigFilePath, address) internal override { - string memory _toml = vm.readFile(_taskConfigFilePath); - - portal = _toml.readAddress(".portal"); - require(portal != address(0), "portal must be set in config"); - - saltSeed = _toml.readString(".saltSeed"); - require(bytes(saltSeed).length != 0, "saltSeed must be set in the config"); - - // Read whether to use the default calculator - useDefaultCalculator = _toml.readBool(".useDefaultCalculator"); - - // If useDefaultCalculator is true, deploy the default calculator and L1Withdrawer - if (useDefaultCalculator) { - l1WithdrawerMinWithdrawalAmount = _toml.readUint(".l1WithdrawerMinWithdrawalAmount"); - - l1WithdrawerRecipient = _toml.readAddress(".l1WithdrawerRecipient"); - require(l1WithdrawerRecipient != address(0), "l1WithdrawerRecipient must be set in config"); - - uint256 _l1WithdrawerGasLimitRaw = _toml.readUint(".l1WithdrawerGasLimit"); - require(_l1WithdrawerGasLimitRaw > 0, "l1WithdrawerGasLimit must be greater than 0"); - require(_l1WithdrawerGasLimitRaw <= type(uint32).max, "l1WithdrawerGasLimit must be less than uint32.max"); - l1WithdrawerGasLimit = uint32(_l1WithdrawerGasLimitRaw); - - // Calculate addresses and data to deploy L1 Withdrawer - bytes memory _l1WithdrawerInitCode = bytes.concat( - RevShareCodeRepo.l1WithdrawerCreationCode, - abi.encode(l1WithdrawerMinWithdrawalAmount, l1WithdrawerRecipient, l1WithdrawerGasLimit) - ); - _l1WithdrawerCalldata = - abi.encodeCall(ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "L1Withdrawer"), _l1WithdrawerInitCode)); - _l1WithdrawerPrecalculatedAddress = - Utils.getCreate2Address(_getSalt(saltSeed, "L1Withdrawer"), _l1WithdrawerInitCode, CREATE2_DEPLOYER); - // Expected calls for L1 Withdrawer: 1 (deploy) - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, - false, - _l1WithdrawerCalldata - ) - ) - ); - - // Calculate addresses and data to deploy SC Rev Share Calculator - scRevShareCalcChainFeesRecipient = _toml.readAddress(".scRevShareCalcChainFeesRecipient"); - require( - scRevShareCalcChainFeesRecipient != address(0), "scRevShareCalcChainFeesRecipient must be set in config" - ); - - bytes memory _scRevShareCalculatorInitCode = bytes.concat( - RevShareCodeRepo.scRevShareCalculatorCreationCode, - abi.encode(_l1WithdrawerPrecalculatedAddress, scRevShareCalcChainFeesRecipient) - ); - _scRevShareCalculatorCalldata = abi.encodeCall( - ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "SCRevShareCalculator"), _scRevShareCalculatorInitCode) - ); - - _scRevShareCalculatorPrecalculatedAddress = Utils.getCreate2Address( - _getSalt(saltSeed, "SCRevShareCalculator"), _scRevShareCalculatorInitCode, CREATE2_DEPLOYER - ); - - // Expected calls for SC Rev Shares Calculator: 1 (deploy) - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, - false, - _scRevShareCalculatorCalldata - ) - ) - ); - } else { - // Use custom calculator, read it from config and set it as the calculator address for the fee splitter - customCalculator = _toml.readAddress(".customCalculator"); - require(customCalculator != address(0), "customCalculator must be set when useDefaultCalculator is false"); - _scRevShareCalculatorPrecalculatedAddress = customCalculator; - } - - // Calculate addresses and data to deploy vaults - // Calculate addresses and data to deploy OperatorFeeVault - bytes memory _operatorFeeVaultInitCode = RevShareCodeRepo.operatorFeeVaultCreationCode; - _operatorFeeVaultPrecalculatedAddress = - Utils.getCreate2Address(_getSalt(saltSeed, "OperatorFeeVault"), _operatorFeeVaultInitCode, CREATE2_DEPLOYER); - - _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, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _operatorFeeVaultCalldata - ) - ) - ); - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(OPERATOR_FEE_VAULT), - address(_operatorFeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - ( - FEE_VAULT_RECIPIENT, - FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, - FEE_VAULT_WITHDRAWAL_NETWORK - ) - ) - ) - ) - ) - ) - ); - - // Calculate addresses and data to deploy SequencerFeeVault - bytes memory _sequencerFeeVaultInitCode = RevShareCodeRepo.sequencerFeeVaultCreationCode; - _sequencerFeeVaultPrecalculatedAddress = Utils.getCreate2Address( - _getSalt(saltSeed, "SequencerFeeVault"), _sequencerFeeVaultInitCode, CREATE2_DEPLOYER - ); - _sequencerFeeVaultCalldata = abi.encodeCall( - ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "SequencerFeeVault"), _sequencerFeeVaultInitCode) - ); - - // Expected calls for SequencerFeeVault: 2 (deploy + upgrade) - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _sequencerFeeVaultCalldata - ) - ) - ); - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(SEQUENCER_FEE_WALLET), - address(_sequencerFeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - ( - FEE_VAULT_RECIPIENT, - FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, - FEE_VAULT_WITHDRAWAL_NETWORK - ) - ) - ) - ) - ) - ) - ); - - // Calculate addresses and data to deploy BaseFeeVault - bytes memory _baseFeeVaultInitCode = RevShareCodeRepo.baseFeeVaultCreationCode; - _baseFeeVaultPrecalculatedAddress = - Utils.getCreate2Address(_getSalt(saltSeed, "BaseFeeVault"), _baseFeeVaultInitCode, CREATE2_DEPLOYER); - _baseFeeVaultCalldata = - abi.encodeCall(ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "BaseFeeVault"), _baseFeeVaultInitCode)); - - // Expected calls for BaseFeeVault: 2 (deploy + upgradeAndCall) - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _baseFeeVaultCalldata - ) - ) - ); - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(BASE_FEE_VAULT), - address(_baseFeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - (FEE_VAULT_RECIPIENT, FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, FEE_VAULT_WITHDRAWAL_NETWORK) - ) - ) - ) - ) - ) - ); - - // Calculate addresses and data to deploy L1FeeVault - bytes memory _l1FeeVaultInitCode = RevShareCodeRepo.l1FeeVaultCreationCode; - _l1FeeVaultPrecalculatedAddress = - Utils.getCreate2Address(_getSalt(saltSeed, "L1FeeVault"), _l1FeeVaultInitCode, CREATE2_DEPLOYER); - _l1FeeVaultCalldata = - abi.encodeCall(ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "L1FeeVault"), _l1FeeVaultInitCode)); - - // Expected calls for L1FeeVault: 2 (deploy + upgradeAndCall) - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _l1FeeVaultCalldata - ) - ) - ); - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(L1_FEE_VAULT), - address(_l1FeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - (FEE_VAULT_RECIPIENT, FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, FEE_VAULT_WITHDRAWAL_NETWORK) - ) - ) - ) - ) - ) - ); - - // Calculate addresses and data to deploy Fee Splitter - _feeSplitterCalldata = abi.encodeCall( - ICreate2Deployer.deploy, (0, _getSalt(saltSeed, "FeeSplitter"), RevShareCodeRepo.feeSplitterCreationCode) - ); - _feeSplitterPrecalculatedAddress = Utils.getCreate2Address( - _getSalt(saltSeed, "FeeSplitter"), RevShareCodeRepo.feeSplitterCreationCode, CREATE2_DEPLOYER - ); - - // Expected calls for FeeSplitter: 2 (deploy + upgradeAndCall) - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, - false, - _feeSplitterCalldata - ) - ) - ); - _incrementCallsToPortal( - abi.encodeCall( - IOptimismPortal2.depositTransaction, - ( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(FEE_SPLITTER), - address(_feeSplitterPrecalculatedAddress), - abi.encodeCall(IFeeSplitter.initialize, (_scRevShareCalculatorPrecalculatedAddress)) - ) - ) - ) - ) - ); - } - - /// @notice Before implementing the `_build` function, template developers must consider the following: - /// 1. Which Multicall contract does this template use — `Multicall3` or `Multicall3Delegatecall`? - /// 2. Based on the contract, should the target be called using `call` or `delegatecall`? - /// 3. Ensure that the call to the target uses the appropriate method (`call` or `delegatecall`) accordingly. - /// Guidelines: - /// - `Multicall3`: - /// If the template directly inherits from `L2TaskBase` or `SimpleTaskBase`, it uses the `Multicall3` contract. - /// In this case, calls to the target **must** use `call`, e.g.: - /// ` dgm.setRespectedGameType(IOptimismPortal2(payable(portalAddress)), cfg[chainId].gameType);` - /// WARNING: Any state written to in this function will be reverted after the build function has been run. - /// Do not rely on setting global variables in this function. - function _build(address) internal override { - // Only deploy L1 Withdrawer and SC Rev Share Calculator if using default calculator - if (useDefaultCalculator) { - // Deploy L1 Withdrawer - IOptimismPortal2(payable(portal)).depositTransaction( - 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, - RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, - false, - _scRevShareCalculatorCalldata - ); - } - - _deployFeeSplitter(); - _deployFeeVaults(); - } - - /// @notice This method performs all validations and assertions that verify the calls executed as expected. - function _validate(VmSafe.AccountAccess[] memory, Action[] memory _actions, address) internal override { - MultisigTaskPrinter.printTitle("Validating calls to portal"); - // Expected portal calls: - // - 10 (base vault operations + fee splitter) - // - 12 if using default calculator (+ L1 withdrawer + calculator) - uint256 _expectedCallsToPortal = useDefaultCalculator ? 12 : 10; - uint256 _actualCallsToPortal = 0; - for (uint256 i = 0; i < _actions.length; i++) { - Action memory action = _actions[i]; - if (action.target == address(portal) && action.arguments.length > 0) { - _verifyAndDecrementCallsToPortal(action.arguments); - _actualCallsToPortal += 1; - } - } - - require(_actualCallsToPortal == _expectedCallsToPortal, "Invalid number of calls to portal"); - } - - /// @notice Override to return a list of addresses that should not be checked for code length. - function _getCodeExceptions() internal view virtual override returns (address[] memory) {} - - /// @notice Deploys the fee vaults implementation and upgrades the proxies to the calculated addresses. - function _deployFeeVaults() private { - // Deploy the fee vaults - // Deploy the operator fee vault - IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _operatorFeeVaultCalldata - ); - IOptimismPortal2(payable(portal)).depositTransaction( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(OPERATOR_FEE_VAULT), - address(_operatorFeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - ( - FEE_VAULT_RECIPIENT, - FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, - FEE_VAULT_WITHDRAWAL_NETWORK - ) - ) - ) - ) - ); - - // Deploy the sequencer fee vault - IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _sequencerFeeVaultCalldata - ); - IOptimismPortal2(payable(portal)).depositTransaction( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(SEQUENCER_FEE_WALLET), - address(_sequencerFeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - ( - FEE_VAULT_RECIPIENT, - FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, - FEE_VAULT_WITHDRAWAL_NETWORK - ) - ) - ) - ) - ); - - // Deploy the base fee vault - IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - false, - _baseFeeVaultCalldata - ); - IOptimismPortal2(payable(portal)).depositTransaction( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(BASE_FEE_VAULT), - address(_baseFeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - (FEE_VAULT_RECIPIENT, FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, FEE_VAULT_WITHDRAWAL_NETWORK) - ) - ) - ) - ); - - // Deploy the l1 fee vault - IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), 0, RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, false, _l1FeeVaultCalldata - ); - IOptimismPortal2(payable(portal)).depositTransaction( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(L1_FEE_VAULT), - address(_l1FeeVaultPrecalculatedAddress), - abi.encodeCall( - IFeeVault.initialize, - (FEE_VAULT_RECIPIENT, FEE_VAULT_MIN_WITHDRAWAL_AMOUNT, FEE_VAULT_WITHDRAWAL_NETWORK) - ) - ) - ) - ); - } - - /// @notice Deploys the fee splitter implementation using Create2. - function _deployFeeSplitter() private { - // Deploy Fee Splitter - IOptimismPortal2(payable(portal)).depositTransaction( - address(CREATE2_DEPLOYER), - 0, - RevShareGasLimits.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, - false, - _feeSplitterCalldata - ); - - IOptimismPortal2(payable(portal)).depositTransaction( - address(PROXY_ADMIN), - 0, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - false, - abi.encodeCall( - IProxyAdmin.upgradeAndCall, - ( - payable(FEE_SPLITTER), - address(_feeSplitterPrecalculatedAddress), - abi.encodeCall(IFeeSplitter.initialize, (_scRevShareCalculatorPrecalculatedAddress)) - ) - ) - ); - } - - function _incrementCallsToPortal(bytes memory _calldata) private { - _callsToPortal[keccak256(_calldata)] += 1; - } - - function _verifyAndDecrementCallsToPortal(bytes memory _calldata) private { - bytes32 _calldataHash = keccak256(_calldata); - require(_callsToPortal[_calldataHash] > 0, "Invalid number of calls with this calldata"); - _callsToPortal[_calldataHash] -= 1; - } - - function _getSalt(string memory _prefix, string memory _suffix) private pure returns (bytes32) { - return keccak256(abi.encodePacked(bytes(_prefix), bytes(":"), bytes(_suffix))); - } -} diff --git a/test/integration/IntegrationBase.t.sol b/test/integration/IntegrationBase.t.sol index 5a478bfb83..1fed75da1b 100644 --- a/test/integration/IntegrationBase.t.sol +++ b/test/integration/IntegrationBase.t.sol @@ -9,32 +9,55 @@ import {AddressAliasHelper} from "@eth-optimism-bedrock/src/vendor/AddressAliasH /// @title IntegrationBase /// @notice Base contract for integration tests with L1->L2 deposit transaction replay functionality abstract contract IntegrationBase is Test { - /// @notice Replay all deposit transactions from L1 to L2 - /// @param _forkId The fork ID to switch to for L2 execution + /// @notice Replay all deposit transactions from L1 to multiple L2s + /// @param _forkIds Array of fork IDs for each L2 chain /// @param _isSimulate If true, only process the second half of logs to avoid duplicates. /// Task simulations emit events twice: once during the initial dry-run /// and once during the actual simulation. Taking the second half ensures /// we only process the final simulation results. - function _relayAllMessages(uint256 _forkId, bool _isSimulate) internal { + /// @param _portals Array of Portal addresses corresponding to each fork. + /// Only events emitted by each portal will be replayed on its corresponding L2. + function _relayAllMessages(uint256[] memory _forkIds, bool _isSimulate, address[] memory _portals) internal { + require(_forkIds.length == _portals.length, "Fork IDs and portals length mismatch"); + + // Get logs from L1 execution (currently active fork should be L1) + Vm.Log[] memory _allLogs = vm.getRecordedLogs(); + + // Process each L2 chain + for (uint256 _chainIdx; _chainIdx < _forkIds.length; _chainIdx++) { + _relayMessagesForChain(_allLogs, _forkIds[_chainIdx], _isSimulate, _portals[_chainIdx]); + } + } + + /// @notice Replay deposit transactions for a single L2 chain + /// @param _allLogs All recorded logs from L1 execution + /// @param _forkId The fork ID to switch to for L2 execution + /// @param _isSimulate If true, only process the second half of logs + /// @param _portal The Portal address to filter events by + function _relayMessagesForChain( + Vm.Log[] memory _allLogs, + uint256 _forkId, + bool _isSimulate, + address _portal + ) internal { + // Switch to L2 fork for execution vm.selectFork(_forkId); console2.log("\n"); console2.log("================================================================================"); console2.log("=== Replaying Deposit Transactions on L2 ==="); + console2.log("=== Portal:", _portal); console2.log("=== Each transaction includes Tenderly simulation link ==="); - console2.log("=== Network is set to 10 (OP Mainnet) - adjust if testing on different L2 ==="); + console2.log("=== Network is set to", block.chainid, "- adjust if testing on different L2 ==="); console2.log("================================================================================"); - // Get logs from L1 execution - Vm.Log[] memory _allLogs = vm.getRecordedLogs(); - // If this is a simulation, only take the second half of logs to avoid processing duplicates // Simulations emit events twice, so we skip the first half uint256 _startIndex = _isSimulate ? _allLogs.length / 2 : 0; uint256 _logsCount = _isSimulate ? _allLogs.length - _startIndex : _allLogs.length; Vm.Log[] memory _logs = new Vm.Log[](_logsCount); - for (uint256 _i = 0; _i < _logsCount; _i++) { + for (uint256 _i; _i < _logsCount; _i++) { _logs[_i] = _allLogs[_startIndex + _i]; } @@ -45,9 +68,9 @@ abstract contract IntegrationBase is Test { uint256 _successCount; uint256 _failureCount; - for (uint256 _i = 0; _i < _logs.length; _i++) { - // Check if this is a TransactionDeposited event - if (_logs[_i].topics[0] == _transactionDepositedHash) { + for (uint256 _i; _i < _logs.length; _i++) { + // Check if this is a TransactionDeposited event AND it was emitted by the specified portal + if (_logs[_i].topics[0] == _transactionDepositedHash && _logs[_i].emitter == _portal) { // Decode indexed parameters address _from = address(uint160(uint256(_logs[_i].topics[1]))); address _to = address(uint160(uint256(_logs[_i].topics[2]))); @@ -69,7 +92,7 @@ abstract contract IntegrationBase is Test { } console2.log("\n=== Summary ==="); - console2.log("Total transactions:", _transactionCount); + console2.log("Total transactions processed:", _transactionCount); console2.log("Successful transactions:", _successCount); console2.log("Failed transactions:", _failureCount); @@ -127,7 +150,7 @@ abstract contract IntegrationBase is Test { /// @notice Helper function to slice bytes function _slice(bytes memory _data, uint256 _start, uint256 _length) internal pure returns (bytes memory) { bytes memory _result = new bytes(_length); - for (uint256 _i = 0; _i < _length; _i++) { + for (uint256 _i; _i < _length; _i++) { _result[_i] = _data[_start + _i]; } return _result; @@ -165,7 +188,7 @@ abstract contract IntegrationBase is Test { /// @notice Convert address to lowercase hex string without 0x prefix function _toAsciiString(address _addr) internal pure returns (string memory) { bytes memory _s = new bytes(40); - for (uint256 _i = 0; _i < 20; _i++) { + for (uint256 _i; _i < 20; _i++) { bytes1 _b = bytes1(uint8(uint256(uint160(_addr)) / (2 ** (8 * (19 - _i))))); bytes1 _hi = bytes1(uint8(_b) / 16); bytes1 _lo = bytes1(uint8(_b) - 16 * uint8(_hi)); @@ -179,7 +202,7 @@ abstract contract IntegrationBase is Test { function _bytesToHexString(bytes memory _data) internal pure returns (string memory) { bytes memory _hexChars = "0123456789abcdef"; bytes memory _result = new bytes(_data.length * 2); - for (uint256 _i = 0; _i < _data.length; _i++) { + for (uint256 _i; _i < _data.length; _i++) { _result[_i * 2] = _hexChars[uint8(_data[_i] >> 4)]; _result[_i * 2 + 1] = _hexChars[uint8(_data[_i] & 0x0f)]; } diff --git a/test/integration/RevShareContractsUpgraderIntegration.t.sol b/test/integration/RevShareContractsUpgraderIntegration.t.sol new file mode 100644 index 0000000000..c47ff0ef36 --- /dev/null +++ b/test/integration/RevShareContractsUpgraderIntegration.t.sol @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +import {RevShareContractsUpgrader} from "src/RevShareContractsUpgrader.sol"; +import {RevShareUpgradeAndSetup} from "src/template/RevShareUpgradeAndSetup.sol"; +import {IntegrationBase} from "./IntegrationBase.t.sol"; +import {Test} from "forge-std/Test.sol"; + +// Interfaces +import {IOptimismPortal2} from "@eth-optimism-bedrock/interfaces/L1/IOptimismPortal2.sol"; +import {IProxyAdmin} from "@eth-optimism-bedrock/interfaces/universal/IProxyAdmin.sol"; +import {ICreate2Deployer} from "src/interfaces/ICreate2Deployer.sol"; +import {IFeeSplitter} from "src/interfaces/IFeeSplitter.sol"; +import {IFeeVault} from "src/interfaces/IFeeVault.sol"; +import {IL1Withdrawer} from "src/interfaces/IL1Withdrawer.sol"; +import {ISuperchainRevSharesCalculator} from "src/interfaces/ISuperchainRevSharesCalculator.sol"; + +contract RevShareContractsUpgraderIntegrationTest is IntegrationBase { + RevShareContractsUpgrader public revShareUpgrader; + RevShareUpgradeAndSetup public revShareTask; + + // Fork IDs + uint256 internal _mainnetForkId; + uint256 internal _opMainnetForkId; + uint256 internal _inkMainnetForkId; + + // L1 addresses + address internal constant PROXY_ADMIN_OWNER = 0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A; + address internal constant OP_MAINNET_PORTAL = 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed; + address internal constant INK_MAINNET_PORTAL = 0x5d66C1782664115999C47c9fA5cd031f495D3e4F; + address internal constant REV_SHARE_UPGRADER_ADDRESS = 0x0000000000000000000000000000000000001337; + + // L2 predeploys (same across all OP Stack chains) + address internal constant SEQUENCER_FEE_VAULT = 0x4200000000000000000000000000000000000011; + address internal constant OPERATOR_FEE_VAULT = 0x420000000000000000000000000000000000001b; + address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019; + address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A; + address internal constant FEE_SPLITTER = 0x420000000000000000000000000000000000002B; + + // Expected deployed contracts (deterministic CREATE2 addresses) + address internal constant OP_L1_WITHDRAWER = 0xB3AeB34b88D73Fb4832f65BEa5Bd865017fB5daC; + address internal constant OP_REV_SHARE_CALCULATOR = 0x3E806Fd8592366E850197FEC8D80608b5526Bba2; + + address internal constant INK_L1_WITHDRAWER = 0x70e26B12a578176BccCD3b7e7f58f605871c5eF7; + address internal constant INK_REV_SHARE_CALCULATOR = 0xd7a5307B4Ce92B0269903191007b95dF42552Dfa; + + // Test configuration - OP Mainnet + uint256 internal constant OP_MIN_WITHDRAWAL_AMOUNT = 350000; + address internal constant OP_L1_WITHDRAWAL_RECIPIENT = 0x0000000000000000000000000000000000000001; + uint32 internal constant OP_WITHDRAWAL_GAS_LIMIT = 800000; + address internal constant OP_CHAIN_FEES_RECIPIENT = 0x0000000000000000000000000000000000000001; + + // Test configuration - Ink Mainnet + uint256 internal constant INK_MIN_WITHDRAWAL_AMOUNT = 500000; + address internal constant INK_L1_WITHDRAWAL_RECIPIENT = 0x0000000000000000000000000000000000000002; + uint32 internal constant INK_WITHDRAWAL_GAS_LIMIT = 1000000; + address internal constant INK_CHAIN_FEES_RECIPIENT = 0x0000000000000000000000000000000000000002; + + bool internal constant IS_SIMULATE = true; + + function setUp() public { + // Create forks for L1 (mainnet) and L2 (OP Mainnet) + _mainnetForkId = vm.createFork("http://127.0.0.1:8545"); + _opMainnetForkId = vm.createFork("http://127.0.0.1:9545"); + _inkMainnetForkId = vm.createFork("http://127.0.0.1:9546"); + + // Deploy contracts on L1 + vm.selectFork(_mainnetForkId); + + // Deploy RevShareContractsUpgrader and etch at predetermined address + revShareUpgrader = new RevShareContractsUpgrader(); + vm.etch(REV_SHARE_UPGRADER_ADDRESS, address(revShareUpgrader).code); + revShareUpgrader = RevShareContractsUpgrader(REV_SHARE_UPGRADER_ADDRESS); + + // Deploy RevShareUpgradeAndSetup task + revShareTask = new RevShareUpgradeAndSetup(); + } + + /// @notice Test the integration of upgradeAndSetupRevShare + function test_upgradeAndSetupRevShare_integration() public { + // Step 1: Record logs for L1→L2 message replay + vm.recordLogs(); + + // Step 2: Execute task simulation + revShareTask.simulate("test/tasks/example/eth/016-revshare-upgrade-and-setup/config.toml"); + + // Step 3: Relay deposit transactions from L1 to all L2s + uint256[] memory forkIds = new uint256[](2); + forkIds[0] = _opMainnetForkId; + forkIds[1] = _inkMainnetForkId; + + address[] memory portals = new address[](2); + portals[0] = OP_MAINNET_PORTAL; + portals[1] = INK_MAINNET_PORTAL; + + _relayAllMessages(forkIds, IS_SIMULATE, portals); + + // Step 4: Assert the state of the OP Mainnet contracts + vm.selectFork(_opMainnetForkId); + _assertL2State(OP_L1_WITHDRAWER, OP_REV_SHARE_CALCULATOR, OP_MIN_WITHDRAWAL_AMOUNT, OP_L1_WITHDRAWAL_RECIPIENT, OP_WITHDRAWAL_GAS_LIMIT, OP_CHAIN_FEES_RECIPIENT); + + // Step 5: Assert the state of the Ink Mainnet contracts + vm.selectFork(_inkMainnetForkId); + _assertL2State(INK_L1_WITHDRAWER, INK_REV_SHARE_CALCULATOR, INK_MIN_WITHDRAWAL_AMOUNT, INK_L1_WITHDRAWAL_RECIPIENT, INK_WITHDRAWAL_GAS_LIMIT, INK_CHAIN_FEES_RECIPIENT); + } + + /// @notice Assert the state of all L2 contracts after upgrade + /// @param _minWithdrawalAmount Expected minimum withdrawal amount for L1Withdrawer + /// @param _l1Recipient Expected recipient address for L1Withdrawer + /// @param _gasLimit Expected gas limit for L1Withdrawer + /// @param _chainFeesRecipient Expected chain fees recipient (remainder recipient) + function _assertL2State( + address _l1Withdrawer, + address _revShareCalculator, + uint256 _minWithdrawalAmount, + address _l1Recipient, + uint32 _gasLimit, + address _chainFeesRecipient + ) internal view { + // L1Withdrawer: check configuration + assertEq(IL1Withdrawer(_l1Withdrawer).minWithdrawalAmount(), _minWithdrawalAmount, "L1Withdrawer minWithdrawalAmount mismatch"); + assertEq(IL1Withdrawer(_l1Withdrawer).recipient(), _l1Recipient, "L1Withdrawer recipient mismatch"); + assertEq(IL1Withdrawer(_l1Withdrawer).withdrawalGasLimit(), _gasLimit, "L1Withdrawer gasLimit mismatch"); + + // Rev Share Calculator: check it's linked correctly + assertEq( + ISuperchainRevSharesCalculator(_revShareCalculator).shareRecipient(), + _l1Withdrawer, + "Calculator shareRecipient should be L1Withdrawer" + ); + assertEq( + ISuperchainRevSharesCalculator(_revShareCalculator).remainderRecipient(), + _chainFeesRecipient, + "Calculator remainderRecipient mismatch" + ); + + // Fee Splitter: check calculator is set + assertEq( + IFeeSplitter(FEE_SPLITTER).sharesCalculator(), + _revShareCalculator, + "FeeSplitter calculator should be set to RevShareCalculator" + ); + + // Vaults: recipient should be fee splitter, withdrawal network should be L2, min withdrawal amount 0 + _assertFeeVaultsState(); + } + + /// @notice Assert the configuration of all fee vaults + function _assertFeeVaultsState() internal view { + _assertVaultGetters(SEQUENCER_FEE_VAULT, FEE_SPLITTER, IFeeVault.WithdrawalNetwork.L2, 0); + _assertVaultGetters(OPERATOR_FEE_VAULT, FEE_SPLITTER, IFeeVault.WithdrawalNetwork.L2, 0); + _assertVaultGetters(BASE_FEE_VAULT, FEE_SPLITTER, IFeeVault.WithdrawalNetwork.L2, 0); + _assertVaultGetters(L1_FEE_VAULT, FEE_SPLITTER, IFeeVault.WithdrawalNetwork.L2, 0); + } + + /// @notice Assert the configuration of a single fee vault + /// @param _vault The address of the fee vault + /// @param _recipient The expected recipient of the fee vault + /// @param _withdrawalNetwork The expected withdrawal network + /// @param _minWithdrawalAmount The expected minimum withdrawal amount + /// @dev Ensures both the legacy and the new getters return the same value + function _assertVaultGetters( + address _vault, + address _recipient, + IFeeVault.WithdrawalNetwork _withdrawalNetwork, + uint256 _minWithdrawalAmount + ) internal view { + // Check new getters + assertEq(IFeeVault(_vault).recipient(), _recipient, "Vault recipient mismatch"); + assertEq( + uint256(IFeeVault(_vault).withdrawalNetwork()), + uint256(_withdrawalNetwork), + "Vault withdrawalNetwork mismatch" + ); + assertEq(IFeeVault(_vault).minWithdrawalAmount(), _minWithdrawalAmount, "Vault minWithdrawalAmount mismatch"); + + // Check legacy getters (should return same values) + assertEq(IFeeVault(_vault).RECIPIENT(), _recipient, "Vault RECIPIENT (legacy) mismatch"); + assertEq( + uint256(IFeeVault(_vault).WITHDRAWAL_NETWORK()), + uint256(_withdrawalNetwork), + "Vault WITHDRAWAL_NETWORK (legacy) mismatch" + ); + assertEq( + IFeeVault(_vault).MIN_WITHDRAWAL_AMOUNT(), + _minWithdrawalAmount, + "Vault MIN_WITHDRAWAL_AMOUNT (legacy) mismatch" + ); + } +} diff --git a/test/integration/RevenueShareIntegration.t.sol b/test/integration/RevenueShareIntegration.t.sol deleted file mode 100644 index 02081aed89..0000000000 --- a/test/integration/RevenueShareIntegration.t.sol +++ /dev/null @@ -1,165 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.15; - -import {RevenueShareV100UpgradePath} from "src/template/RevenueShareUpgradePath.sol"; -import {Action} from "src/libraries/MultisigTypes.sol"; -import {IntegrationBase} from "./IntegrationBase.t.sol"; -import {Test} from "forge-std/Test.sol"; - -enum WithdrawalNetwork { - L1, - L2 -} - -interface IFeeVault { - function MIN_WITHDRAWAL_AMOUNT() external view returns (uint256); - function RECIPIENT() external view returns (address); - function WITHDRAWAL_NETWORK() external view returns (WithdrawalNetwork); - function minWithdrawalAmount() external view returns (uint256); - function recipient() external view returns (address); - function withdrawalNetwork() external view returns (WithdrawalNetwork); -} - -interface IFeeSplitter { - function sharesCalculator() external view returns (address); -} - -interface IL1Withdrawer { - function minWithdrawalAmount() external view returns (uint256); - function recipient() external view returns (address); - function withdrawalGasLimit() external view returns (uint32); -} - -interface ISuperchainRevSharesCalculator { - function shareRecipient() external view returns (address payable); - function remainderRecipient() external view returns (address payable); -} - -contract RevenueShareIntegrationTest is IntegrationBase { - RevenueShareV100UpgradePath public revenueShareTemplate; - - // Fork IDs - uint256 internal _mainnetForkId; - uint256 internal _l2ForkId; - - // L2 predeploys - /// @notice Address of the Sequencer Fee Vault Predeploy on L2. - address internal constant SEQUENCER_FEE_VAULT = 0x4200000000000000000000000000000000000011; - /// @notice Address of the Operator Fee Vault Predeploy on L2. - address internal constant OPERATOR_FEE_VAULT = 0x420000000000000000000000000000000000001b; - /// @notice Address of the Base Fee Vault Predeploy on L2. - address internal constant BASE_FEE_VAULT = 0x4200000000000000000000000000000000000019; - /// @notice Address of the L1 Fee Vault Predeploy on L2. - address internal constant L1_FEE_VAULT = 0x420000000000000000000000000000000000001A; - /// @notice Address of the FeeSplitter Predeploy on L2. - address internal constant FEE_SPLITTER = 0x420000000000000000000000000000000000002B; - - // Deployed contracts (precalculated as they are deployed with CREATE2) - /// @notice Address of the L1 Withdrawer Predeploy on L2. - address internal constant L1_WITHDRAWER = 0x524E512Dd372C70E7866a7825481385b7b533af0; - /// @notice Address of the Rev Share Calculator Predeploy on L2. - address internal constant REV_SHARE_CALCULATOR = 0x72aa66CaA04C9bd83Ecc43c65cff2Cf837EE4BB3; - - function setUp() public { - _mainnetForkId = vm.createFork("http://127.0.0.1:8545"); - _l2ForkId = vm.createFork("http://127.0.0.1:9545"); - vm.selectFork(_mainnetForkId); - revenueShareTemplate = new RevenueShareV100UpgradePath(); - } - - /// @notice Test the integration of the revenue share system when the chain is opting in - function test_revenueShare_defaultCalculator_integration() public { - string memory _configPath = "test/tasks/example/eth/015-revenue-share-upgrade/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); - - // L1Withdrawer: check withdrawal threshold and fees depositor - assertEq( - IL1Withdrawer(L1_WITHDRAWER).minWithdrawalAmount(), - vm.parseTomlUint(_config, ".l1WithdrawerMinWithdrawalAmount") - ); - assertEq(IL1Withdrawer(L1_WITHDRAWER).recipient(), vm.parseTomlAddress(_config, ".l1WithdrawerRecipient")); - assertEq(IL1Withdrawer(L1_WITHDRAWER).withdrawalGasLimit(), vm.parseTomlUint(_config, ".l1WithdrawerGasLimit")); - - // Rev Share Calculator: check chain fees recipient and remainder recipient - assertEq(ISuperchainRevSharesCalculator(REV_SHARE_CALCULATOR).shareRecipient(), L1_WITHDRAWER); - assertEq( - ISuperchainRevSharesCalculator(REV_SHARE_CALCULATOR).remainderRecipient(), - vm.parseTomlAddress(_config, ".scRevShareCalcChainFeesRecipient") - ); - - // Fee Splitter: check calculator is set - assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), REV_SHARE_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(); - } - - /// @notice Test the integration of the revenue share system when the chain is opting in with a custom calculator - function test_revenueShare_customCalculator_integration() public { - string memory _configPath = "test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/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); - - // L1Withdrawer: check it wasn't deployed - assertEq(L1_WITHDRAWER.code.length, 0); - - // Rev Share Calculator: check it wasn't deployed - assertEq(REV_SHARE_CALCULATOR.code.length, 0); - - // Fee Splitter: check calculator is set - assertEq(IFeeSplitter(FEE_SPLITTER).sharesCalculator(), vm.parseTomlAddress(_config, ".customCalculator")); - - // 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(); - } - - /// @notice Assert the configuration of the fee vaults - /// @dev Ensures both the legacy and the new getters return the same value - function _assertFeeVaultsState() internal view { - _assertVaultGetters(SEQUENCER_FEE_VAULT, FEE_SPLITTER, WithdrawalNetwork.L2, 0); - _assertVaultGetters(OPERATOR_FEE_VAULT, FEE_SPLITTER, WithdrawalNetwork.L2, 0); - _assertVaultGetters(BASE_FEE_VAULT, FEE_SPLITTER, WithdrawalNetwork.L2, 0); - _assertVaultGetters(L1_FEE_VAULT, FEE_SPLITTER, WithdrawalNetwork.L2, 0); - } - - /// @notice Assert the configuration of a fee vault - /// @param _vault The address of the fee vault - /// @param _recipient The recipient of the fee vault - /// @param _withdrawalNetwork The withdrawal network of the fee vault - /// @param _minWithdrawalAmount The minimum withdrawal amount of the fee vault - /// @dev Ensures both the legacy and the new getters return the same value - function _assertVaultGetters( - address _vault, - address _recipient, - WithdrawalNetwork _withdrawalNetwork, - uint256 _minWithdrawalAmount - ) internal view { - assertEq(IFeeVault(_vault).recipient(), _recipient); - assertEq(uint256(IFeeVault(_vault).withdrawalNetwork()), uint256(_withdrawalNetwork)); - assertEq(IFeeVault(_vault).minWithdrawalAmount(), _minWithdrawalAmount); - assertEq(IFeeVault(_vault).RECIPIENT(), _recipient); - assertEq(uint256(IFeeVault(_vault).WITHDRAWAL_NETWORK()), uint256(_withdrawalNetwork)); - assertEq(IFeeVault(_vault).MIN_WITHDRAWAL_AMOUNT(), _minWithdrawalAmount); - } -} diff --git a/test/tasks/Regression.t.sol b/test/tasks/Regression.t.sol index 139457f049..293da94ce4 100644 --- a/test/tasks/Regression.t.sol +++ b/test/tasks/Regression.t.sol @@ -39,8 +39,6 @@ import {BlacklistGamesV400} from "src/template/BlacklistGamesV400.sol"; import {OPCMUpgradeV220toV410} from "src/template/OPCMUpgradeV220toV410.sol"; import {OPCMUpgradeV410} from "src/template/OPCMUpgradeV410.sol"; import {OPCMUpgradeSuperchainConfigV410} from "src/template/OPCMUpgradeSuperchainConfigV410.sol"; -import {RevenueShareV100UpgradePath} from "src/template/RevenueShareUpgradePath.sol"; -import {DeployFeesDepositor} from "src/template/DeployFeesDepositor.sol"; import {L1PortalExecuteL2Call} from "src/template/L1PortalExecuteL2Call.sol"; import {AddGameTypeTemplate} from "src/template/AddGameTypeTemplate.sol"; @@ -923,85 +921,6 @@ contract RegressionTest is Test { _assertDataToSignNestedMultisig(multisigTask, actions, expectedDataToSign, MULTICALL3_ADDRESS, rootSafe); } - /// @notice Expected call data and data to sign generated by manually running the RevenueShareV100UpgradePath template at block 23434662 on mainnet. - /// Simulate from task directory (test/tasks/example/eth/015-revenue-share-upgrade/config.toml) with: - /// just --dotenv-path $(pwd)/.env --justfile ../../../../../src/improvements/justfile simulate (foundation|council) - function testRegressionCallDataMatches_RevenueShareV100UpgradePath() public { - string memory taskConfigFilePath = "test/tasks/example/eth/015-revenue-share-upgrade/config.toml"; - string memory expectedCallData = - "0x174dea710000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000d2000000000000000000000000000000000000000000000000000000000000018e00000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000000000000000003140000000000000000000000000000000000000000000000000000000000000430000000000000000000000000000000000000000000000000000000000000045a000000000000000000000000000000000000000000000000000000000000057600000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000006bc00000000000000000000000000000000000000000000000000000000000006e600000000000000000000000000000000000000000000000000000000000008020000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000ae4e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0498000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000a0466cfa0570000000000000000000000000000000000000000000000000000000000000000fa8e542d08c461382d17d78973c846bafcf01f0c60f78f77abd977884fd393ff000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000009686080604052348015600e575f80fd5b50604051610908380380610908833981016040819052602b916067565b5f929092556001805463ffffffff909316600160a01b026001600160c01b03199093166001600160a01b039092169190911791909117905560b8565b5f805f606084860312156078575f80fd5b835160208501519093506001600160a01b03811681146095575f80fd5b604085015190925063ffffffff8116811460ad575f80fd5b809150509250925092565b610843806100c55f395ff3fe608060405260043610610071575f3560e01c806366d003ac1161004c57806366d003ac146102995780638312f149146102ea57806385b5b14d1461030c5780639d7955b41461032b575f80fd5b80633bbed4a0146101d7578063500bf72f146101f657806354fd4d5014610244575f80fd5b366101d3576040805134815247602082018190529133917f363f315f930a17d1266b86a20d6dd34b1cfbc5a9db9f13a65d06a689c3a2af8a910160405180910390a25f5481106101d1576001546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff82166004820152606060248201525f60648201527401000000000000000000000000000000000000000090910463ffffffff16604482015273420000000000000000000000000000000000000790633dbb202b9083906084015f604051808303818588803b158015610169575f80fd5b505af115801561017b573d5f803e3d5ffd5b505060015460405185815273ffffffffffffffffffffffffffffffffffffffff90911693507f6d92f7d3303f995bf21956bb0c51b388bae348eaf45c23debd2cfa3fcd9ec6469250602001905060405180910390a25b005b5f80fd5b3480156101e2575f80fd5b506101d16101f136600461076c565b61034a565b348015610201575f80fd5b5060015461022a9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020015b60405180910390f35b34801561024f575f80fd5b5061028c6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161023b919061078e565b3480156102a4575f80fd5b506001546102c59073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161023b565b3480156102f5575f80fd5b506102fe5f5481565b60405190815260200161023b565b348015610317575f80fd5b506101d16103263660046107e1565b6104b6565b348015610336575f80fd5b506101d16103453660046107f8565b6105d8565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103cb919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461042f576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e459391015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610513573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610537919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461059b576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e420391016104aa565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610635573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610659919061081b565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106bd576040517f807b982000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805463ffffffff838116740100000000000000000000000000000000000000008181027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff85161790945560408051949093049091168084526020840191909152917fd00b9b2acb0059a20066ca19b541618141c03305a0a6644d43277758c539b5de91016104aa565b73ffffffffffffffffffffffffffffffffffffffff81168114610769575f80fd5b50565b5f6020828403121561077c575f80fd5b813561078781610748565b9392505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156107f1575f80fd5b5035919050565b5f60208284031215610808575f80fd5b813563ffffffff81168114610787575f80fd5b5f6020828403121561082b575f80fd5b81516107878161074856fea164736f6c6343000819000a0000000000000000000000000000000000000000000000000000000000055730000000000000000000000000742d35cc6634c0532925a3b8d0c0c8b8b0c0c8b800000000000000000000000000000000000000000000000000000000000c35000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000b04e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a6802000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000a2466cfa0570000000000000000000000000000000000000000000000000000000000000000d07fd81b3e1bcfbf3c91e5b2f6b54443cff180a787261d425462132920599561000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000009956080604052348015600e575f80fd5b50604051610955380380610955833981016040819052602b916074565b5f80546001600160a01b039384166001600160a01b0319918216179091556001805492909316911617905560a0565b80516001600160a01b0381168114606f575f80fd5b919050565b5f80604083850312156084575f80fd5b608b83605a565b9150609760208401605a565b90509250929050565b6108a8806100ad5f395ff3fe608060405234801561000f575f80fd5b506004361061009f575f3560e01c80635b201d83116100725780637b42d6c2116100585780637b42d6c21461019157806396d842be1461019a5780639c662fdd146101b9575f80fd5b80635b201d831461016b578063712d7bb814610189575f80fd5b806329f33ec8146100a35780634b012e9a146100ed57806354e7f42d1461010257806354fd4d5014610122575b5f80fd5b6001546100c39073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6101006100fb3660046106a3565b6101cc565b005b6101156101103660046106c5565b610325565b6040516100e491906106f4565b61015e6040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516100e49190610758565b61017461271081565b60405163ffffffff90911681526020016100e4565b61017460fa81565b6101746105dc81565b5f546100c39073ffffffffffffffffffffffffffffffffffffffff1681565b6101006101c73660046106a3565b610524565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610229573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061024d91906107ab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146102b1576040517f67102c4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917fc7b7459ad1ab31862524bf0c4a5e6a8518c60f27607a5c483a58ea27e30c214c9190a35050565b6040805160028082526060828101909352816020015b604080518082019091525f808252602082015281526020019060019003908161033b575050604080518082019091525f805473ffffffffffffffffffffffffffffffffffffffff16825260208201819052825192935090918391906103a2576103a26107c6565b6020026020010181905250604051806040016040528060015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020015f8152508160018151811061040c5761040c6107c6565b60209081029190910101525f82846104248789610820565b61042e9190610820565b6104389190610820565b90505f61271061044960fa84610839565b6104539190610850565b9050805f0361048e576040517f0174e42600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f6104998584610888565b90505f6127106104ab6105dc84610839565b6104b59190610850565b90505f8184116104c557816104c7565b835b905080865f815181106104dc576104dc6107c6565b60209081029190910181015101526104f48186610888565b86600181518110610507576105076107c6565b602002602001015160200181815250505050505050949350505050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610581573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105a591906107ab565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610609576040517f67102c4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f28c1e0a919cd3b91d6d516417dedc06a2bd7954ad8960315347250b1aee2a4f1905f90a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146106a0575f80fd5b50565b5f602082840312156106b3575f80fd5b81356106be8161067f565b9392505050565b5f805f80608085870312156106d8575f80fd5b5050823594602084013594506040840135936060013592509050565b602080825282518282018190525f919060409081850190868401855b8281101561074b578151805173ffffffffffffffffffffffffffffffffffffffff168552860151868501529284019290850190600101610710565b5091979650505050505050565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f602082840312156107bb575f80fd5b81516106be8161067f565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b80820180821115610833576108336107f3565b92915050565b8082028115828204841417610833576108336107f3565b5f82610883577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610833576108336107f356fea164736f6c6343000819000a000000000000000000000000524e512dd372c70e7866a7825481385b7b533af00000000000000000000000008b0c0c8b8b0c0c8b8b0c0c8b8b0c0c8b8b0c0c8b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001544e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000142316000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000146466cfa0570000000000000000000000000000000000000000000000000000000000000000d7c04619bfc311a92d20723f9d08baaba18c3c8c7dcd85736bf66b85f59c37f6000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000013d26080604052348015600e575f80fd5b5060156019565b60d4565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff908116101560d2575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6112f1806100e15f395ff3fe608060405260043610610096575f3560e01c80637dfbd04911610066578063b87ea8d41161004c578063b87ea8d414610313578063c4d66de814610327578063d61a398b14610346575f80fd5b80637dfbd049146102dd5780637fc81bb7146102f4575f80fd5b80630a7617b3146101dd5780630c0544a3146101fe578063394d27311461026057806354fd4d5014610288575f80fd5b366101d9577fe3007e9730850b5618eacb0537bef0cf0f1600267ae8549e472449d77b731e455c6100f3576040517f17617f6100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337342000000000000000000000000000000000000111480159061012b57503373420000000000000000000000000000000000001914155b801561014b57503373420000000000000000000000000000000000001a14155b801561016b57503373420000000000000000000000000000000000001b14155b156101a2576040517f9dcde10900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405134815233907f2ccfc58c2cef4ee590b5f16be0548cc54afc12e1c66a67b362b7d640fd16bb2d9060200160405180910390a2005b5f80fd5b3480156101e8575f80fd5b506101fc6101f7366004610f4b565b61039c565b005b348015610209575f80fd5b5060015461023a9070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561026b575f80fd5b5060015461023a906fffffffffffffffffffffffffffffffff1681565b348015610293575f80fd5b506102d06040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516102579190610f66565b3480156102e8575f80fd5b5061023a6301e1338081565b3480156102ff575f80fd5b506101fc61030e366004610fb9565b61055e565b34801561031e575f80fd5b506101fc610706565b348015610332575f80fd5b506101fc610341366004610f4b565b610aea565b348015610351575f80fd5b505f546103779062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610257565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061041d9190610fe8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166104ce576040517f99c6ec0800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff85161790945560408051949093049091168084526020840191909152917f16417cc372deec0caee5f52e2ad77a5f07b4591fd56b4ff31b6e20f817d4daeb91015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105bb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105df9190610fe8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610643576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6301e133806fffffffffffffffffffffffffffffffff82161115610693576040517f30b9f35e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546fffffffffffffffffffffffffffffffff8381167001000000000000000000000000000000008181028385161790945560408051949093049091168084526020840191909152917f4492086b630ed3846eec0979dd87a71c814ceb1c6dab80ab81e3450b21e4de289101610552565b60015461073b906fffffffffffffffffffffffffffffffff700100000000000000000000000000000000820481169116611030565b6fffffffffffffffffffffffffffffffff16421015610786576040517f1e4a9f3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016426fffffffffffffffffffffffffffffffff161781556107cb90610ce0565b5f6107e9734200000000000000000000000000000000000011610d06565b90505f610809734200000000000000000000000000000000000019610d06565b90505f61082973420000000000000000000000000000000000001a610d06565b90505f61084973420000000000000000000000000000000000001b610d06565b90506108545f610ce0565b5f82826108618688611060565b61086b9190611060565b6108759190611060565b9050805f036108b0576040517fc8972e5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546040517f54e7f42d000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260448101859052606481018690526201000090910473ffffffffffffffffffffffffffffffffffffffff16906354e7f42d906084015f60405180830381865afa158015610936573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261097b9190810190611118565b905080515f036109b7576040517f763970d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8251811015610a6e575f8382815181106109d6576109d66111e7565b60200260200101515f015190505f8483815181106109f6576109f66111e7565b6020026020010151602001519050805f03610a12575050610a66565b5f610a1d8383610f03565b905080610a56576040517fd68d1b1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a608286611060565b94505050505b6001016109ba565b50828114610aa8576040517f9c01eac000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f73f9a13241a1848ec157967f3a85601709353e616f1f2605d818c0f2d21774df8284604051610ad9929190611214565b60405180910390a150505050505050565b5f54610100900460ff1615808015610b0857505f54600160ff909116105b80610b215750303b158015610b2157505f5460ff166001145b610bb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610c0d575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f80547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff851602179055600180546fffffffffffffffffffffffffffffffff1672015180000000000000000000000000000000001790558015610cdc575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610552565b5050565b807fe3007e9730850b5618eacb0537bef0cf0f1600267ae8549e472449d77b731e455d50565b5f60018273ffffffffffffffffffffffffffffffffffffffff166382356d8a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7691906112af565b6001811115610d8757610d87611282565b14610dbe576040517fb4726cbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff166366d003ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e1e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e429190610fe8565b73ffffffffffffffffffffffffffffffffffffffff1614610e8f576040517fc3380cef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610ed9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610efd91906112cd565b92915050565b5f610f0f835a84610f16565b9392505050565b5f805f805f858888f1949350505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f48575f80fd5b50565b5f60208284031215610f5b575f80fd5b8135610f0f81610f27565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f60208284031215610fc9575f80fd5b81356fffffffffffffffffffffffffffffffff81168114610f0f575f80fd5b5f60208284031215610ff8575f80fd5b8151610f0f81610f27565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6fffffffffffffffffffffffffffffffff81811683821601908082111561105957611059611003565b5092915050565b80820180821115610efd57610efd611003565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156110c3576110c3611073565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561111057611110611073565b604052919050565b5f6020808385031215611129575f80fd5b825167ffffffffffffffff80821115611140575f80fd5b818501915085601f830112611153575f80fd5b81518181111561116557611165611073565b611173848260051b016110c9565b818152848101925060069190911b830184019087821115611192575f80fd5b928401925b818410156111dc57604084890312156111ae575f80fd5b6111b66110a0565b84516111c181610f27565b81528486015186820152835260409093019291840191611197565b979650505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b604080825283518282018190525f91906020906060850190828801855b8281101561126c578151805173ffffffffffffffffffffffffffffffffffffffff168552850151858501529285019290840190600101611231565b5050508093505050508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f602082840312156112bf575f80fd5b815160028110610f0f575f80fd5b5f602082840312156112dd575f80fd5b505191905056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001a4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c49623609d000000000000000000000000420000000000000000000000000000000000002b0000000000000000000000006b0d0b5d65c13ed9ec80617772aee4d6c594a66e00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de800000000000000000000000072aa66caa04c9bd83ecc43c65cff2cf837ee4bb3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa0570000000000000000000000000000000000000000000000000000000000000000783aa8b3e401c8404e3eff9401ba29702719ddc0c0f69ec9ac77188bacea107300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f8f6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000420000000000000000000000000000000000001b000000000000000000000000bb8accad49adb30084bdf22d01a109883fd13dce00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa0570000000000000000000000000000000000000000000000000000000000000000204cb368f75f2d6cade61b62cb318bffd2bd31a57a3f86dff75f5bfd9d2dd14900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f9a6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610ec4806100d65f395ff3fe6080604052600436106100dc575f3560e01c80638312f1491161007c578063b49dc74111610057578063b49dc741146102a0578063d0e12f90146102bf578063d3e5792b146102ee578063d4ff9218146100e7575f80fd5b80638312f1491461025857806384411d651461026d57806385b5b14d14610281575f80fd5b80633ccfd60b116100b75780633ccfd60b1461017757806354fd4d501461019957806366d003ac146101ee57806382356d8a1461021a575f80fd5b80630d9019e1146100e7578063307f2962146101375780633bbed4a014610158575f80fd5b366100e357005b5f80fd5b3480156100f2575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610142575f80fd5b50610156610151366004610c91565b610302565b005b348015610163575f80fd5b50610156610172366004610cce565b610485565b348015610182575f80fd5b5061018b6105e9565b60405190815260200161012e565b3480156101a4575f80fd5b506101e16040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b60405161012e9190610ce9565b3480156101f9575f80fd5b5060025461010d9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610225575f80fd5b5060025461024b9074010000000000000000000000000000000000000000900460ff1681565b60405161012e9190610da2565b348015610263575f80fd5b5061018b60015481565b348015610278575f80fd5b5061018b5f5481565b34801561028c575f80fd5b5061015661029b366004610db6565b610923565b3480156102ab575f80fd5b506101566102ba366004610dcd565b610a46565b3480156102ca575f80fd5b5060025474010000000000000000000000000000000000000000900460ff1661024b565b3480156102f9575f80fd5b5060015461018b565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103839190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103e7576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561044357610443610d3c565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc88183604051610479929190610e23565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105069190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461056a576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e45939101610479565b5f6001544710156106a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106ba9190610e3e565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077f91849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e76565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107b8576107b8610d3c565b03610875576002545f906107e29073ffffffffffffffffffffffffffffffffffffffff1683610c5a565b905080610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e7400000000000000000000000000000000606482015260840161069e565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b158015610909575f80fd5b505af115801561091b573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610980573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a49190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a08576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e42039101610479565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a905750825b90505f8267ffffffffffffffff166001148015610aac5750303b155b905081158015610aba575080155b15610af1576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b525784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bea57610bea610d3c565b02179055508315610c505784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c66835a84610c6d565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c8c575f80fd5b919050565b5f60208284031215610ca1575f80fd5b610c6682610c7e565b73ffffffffffffffffffffffffffffffffffffffff81168114610ccb575f80fd5b50565b5f60208284031215610cde575f80fd5b8135610c6681610caa565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d9e577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610db08284610d69565b92915050565b5f60208284031215610dc6575f80fd5b5035919050565b5f805f60608486031215610ddf575f80fd5b8335610dea81610caa565b925060208401359150610dff60408501610c7e565b90509250925092565b5f60208284031215610e18575f80fd5b8151610c6681610caa565b60408101610e318285610d69565b610c666020830184610d69565b80820180821115610db0577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610eae6060830184610d69565b9594505050505056fea164736f6c6343000819000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d00000000000000000000000042000000000000000000000000000000000000110000000000000000000000006ca5002ca794cfeebc0ec0d04ef89a382bb3942500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa05700000000000000000000000000000000000000000000000000000000000000007a2bde9cfb7f80a4198677bdf885a43dc36c598688294f694cf64429164f140000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f8f6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d00000000000000000000000042000000000000000000000000000000000000190000000000000000000000003240dd3b3ba917563f63ea129cddff7fb696070500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa05700000000000000000000000000000000000000000000000000000000000000004ac8e160bee0acc95b22d1744fa9cc7068869945397f78a77ed68ef8ae1d87a900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f8f6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000420000000000000000000000000000000000001a0000000000000000000000006b692240ef7a6b18aaf63a56a94d423c1b5cec0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - MultisigTask multisigTask = new RevenueShareV100UpgradePath(); - address rootSafe = address(0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A); // L1PAO - address securityCouncilChildMultisig = address(0xc2819DC788505Aac350142A7A707BF9D03E3Bd03); - address[] memory allSafes = MultisigTaskTestHelper.getAllSafes(rootSafe, securityCouncilChildMultisig); - - (Action[] memory actions, uint256[] memory allOriginalNonces) = - _setupAndSimulate(taskConfigFilePath, 23434662, "mainnet", multisigTask, allSafes); - _assertCallDataMatches(multisigTask, actions, allSafes, allOriginalNonces, expectedCallData); - - string[] memory expectedDataToSign = new string[](2); - // Foundation - expectedDataToSign[0] = - "0x1901a4a9c312badf3fcaa05eafe5dc9bee8bd9316c78ee8b0bebe3115bb21b732672eaf1963e1b8fce113ea7218a1f023ca5475fb3f07f7f0cc8e31a8909ea48c2b5"; - // Security Council - expectedDataToSign[1] = - "0x1901df53d510b56e539b90b369ef08fce3631020fbf921e3136ea5f8747c20bce9676b689c001fc27e79bcb565c7c5c376c301fb5ec47176b205c5b216fa5da4193c"; - _assertDataToSignNestedMultisig(multisigTask, actions, expectedDataToSign, MULTICALL3_ADDRESS, rootSafe); - } - - - /// @notice Expected call data and data to sign generated by manually running the RevenueShareV100UpgradePath template at block 23434662 on mainnet. - /// Simulate from task directory (test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/config.toml) with: - /// just --dotenv-path $(pwd)/.env --justfile ../../../../../src/improvements/justfile simulate (foundation|council) - function testRegressionCallDataMatches_RevenueShareV100UpgradePath_CustomCalculator() public { - string memory taskConfigFilePath = "test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/config.toml"; - string memory expectedCallData = - "0x174dea710000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000174000000000000000000000000000000000000000000000000000000000000019a00000000000000000000000000000000000000000000000000000000000002b600000000000000000000000000000000000000000000000000000000000002e000000000000000000000000000000000000000000000000000000000000003fc00000000000000000000000000000000000000000000000000000000000004260000000000000000000000000000000000000000000000000000000000000542000000000000000000000000000000000000000000000000000000000000056c00000000000000000000000000000000000000000000000000000000000006880000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001544e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000142316000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000146466cfa0570000000000000000000000000000000000000000000000000000000000000000d7c04619bfc311a92d20723f9d08baaba18c3c8c7dcd85736bf66b85f59c37f6000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000013d26080604052348015600e575f80fd5b5060156019565b60d4565b5f54610100900460ff161560835760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b5f5460ff908116101560d2575f805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b6112f1806100e15f395ff3fe608060405260043610610096575f3560e01c80637dfbd04911610066578063b87ea8d41161004c578063b87ea8d414610313578063c4d66de814610327578063d61a398b14610346575f80fd5b80637dfbd049146102dd5780637fc81bb7146102f4575f80fd5b80630a7617b3146101dd5780630c0544a3146101fe578063394d27311461026057806354fd4d5014610288575f80fd5b366101d9577fe3007e9730850b5618eacb0537bef0cf0f1600267ae8549e472449d77b731e455c6100f3576040517f17617f6100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b337342000000000000000000000000000000000000111480159061012b57503373420000000000000000000000000000000000001914155b801561014b57503373420000000000000000000000000000000000001a14155b801561016b57503373420000000000000000000000000000000000001b14155b156101a2576040517f9dcde10900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405134815233907f2ccfc58c2cef4ee590b5f16be0548cc54afc12e1c66a67b362b7d640fd16bb2d9060200160405180910390a2005b5f80fd5b3480156101e8575f80fd5b506101fc6101f7366004610f4b565b61039c565b005b348015610209575f80fd5b5060015461023a9070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1681565b6040516fffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b34801561026b575f80fd5b5060015461023a906fffffffffffffffffffffffffffffffff1681565b348015610293575f80fd5b506102d06040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b6040516102579190610f66565b3480156102e8575f80fd5b5061023a6301e1338081565b3480156102ff575f80fd5b506101fc61030e366004610fb9565b61055e565b34801561031e575f80fd5b506101fc610706565b348015610332575f80fd5b506101fc610341366004610f4b565b610aea565b348015610351575f80fd5b505f546103779062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610257565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061041d9190610fe8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610481576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff81166104ce576040517f99c6ec0800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805473ffffffffffffffffffffffffffffffffffffffff838116620100008181027fffffffffffffffffffff0000000000000000000000000000000000000000ffff85161790945560408051949093049091168084526020840191909152917f16417cc372deec0caee5f52e2ad77a5f07b4591fd56b4ff31b6e20f817d4daeb91015b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105bb573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105df9190610fe8565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610643576040517f38bac74200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6301e133806fffffffffffffffffffffffffffffffff82161115610693576040517f30b9f35e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546fffffffffffffffffffffffffffffffff8381167001000000000000000000000000000000008181028385161790945560408051949093049091168084526020840191909152917f4492086b630ed3846eec0979dd87a71c814ceb1c6dab80ab81e3450b21e4de289101610552565b60015461073b906fffffffffffffffffffffffffffffffff700100000000000000000000000000000000820481169116611030565b6fffffffffffffffffffffffffffffffff16421015610786576040517f1e4a9f3a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffffffffffff0000000000000000000000000000000016426fffffffffffffffffffffffffffffffff161781556107cb90610ce0565b5f6107e9734200000000000000000000000000000000000011610d06565b90505f610809734200000000000000000000000000000000000019610d06565b90505f61082973420000000000000000000000000000000000001a610d06565b90505f61084973420000000000000000000000000000000000001b610d06565b90506108545f610ce0565b5f82826108618688611060565b61086b9190611060565b6108759190611060565b9050805f036108b0576040517fc8972e5200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546040517f54e7f42d000000000000000000000000000000000000000000000000000000008152600481018890526024810187905260448101859052606481018690526201000090910473ffffffffffffffffffffffffffffffffffffffff16906354e7f42d906084015f60405180830381865afa158015610936573d5f803e3d5ffd5b505050506040513d5f823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261097b9190810190611118565b905080515f036109b7576040517f763970d600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805b8251811015610a6e575f8382815181106109d6576109d66111e7565b60200260200101515f015190505f8483815181106109f6576109f66111e7565b6020026020010151602001519050805f03610a12575050610a66565b5f610a1d8383610f03565b905080610a56576040517fd68d1b1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a608286611060565b94505050505b6001016109ba565b50828114610aa8576040517f9c01eac000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f73f9a13241a1848ec157967f3a85601709353e616f1f2605d818c0f2d21774df8284604051610ad9929190611214565b60405180910390a150505050505050565b5f54610100900460ff1615808015610b0857505f54600160ff909116105b80610b215750303b158015610b2157505f5460ff166001145b610bb1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610c0d575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b5f80547fffffffffffffffffffff0000000000000000000000000000000000000000ffff166201000073ffffffffffffffffffffffffffffffffffffffff851602179055600180546fffffffffffffffffffffffffffffffff1672015180000000000000000000000000000000001790558015610cdc575f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249890602001610552565b5050565b807fe3007e9730850b5618eacb0537bef0cf0f1600267ae8549e472449d77b731e455d50565b5f60018273ffffffffffffffffffffffffffffffffffffffff166382356d8a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d7691906112af565b6001811115610d8757610d87611282565b14610dbe576040517fb4726cbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff166366d003ac6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e1e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e429190610fe8565b73ffffffffffffffffffffffffffffffffffffffff1614610e8f576040517fc3380cef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16633ccfd60b6040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610ed9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610efd91906112cd565b92915050565b5f610f0f835a84610f16565b9392505050565b5f805f805f858888f1949350505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610f48575f80fd5b50565b5f60208284031215610f5b575f80fd5b8135610f0f81610f27565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b5f60208284031215610fc9575f80fd5b81356fffffffffffffffffffffffffffffffff81168114610f0f575f80fd5b5f60208284031215610ff8575f80fd5b8151610f0f81610f27565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b6fffffffffffffffffffffffffffffffff81811683821601908082111561105957611059611003565b5092915050565b80820180821115610efd57610efd611003565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040805190810167ffffffffffffffff811182821017156110c3576110c3611073565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561111057611110611073565b604052919050565b5f6020808385031215611129575f80fd5b825167ffffffffffffffff80821115611140575f80fd5b818501915085601f830112611153575f80fd5b81518181111561116557611165611073565b611173848260051b016110c9565b818152848101925060069190911b830184019087821115611192575f80fd5b928401925b818410156111dc57604084890312156111ae575f80fd5b6111b66110a0565b84516111c181610f27565b81528486015186820152835260409093019291840191611197565b979650505050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b604080825283518282018190525f91906020906060850190828801855b8281101561126c578151805173ffffffffffffffffffffffffffffffffffffffff168552850151858501529285019290840190600101611231565b5050508093505050508260208301529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b5f602082840312156112bf575f80fd5b815160028110610f0f575f80fd5b5f602082840312156112dd575f80fd5b505191905056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001a4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000c49623609d000000000000000000000000420000000000000000000000000000000000002b0000000000000000000000006b0d0b5d65c13ed9ec80617772aee4d6c594a66e00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000024c4d66de80000000000000000000000008b0c0c8b8b0c0c8b8b0c0c8b8b0c0c8b8b0c0c8b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa0570000000000000000000000000000000000000000000000000000000000000000783aa8b3e401c8404e3eff9401ba29702719ddc0c0f69ec9ac77188bacea107300000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f8f6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e312e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000420000000000000000000000000000000000001b000000000000000000000000bb8accad49adb30084bdf22d01a109883fd13dce00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa0570000000000000000000000000000000000000000000000000000000000000000204cb368f75f2d6cade61b62cb318bffd2bd31a57a3f86dff75f5bfd9d2dd14900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f9a6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610ec4806100d65f395ff3fe6080604052600436106100dc575f3560e01c80638312f1491161007c578063b49dc74111610057578063b49dc741146102a0578063d0e12f90146102bf578063d3e5792b146102ee578063d4ff9218146100e7575f80fd5b80638312f1491461025857806384411d651461026d57806385b5b14d14610281575f80fd5b80633ccfd60b116100b75780633ccfd60b1461017757806354fd4d501461019957806366d003ac146101ee57806382356d8a1461021a575f80fd5b80630d9019e1146100e7578063307f2962146101375780633bbed4a014610158575f80fd5b366100e357005b5f80fd5b3480156100f2575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610142575f80fd5b50610156610151366004610c91565b610302565b005b348015610163575f80fd5b50610156610172366004610cce565b610485565b348015610182575f80fd5b5061018b6105e9565b60405190815260200161012e565b3480156101a4575f80fd5b506101e16040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b60405161012e9190610ce9565b3480156101f9575f80fd5b5060025461010d9073ffffffffffffffffffffffffffffffffffffffff1681565b348015610225575f80fd5b5060025461024b9074010000000000000000000000000000000000000000900460ff1681565b60405161012e9190610da2565b348015610263575f80fd5b5061018b60015481565b348015610278575f80fd5b5061018b5f5481565b34801561028c575f80fd5b5061015661029b366004610db6565b610923565b3480156102ab575f80fd5b506101566102ba366004610dcd565b610a46565b3480156102ca575f80fd5b5060025474010000000000000000000000000000000000000000900460ff1661024b565b3480156102f9575f80fd5b5060015461018b565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561035f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103839190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103e7576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561044357610443610d3c565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc88183604051610479929190610e23565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104e2573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105069190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461056a576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e45939101610479565b5f6001544710156106a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106ba9190610e3e565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077f91849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e76565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107b8576107b8610d3c565b03610875576002545f906107e29073ffffffffffffffffffffffffffffffffffffffff1683610c5a565b905080610871576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e7400000000000000000000000000000000606482015260840161069e565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b158015610909575f80fd5b505af115801561091b573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610980573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109a49190610e08565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a08576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e42039101610479565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a905750825b90505f8267ffffffffffffffff166001148015610aac5750303b155b905081158015610aba575080155b15610af1576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b525784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bea57610bea610d3c565b02179055508315610c505784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c66835a84610c6d565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c8c575f80fd5b919050565b5f60208284031215610ca1575f80fd5b610c6682610c7e565b73ffffffffffffffffffffffffffffffffffffffff81168114610ccb575f80fd5b50565b5f60208284031215610cde575f80fd5b8135610c6681610caa565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d9e577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610db08284610d69565b92915050565b5f60208284031215610dc6575f80fd5b5035919050565b5f805f60608486031215610ddf575f80fd5b8335610dea81610caa565b925060208401359150610dff60408501610c7e565b90509250925092565b5f60208284031215610e18575f80fd5b8151610c6681610caa565b60408101610e318285610d69565b610c666020830184610d69565b80820180821115610db0577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610eae6060830184610d69565b9594505050505056fea164736f6c6343000819000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d00000000000000000000000042000000000000000000000000000000000000110000000000000000000000006ca5002ca794cfeebc0ec0d04ef89a382bb3942500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa05700000000000000000000000000000000000000000000000000000000000000007a2bde9cfb7f80a4198677bdf885a43dc36c598688294f694cf64429164f140000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f8f6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d00000000000000000000000042000000000000000000000000000000000000190000000000000000000000003240dd3b3ba917563f63ea129cddff7fb696070500000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000001104e9e05c4200000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000124f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000102466cfa05700000000000000000000000000000000000000000000000000000000000000004ac8e160bee0acc95b22d1744fa9cc7068869945397f78a77ed68ef8ae1d87a900000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000f8f6080604052348015600e575f80fd5b5060156019565b60c9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff161560685760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b039081161460c65780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b610eb9806100d65f395ff3fe6080604052600436106100d1575f3560e01c806382356d8a1161007c57806385b5b14d1161005757806385b5b14d14610276578063b49dc74114610295578063d0e12f90146102b4578063d3e5792b146102e3575f80fd5b806382356d8a1461020f5780638312f1491461024d57806384411d6514610262575f80fd5b80633ccfd60b116100ac5780633ccfd60b1461016c57806354fd4d501461018e57806366d003ac146101e3575f80fd5b80630d9019e1146100dc578063307f29621461012c5780633bbed4a01461014d575f80fd5b366100d857005b5f80fd5b3480156100e7575f80fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b348015610137575f80fd5b5061014b610146366004610c86565b6102f7565b005b348015610158575f80fd5b5061014b610167366004610cc3565b61047a565b348015610177575f80fd5b506101806105de565b604051908152602001610123565b348015610199575f80fd5b506101d66040518060400160405280600581526020017f312e362e3000000000000000000000000000000000000000000000000000000081525081565b6040516101239190610cde565b3480156101ee575f80fd5b506002546101029073ffffffffffffffffffffffffffffffffffffffff1681565b34801561021a575f80fd5b506002546102409074010000000000000000000000000000000000000000900460ff1681565b6040516101239190610d97565b348015610258575f80fd5b5061018060015481565b34801561026d575f80fd5b506101805f5481565b348015610281575f80fd5b5061014b610290366004610dab565b610918565b3480156102a0575f80fd5b5061014b6102af366004610dc2565b610a3b565b3480156102bf575f80fd5b5060025474010000000000000000000000000000000000000000900460ff16610240565b3480156102ee575f80fd5b50600154610180565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610354573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103789190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146103dc576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547401000000000000000000000000000000000000000080820460ff1692849290917fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9091169083600181111561043857610438610d31565b02179055507ff2ec44eb1c3b3acd547b76333eb2c4b27eee311860c57a9fdb04c95f62398fc8818360405161046e929190610e18565b60405180910390a15050565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fb9190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461055f576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff000000000000000000000000000000000000000083168117909355604080519190921680825260208201939093527f62e69886a5df0ba8ffcacbfc1388754e7abd9bde24b036354c561f1acd4e4593910161046e565b5f60015447101561069c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604a60248201527f4665655661756c743a207769746864726177616c20616d6f756e74206d75737460448201527f2062652067726561746572207468616e206d696e696d756d207769746864726160648201527f77616c20616d6f756e7400000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b479050805f808282546106af9190610e33565b90915550506002546040805183815273ffffffffffffffffffffffffffffffffffffffff90921660208301523382820152517fc8a211cc64b6ed1b50595a9fcb1932b6d1e5a6e8ef15b60e5b1f988ea9086bba9181900360600190a16002546040517f38e04cbeb8c10f8f568618aa75be0f10b6729b8b4237743b4de20cbcde2839ee9161077491849173ffffffffffffffffffffffffffffffffffffffff811691339174010000000000000000000000000000000000000000900460ff1690610e6b565b60405180910390a1600160025474010000000000000000000000000000000000000000900460ff1660018111156107ad576107ad610d31565b0361086a576002545f906107d79073ffffffffffffffffffffffffffffffffffffffff1683610c4f565b905080610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4665655661756c743a206661696c656420746f2073656e642045544820746f2060448201527f4c322066656520726563697069656e74000000000000000000000000000000006064820152608401610693565b5090565b6002546040517fc2b3e5ac00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015262061a806024820152606060448201525f60648201527342000000000000000000000000000000000000169063c2b3e5ac9083906084015f604051808303818588803b1580156108fe575f80fd5b505af1158015610910573d5f803e3d5ffd5b505050505090565b73420000000000000000000000000000000000001873ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610975573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109999190610dfd565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109fd576040517f7cd7e09f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180549082905560408051828152602081018490527f895a067c78583e800418fabf3da26a9496aab2ff3429cebdf7fefa642b2e4203910161046e565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f81158015610a855750825b90505f8267ffffffffffffffff166001148015610aa15750303b155b905081158015610aaf575080155b15610ae6576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001660011785558315610b475784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b6002805473ffffffffffffffffffffffffffffffffffffffff8a167fffffffffffffffffffffffff000000000000000000000000000000000000000082168117835560018a81558993927fffffffffffffffffffffff000000000000000000000000000000000000000000169091179074010000000000000000000000000000000000000000908490811115610bdf57610bdf610d31565b02179055508315610c455784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b5f610c5b835a84610c62565b9392505050565b5f805f805f858888f1949350505050565b803560028110610c81575f80fd5b919050565b5f60208284031215610c96575f80fd5b610c5b82610c73565b73ffffffffffffffffffffffffffffffffffffffff81168114610cc0575f80fd5b50565b5f60208284031215610cd3575f80fd5b8135610c5b81610c9f565b602081525f82518060208401528060208501604085015e5f6040828501015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011684010191505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b60028110610d93577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b60208101610da58284610d5e565b92915050565b5f60208284031215610dbb575f80fd5b5035919050565b5f805f60608486031215610dd4575f80fd5b8335610ddf81610c9f565b925060208401359150610df460408501610c73565b90509250925092565b5f60208284031215610e0d575f80fd5b8151610c5b81610c9f565b60408101610e268285610d5e565b610c5b6020830184610d5e565b80820180821115610da5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b84815273ffffffffffffffffffffffffffffffffffffffff84811660208301528316604082015260808101610ea36060830184610d5e565b9594505050505056fea164736f6c6343000819000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001e4e9e05c420000000000000000000000004200000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000001049623609d000000000000000000000000420000000000000000000000000000000000001a0000000000000000000000006b692240ef7a6b18aaf63a56a94d423c1b5cec0a00000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000064b49dc741000000000000000000000000420000000000000000000000000000000000002b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - MultisigTask multisigTask = new RevenueShareV100UpgradePath(); - address rootSafe = address(0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A); // L1PAO - address securityCouncilChildMultisig = address(0xc2819DC788505Aac350142A7A707BF9D03E3Bd03); - address[] memory allSafes = MultisigTaskTestHelper.getAllSafes(rootSafe, securityCouncilChildMultisig); - - (Action[] memory actions, uint256[] memory allOriginalNonces) = - _setupAndSimulate(taskConfigFilePath, 23434662, "mainnet", multisigTask, allSafes); - _assertCallDataMatches(multisigTask, actions, allSafes, allOriginalNonces, expectedCallData); - - string[] memory expectedDataToSign = new string[](2); - // Foundation - expectedDataToSign[0] = - "0x1901a4a9c312badf3fcaa05eafe5dc9bee8bd9316c78ee8b0bebe3115bb21b732672e9058ad53a314a39d8d71024bbae802345cd5b86f0133c8f1897b4b1c70ae80e"; - // Security Council - expectedDataToSign[1] = - "0x1901df53d510b56e539b90b369ef08fce3631020fbf921e3136ea5f8747c20bce96704658710877bdaa7bc6e316c9db98bd7e5c687ef31f09148c5dcf890475eccd7"; - _assertDataToSignNestedMultisig(multisigTask, actions, expectedDataToSign, MULTICALL3_ADDRESS, rootSafe); - } - - /// @notice Expected call data and data to sign generated by manually running the DeployFeesDepositor template at block 23197819 on mainnet. - /// Simulate from task directory (test/tasks/example/eth/016-deploy-fees-depositor/config.toml) with: - /// just --dotenv-path $(pwd)/.env --justfile ../../../../../src/improvements/justfile simulate (foundation|council) - function testRegressionCallDataMatches_DeployFeesDepositor() public { - string memory taskConfigFilePath = "test/tasks/example/eth/016-deploy-fees-depositor/config.toml"; - string memory expectedCallData = - "0x174dea7100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000010400000000000000000000000000000000000000000000000000000000000001e8000000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000f2466cfa0570000000000000000000000000000000000000000000000000000000000000000666565732d6465706f7369746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000e9660a060405234801561001057600080fd5b50600160805261001e610023565b6100e3565b600054610100900460ff161561008f5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff90811610156100e1576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b608051610d9161010560003960008181610274015261048e0152610d916000f3fe6080604052600436106100cb5760003560e01c8063645006ca11610074578063a2a956171161004e578063a2a9561714610425578063dad544e014610445578063f68016b71461045a57600080fd5b8063645006ca1461038657806366125607146103c85780637b11936e146103e857600080fd5b80633e47158c116100a55780633e47158c146102fb57806352d84c621461031057806354fd4d501461033057600080fd5b80630de2db4d1461024057806338d38c97146102605780633cb747bf146102a357600080fd5b3661023b576040805134815247602082018190529133917f363f315f930a17d1266b86a20d6dd34b1cfbc5a9db9f13a65d06a689c3a2af8a910160405180910390a26001546bffffffffffffffffffffffff16811061023957600154600080546002546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff6c0100000000000000000000000090950485166004820181905260606024830152606482019490945263ffffffff90911660448201529192620100009091041690633dbb202b9084906084016000604051808303818588803b1580156101ce57600080fd5b505af11580156101e2573d6000803e3d6000fd5b50505050508073ffffffffffffffffffffffffffffffffffffffff167f2acaf92365a0b69fb3570802396f62d51aabccd684036b72c3ce78699425e7ee8360405161022f91815260200190565b60405180910390a2505b005b600080fd5b34801561024c57600080fd5b5061023961025b366004610bde565b61048c565b34801561026c57600080fd5b5060405160ff7f00000000000000000000000000000000000000000000000000000000000000001681526020015b60405180910390f35b3480156102af57600080fd5b506000546102d69062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161029a565b34801561030757600080fd5b506102d661069e565b34801561031c57600080fd5b5061023961032b366004610c36565b6108a9565b34801561033c57600080fd5b506103796040518060400160405280600581526020017f312e302e3000000000000000000000000000000000000000000000000000000081525081565b60405161029a9190610c58565b34801561039257600080fd5b506001546103ab906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff909116815260200161029a565b3480156103d457600080fd5b506102396103e3366004610ccb565b610928565b3480156103f457600080fd5b506001546102d6906c01000000000000000000000000900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561043157600080fd5b50610239610440366004610ce8565b6109af565b34801561045157600080fd5b506102d6610a2e565b34801561046657600080fd5b506002546104779063ffffffff1681565b60405163ffffffff909116815260200161029a565b7f0000000000000000000000000000000000000000000000000000000000000000600054610100900460ff161580156104cc575060005460ff8083169116105b61055c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840160405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00001660ff831617610100179055610595610aab565b6000805473ffffffffffffffffffffffffffffffffffffffff8681166c01000000000000000000000000026bffffffffffffffffffffffff8916176001556002805463ffffffff87167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff9086166201000002167fffffffffffffffffffff000000000000000000000000000000000000000000ff9091161790556040517f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989061068f90839060ff91909116815260200190565b60405180910390a15050505050565b6000806106c97fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035490565b905073ffffffffffffffffffffffffffffffffffffffff8116156106ec57919050565b6040518060400160405280601a81526020017f4f564d5f4c3143726f7373446f6d61696e4d657373656e67657200000000000081525051600261072f9190610d03565b604080513060208201526000918101919091527f4f564d5f4c3143726f7373446f6d61696e4d657373656e676572000000000000919091179061078a906060015b604051602081830303815290604052805190602001205490565b146107c1576040517f54e433cd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080513060208201526001918101919091526000906107e390606001610770565b905073ffffffffffffffffffffffffffffffffffffffff811615610877578073ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561084c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108709190610d67565b9250505090565b6040517f332144db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6108b1610b2e565b6002805463ffffffff8381167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000083168117909355604080519190921680825260208201939093527f84858bb3fb3ecf87e268ebef250ef9ad9cd53ef7973ef7a0ec9d89470bb00a8091015b60405180910390a15050565b610930610b2e565b6001805473ffffffffffffffffffffffffffffffffffffffff8381166c010000000000000000000000008181026bffffffffffffffffffffffff85161790945560408051949093049091168084526020840191909152917f158f04d12e0403fdd63fbced694e8f70d3b87d04d8e2dfad526f5fcf6e49bbcf910161091c565b6109b7610b2e565b600180546bffffffffffffffffffffffff8381167fffffffffffffffffffffffffffffffffffffffff00000000000000000000000083168117909355604080519190921680825260208201939093527f132832be4270c0d1573ca543c41517dd443fe9daf5f21a9c74940e6db282e229910161091c565b6000610a3861069e565b73ffffffffffffffffffffffffffffffffffffffff16638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aa69190610d67565b905090565b33610ab461069e565b73ffffffffffffffffffffffffffffffffffffffff1614158015610af5575033610adc610a2e565b73ffffffffffffffffffffffffffffffffffffffff1614155b15610b2c576040517fc4050a2600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b33610b37610a2e565b73ffffffffffffffffffffffffffffffffffffffff1614610b2c576040517f7f12c64b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80356bffffffffffffffffffffffff81168114610ba057600080fd5b919050565b73ffffffffffffffffffffffffffffffffffffffff81168114610bc757600080fd5b50565b803563ffffffff81168114610ba057600080fd5b60008060008060808587031215610bf457600080fd5b610bfd85610b84565b93506020850135610c0d81610ba5565b92506040850135610c1d81610ba5565b9150610c2b60608601610bca565b905092959194509250565b600060208284031215610c4857600080fd5b610c5182610bca565b9392505050565b600060208083528351808285015260005b81811015610c8557858101830151858201604001528201610c69565b81811115610c97576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b600060208284031215610cdd57600080fd5b8135610c5181610ba5565b600060208284031215610cfa57600080fd5b610c5182610b84565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610d62577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500290565b600060208284031215610d7957600080fd5b8151610c5181610ba556fea164736f6c634300080f000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000013b0d85ccb8bf860b6b79af3029fca081ae9bef20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000d8466cfa0570000000000000000000000000000000000000000000000000000000000000000666565732d6465706f7369746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000ce760806040523480156200001157600080fd5b5060405162000cc738038062000cc783398181016040528101906200003791906200016f565b62000048816200004f60201b60201c565b50620001df565b600062000061620000ce60201b60201c565b905060007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b90508281557f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f8284604051620000c1929190620001b2565b60405180910390a1505050565b60008060007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b905080549150819250505090565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000137826200010a565b9050919050565b62000149816200012a565b81146200015557600080fd5b50565b60008151905062000169816200013e565b92915050565b60006020828403121562000188576200018762000105565b5b6000620001988482850162000158565b91505092915050565b620001ac816200012a565b82525050565b6000604082019050620001c96000830185620001a1565b620001d86020830184620001a1565b9392505050565b610ad880620001ef6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100675780634f1ef286146100905780635c60da1b146100c05780638f283970146100eb578063f851a440146101145761005d565b3661005d5761005b61013f565b005b61006561013f565b005b34801561007357600080fd5b5061008e60048036038101906100899190610715565b6101dc565b005b6100aa60048036038101906100a591906107a7565b610268565b6040516100b791906108a0565b60405180910390f35b3480156100cc57600080fd5b506100d56103ae565b6040516100e291906108d1565b60405180910390f35b3480156100f757600080fd5b50610112600480360381019061010d9190610715565b61043d565b005b34801561012057600080fd5b506101296104c9565b60405161013691906108d1565b60405180910390f35b6000610149610558565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101b19061096f565b60405180910390fd5b3660008037600080366000845af43d6000803e806101d7573d6000fd5b3d6000f35b6101e461058f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102495750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561025c57610257816105c6565b610265565b61026461013f565b5b50565b606061027261058f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806102d75750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561039e576102e5846105c6565b6000808573ffffffffffffffffffffffffffffffffffffffff16858560405161030f9291906109ce565b600060405180830381855af49150503d806000811461034a576040519150601f19603f3d011682016040523d82523d6000602084013e61034f565b606091505b509150915081610394576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161038b90610a59565b60405180910390fd5b80925050506103a7565b6103a661013f565b5b9392505050565b60006103b861058f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061041d5750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b156104315761042a610558565b905061043a565b61043961013f565b5b90565b61044561058f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806104aa5750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b156104bd576104b881610638565b6104c6565b6104c561013f565b5b50565b60006104d361058f565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806105385750600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b1561054c5761054561058f565b9050610555565b61055461013f565b5b90565b60008060007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905080549150819250505090565b60008060007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b905080549150819250505090565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b90508181558173ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a25050565b600061064261058f565b905060007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b90508281557f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f82846040516106a0929190610a79565b60405180910390a1505050565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006106e2826106b7565b9050919050565b6106f2816106d7565b81146106fd57600080fd5b50565b60008135905061070f816106e9565b92915050565b60006020828403121561072b5761072a6106ad565b5b600061073984828501610700565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261076757610766610742565b5b8235905067ffffffffffffffff81111561078457610783610747565b5b6020830191508360018202830111156107a05761079f61074c565b5b9250929050565b6000806000604084860312156107c0576107bf6106ad565b5b60006107ce86828701610700565b935050602084013567ffffffffffffffff8111156107ef576107ee6106b2565b5b6107fb86828701610751565b92509250509250925092565b600081519050919050565b600082825260208201905092915050565b60005b83811015610841578082015181840152602081019050610826565b83811115610850576000848401525b50505050565b6000601f19601f8301169050919050565b600061087282610807565b61087c8185610812565b935061088c818560208601610823565b61089581610856565b840191505092915050565b600060208201905081810360008301526108ba8184610867565b905092915050565b6108cb816106d7565b82525050565b60006020820190506108e660008301846108c2565b92915050565b600082825260208201905092915050565b7f50726f78793a20696d706c656d656e746174696f6e206e6f7420696e6974696160008201527f6c697a6564000000000000000000000000000000000000000000000000000000602082015250565b60006109596025836108ec565b9150610964826108fd565b604082019050919050565b600060208201905081810360008301526109888161094c565b9050919050565b600081905092915050565b82818337600083830152505050565b60006109b5838561098f565b93506109c283858461099a565b82840190509392505050565b60006109db8284866109a9565b91508190509392505050565b7f50726f78793a2064656c656761746563616c6c20746f206e657720696d706c6560008201527f6d656e746174696f6e20636f6e7472616374206661696c656400000000000000602082015250565b6000610a436039836108ec565b9150610a4e826109e7565b604082019050919050565b60006020820190508181036000830152610a7281610a36565b9050919050565b6000604082019050610a8e60008301856108c2565b610a9b60208301846108c2565b939250505056fea2646970667358221220e170e6bf8ee3cc199be5ea3ca30084b98725d89b560e407f600f4a174236633364736f6c634300080f0033000000000000000000000000543ba4aadbab8f9025686bd03993043599c6fb040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000543ba4aadbab8f9025686bd03993043599c6fb0400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001249623609d0000000000000000000000004070ef4adfc04f537c7cf5742bb005b4e87b953000000000000000000000000090a79d28ad7f6d472ad1cfe3bad65204ab2969a2000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000840de2db4d0000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000beb5fc579115071764c7423a4f12edde41f106ed00000000000000000000000000000000000000000000000000000000000493e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; - MultisigTask multisigTask = new DeployFeesDepositor(); - address rootSafe = address(0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A); // L1PAO - address securityCouncilChildMultisig = address(0xc2819DC788505Aac350142A7A707BF9D03E3Bd03); - address[] memory allSafes = MultisigTaskTestHelper.getAllSafes(rootSafe, securityCouncilChildMultisig); - - (Action[] memory actions, uint256[] memory allOriginalNonces) = - _setupAndSimulate(taskConfigFilePath, 23197819, "mainnet", multisigTask, allSafes); - _assertCallDataMatches(multisigTask, actions, allSafes, allOriginalNonces, expectedCallData); - - string[] memory expectedDataToSign = new string[](2); - // Foundation - expectedDataToSign[0] = - "0x1901a4a9c312badf3fcaa05eafe5dc9bee8bd9316c78ee8b0bebe3115bb21b7326725164231e485f6dc9e25f4d32abf7ec7b88314ba0a65c7602e61c85f77d77f160"; - // Security Council - expectedDataToSign[1] = - "0x1901df53d510b56e539b90b369ef08fce3631020fbf921e3136ea5f8747c20bce96780d02fe7f03794508b9de312452403babba436c704cbd50c418d85a0fec772ef"; - _assertDataToSignNestedMultisig(multisigTask, actions, expectedDataToSign, MULTICALL3_ADDRESS, rootSafe); - } - /// @notice Expected call data and data to sign generated by manually running the GnosisSafeRotateSigner at block 9264006 on sepolia using script: /// forge script GnosisSafeRotateSigner --sig "simulate(string)" test/tasks/example/sep/016-gnosis-safe-remove-owner/config.toml --rpc-url sepolia --fork-block-number 9264006 -vv function testRegressionCallDataMatches_GnosisSafeRotateSigner() public { diff --git a/test/tasks/example/eth/015-revenue-share-upgrade/.env b/test/tasks/example/eth/015-revenue-share-upgrade/.env deleted file mode 100644 index be0c0bdcfe..0000000000 --- a/test/tasks/example/eth/015-revenue-share-upgrade/.env +++ /dev/null @@ -1,3 +0,0 @@ -TENDERLY_GAS=15000000 -FORK_BLOCK_NUMBER=23434662 -NESTED_SAFE_NAME_DEPTH_1=foundation \ No newline at end of file diff --git a/test/tasks/example/eth/015-revenue-share-upgrade/config.toml b/test/tasks/example/eth/015-revenue-share-upgrade/config.toml deleted file mode 100644 index 4cdeb7b8b2..0000000000 --- a/test/tasks/example/eth/015-revenue-share-upgrade/config.toml +++ /dev/null @@ -1,23 +0,0 @@ -templateName = "RevenueShareV100UpgradePath" - -# Portal and deployment configuration -portal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" # OptimismPortal address -saltSeed = "DeploymentSalt" # Deployment salt - -# Calculator Configuration -# Set to true to deploy the default SC Rev Share Calculator and L1Withdrawer -useDefaultCalculator = true - -# L1 Withdrawer Configuration -l1WithdrawerMinWithdrawalAmount = 350000 -# TODO(17505): This address MUST be updated once the appropriate FeesDepositor is deployed -# The deployment is done by running the task at test/tasks/example/eth/016-deploy-fees-depositor -l1WithdrawerRecipient = "0x742d35Cc6634C0532925a3b8D0C0C8b8B0c0C8b8" # L1 recipient address -l1WithdrawerGasLimit = 800000 # Gas limit for L1 withdrawal transactions - -# SC Rev Share Calculator Configuration -scRevShareCalcChainFeesRecipient = "0x8B0c0C8b8B0c0C8b8B0c0C8b8B0c0C8b8B0c0C8b" # Chain fees recipient - -[addresses] -ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" -OptimismPortal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" \ No newline at end of file diff --git a/test/tasks/example/eth/016-deploy-fees-depositor/.env b/test/tasks/example/eth/016-deploy-fees-depositor/.env deleted file mode 100644 index d4a7b76058..0000000000 --- a/test/tasks/example/eth/016-deploy-fees-depositor/.env +++ /dev/null @@ -1,3 +0,0 @@ -TENDERLY_GAS=10000000 -NESTED_SAFE_NAME_DEPTH_1=council -FORK_BLOCK_NUMBER=23197819 \ No newline at end of file diff --git a/test/tasks/example/eth/016-deploy-fees-depositor/config.toml b/test/tasks/example/eth/016-deploy-fees-depositor/config.toml deleted file mode 100644 index 5efafdbd0b..0000000000 --- a/test/tasks/example/eth/016-deploy-fees-depositor/config.toml +++ /dev/null @@ -1,11 +0,0 @@ -templateName = "DeployFeesDepositor" - -salt = "fees-depositor" -minDepositAmount = 5000000000000000000 -l2Recipient = "0x0000000000000000000000000000000000000001" -portal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" -gasLimit = 300000 -proxyAdmin = "0x543bA4AADBAb8f9025686Bd03993043599c6fB04" - -[addresses] -ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" \ No newline at end of file diff --git a/test/tasks/example/eth/016-revshare-upgrade-and-setup/config.toml b/test/tasks/example/eth/016-revshare-upgrade-and-setup/config.toml new file mode 100644 index 0000000000..4ed92ba25e --- /dev/null +++ b/test/tasks/example/eth/016-revshare-upgrade-and-setup/config.toml @@ -0,0 +1,31 @@ +# RevShare Setup Configuration + +templateName = "RevShareUpgradeAndSetup" + +# L2 chains to target +l2chains = [{name = "OP Mainnet", chainId = 10}, {name = "Ink", chainId = 57073}] + +safeAddress = "ProxyAdminOwner" + +# RevShareContractsUpgrader address +revShareUpgrader = "0x0000000000000000000000000000000000001337" + +# RevShare configurations (one per chain) +[[configs]] +portal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" # OP Mainnet Portal +chainFeesRecipient = "0x0000000000000000000000000000000000000001" # OP Mainnet chain fees recipient +[configs.l1WithdrawerConfig] +minWithdrawalAmount = 350000 +recipient = "0x0000000000000000000000000000000000000001" +gasLimit = 800000 + +[[configs]] +portal = "0x5d66C1782664115999C47c9fA5cd031f495D3e4F" # Ink Mainnet Portal +chainFeesRecipient = "0x0000000000000000000000000000000000000002" # Ink Mainnet chain fees recipient +[configs.l1WithdrawerConfig] +minWithdrawalAmount = 500000 +recipient = "0x0000000000000000000000000000000000000002" +gasLimit = 1000000 + +[addresses] +ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" diff --git a/test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/.env b/test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/.env deleted file mode 100644 index cbd4c581e3..0000000000 --- a/test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/.env +++ /dev/null @@ -1,3 +0,0 @@ -TENDERLY_GAS=15000000 -FORK_BLOCK_NUMBER=23434662 -NESTED_SAFE_NAME_DEPTH_1=foundation diff --git a/test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/config.toml b/test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/config.toml deleted file mode 100644 index c0bf6f0908..0000000000 --- a/test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/config.toml +++ /dev/null @@ -1,16 +0,0 @@ -templateName = "RevenueShareV100UpgradePath" - -# Portal and deployment configuration -portal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" # OptimismPortal address -saltSeed = "DeploymentSalt" # Deployment salt - -# Calculator Configuration -# Set to false to use a custom calculator (skips deploying L1Withdrawer and SC Rev Share Calculator) -useDefaultCalculator = false - -# Custom Calculator Configuration -customCalculator = "0x8B0c0C8b8B0c0C8b8B0c0C8b8B0c0C8b8B0c0C8b" - -[addresses] -ProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A" -OptimismPortal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed" diff --git a/test/template/deploy-fees-depositor/DeployFeesDepositor.t.sol b/test/template/deploy-fees-depositor/DeployFeesDepositor.t.sol deleted file mode 100644 index ac50b54deb..0000000000 --- a/test/template/deploy-fees-depositor/DeployFeesDepositor.t.sol +++ /dev/null @@ -1,223 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -import {Test} from "forge-std/Test.sol"; -import {DeployFeesDepositor, IFeesDepositor} from "src/template/DeployFeesDepositor.sol"; -import {Action} from "src/libraries/MultisigTypes.sol"; -import {Create2} from "@openzeppelin/contracts/utils/Create2.sol"; -import {Proxy} from "optimism/packages/contracts-bedrock/src/universal/Proxy.sol"; -import {RevShareCodeRepo} from "src/libraries/RevShareCodeRepo.sol"; -import {IProxyAdmin} from "optimism/packages/contracts-bedrock/interfaces/universal/IProxyAdmin.sol"; - -/// @notice Test contract for the DeployFeesDepositor that expect reverts on misconfiguration of required fields. -contract DeployFeesDepositorRequiredFieldsTest is Test { - DeployFeesDepositor public template; - string internal constant TEMP_CONFIG_DIR = "test/template/deploy-fees-depositor/"; - - // Default valid values for tests - string internal constant DEFAULT_SALT = "test-fees-depositor"; - string internal constant DEFAULT_L2_RECIPIENT = "0x0000000000000000000000000000000000000001"; - string internal constant DEFAULT_PORTAL = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"; - uint256 internal constant DEFAULT_GAS_LIMIT = 300000; - string internal constant DEFAULT_PROXY_ADMIN = "0x543bA4AADBAb8f9025686Bd03993043599c6fB04"; - - // Invalid values for tests - string internal constant ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; - string internal constant EMPTY_STRING = ""; - uint256 internal constant UINT32_MAX_PLUS_ONE = 4294967296; - - function setUp() public { - vm.createSelectFork("mainnet", 23197819); - template = new DeployFeesDepositor(); - } - - /// @notice Helper to write a minimal config for testing validation - /// @param _salt Salt for deployment - /// @param _l2Recipient L2 recipient address - /// @param _portal Portal address - /// @param _gasLimit Gas limit for transactions - /// @param _proxyAdmin ProxyAdmin address - /// @return Path to the created config file - function _writeTestConfig( - string memory _salt, - string memory _l2Recipient, - string memory _portal, - uint256 _gasLimit, - string memory _proxyAdmin - ) internal returns (string memory) { - string memory config = string.concat( - 'templateName = "DeployFeesDepositor"\n\nsalt = "', - _salt, - '"\nminDepositAmount = 5000000000000000000\nl2Recipient = "', - _l2Recipient, - '"\nportal = "', - _portal, - '"\ngasLimit = ', - vm.toString(_gasLimit), - '\nproxyAdmin = "', - _proxyAdmin, - '"\n\n[addresses]\nProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A"' - ); - string memory configPath = string.concat(TEMP_CONFIG_DIR, "temp-config-", vm.toString(uint256(uint32(msg.sig))), ".toml"); - vm.writeFile(configPath, config); - return configPath; - } - - /// @notice Tests that the template reverts when the salt is an empty string. - function test_deployFeesDepositor_salt_empty_string_reverts() public { - string memory configPath = _writeTestConfig( - EMPTY_STRING, // INVALID - salt is empty - DEFAULT_L2_RECIPIENT, - DEFAULT_PORTAL, - DEFAULT_GAS_LIMIT, - DEFAULT_PROXY_ADMIN - ); - vm.expectRevert("salt must be set"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the l2Recipient is a zero address. - function test_deployFeesDepositor_l2Recipient_zero_address_reverts() public { - string memory configPath = _writeTestConfig( - DEFAULT_SALT, - ZERO_ADDRESS, // INVALID - l2Recipient is zero address - DEFAULT_PORTAL, - DEFAULT_GAS_LIMIT, - DEFAULT_PROXY_ADMIN - ); - vm.expectRevert("l2Recipient must be set"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the portal is a zero address. - function test_deployFeesDepositor_portal_zero_address_reverts() public { - string memory configPath = _writeTestConfig( - DEFAULT_SALT, - DEFAULT_L2_RECIPIENT, - ZERO_ADDRESS, // INVALID - portal is zero address - DEFAULT_GAS_LIMIT, - DEFAULT_PROXY_ADMIN - ); - vm.expectRevert("portal must be set"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the gasLimit is zero. - function test_deployFeesDepositor_gasLimit_zero_reverts() public { - string memory configPath = _writeTestConfig( - DEFAULT_SALT, - DEFAULT_L2_RECIPIENT, - DEFAULT_PORTAL, - 0, // INVALID - gasLimit is zero - DEFAULT_PROXY_ADMIN - ); - vm.expectRevert("gasLimit must be set"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the gasLimit is too high. - function test_deployFeesDepositor_gasLimit_too_high_reverts() public { - string memory configPath = _writeTestConfig( - DEFAULT_SALT, - DEFAULT_L2_RECIPIENT, - DEFAULT_PORTAL, - UINT32_MAX_PLUS_ONE, // INVALID - gasLimit exceeds uint32.max - DEFAULT_PROXY_ADMIN - ); - vm.expectRevert("gasLimit must be less than uint32.max"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the ProxyAdmin is a zero address. - function test_deployFeesDepositor_proxyAdmin_zero_address_reverts() public { - string memory configPath = _writeTestConfig( - DEFAULT_SALT, - DEFAULT_L2_RECIPIENT, - DEFAULT_PORTAL, - DEFAULT_GAS_LIMIT, - ZERO_ADDRESS // INVALID - proxyAdmin is zero address - ); - vm.expectRevert("proxyAdmin must be set"); - template.simulate(configPath); - vm.removeFile(configPath); - } -} - -/// @notice Test contract for successful deployment of the FeesDepositor template. -contract DeployFeesDepositorSuccessTest is Test { - DeployFeesDepositor public template; - - // Expected configuration values from the task config - string public constant SALT = "fees-depositor"; - uint96 public constant MIN_DEPOSIT_AMOUNT = 5000000000000000000; - address public constant L2_RECIPIENT = 0x0000000000000000000000000000000000000001; - address public constant PORTAL = 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed; - uint32 public constant GAS_LIMIT = 300000; - address public constant PROXY_ADMIN = 0x543bA4AADBAb8f9025686Bd03993043599c6fB04; - address public constant PROXY_ADMIN_OWNER = 0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A; - address internal constant CREATE2_DEPLOYER = address(0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2); - - string public constant configPath = "test/tasks/example/eth/016-deploy-fees-depositor/config.toml"; - - function setUp() public { - vm.createSelectFork("mainnet", 23197819); - template = new DeployFeesDepositor(); - } - - /// @notice Tests successful deployment and initialization of FeesDepositor - function test_deployFeesDepositor_succeds() public { - // Execute the simulation - (, Action[] memory actions,, address rootSafe) = template.simulate(configPath, new address[](0)); - - // Verify the root safe is correct - assertEq(rootSafe, PROXY_ADMIN_OWNER, "Root safe should be ProxyAdminOwner"); - - // Verify actions were created (should have 3: deploy impl, deploy proxy, upgradeAndCall) - assertEq(actions.length, 3, "Should have exactly 3 actions"); - - // Calculate expected deployed addresses using the same logic as the template - bytes memory proxyInitCode = bytes.concat(type(Proxy).creationCode, abi.encode(PROXY_ADMIN)); - address proxyAddress = Create2.computeAddress(bytes32(bytes(SALT)), keccak256(proxyInitCode), CREATE2_DEPLOYER); - address implAddress = Create2.computeAddress( - bytes32(bytes(SALT)), keccak256(RevShareCodeRepo.feesDepositorCreationCode), CREATE2_DEPLOYER - ); - - // Verify action 0: Deploy implementation - assertEq(actions[0].target, CREATE2_DEPLOYER, "Action 0 should target CREATE2_DEPLOYER"); - assertEq(actions[0].value, 0, "Action 0 should have no value"); - assertGt(actions[0].arguments.length, 0, "Action 0 should have calldata"); - - // Verify action 1: Deploy proxy - assertEq(actions[1].target, CREATE2_DEPLOYER, "Action 1 should target CREATE2_DEPLOYER"); - assertEq(actions[1].value, 0, "Action 1 should have no value"); - assertGt(actions[1].arguments.length, 0, "Action 1 should have calldata"); - - // Verify action 2: UpgradeAndCall - assertEq(actions[2].target, PROXY_ADMIN, "Action 2 should target ProxyAdmin"); - assertEq(actions[2].value, 0, "Action 2 should have no value"); - assertGt(actions[2].arguments.length, 0, "Action 2 should have calldata"); - - // Verify both contracts were deployed - assertTrue(proxyAddress.code.length > 0, "Proxy should be deployed"); - assertTrue(implAddress.code.length > 0, "Implementation should be deployed"); - - // Verify proxy was initialized with correct values - IFeesDepositor feesDepositor = IFeesDepositor(payable(proxyAddress)); - assertEq(feesDepositor.minDepositAmount(), MIN_DEPOSIT_AMOUNT, "minDepositAmount should match config"); - assertEq(feesDepositor.l2Recipient(), L2_RECIPIENT, "l2Recipient should match config"); - assertEq(feesDepositor.gasLimit(), GAS_LIMIT, "gasLimit should match config"); - - // Verify the template's public variables were set correctly - assertEq(template.salt(), SALT, "Salt should match config"); - assertEq(template.l2Recipient(), L2_RECIPIENT, "l2Recipient should match config"); - assertEq(template.minDepositAmount(), MIN_DEPOSIT_AMOUNT, "minDepositAmount should match config"); - assertEq(template.portal(), PORTAL, "portal should match config"); - assertEq(template.gasLimit(), GAS_LIMIT, "gasLimit should match config"); - assertEq(template.proxyAdmin(), PROXY_ADMIN, "proxyAdmin should match config"); - } -} diff --git a/test/template/revenue-share-upgrade-path/RevShareContractsUpgrader.t.sol b/test/template/revenue-share-upgrade-path/RevShareContractsUpgrader.t.sol new file mode 100644 index 0000000000..d669822d69 --- /dev/null +++ b/test/template/revenue-share-upgrade-path/RevShareContractsUpgrader.t.sol @@ -0,0 +1,657 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.15; + +// Testing +import {Test} from "forge-std/Test.sol"; + +// Contract under test +import {RevShareContractsUpgrader} from "src/RevShareContractsUpgrader.sol"; + +// Libraries +import {RevShareLibrary} from "src/libraries/RevShareLibrary.sol"; +import {Utils} from "src/libraries/Utils.sol"; + +// Interfaces +import {IOptimismPortal2} from "@eth-optimism-bedrock/interfaces/L1/IOptimismPortal2.sol"; +import {IProxyAdmin} from "@eth-optimism-bedrock/interfaces/universal/IProxyAdmin.sol"; +import {ICreate2Deployer} from "src/interfaces/ICreate2Deployer.sol"; +import {IFeeSplitter} from "src/interfaces/IFeeSplitter.sol"; +import {IFeeVault} from "src/interfaces/IFeeVault.sol"; + +/// @title RevShareContractsUpgrader_TestInit +/// @notice Base test contract with shared setup and helpers for RevShareContractsUpgrader tests. +contract RevShareContractsUpgrader_TestInit is Test { + // Events + event ChainProcessed(address portal, uint256 chainIndex); + + // Contract under test + RevShareContractsUpgrader internal upgrader; + + // Test constants + address internal immutable PORTAL_ONE = makeAddr("PORTAL_ONE"); + address internal immutable PORTAL_TWO = makeAddr("PORTAL_TWO"); + address internal immutable L1_RECIPIENT_ONE = makeAddr("L1_RECIPIENT_ONE"); + address internal immutable L1_RECIPIENT_TWO = makeAddr("L1_RECIPIENT_TWO"); + address internal immutable CHAIN_FEES_RECIPIENT_ONE = makeAddr("CHAIN_FEES_RECIPIENT_ONE"); + address internal immutable CHAIN_FEES_RECIPIENT_TWO = makeAddr("CHAIN_FEES_RECIPIENT_TWO"); + uint256 internal immutable MIN_WITHDRAWAL_AMOUNT = 1 ether; + uint32 internal immutable GAS_LIMIT = 500_000; + + /// @notice Test setup + function setUp() public { + upgrader = new RevShareContractsUpgrader(); + } + + function _assumeValidAddress(address _address) internal pure { + assumeNotZeroAddress(_address); + assumeNotForgeAddress(_address); + assumeNotPrecompile(_address); + } + + /// @notice Helper function to setup a mock and expect a call to it. + function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal { + vm.mockCall(_receiver, _calldata, _returned); + vm.expectCall(_receiver, _calldata); + } + + /// @notice Helper to create RevShareConfig + function _createRevShareConfig( + address _portal, + uint256 _minWithdrawalAmount, + address _l1Recipient, + uint32 _gasLimit, + address _chainFeesRecipient + ) internal pure returns (RevShareContractsUpgrader.RevShareConfig memory) { + return RevShareContractsUpgrader.RevShareConfig({ + portal: _portal, + l1WithdrawerConfig: RevShareContractsUpgrader.L1WithdrawerConfig({ + minWithdrawalAmount: _minWithdrawalAmount, + recipient: _l1Recipient, + gasLimit: _gasLimit + }), + chainFeesRecipient: _chainFeesRecipient + }); + } + + /// @notice Helper to calculate expected CREATE2 address + function _calculateExpectedCreate2Address(string memory _suffix, bytes memory _initCode) + internal + pure + returns (address _expectedAddress) + { + bytes32 salt = keccak256(abi.encodePacked("RevShare", ":", _suffix)); + _expectedAddress = Utils.getCreate2Address(salt, _initCode, RevShareLibrary.CREATE2_DEPLOYER); + assumeNotZeroAddress(_expectedAddress); + } + + /// @notice Helper to mock L1Withdrawer deployment + function _mockAndExpectL1WithdrawerDeploy( + address _portal, + uint256 _minWithdrawalAmount, + address _recipient, + uint32 _gasLimit + ) internal { + bytes memory l1WithdrawerInitCode = bytes.concat( + RevShareLibrary.l1WithdrawerCreationCode, abi.encode(_minWithdrawalAmount, _recipient, _gasLimit) + ); + bytes32 salt = keccak256(abi.encodePacked("RevShare", ":", "L1Withdrawer")); + + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + RevShareLibrary.CREATE2_DEPLOYER, + 0, + RevShareLibrary.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, + false, + abi.encodeCall(ICreate2Deployer.deploy, (0, salt, l1WithdrawerInitCode)) + ) + ), + abi.encode() + ); + } + + /// @notice Helper to mock Calculator deployment + function _mockAndExpectCalculatorDeploy(address _portal, address _l1Withdrawer, address _chainFeesRecipient) + internal + { + bytes memory calculatorInitCode = bytes.concat( + RevShareLibrary.scRevShareCalculatorCreationCode, abi.encode(_l1Withdrawer, _chainFeesRecipient) + ); + bytes32 salt = keccak256(abi.encodePacked("RevShare", ":", "SCRevShareCalculator")); + + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + RevShareLibrary.CREATE2_DEPLOYER, + 0, + RevShareLibrary.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, + false, + abi.encodeCall(ICreate2Deployer.deploy, (0, salt, calculatorInitCode)) + ) + ), + abi.encode() + ); + } + + /// @notice Helper to mock FeeSplitter deployment + function _mockAndExpectFeeSplitterDeployAndSetup(address _portal, address _calculator) internal { + // FeeSplitter deployment deposit + bytes32 salt = keccak256(abi.encodePacked("RevShare", ":", "FeeSplitter")); + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + RevShareLibrary.CREATE2_DEPLOYER, + 0, + RevShareLibrary.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, + false, + abi.encodeCall(ICreate2Deployer.deploy, (0, salt, RevShareLibrary.feeSplitterCreationCode)) + ) + ), + abi.encode() + ); + + // Initialize FeeSplitter with calculator deposit + address feeSplitterImpl = + _calculateExpectedCreate2Address("FeeSplitter", RevShareLibrary.feeSplitterCreationCode); + + bytes memory upgradeCall = abi.encodeCall( + IProxyAdmin.upgradeAndCall, + ( + payable(RevShareLibrary.FEE_SPLITTER), + feeSplitterImpl, + abi.encodeCall(IFeeSplitter.initialize, (_calculator)) + ) + ); + + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + (RevShareLibrary.PROXY_ADMIN, 0, RevShareLibrary.UPGRADE_GAS_LIMIT, false, upgradeCall) + ), + abi.encode() + ); + } + + /// @notice Helper to mock FeeSplitter setSharesCalculator call + function _mockAndExpectFeeSplitterSetCalculator(address _portal, address _calculator) internal { + bytes memory setCalculatorCall = abi.encodeCall(IFeeSplitter.setSharesCalculator, (_calculator)); + + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + (RevShareLibrary.FEE_SPLITTER, 0, RevShareLibrary.SETTERS_GAS_LIMIT, false, setCalculatorCall) + ), + abi.encode() + ); + } + + /// @notice Helper to mock a single vault deployment and upgrade + function _mockAndExpectVaultUpgrade( + address _portal, + address _vault, + string memory _vaultName, + bytes memory _creationCode + ) internal { + // Mock vault implementation deployment + bytes32 salt = keccak256(abi.encodePacked("RevShare", ":", _vaultName)); + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + RevShareLibrary.CREATE2_DEPLOYER, + 0, + RevShareLibrary.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, + false, + abi.encodeCall(ICreate2Deployer.deploy, (0, salt, _creationCode)) + ) + ), + abi.encode() + ); + + // Mock vault upgrade call + address vaultImpl = _calculateExpectedCreate2Address(_vaultName, _creationCode); + bytes memory vaultUpgradeCall = abi.encodeCall( + IProxyAdmin.upgradeAndCall, + ( + payable(_vault), + vaultImpl, + abi.encodeCall(IFeeVault.initialize, (RevShareLibrary.FEE_SPLITTER, 0, IFeeVault.WithdrawalNetwork.L2)) + ) + ); + + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + (RevShareLibrary.PROXY_ADMIN, 0, RevShareLibrary.UPGRADE_GAS_LIMIT, false, vaultUpgradeCall) + ), + abi.encode() + ); + } + + /// @notice Helper to mock a single vault setter calls + function _mockAndExpectVaultSetter(address _portal, address _vault) internal { + // Mock setRecipient call + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + _vault, + 0, + RevShareLibrary.SETTERS_GAS_LIMIT, + false, + abi.encodeCall(IFeeVault.setRecipient, (RevShareLibrary.FEE_SPLITTER)) + ) + ), + abi.encode() + ); + + // Mock setMinWithdrawalAmount call + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + _vault, + 0, + RevShareLibrary.SETTERS_GAS_LIMIT, + false, + abi.encodeCall(IFeeVault.setMinWithdrawalAmount, (0)) + ) + ), + abi.encode() + ); + + // Mock setWithdrawalNetwork call + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + ( + _vault, + 0, + RevShareLibrary.SETTERS_GAS_LIMIT, + false, + abi.encodeCall(IFeeVault.setWithdrawalNetwork, (IFeeVault.WithdrawalNetwork.L2)) + ) + ), + abi.encode() + ); + } + + /// @notice Helper to mock only a vault upgrade (no deployment) - for vaults that reuse another vault's implementation + /// @param _portal The portal address + /// @param _vault The vault proxy address to upgrade + /// @param _implVaultName The vault name whose implementation to reuse (e.g., "BaseFeeVault" for L1FeeVault) + /// @param _creationCode The creation code of the implementation being reused + function _mockAndExpectVaultUpgradeOnly( + address _portal, + address _vault, + string memory _implVaultName, + bytes memory _creationCode + ) internal { + // Calculate the implementation address (using the name of the vault whose impl we're reusing) + address vaultImpl = _calculateExpectedCreate2Address(_implVaultName, _creationCode); + + // Mock vault upgrade call (no deployment, just upgrade) + bytes memory vaultUpgradeCall = abi.encodeCall( + IProxyAdmin.upgradeAndCall, + ( + payable(_vault), + vaultImpl, + abi.encodeCall(IFeeVault.initialize, (RevShareLibrary.FEE_SPLITTER, 0, IFeeVault.WithdrawalNetwork.L2)) + ) + ); + + _mockAndExpect( + _portal, + abi.encodeCall( + IOptimismPortal2.depositTransaction, + (RevShareLibrary.PROXY_ADMIN, 0, RevShareLibrary.UPGRADE_GAS_LIMIT, false, vaultUpgradeCall) + ), + abi.encode() + ); + } + + /// @notice Helper to mock all vault upgrades (3 vault deployments + 4 upgrades) + /// @dev BaseFeeVault and L1FeeVault share the same implementation, so only BaseFeeVault is deployed + function _mockAndExpectAllVaultUpgrades(address _portal) internal { + // Deploy and upgrade OperatorFeeVault + _mockAndExpectVaultUpgrade( + _portal, + RevShareLibrary.OPERATOR_FEE_VAULT, + "OperatorFeeVault", + RevShareLibrary.operatorFeeVaultCreationCode + ); + + // Deploy and upgrade SequencerFeeVault + _mockAndExpectVaultUpgrade( + _portal, + RevShareLibrary.SEQUENCER_FEE_WALLET, + "SequencerFeeVault", + RevShareLibrary.sequencerFeeVaultCreationCode + ); + + // Deploy and upgrade BaseFeeVault (this deployment is shared with L1FeeVault) + _mockAndExpectVaultUpgrade( + _portal, RevShareLibrary.BASE_FEE_VAULT, "BaseFeeVault", RevShareLibrary.defaultFeeVaultCreationCode + ); + + // L1FeeVault upgrade only (reuses BaseFeeVault's implementation, no deployment) + _mockAndExpectVaultUpgradeOnly( + _portal, RevShareLibrary.L1_FEE_VAULT, "BaseFeeVault", RevShareLibrary.defaultFeeVaultCreationCode + ); + } + + /// @notice Helper to mock all vault setters (4 vaults, 3 calls each = 12 calls total) + function _mockAndExpectAllVaultSetters(address _portal) internal { + _mockAndExpectVaultSetter(_portal, RevShareLibrary.OPERATOR_FEE_VAULT); + _mockAndExpectVaultSetter(_portal, RevShareLibrary.SEQUENCER_FEE_WALLET); + _mockAndExpectVaultSetter(_portal, RevShareLibrary.BASE_FEE_VAULT); + _mockAndExpectVaultSetter(_portal, RevShareLibrary.L1_FEE_VAULT); + } +} + +/// @title RevShareContractsUpgrader_UpgradeAndSetupRevShare_Test +/// @notice Tests for the upgradeAndSetupRevShare function of the RevShareContractsUpgrader contract. +contract RevShareContractsUpgrader_UpgradeAndSetupRevShare_Test is RevShareContractsUpgrader_TestInit { + /// @notice Test that upgradeAndSetupRevShare reverts when configs array is empty + function test_upgradeAndSetupRevShare_whenEmptyArray_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](0); + + vm.expectRevert(RevShareContractsUpgrader.EmptyArray.selector); + upgrader.upgradeAndSetupRevShare(configs); + } + + /// @notice Test that upgradeAndSetupRevShare reverts when portal address is zero + function test_upgradeAndSetupRevShare_whenPortalIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = _createRevShareConfig( + address(0), MIN_WITHDRAWAL_AMOUNT, L1_RECIPIENT_ONE, GAS_LIMIT, CHAIN_FEES_RECIPIENT_ONE + ); + + vm.expectRevert(RevShareContractsUpgrader.PortalCannotBeZeroAddress.selector); + upgrader.upgradeAndSetupRevShare(configs); + } + + /// @notice Test that upgradeAndSetupRevShare reverts when L1Withdrawer recipient is zero + function test_upgradeAndSetupRevShare_whenL1WithdrawerRecipientIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = + _createRevShareConfig(PORTAL_ONE, MIN_WITHDRAWAL_AMOUNT, address(0), GAS_LIMIT, CHAIN_FEES_RECIPIENT_ONE); + + vm.expectRevert(RevShareContractsUpgrader.L1WithdrawerRecipientCannotBeZeroAddress.selector); + upgrader.upgradeAndSetupRevShare(configs); + } + + /// @notice Test that upgradeAndSetupRevShare reverts when chain fees recipient is zero + function test_upgradeAndSetupRevShare_whenChainFeesRecipientIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = _createRevShareConfig(PORTAL_ONE, MIN_WITHDRAWAL_AMOUNT, L1_RECIPIENT_ONE, GAS_LIMIT, address(0)); + + vm.expectRevert(RevShareContractsUpgrader.ChainFeesRecipientCannotBeZeroAddress.selector); + upgrader.upgradeAndSetupRevShare(configs); + } + + /// @notice Test that upgradeAndSetupRevShare reverts when gas limit is zero + function test_upgradeAndSetupRevShare_whenGasLimitIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = + _createRevShareConfig(PORTAL_ONE, MIN_WITHDRAWAL_AMOUNT, L1_RECIPIENT_ONE, 0, CHAIN_FEES_RECIPIENT_ONE); + + vm.expectRevert(RevShareContractsUpgrader.GasLimitCannotBeZero.selector); + upgrader.upgradeAndSetupRevShare(configs); + } + + /// @notice Fuzz test successful upgradeAndSetupRevShare with single chain + function testFuzz_upgradeAndSetupRevShare_singleChain_succeeds( + address _portal, + uint256 _minWithdrawalAmount, + address _l1Recipient, + uint32 _gasLimit, + address _chainFeesRecipient + ) public { + // Bound inputs to valid ranges + _assumeValidAddress(_portal); + _assumeValidAddress(_l1Recipient); + _assumeValidAddress(_chainFeesRecipient); + _gasLimit = uint32(bound(_gasLimit, 1, type(uint32).max)); + + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = _createRevShareConfig(_portal, _minWithdrawalAmount, _l1Recipient, _gasLimit, _chainFeesRecipient); + + // Calculate expected L1Withdrawer address + bytes memory l1WithdrawerInitCode = bytes.concat( + RevShareLibrary.l1WithdrawerCreationCode, abi.encode(_minWithdrawalAmount, _l1Recipient, _gasLimit) + ); + address expectedL1Withdrawer = _calculateExpectedCreate2Address("L1Withdrawer", l1WithdrawerInitCode); + + // Calculate expected Calculator address + bytes memory calculatorInitCode = bytes.concat( + RevShareLibrary.scRevShareCalculatorCreationCode, abi.encode(expectedL1Withdrawer, _chainFeesRecipient) + ); + address expectedCalculator = _calculateExpectedCreate2Address("SCRevShareCalculator", calculatorInitCode); + + // Mock all calls with strict abi.encodeCall + _mockAndExpectL1WithdrawerDeploy(_portal, _minWithdrawalAmount, _l1Recipient, _gasLimit); + _mockAndExpectCalculatorDeploy(_portal, expectedL1Withdrawer, _chainFeesRecipient); + _mockAndExpectFeeSplitterDeployAndSetup(_portal, expectedCalculator); + _mockAndExpectAllVaultUpgrades(_portal); + + // Expect event + vm.expectEmit(address(upgrader)); + emit ChainProcessed(_portal, 0); + + // Execute + upgrader.upgradeAndSetupRevShare(configs); + } + + /// @notice Fuzz test successful upgradeAndSetupRevShare with multiple chains + function testFuzz_upgradeAndSetupRevShare_multipleChains_succeeds(uint8 _numChains, uint256 _seed) public { + // Bound to reasonable range: 2-50 chains + _numChains = uint8(bound(_numChains, 2, 50)); + + // Setup configs array + RevShareContractsUpgrader.RevShareConfig[] memory configs = + new RevShareContractsUpgrader.RevShareConfig[](_numChains); + + // Generate random configs and setup mocks for each chain + for (uint256 i; i < _numChains; ++i) { + // Use seed + index to generate pseudo-random but deterministic values + uint256 chainSeed = uint256(keccak256(abi.encode(_seed, i))); + + // Generate random but valid addresses (non-zero) + address portal = makeAddr(string.concat("portal_", vm.toString(chainSeed))); + address l1Recipient = makeAddr(string.concat("l1recipient_", vm.toString(chainSeed))); + address chainFeeRecipient = makeAddr(string.concat("chainfee_", vm.toString(chainSeed))); + + // Generate random config values + uint256 minWithdrawalAmount = + bound(uint256(keccak256(abi.encode(chainSeed, "minwithdrawal"))), 1, type(uint256).max); + uint32 gasLimit = uint32(bound(uint256(keccak256(abi.encode(chainSeed, "gaslimit"))), 1, type(uint32).max)); + + configs[i] = _createRevShareConfig(portal, minWithdrawalAmount, l1Recipient, gasLimit, chainFeeRecipient); + + // Calculate expected addresses for this chain + bytes memory l1WithdrawerInitCode = bytes.concat( + RevShareLibrary.l1WithdrawerCreationCode, abi.encode(minWithdrawalAmount, l1Recipient, gasLimit) + ); + address expectedL1Withdrawer = _calculateExpectedCreate2Address("L1Withdrawer", l1WithdrawerInitCode); + + bytes memory calculatorInitCode = bytes.concat( + RevShareLibrary.scRevShareCalculatorCreationCode, abi.encode(expectedL1Withdrawer, chainFeeRecipient) + ); + address expectedCalculator = _calculateExpectedCreate2Address("SCRevShareCalculator", calculatorInitCode); + + // Setup mocks for this chain + _mockAndExpectL1WithdrawerDeploy(portal, minWithdrawalAmount, l1Recipient, gasLimit); + _mockAndExpectCalculatorDeploy(portal, expectedL1Withdrawer, chainFeeRecipient); + _mockAndExpectFeeSplitterDeployAndSetup(portal, expectedCalculator); + _mockAndExpectAllVaultUpgrades(portal); + + // Expect event for this chain + vm.expectEmit(address(upgrader)); + emit ChainProcessed(portal, i); + } + + // Execute once with all chains + upgrader.upgradeAndSetupRevShare(configs); + } +} + +/// @title RevShareContractsUpgrader_SetupRevShare_Test +/// @notice Tests for the setupRevShare function of the RevShareContractsUpgrader contract. +contract RevShareContractsUpgrader_SetupRevShare_Test is RevShareContractsUpgrader_TestInit { + /// @notice Test that setupRevShare reverts when configs array is empty + function test_setupRevShare_whenEmptyArray_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](0); + + vm.expectRevert(RevShareContractsUpgrader.EmptyArray.selector); + upgrader.setupRevShare(configs); + } + + /// @notice Test that setupRevShare reverts when portal address is zero + function test_setupRevShare_whenPortalIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = _createRevShareConfig( + address(0), MIN_WITHDRAWAL_AMOUNT, L1_RECIPIENT_ONE, GAS_LIMIT, CHAIN_FEES_RECIPIENT_ONE + ); + + vm.expectRevert(RevShareContractsUpgrader.PortalCannotBeZeroAddress.selector); + upgrader.setupRevShare(configs); + } + + /// @notice Test that setupRevShare reverts when L1Withdrawer recipient is zero + function test_setupRevShare_whenL1WithdrawerRecipientIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = + _createRevShareConfig(PORTAL_ONE, MIN_WITHDRAWAL_AMOUNT, address(0), GAS_LIMIT, CHAIN_FEES_RECIPIENT_ONE); + + vm.expectRevert(RevShareContractsUpgrader.L1WithdrawerRecipientCannotBeZeroAddress.selector); + upgrader.setupRevShare(configs); + } + + /// @notice Test that setupRevShare reverts when chain fees recipient is zero + function test_setupRevShare_whenChainFeesRecipientIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = _createRevShareConfig(PORTAL_ONE, MIN_WITHDRAWAL_AMOUNT, L1_RECIPIENT_ONE, GAS_LIMIT, address(0)); + + vm.expectRevert(RevShareContractsUpgrader.ChainFeesRecipientCannotBeZeroAddress.selector); + upgrader.setupRevShare(configs); + } + + /// @notice Test that setupRevShare reverts when gas limit is zero + function test_setupRevShare_whenGasLimitIsZero_reverts() public { + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = + _createRevShareConfig(PORTAL_ONE, MIN_WITHDRAWAL_AMOUNT, L1_RECIPIENT_ONE, 0, CHAIN_FEES_RECIPIENT_ONE); + + vm.expectRevert(RevShareContractsUpgrader.GasLimitCannotBeZero.selector); + upgrader.setupRevShare(configs); + } + + /// @notice Fuzz test successful setupRevShare with single chain + function testFuzz_setupRevShare_singleChain_succeeds( + address _portal, + uint256 _minWithdrawalAmount, + address _l1Recipient, + uint32 _gasLimit, + address _chainFeesRecipient + ) public { + // Bound inputs to valid ranges + assumeNotForgeAddress(_portal); + _assumeValidAddress(_portal); + _assumeValidAddress(_l1Recipient); + _assumeValidAddress(_chainFeesRecipient); + _gasLimit = uint32(bound(_gasLimit, 1, type(uint32).max)); + + RevShareContractsUpgrader.RevShareConfig[] memory configs = new RevShareContractsUpgrader.RevShareConfig[](1); + configs[0] = _createRevShareConfig(_portal, _minWithdrawalAmount, _l1Recipient, _gasLimit, _chainFeesRecipient); + + // Calculate expected addresses + bytes memory l1WithdrawerInitCode = bytes.concat( + RevShareLibrary.l1WithdrawerCreationCode, abi.encode(_minWithdrawalAmount, _l1Recipient, _gasLimit) + ); + address expectedL1Withdrawer = _calculateExpectedCreate2Address("L1Withdrawer", l1WithdrawerInitCode); + + bytes memory calculatorInitCode = bytes.concat( + RevShareLibrary.scRevShareCalculatorCreationCode, abi.encode(expectedL1Withdrawer, _chainFeesRecipient) + ); + address expectedCalculator = _calculateExpectedCreate2Address("SCRevShareCalculator", calculatorInitCode); + + // Mock all calls (setupRevShare deploys periphery, sets calculator, and configures vaults) + _mockAndExpectL1WithdrawerDeploy(_portal, _minWithdrawalAmount, _l1Recipient, _gasLimit); + _mockAndExpectCalculatorDeploy(_portal, expectedL1Withdrawer, _chainFeesRecipient); + _mockAndExpectFeeSplitterSetCalculator(_portal, expectedCalculator); + _mockAndExpectAllVaultSetters(_portal); + + // Expect event + vm.expectEmit(address(upgrader)); + emit ChainProcessed(_portal, 0); + + // Execute + upgrader.setupRevShare(configs); + } + + /// @notice Fuzz test successful setupRevShare with multiple chains + function testFuzz_setupRevShare_multipleChains_succeeds(uint8 _numChains, uint256 _seed) public { + // Bound to reasonable range: 2-50 chains + _numChains = uint8(bound(_numChains, 2, 50)); + + // Setup configs array + RevShareContractsUpgrader.RevShareConfig[] memory configs = + new RevShareContractsUpgrader.RevShareConfig[](_numChains); + + // Generate random configs and setup mocks for each chain + for (uint256 i; i < _numChains; ++i) { + // Use seed + index to generate pseudo-random but deterministic values + uint256 chainSeed = uint256(keccak256(abi.encode(_seed, i))); + + // Generate random but valid addresses (non-zero) + address portal = makeAddr(string.concat("portal_", vm.toString(chainSeed))); + address l1Recipient = makeAddr(string.concat("l1recipient_", vm.toString(chainSeed))); + address chainFeeRecipient = makeAddr(string.concat("chainfee_", vm.toString(chainSeed))); + + // Generate random config values + uint256 minWithdrawalAmount = + bound(uint256(keccak256(abi.encode(chainSeed, "minwithdrawal"))), 1, type(uint256).max); + uint32 gasLimit = uint32(bound(uint256(keccak256(abi.encode(chainSeed, "gaslimit"))), 1, type(uint32).max)); + + configs[i] = _createRevShareConfig(portal, minWithdrawalAmount, l1Recipient, gasLimit, chainFeeRecipient); + + // Calculate expected addresses for this chain + bytes memory l1WithdrawerInitCode = bytes.concat( + RevShareLibrary.l1WithdrawerCreationCode, abi.encode(minWithdrawalAmount, l1Recipient, gasLimit) + ); + address expectedL1Withdrawer = _calculateExpectedCreate2Address("L1Withdrawer", l1WithdrawerInitCode); + + bytes memory calculatorInitCode = bytes.concat( + RevShareLibrary.scRevShareCalculatorCreationCode, abi.encode(expectedL1Withdrawer, chainFeeRecipient) + ); + address expectedCalculator = _calculateExpectedCreate2Address("SCRevShareCalculator", calculatorInitCode); + + // Setup mocks for this chain (setupRevShare deploys periphery, sets calculator, and configures vaults) + _mockAndExpectL1WithdrawerDeploy(portal, minWithdrawalAmount, l1Recipient, gasLimit); + _mockAndExpectCalculatorDeploy(portal, expectedL1Withdrawer, chainFeeRecipient); + _mockAndExpectFeeSplitterSetCalculator(portal, expectedCalculator); + _mockAndExpectAllVaultSetters(portal); + + // Expect event for this chain + vm.expectEmit(address(upgrader)); + emit ChainProcessed(portal, i); + } + + // Execute once with all chains + upgrader.setupRevShare(configs); + } +} diff --git a/test/template/revenue-share-upgrade-path/RevenueShareUpgradePath.t.sol b/test/template/revenue-share-upgrade-path/RevenueShareUpgradePath.t.sol deleted file mode 100644 index 36c72fa33a..0000000000 --- a/test/template/revenue-share-upgrade-path/RevenueShareUpgradePath.t.sol +++ /dev/null @@ -1,570 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.15; - -import {Test} from "forge-std/Test.sol"; -import {stdStorage, StdStorage} from "forge-std/StdStorage.sol"; -import {VmSafe} from "forge-std/Vm.sol"; -import {IGnosisSafe, Enum} from "@base-contracts/script/universal/IGnosisSafe.sol"; -import {IMulticall3} from "forge-std/interfaces/IMulticall3.sol"; -import {Signatures} from "@base-contracts/script/universal/Signatures.sol"; - -import {RevenueShareV100UpgradePath} from "src/template/RevenueShareUpgradePath.sol"; -import {SimpleAddressRegistry} from "src/SimpleAddressRegistry.sol"; -import {Action, TaskPayload, SafeData} from "src/libraries/MultisigTypes.sol"; -import {Utils} from "src/libraries/Utils.sol"; -import {AddressAliasHelper} from "@eth-optimism-bedrock/src/vendor/AddressAliasHelper.sol"; -import {RevShareGasLimits} from "src/libraries/RevShareGasLimits.sol"; - -interface IOptimismPortal2 { - function depositTransaction(address _to, uint256 _value, uint64 _gasLimit, bool _isCreation, bytes memory _data) - external - payable; -} - -interface ICreate2Deployer { - function deploy(uint256 _value, bytes32 _salt, bytes memory _code) external; -} - -interface IProxyAdmin { - function upgrade(address _proxy, address _implementation) external; - function upgradeAndCall(address _proxy, address _implementation, bytes memory _data) - external - payable - returns (bytes memory); -} - -/// @notice Test contract for the RevenueShareUpgradePath that expect reverts on misconfiguration of required fields. -contract RevenueShareUpgradePathRequiredFieldsTest is Test { - RevenueShareV100UpgradePath public template; - string internal constant TEMP_CONFIG_DIR = "test/template/revenue-share-upgrade-path/"; - - // Default valid values for tests - string internal constant DEFAULT_PORTAL = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"; - string internal constant DEFAULT_SALT_SEED = "test-salt"; - string internal constant DEFAULT_CUSTOM_CALCULATOR = "0x1111111111111111111111111111111111111111"; - string internal constant DEFAULT_L1_WITHDRAWER_RECIPIENT = "0x742d35Cc6634C0532925a3b8D0C0C8b8B0c0C8b8"; - uint256 internal constant DEFAULT_L1_WITHDRAWER_GAS_LIMIT = 800000; - string internal constant DEFAULT_SC_REV_SHARE_CALC_CHAIN_FEES_RECIPIENT = "0x8B0c0C8b8B0c0C8b8B0c0C8b8B0c0C8b8B0c0C8b"; - - // Invalid values for tests - string internal constant ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; - string internal constant EMPTY_STRING = ""; - uint256 internal constant UINT32_MAX_PLUS_ONE = 4294967296; - - function setUp() public { - vm.createSelectFork("mainnet", 23197819); - template = new RevenueShareV100UpgradePath(); - } - - /// @notice Helper to write a minimal config for testing validation - /// @param _portal Portal address - /// @param _saltSeed Salt seed for deployment - /// @param _useDefaultCalculator Whether to use default calculator (true) or custom calculator (false) - /// @param _customCalculator Custom calculator address (only needed if _useDefaultCalculator is false) - /// @param _l1WithdrawerRecipient L1 withdrawer recipient (only needed if using default calculator) - /// @param _l1WithdrawerGasLimit L1 withdrawer gas limit (only needed if using default calculator) - /// @param _scRevShareCalcChainFeesRecipient Chain fees recipient (only needed if using default calculator) - /// @return Path to the created config file - function _writeTestConfig( - string memory _portal, - string memory _saltSeed, - bool _useDefaultCalculator, - string memory _customCalculator, - string memory _l1WithdrawerRecipient, - uint256 _l1WithdrawerGasLimit, - string memory _scRevShareCalcChainFeesRecipient - ) internal returns (string memory) { - string memory config = string.concat( - 'templateName = "RevenueShareV100UpgradePath"\n\nportal = "', - _portal, - '"\nsaltSeed = "', - _saltSeed, - '"\nuseDefaultCalculator = ', - _useDefaultCalculator ? 'true' : 'false', - '\n\n' - ); - - // Add calculator-specific fields based on useDefaultCalculator - if (_useDefaultCalculator) { - config = string.concat( - config, - 'l1WithdrawerMinWithdrawalAmount = 350000\nl1WithdrawerRecipient = "', - _l1WithdrawerRecipient, - '"\nl1WithdrawerGasLimit = ', - vm.toString(_l1WithdrawerGasLimit), - '\n\nscRevShareCalcChainFeesRecipient = "', - _scRevShareCalcChainFeesRecipient, - '"\n\n' - ); - } else { - config = string.concat( - config, - 'customCalculator = "', - _customCalculator, - '"\n\n' - ); - } - - config = string.concat( - config, - '[addresses]\nProxyAdminOwner = "0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A"\n', - 'OptimismPortal = "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"' - ); - - string memory configPath = string.concat(TEMP_CONFIG_DIR, "temp-config-", vm.toString(uint256(uint32(msg.sig))), ".toml"); - vm.writeFile(configPath, config); - return configPath; - } - - /// @notice Tests that the template reverts when the portal is a zero address. - function test_revenueShareUpgradePath_portal_zero_address_reverts() public { - bool useDefaultCalculator = true; - - string memory configPath = _writeTestConfig( - ZERO_ADDRESS, // INVALID - portal is zero address - DEFAULT_SALT_SEED, - useDefaultCalculator, - ZERO_ADDRESS, // customCalculator (not used when useDefaultCalculator=true) - DEFAULT_L1_WITHDRAWER_RECIPIENT, - DEFAULT_L1_WITHDRAWER_GAS_LIMIT, - DEFAULT_SC_REV_SHARE_CALC_CHAIN_FEES_RECIPIENT - ); - vm.expectRevert("portal must be set in config"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the salt seed is an empty string. - function test_revenueShareUpgradePath_saltSeed_empty_string_reverts() public { - bool useDefaultCalculator = true; - - string memory configPath = _writeTestConfig( - DEFAULT_PORTAL, - EMPTY_STRING, // INVALID - saltSeed is empty - useDefaultCalculator, - ZERO_ADDRESS, // customCalculator (not used when useDefaultCalculator=true) - DEFAULT_L1_WITHDRAWER_RECIPIENT, - DEFAULT_L1_WITHDRAWER_GAS_LIMIT, - DEFAULT_SC_REV_SHARE_CALC_CHAIN_FEES_RECIPIENT - ); - vm.expectRevert("saltSeed must be set in the config"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the l1 withdrawer recipient is a zero address. - function test_revenueShareUpgradePath_l1WithdrawerRecipient_zero_address_reverts() public { - bool useDefaultCalculator = true; - - string memory configPath = _writeTestConfig( - DEFAULT_PORTAL, - DEFAULT_SALT_SEED, - useDefaultCalculator, - ZERO_ADDRESS, // customCalculator (not used when useDefaultCalculator=true) - ZERO_ADDRESS, // INVALID - l1WithdrawerRecipient is zero address - DEFAULT_L1_WITHDRAWER_GAS_LIMIT, - DEFAULT_SC_REV_SHARE_CALC_CHAIN_FEES_RECIPIENT - ); - vm.expectRevert("l1WithdrawerRecipient must be set in config"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the l1 withdrawer gas limit is zero. - function test_revenueShareUpgradePath_l1WithdrawerGasLimit_zero_reverts() public { - bool useDefaultCalculator = true; - - string memory configPath = _writeTestConfig( - DEFAULT_PORTAL, - DEFAULT_SALT_SEED, - useDefaultCalculator, - ZERO_ADDRESS, // customCalculator (not used when useDefaultCalculator=true) - DEFAULT_L1_WITHDRAWER_RECIPIENT, - 0, // INVALID - l1WithdrawerGasLimit is zero - DEFAULT_SC_REV_SHARE_CALC_CHAIN_FEES_RECIPIENT - ); - vm.expectRevert("l1WithdrawerGasLimit must be greater than 0"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the l1 withdrawer gas limit is too high. - function test_revenueShareUpgradePath_l1WithdrawerGasLimit_too_high_reverts() public { - bool useDefaultCalculator = true; - - string memory configPath = _writeTestConfig( - DEFAULT_PORTAL, - DEFAULT_SALT_SEED, - useDefaultCalculator, - ZERO_ADDRESS, // customCalculator (not used when useDefaultCalculator=true) - DEFAULT_L1_WITHDRAWER_RECIPIENT, - UINT32_MAX_PLUS_ONE, // INVALID - l1WithdrawerGasLimit exceeds uint32.max - DEFAULT_SC_REV_SHARE_CALC_CHAIN_FEES_RECIPIENT - ); - vm.expectRevert("l1WithdrawerGasLimit must be less than uint32.max"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when the chain fees recipient is a zero address. - function test_revenueShareUpgradePath_scRevShareCalcChainFeesRecipient_zero_address_reverts() public { - bool useDefaultCalculator = true; - - string memory configPath = _writeTestConfig( - DEFAULT_PORTAL, - DEFAULT_SALT_SEED, - useDefaultCalculator, - ZERO_ADDRESS, // customCalculator (not used when useDefaultCalculator=true) - DEFAULT_L1_WITHDRAWER_RECIPIENT, - DEFAULT_L1_WITHDRAWER_GAS_LIMIT, - ZERO_ADDRESS // INVALID - scRevShareCalcChainFeesRecipient is zero address - ); - vm.expectRevert("scRevShareCalcChainFeesRecipient must be set in config"); - template.simulate(configPath); - vm.removeFile(configPath); - } - - /// @notice Tests that the template reverts when using custom calculator with zero address. - function test_revenueShareUpgradePath_customCalculator_zero_address_reverts() public { - bool useDefaultCalculator = false; - - string memory configPath = _writeTestConfig( - DEFAULT_PORTAL, - DEFAULT_SALT_SEED, - useDefaultCalculator, - ZERO_ADDRESS, // INVALID - customCalculator is zero address when useDefaultCalculator=false - ZERO_ADDRESS, // Not used when useDefaultCalculator=false - 0, // Not used when useDefaultCalculator=false - ZERO_ADDRESS // Not used when useDefaultCalculator=false - ); - vm.expectRevert("customCalculator must be set when useDefaultCalculator is false"); - template.simulate(configPath); - vm.removeFile(configPath); - } -} - -contract RevenueShareUpgradePathTest is Test { - using stdStorage for StdStorage; - - event TransactionDeposited(address indexed from, address indexed to, uint256 indexed version, bytes opaqueData); - - RevenueShareV100UpgradePath public template; - - // Expected addresses from config - address public constant PORTAL = 0xbEb5Fc579115071764c7423A4f12eDde41f106Ed; - address public constant PROXY_ADMIN_OWNER = 0x5a0Aae59D09fccBdDb6C6CcEB07B7279367C3d2A; - - // Expected number of actions - uint256 public constant EXPECTED_DEPLOYMENTS_DEFAULT_CALC = 7; - uint256 public constant EXPECTED_UPGRADES_DEFAULT_CALC = 5; - uint256 public constant EXPECTED_DEPLOYMENTS_CUSTOM_CALC = 5; - uint256 public constant EXPECTED_UPGRADES_CUSTOM_CALC = 5; - - // L2 predeploys - address internal constant CREATE2_DEPLOYER = 0x13b0D85CcB8bf860b6b79AF3029fCA081AE9beF2; - address internal constant FEE_SPLITTER = 0x420000000000000000000000000000000000002B; - address internal constant PROXY_ADMIN = 0x4200000000000000000000000000000000000018; - uint64[12] internal EXPECTED_GAS_LIMITS_DEFAULT_CALC = [ - RevShareGasLimits.L1_WITHDRAWER_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.SC_REV_SHARE_CALCULATOR_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT - ]; - - uint64[10] internal EXPECTED_GAS_LIMITS_CUSTOM_CALC = [ - RevShareGasLimits.FEE_SPLITTER_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT, - RevShareGasLimits.FEE_VAULTS_DEPLOYMENT_GAS_LIMIT, - RevShareGasLimits.UPGRADE_GAS_LIMIT - ]; - - uint256 internal constant DEPOSIT_VERSION = 0; - - function _mockAndExpect(address _receiver, bytes memory _calldata, bytes memory _returned) internal { - vm.mockCall(_receiver, _calldata, _returned); - vm.expectCall(_receiver, _calldata); - } - - function setUp() public { - vm.createSelectFork("mainnet"); - - template = new RevenueShareV100UpgradePath(); - } - - function test_defaultCalculator_succeeds() public { - bool _isDefaultCalculator = true; - - _testRevenueShareUpgrade( - "test/tasks/example/eth/015-revenue-share-upgrade/config.toml", - _isDefaultCalculator, - EXPECTED_DEPLOYMENTS_DEFAULT_CALC + EXPECTED_UPGRADES_DEFAULT_CALC, - EXPECTED_DEPLOYMENTS_DEFAULT_CALC, - EXPECTED_UPGRADES_DEFAULT_CALC, - "Should have 12 actions for default calculator scenario" - ); - } - - function test_customCalculator_succeeds() public { - bool _isDefaultCalculator = false; - - _testRevenueShareUpgrade( - "test/tasks/example/eth/017-revenue-share-upgrade-custom-calc/config.toml", - _isDefaultCalculator, - EXPECTED_DEPLOYMENTS_CUSTOM_CALC + EXPECTED_UPGRADES_CUSTOM_CALC, - EXPECTED_DEPLOYMENTS_CUSTOM_CALC, - EXPECTED_UPGRADES_CUSTOM_CALC, - "Should have 10 actions for custom calculator scenario" - ); - } - - /// @notice Helper function to test revenue share upgrade scenarios - /// @param _configPath Path to the config file - /// @param _isDefaultCalculator Whether this uses the default calculator (true) or custom calculator (false) - /// @param _expectedTotalActions Expected total number of actions - /// @param _expectedDeployments Expected number of deployment actions - /// @param _expectedUpgrades Expected number of upgrade actions - /// @param _actionCountMessage Assertion message for action count verification - function _testRevenueShareUpgrade( - string memory _configPath, - bool _isDefaultCalculator, - uint256 _expectedTotalActions, - uint256 _expectedDeployments, - uint256 _expectedUpgrades, - string memory _actionCountMessage - ) internal { - // Step 1: Run simulate to prepare everything and get the actions - (, Action[] memory _actions,, address _rootSafe) = template.simulate(_configPath, new address[](0)); - - // Verify we got the expected safe and action count - assertEq(_rootSafe, PROXY_ADMIN_OWNER, "Root safe should be ProxyAdminOwner"); - assertEq(_actions.length, _expectedTotalActions, _actionCountMessage); - - // Step 2: Get the safe's owners - IGnosisSafe _safe = IGnosisSafe(_rootSafe); - address[] memory _owners = _safe.getOwners(); - - // Step 3: Get the multicall calldata that will be executed - IMulticall3.Call3Value[] memory _calls = new IMulticall3.Call3Value[](_actions.length); - for (uint256 i; i < _actions.length; i++) { - _calls[i] = IMulticall3.Call3Value({ - target: _actions[i].target, - allowFailure: false, - value: _actions[i].value, - callData: _actions[i].arguments - }); - } - bytes memory _multicallData = abi.encodeCall(IMulticall3.aggregate3Value, (_calls)); - - // Step 4: Get the nonce and compute transaction hash before any state changes - uint256 _nonceBefore = _safe.nonce(); - - bytes32 _txHash = _safe.getTransactionHash( - template.multicallTarget(), - 0, // value - _multicallData, - Enum.Operation.DelegateCall, - 0, // safeTxGas - 0, // baseGas - 0, // gasPrice - address(0), // gasToken - payable(address(0)), // refundReceiver - _nonceBefore - ); - - // Step 5: Manually verify expected portal calls based on known config values - _verifyExpectedPortalCalls(_actions, _isDefaultCalculator); - - // Step 6: Prank owners to approve the transaction - for (uint256 i; i < _owners.length; i++) { - vm.prank(_owners[i]); - _safe.approveHash(_txHash); - } - - // Step 7: Generate signatures after approval - bytes memory _signatures = Signatures.genPrevalidatedSignatures(_owners); - - _expectPortalEvents(_actions); - - // Step 8: Execute the transaction - bool _success = _safe.execTransaction( - template.multicallTarget(), - 0, // value - _multicallData, - Enum.Operation.DelegateCall, - 0, // safeTxGas - 0, // baseGas - 0, // gasPrice - address(0), // gasToken - payable(address(0)), // refundReceiver - _signatures - ); - - assertTrue(_success, "Transaction should execute successfully"); - assertEq(_safe.nonce(), _nonceBefore + 1, "Safe nonce should increment"); - - // Step 9: Verify the portal calls - _verifyPortalCalls(_actions, _expectedDeployments, _expectedUpgrades); - } - - /// @notice Verify the portal calls based on the expected deployments and upgrades - /// @param _actions The actions to verify - /// @param _expectedDeployments The expected number of deployments - /// @param _expectedUpgrades The expected number of upgrades - function _verifyPortalCalls(Action[] memory _actions, uint256 _expectedDeployments, uint256 _expectedUpgrades) - internal - pure - { - uint256 _deploymentCalls = 0; - uint256 _upgradeCalls = 0; - - for (uint256 i; i < _actions.length; i++) { - // Decode the depositTransaction parameters - bytes memory _params = new bytes(_actions[i].arguments.length - 4); - for (uint256 j; j < _params.length; j++) { - _params[j] = _actions[i].arguments[j + 4]; - } - (address _to,,,,) = abi.decode(_params, (address, uint256, uint64, bool, bytes)); - - if (_to == CREATE2_DEPLOYER) { - _deploymentCalls++; - } else { - _upgradeCalls++; - } - } - - assertEq(_deploymentCalls, _expectedDeployments, "Incorrect number of deployment calls"); - assertEq(_upgradeCalls, _expectedUpgrades, "Incorrect number of upgrade calls"); - } - - /// @notice Manually construct and expect portal calls based on known config values - /// This ensures the template generates correct calldata, not just circular validation - function _verifyExpectedPortalCalls(Action[] memory _actions, bool _isDefaultCalculator) internal { - uint256 _deploymentCount; - uint256 _upgradeCount; - - for (uint256 i; i < _actions.length; i++) { - bytes memory _params = _extractParams(_actions[i].arguments); - // depending on if using default calculator or custom calculator, we use the expected gas limits - uint64 _gasLimit = _isDefaultCalculator ? EXPECTED_GAS_LIMITS_DEFAULT_CALC[i] : EXPECTED_GAS_LIMITS_CUSTOM_CALC[i]; - (address _to, uint256 _value, uint64 _actualGasLimit, bool _isCreation, bytes memory _data) = - abi.decode(_params, (address, uint256, uint64, bool, bytes)); - - assertEq(_actions[i].target, PORTAL, "All actions should target the portal"); - _verifyCommonParams(_value, _actualGasLimit, _gasLimit, _isCreation, _data); - - if (_to == CREATE2_DEPLOYER) { - _deploymentCount++; - _verifyDeploymentCall(_gasLimit, _data); - } else { - _upgradeCount++; - _verifyUpgradeCall(_to, _gasLimit, _data); - } - } - - assertGt(_deploymentCount, 0, "Should have at least one deployment"); - assertGt(_upgradeCount, 0, "Should have at least one upgrade"); - assertEq(_deploymentCount + _upgradeCount, _actions.length, "All actions should be accounted for"); - } - - /// @notice Extract the parameters from the arguments - /// @param _arguments The arguments to extract the parameters from - /// @return The parameters - function _extractParams(bytes memory _arguments) internal pure returns (bytes memory) { - bytes memory _params = new bytes(_arguments.length - 4); - for (uint256 j; j < _params.length; j++) { - _params[j] = _arguments[j + 4]; - } - return _params; - } - - /// @notice Verify the parameters on the expected portal calls - /// @param _value The value - /// @param _actualGasLimit The actual gas limit - /// @param _expectedGasLimit The expected gas limit - /// @param _isCreation The is creation - /// @param _data The data, only checking calldata length - /// it is better tested in RevenueShareUpgradePath.sol::_validate - function _verifyCommonParams( - uint256 _value, - uint64 _actualGasLimit, - uint64 _expectedGasLimit, - bool _isCreation, - bytes memory _data - ) internal pure { - require(_value == 0, "All calls should have 0 value"); - require(_actualGasLimit == _expectedGasLimit, "Gas limit should match config"); - require(!_isCreation, "Should not use creation flag"); - require(_data.length > 0, "Should have calldata"); - } - - /// @notice Verify the deployment call - /// @param _gasLimit The expected gas limit - /// @param _data The expected data - function _verifyDeploymentCall(uint64 _gasLimit, bytes memory _data) internal { - vm.expectCall( - PORTAL, abi.encodeCall(IOptimismPortal2.depositTransaction, (CREATE2_DEPLOYER, 0, _gasLimit, false, _data)) - ); - - bytes4 _actualSelector; - assembly { - _actualSelector := mload(add(_data, 32)) - } - assertEq(_actualSelector, ICreate2Deployer.deploy.selector, "Deployment should call CREATE2 deploy"); - } - - /// @notice Verify the upgrade call - /// @param _to The target address, it MUST be the proxy admin - /// @param _gasLimit The expected gas limit - /// @param _data The expected data - function _verifyUpgradeCall(address _to, uint64 _gasLimit, bytes memory _data) internal { - vm.expectCall(PORTAL, abi.encodeCall(IOptimismPortal2.depositTransaction, (_to, 0, _gasLimit, false, _data))); - - _assertIsProxyAdmin(_to); - - bytes4 _selector; - assembly { - _selector := mload(add(_data, 32)) - } - assertTrue( - _selector == IProxyAdmin.upgrade.selector || _selector == IProxyAdmin.upgradeAndCall.selector, - "Upgrade should call upgradeTo or upgradeToAndCall" - ); - } - - /// @notice Verify the target address is the proxy admin - /// @param _to The target address - function _assertIsProxyAdmin(address _to) internal pure { - assertTrue(_to == PROXY_ADMIN, "Upgrade should target the proxy admin"); - } - - /// @notice Expect the portal events - /// @param _actions The actions to expect the events for - function _expectPortalEvents(Action[] memory _actions) internal { - for (uint256 i; i < _actions.length; i++) { - bytes memory _params = _extractParams(_actions[i].arguments); - (address _to,, uint64 _actualGasLimit, bool _isCreation, bytes memory _data) = - abi.decode(_params, (address, uint256, uint64, bool, bytes)); - - bytes memory _opaqueData = abi.encodePacked(uint256(0), uint256(0), _actualGasLimit, _isCreation, _data); - - vm.expectEmit(true, true, true, true, PORTAL); - emit TransactionDeposited( - AddressAliasHelper.applyL1ToL2Alias(PROXY_ADMIN_OWNER), _to, DEPOSIT_VERSION, _opaqueData - ); - } - } -}