From a27c7784bef246661f42993ed32d3d6b3c982380 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Fri, 22 Mar 2024 13:59:05 +0400 Subject: [PATCH 01/60] chore: Compile yul files in parallel within a single folder (#271) --- system-contracts/scripts/compile-yul.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system-contracts/scripts/compile-yul.ts b/system-contracts/scripts/compile-yul.ts index 83ed95a8f..05f5914f3 100644 --- a/system-contracts/scripts/compile-yul.ts +++ b/system-contracts/scripts/compile-yul.ts @@ -16,9 +16,11 @@ export async function compileYul(paths: CompilerPaths, file: string) { export async function compileYulFolder(path: string) { const paths = prepareCompilerPaths(path); const files: string[] = (await fs.promises.readdir(path)).filter((fn) => fn.endsWith(".yul")); + const promises: Promise[] = []; for (const file of files) { - await compileYul(paths, `${file}`); + promises.push(compileYul(paths, `${file}`)); } + await Promise.all(promises); } async function main() { From 4aa7006153ad571643342dff22c16eaf4a70fdc1 Mon Sep 17 00:00:00 2001 From: Rodion Sabodash Date: Tue, 26 Mar 2024 17:55:54 +0200 Subject: [PATCH 02/60] ci: Make build release manual triggered only (#287) --- ...release-manual.yaml => build-release.yaml} | 0 .github/workflows/buld-release.yaml | 50 ------------------- 2 files changed, 50 deletions(-) rename .github/workflows/{build-release-manual.yaml => build-release.yaml} (100%) delete mode 100644 .github/workflows/buld-release.yaml diff --git a/.github/workflows/build-release-manual.yaml b/.github/workflows/build-release.yaml similarity index 100% rename from .github/workflows/build-release-manual.yaml rename to .github/workflows/build-release.yaml diff --git a/.github/workflows/buld-release.yaml b/.github/workflows/buld-release.yaml deleted file mode 100644 index c2be06f80..000000000 --- a/.github/workflows/buld-release.yaml +++ /dev/null @@ -1,50 +0,0 @@ -name: Build and release - -on: - push: - branches: - - "*" - -jobs: - build-contracts: - runs-on: ubuntu-latest - - steps: - - name: Checkout the repository - uses: actions/checkout@v4 - - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: 18.18.0 - cache: yarn - - - name: Init - id: init - run: | - yarn - echo "release_tag=$(echo ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}})-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - - - name: Build contracts - run: | - yarn l1 build - yarn l2 build - yarn sc build - - - name: Prepare artifacts - run: | - tar -czvf l1-contracts.tar.gz ./l1-contracts - tar -czvf l2-contracts.tar.gz ./l2-contracts - tar -czvf system-contracts.tar.gz ./system-contracts - - - name: Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ steps.init.outputs.release_tag }} - fail_on_unmatched_files: true - target_commitish: ${{ github.sha }} - body: "" - files: | - l1-contracts.tar.gz - l2-contracts.tar.gz - system-contracts.tar.gz From a86cf766f91bf30c2974bc6c983bd0d1d0186a0e Mon Sep 17 00:00:00 2001 From: Stanislav Breadless Date: Fri, 19 Apr 2024 12:31:37 +0200 Subject: [PATCH 03/60] to do cleanup --- .../state-transition/chain-interfaces/IZkSyncHyperchain.sol | 1 - l1-contracts/src.ts/hyperchain-upgrade.ts | 2 +- l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol index 830a265c2..6641985a8 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol @@ -7,7 +7,6 @@ import {IExecutor} from "./IExecutor.sol"; import {IGetters} from "./IGetters.sol"; import {IMailbox} from "./IMailbox.sol"; -// kl to do remove this, needed for the server for now import {Diamond} from "../libraries/Diamond.sol"; interface IZkSyncHyperchain is IAdmin, IExecutor, IGetters, IMailbox { diff --git a/l1-contracts/src.ts/hyperchain-upgrade.ts b/l1-contracts/src.ts/hyperchain-upgrade.ts index 6747a117e..132c9a6a2 100644 --- a/l1-contracts/src.ts/hyperchain-upgrade.ts +++ b/l1-contracts/src.ts/hyperchain-upgrade.ts @@ -224,7 +224,7 @@ async function integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer: Dep }; const adminFacet = new Interface(hardhat.artifacts.readArtifactSync("DummyAdminFacetNoOverlap").abi); - const data = adminFacet.encodeFunctionData("executeUpgradeNoOverlap", [diamondCut]); // kl to do calldata might not be "0x" + const data = adminFacet.encodeFunctionData("executeUpgradeNoOverlap", [diamondCut]); await deployer.executeUpgrade(deployer.addresses.StateTransition.DiamondProxy, 0, data); } // register Era in Bridgehub, STM diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index 2d59eded0..930283932 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -106,7 +106,6 @@ export async function deploySharedBridgeProxyOnL2ThroughL1( /// prepare proxyInitializationParams const l2GovernorAddress = applyL1ToL2Alias(deployer.addresses.Governance); const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("L2SharedBridge").abi); - // console.log("kl to do l2GovernorAddress", l2GovernorAddress, deployer.addresses.Governance) const proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initialize", [ l1SharedBridge.address, ethers.constants.AddressZero, From 189a7feeb7490597d64971052e26b7c6e918af0d Mon Sep 17 00:00:00 2001 From: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:39:45 +0200 Subject: [PATCH 04/60] Improvements for hyperchains (#373) Signed-off-by: Danil Co-authored-by: Lyova Potyomkin Co-authored-by: kelemeno Co-authored-by: Stanislav Bezkorovainyi Co-authored-by: Raid Ateir Co-authored-by: kelemeno <34402761+kelemeno@users.noreply.github.com> Co-authored-by: Jmunoz Co-authored-by: Bence Haromi Co-authored-by: Danil --- .../script-config/config-deploy-l1.toml | 1 + l1-contracts-foundry/script/DeployL1.s.sol | 5 +- l1-contracts/.env | 3 +- .../contracts/bridge/L1ERC20Bridge.sol | 20 +-- .../contracts/bridge/L1SharedBridge.sol | 114 +++++++++++------- .../bridge/interfaces/IL1ERC20Bridge.sol | 2 +- .../bridge/interfaces/IL1SharedBridge.sol | 4 +- .../contracts/bridgehub/Bridgehub.sol | 27 ++++- .../test/DummyStateTransitionManager.sol | 8 +- ...eTransitionManagerForValidatorTimelock.sol | 2 +- ...eTransitionManagerWithBridgeHubAddress.sol | 8 +- .../dev-contracts/test/L1SharedBridgeTest.sol | 58 --------- .../IStateTransitionManager.sol | 10 +- .../StateTransitionManager.sol | 96 ++++++++++----- .../state-transition/ValidatorTimelock.sol | 2 +- .../chain-deps/facets/Admin.sol | 4 +- .../chain-deps/facets/Mailbox.sol | 14 +-- l1-contracts/src.ts/deploy.ts | 2 +- .../Bridgehub/experimental_bridge.t.sol | 2 +- .../L1SharedBridge/L1SharedBridgeBase.t.sol | 102 ++-------------- .../L1SharedBridge/L1SharedBridgeFails.t.sol | 14 +-- .../L1SharedBridgeHyperEnabled.t.sol | 95 ++------------- .../L1SharedBridge/L1SharedBridgeLegacy.t.sol | 39 +----- .../_L1SharedBridge_Shared.t.sol | 28 ++++- .../concrete/DiamondCut/UpgradeLogic.t.sol | 8 +- .../CreateNewChain.t.sol | 2 +- .../StateTransitionManager/FreezeChain.t.sol | 2 +- .../RevertBatches.t.sol | 2 +- .../_StateTransitionManager_Shared.t.sol | 2 +- .../facets/Admin/FreezeDiamond.t.sol | 10 +- .../facets/Admin/UnfreezeDiamond.t.sol | 12 +- .../initial_deployment_test.spec.ts | 2 +- .../test/unit_tests/legacy_era_test.spec.ts | 13 +- .../validator_timelock_test.spec.ts | 2 +- yarn.lock | 53 +------- 35 files changed, 287 insertions(+), 481 deletions(-) delete mode 100644 l1-contracts/contracts/dev-contracts/test/L1SharedBridgeTest.sol diff --git a/l1-contracts-foundry/script-config/config-deploy-l1.toml b/l1-contracts-foundry/script-config/config-deploy-l1.toml index e98ac5445..ddcd9b27e 100644 --- a/l1-contracts-foundry/script-config/config-deploy-l1.toml +++ b/l1-contracts-foundry/script-config/config-deploy-l1.toml @@ -4,6 +4,7 @@ owner_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" [contracts] governance_security_council_address = "0x0000000000000000000000000000000000000000" governance_min_delay = 0 +max_number_of_hyperchains = 100 create2_factory_salt = "0x00000000000000000000000000000000000000000000000000000000000000ff" create2_factory_addr = "0x0000000000000000000000000000000000000000" validator_timelock_execution_delay = 0 diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 2bb1aff01..3768787de 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -105,6 +105,7 @@ contract DeployL1Script is Script { uint256 diamondInitMinimalL2GasPrice; address governanceSecurityCouncilAddress; uint256 governanceMinDelay; + uint256 maxNumberOfHyperchains; } struct TokensConfig { @@ -165,6 +166,7 @@ contract DeployL1Script is Script { "$.contracts.governance_security_council_address" ); config.contracts.governanceMinDelay = toml.readUint("$.contracts.governance_min_delay"); + config.contracts.maxNumberOfHyperchains = toml.readUint("$.contracts.max_number_of_hyperchains"); config.contracts.create2FactorySalt = toml.readBytes32("$.contracts.create2_factory_salt"); if (vm.keyExistsToml(toml, "$.contracts.create2_factory_addr")) { config.contracts.create2FactoryAddr = toml.readAddress("$.contracts.create2_factory_addr"); @@ -344,7 +346,8 @@ contract DeployL1Script is Script { function deployStateTransitionManagerImplementation() internal { bytes memory bytecode = abi.encodePacked( type(StateTransitionManager).creationCode, - abi.encode(addresses.bridgehub.bridgehubProxy) + abi.encode(addresses.bridgehub.bridgehubProxy), + abi.encode(config.contracts.maxNumberOfHyperchains) ); address contractAddress = deployViaCreate2(bytecode); console.log("StateTransitionManagerImplementation deployed at:", contractAddress); diff --git a/l1-contracts/.env b/l1-contracts/.env index a55f1264e..10bbdf102 100644 --- a/l1-contracts/.env +++ b/l1-contracts/.env @@ -32,4 +32,5 @@ CONTRACTS_VALIDATOR_TIMELOCK_ADDR=0x0000000000000000000000000000000000000000 CONTRACTS_VALIDATOR_TIMELOCK_EXECUTION_DELAY=0 ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR=0x0000000000000000000000000000000000000000 ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR=0x0000000000000000000000000000000000000001 -CONTRACTS_SHARED_BRIDGE_UPGRADE_STORAGE_SWITCH=0 \ No newline at end of file +CONTRACTS_SHARED_BRIDGE_UPGRADE_STORAGE_SWITCH=0 +CONTRACTS_MAX_NUMBER_OF_HYPERCHAINS=100 \ No newline at end of file diff --git a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol index 85534e5d8..da3098969 100644 --- a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol @@ -20,7 +20,7 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { using SafeERC20 for IERC20; /// @dev The shared bridge that is now used for all bridging, replacing the legacy contract. - IL1SharedBridge public immutable override sharedBridge; + IL1SharedBridge public immutable override SHARED_BRIDGE; /// @dev A mapping L2 batch number => message number => flag. /// @dev Used to indicate that L2 -> L1 message was already processed for zkSync Era withdrawals. @@ -57,7 +57,7 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { /// @dev Contract is expected to be used as proxy implementation. /// @dev Initialize the implementation to prevent Parity hack. constructor(IL1SharedBridge _sharedBridge) reentrancyGuardInitializer { - sharedBridge = _sharedBridge; + SHARED_BRIDGE = _sharedBridge; } /// @dev Initializes the reentrancy guard. Expected to be used in the proxy. @@ -65,9 +65,9 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { /// @dev transfer token to shared bridge as part of upgrade function transferTokenToSharedBridge(address _token) external { - require(msg.sender == address(sharedBridge), "Not shared bridge"); + require(msg.sender == address(SHARED_BRIDGE), "Not shared bridge"); uint256 amount = IERC20(_token).balanceOf(address(this)); - IERC20(_token).safeTransfer(address(sharedBridge), amount); + IERC20(_token).safeTransfer(address(SHARED_BRIDGE), amount); } /*////////////////////////////////////////////////////////////// @@ -152,7 +152,7 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { uint256 amount = _depositFundsToSharedBridge(msg.sender, IERC20(_l1Token), _amount); require(amount == _amount, "3T"); // The token has non-standard transfer logic - l2TxHash = sharedBridge.depositLegacyErc20Bridge{value: msg.value}({ + l2TxHash = SHARED_BRIDGE.depositLegacyErc20Bridge{value: msg.value}({ _msgSender: msg.sender, _l2Receiver: _l2Receiver, _l1Token: _l1Token, @@ -169,9 +169,9 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { /// @dev Transfers tokens from the depositor address to the shared bridge address. /// @return The difference between the contract balance before and after the transferring of funds. function _depositFundsToSharedBridge(address _from, IERC20 _token, uint256 _amount) internal returns (uint256) { - uint256 balanceBefore = _token.balanceOf(address(sharedBridge)); - _token.safeTransferFrom(_from, address(sharedBridge), _amount); - uint256 balanceAfter = _token.balanceOf(address(sharedBridge)); + uint256 balanceBefore = _token.balanceOf(address(SHARED_BRIDGE)); + _token.safeTransferFrom(_from, address(SHARED_BRIDGE), _amount); + uint256 balanceAfter = _token.balanceOf(address(SHARED_BRIDGE)); return balanceAfter - balanceBefore; } @@ -197,7 +197,7 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { require(amount != 0, "2T"); // empty deposit delete depositAmount[_depositSender][_l1Token][_l2TxHash]; - sharedBridge.claimFailedDepositLegacyErc20Bridge({ + SHARED_BRIDGE.claimFailedDepositLegacyErc20Bridge({ _depositSender: _depositSender, _l1Token: _l1Token, _amount: amount, @@ -226,7 +226,7 @@ contract L1ERC20Bridge is IL1ERC20Bridge, ReentrancyGuard { require(!isWithdrawalFinalized[_l2BatchNumber][_l2MessageIndex], "pw"); // We don't need to set finalizeWithdrawal here, as we set it in the shared bridge - (address l1Receiver, address l1Token, uint256 amount) = sharedBridge.finalizeWithdrawalLegacyErc20Bridge({ + (address l1Receiver, address l1Token, uint256 amount) = SHARED_BRIDGE.finalizeWithdrawalLegacyErc20Bridge({ _l2BatchNumber: _l2BatchNumber, _l2MessageIndex: _l2MessageIndex, _l2TxNumberInBatch: _l2TxNumberInBatch, diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index 2c466d00c..8f02dd146 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; @@ -26,20 +27,20 @@ import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "../common/L2ContractAddresses. /// @custom:security-contact security@matterlabs.dev /// @dev Bridges assets between L1 and hyperchains, supporting both ETH and ERC20 tokens. /// @dev Designed for use with a proxy for upgradability. -contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgradeable { +contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgradeable, PausableUpgradeable { using SafeERC20 for IERC20; /// @dev The address of the WETH token on L1. - address public immutable override l1WethAddress; + address public immutable override L1_WETH_TOKEN; /// @dev Bridgehub smart contract that is used to operate with L2 via asynchronous L2 <-> L1 communication. - IBridgehub public immutable override bridgehub; + IBridgehub public immutable override BRIDGE_HUB; /// @dev Era's chainID - uint256 immutable eraChainId; + uint256 immutable ERA_CHAIN_ID; /// @dev The address of zkSync Era diamond proxy contract. - address immutable eraDiamondProxy; + address immutable ERA_DIAMOND_PROXY; /// @dev Stores the first batch number on the zkSync Era Diamond Proxy that was settled after Diamond proxy upgrade. /// This variable is used to differentiate between pre-upgrade and post-upgrade Eth withdrawals. Withdrawals from batches older @@ -85,18 +86,19 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @dev Maps token balances for each chain to prevent unauthorized spending across hyperchains. /// This serves as a security measure until hyperbridging is implemented. - mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) internal chainBalance; + /// NOTE: this function may be removed in the future, don't rely on it! + mapping(uint256 chainId => mapping(address l1Token => uint256 balance)) public chainBalance; /// @notice Checks that the message sender is the bridgehub. modifier onlyBridgehub() { - require(msg.sender == address(bridgehub), "ShB not BH"); + require(msg.sender == address(BRIDGE_HUB), "ShB not BH"); _; } /// @notice Checks that the message sender is the bridgehub or zkSync Era Diamond Proxy. modifier onlyBridgehubOrEra(uint256 _chainId) { require( - msg.sender == address(bridgehub) || (_chainId == eraChainId && msg.sender == eraDiamondProxy), + msg.sender == address(BRIDGE_HUB) || (_chainId == ERA_CHAIN_ID && msg.sender == ERA_DIAMOND_PROXY), "L1SharedBridge: not bridgehub or era chain" ); _; @@ -117,10 +119,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade address _eraDiamondProxy ) reentrancyGuardInitializer { _disableInitializers(); - l1WethAddress = _l1WethAddress; - bridgehub = _bridgehub; - eraChainId = _eraChainId; - eraDiamondProxy = _eraDiamondProxy; + L1_WETH_TOKEN = _l1WethAddress; + BRIDGE_HUB = _bridgehub; + ERA_CHAIN_ID = _eraChainId; + ERA_DIAMOND_PROXY = _eraDiamondProxy; } /// @dev Initializes a contract bridge for later use. Expected to be used in the proxy @@ -181,7 +183,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } function receiveEth(uint256 _chainId) external payable { - require(bridgehub.getHyperchain(_chainId) == msg.sender, "receiveEth not state transition"); + require(BRIDGE_HUB.getHyperchain(_chainId) == msg.sender, "receiveEth not state transition"); } /// @dev Initializes the l2Bridge address by governance for a specific chain. @@ -196,7 +198,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade address _prevMsgSender, address _l1Token, uint256 _amount - ) external payable virtual onlyBridgehubOrEra(_chainId) { + ) external payable virtual onlyBridgehubOrEra(_chainId) whenNotPaused { if (_l1Token == ETH_TOKEN_ADDRESS) { require(msg.value == _amount, "L1SharedBridge: msg.value not equal to amount"); } else { @@ -230,17 +232,24 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _chainId, address _prevMsgSender, // solhint-disable-next-line no-unused-vars - uint256 _l2Value, // l2Value, needed for Weth deposits in the future + uint256 _l2Value, bytes calldata _data - ) external payable override onlyBridgehub returns (L2TransactionRequestTwoBridgesInner memory request) { + ) + external + payable + override + onlyBridgehub + whenNotPaused + returns (L2TransactionRequestTwoBridgesInner memory request) + { require(l2BridgeAddress[_chainId] != address(0), "ShB l2 bridge not deployed"); (address _l1Token, uint256 _depositAmount, address _l2Receiver) = abi.decode( _data, (address, uint256, address) ); - require(_l1Token != l1WethAddress, "ShB: WETH deposit not supported"); - require(bridgehub.baseToken(_chainId) != _l1Token, "ShB: baseToken deposit not supported"); + require(_l1Token != L1_WETH_TOKEN, "ShB: WETH deposit not supported"); + require(BRIDGE_HUB.baseToken(_chainId) != _l1Token, "ShB: baseToken deposit not supported"); uint256 amount; if (_l1Token == ETH_TOKEN_ADDRESS) { @@ -288,7 +297,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _chainId, bytes32 _txDataHash, bytes32 _txHash - ) external override onlyBridgehub { + ) external override onlyBridgehub whenNotPaused { require(depositHappened[_chainId][_txHash] == 0x00, "ShB tx hap"); depositHappened[_chainId][_txHash] = _txDataHash; emit BridgehubDepositFinalized(_chainId, _txDataHash, _txHash); @@ -373,9 +382,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _l2MessageIndex, uint16 _l2TxNumberInBatch, bytes32[] calldata _merkleProof - ) internal nonReentrant { + ) internal nonReentrant whenNotPaused { { - bool proofValid = bridgehub.proveL1ToL2TransactionStatus({ + bool proofValid = BRIDGE_HUB.proveL1ToL2TransactionStatus({ _chainId: _chainId, _l2TxHash: _l2TxHash, _l2BatchNumber: _l2BatchNumber, @@ -434,8 +443,8 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @param _l2BatchNumber The L2 batch number for the withdrawal. /// @return Whether withdrawal was initiated on zkSync Era before diamond proxy upgrade. function _isEraLegacyEthWithdrawal(uint256 _chainId, uint256 _l2BatchNumber) internal view returns (bool) { - require((_chainId != eraChainId) || eraPostDiamondUpgradeFirstBatch != 0, "ShB: diamondUFB not set for Era"); - return (_chainId == eraChainId) && (_l2BatchNumber < eraPostDiamondUpgradeFirstBatch); + require((_chainId != ERA_CHAIN_ID) || eraPostDiamondUpgradeFirstBatch != 0, "ShB: diamondUFB not set for Era"); + return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraPostDiamondUpgradeFirstBatch); } /// @dev Determines if a token withdrawal was initiated on zkSync Era before the upgrade to the Shared Bridge. @@ -444,10 +453,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @return Whether withdrawal was initiated on zkSync Era before Legacy Bridge upgrade. function _isEraLegacyTokenWithdrawal(uint256 _chainId, uint256 _l2BatchNumber) internal view returns (bool) { require( - (_chainId != eraChainId) || eraPostLegacyBridgeUpgradeFirstBatch != 0, + (_chainId != ERA_CHAIN_ID) || eraPostLegacyBridgeUpgradeFirstBatch != 0, "ShB: LegacyUFB not set for Era" ); - return (_chainId == eraChainId) && (_l2BatchNumber < eraPostLegacyBridgeUpgradeFirstBatch); + return (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraPostLegacyBridgeUpgradeFirstBatch); } /// @dev Determines if a deposit was initiated on zkSync Era before the upgrade to the Shared Bridge. @@ -461,11 +470,11 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _l2TxNumberInBatch ) internal view returns (bool) { require( - (_chainId != eraChainId) || (eraLegacyBridgeLastDepositBatch != 0), + (_chainId != ERA_CHAIN_ID) || (eraLegacyBridgeLastDepositBatch != 0), "ShB: last deposit time not set for Era" ); return - (_chainId == eraChainId) && + (_chainId == ERA_CHAIN_ID) && (_l2BatchNumber < eraLegacyBridgeLastDepositBatch || (_l2TxNumberInBatch < eraLegacyBridgeLastDepositTxNumber && _l2BatchNumber == eraLegacyBridgeLastDepositBatch)); @@ -516,14 +525,17 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint16 _l2TxNumberInBatch, bytes calldata _message, bytes32[] calldata _merkleProof - ) internal nonReentrant returns (address l1Receiver, address l1Token, uint256 amount) { + ) internal nonReentrant whenNotPaused returns (address l1Receiver, address l1Token, uint256 amount) { require(!isWithdrawalFinalized[_chainId][_l2BatchNumber][_l2MessageIndex], "Withdrawal is already finalized"); isWithdrawalFinalized[_chainId][_l2BatchNumber][_l2MessageIndex] = true; // Handling special case for withdrawal from zkSync Era initiated before Shared Bridge. if (_isEraLegacyEthWithdrawal(_chainId, _l2BatchNumber)) { // Checks that the withdrawal wasn't finalized already. - bool alreadyFinalized = IGetters(eraDiamondProxy).isEthWithdrawalFinalized(_l2BatchNumber, _l2MessageIndex); + bool alreadyFinalized = IGetters(ERA_DIAMOND_PROXY).isEthWithdrawalFinalized( + _l2BatchNumber, + _l2MessageIndex + ); require(!alreadyFinalized, "Withdrawal is already finalized 2"); } @@ -564,7 +576,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade (l1Receiver, l1Token, amount) = _parseL2WithdrawalMessage(_chainId, _message); L2Message memory l2ToL1Message; { - bool baseTokenWithdrawal = (l1Token == bridgehub.baseToken(_chainId)); + bool baseTokenWithdrawal = (l1Token == BRIDGE_HUB.baseToken(_chainId)); address l2Sender = baseTokenWithdrawal ? L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR : l2BridgeAddress[_chainId]; l2ToL1Message = L2Message({ @@ -574,7 +586,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade }); } - bool success = bridgehub.proveL2MessageInclusion({ + bool success = BRIDGE_HUB.proveL2MessageInclusion({ _chainId: _chainId, _batchNumber: _messageParams.l2BatchNumber, _index: _messageParams.l2MessageIndex, @@ -605,7 +617,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade // this message is a base token withdrawal (l1Receiver, offset) = UnsafeBytes.readAddress(_l2ToL1message, offset); (amount, offset) = UnsafeBytes.readUint256(_l2ToL1message, offset); - l1Token = bridgehub.baseToken(_chainId); + l1Token = BRIDGE_HUB.baseToken(_chainId); } else if (bytes4(functionSignature) == IL1ERC20Bridge.finalizeWithdrawal.selector) { // We use the IL1ERC20Bridge for backward compatibility with old withdrawals. @@ -659,13 +671,13 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade uint256 _l2TxGasLimit, uint256 _l2TxGasPerPubdataByte, address _refundRecipient - ) external payable override onlyLegacyBridge nonReentrant returns (bytes32 l2TxHash) { - require(l2BridgeAddress[eraChainId] != address(0), "ShB b. n dep"); - require(_l1Token != l1WethAddress, "ShB: WETH deposit not supported 2"); + ) external payable override onlyLegacyBridge nonReentrant whenNotPaused returns (bytes32 l2TxHash) { + require(l2BridgeAddress[ERA_CHAIN_ID] != address(0), "ShB b. n dep"); + require(_l1Token != L1_WETH_TOKEN, "ShB: WETH deposit not supported 2"); // Note that funds have been transferred to this contract in the legacy ERC20 bridge. - if (!hyperbridgingEnabled[eraChainId]) { - chainBalance[eraChainId][_l1Token] += _amount; + if (!hyperbridgingEnabled[ERA_CHAIN_ID]) { + chainBalance[ERA_CHAIN_ID][_l1Token] += _amount; } bytes memory l2TxCalldata = _getDepositL2Calldata(_prevMsgSender, _l2Receiver, _l1Token, _amount); @@ -677,8 +689,8 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade address refundRecipient = AddressAliasHelper.actualRefundRecipient(_refundRecipient, _prevMsgSender); L2TransactionRequestDirect memory request = L2TransactionRequestDirect({ - chainId: eraChainId, - l2Contract: l2BridgeAddress[eraChainId], + chainId: ERA_CHAIN_ID, + l2Contract: l2BridgeAddress[ERA_CHAIN_ID], mintValue: msg.value, // l2 gas + l2 msg.Value the bridgehub will withdraw the mintValue from the base token bridge for gas l2Value: 0, // L2 msg.value, this contract doesn't support base token deposits or wrapping functionality, for direct deposits use bridgehub l2Calldata: l2TxCalldata, @@ -687,15 +699,15 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade factoryDeps: new bytes[](0), refundRecipient: refundRecipient }); - l2TxHash = bridgehub.requestL2TransactionDirect{value: msg.value}(request); + l2TxHash = BRIDGE_HUB.requestL2TransactionDirect{value: msg.value}(request); } bytes32 txDataHash = keccak256(abi.encode(_prevMsgSender, _l1Token, _amount)); // Save the deposited amount to claim funds on L1 if the deposit failed on L2 - depositHappened[eraChainId][l2TxHash] = txDataHash; + depositHappened[ERA_CHAIN_ID][l2TxHash] = txDataHash; emit LegacyDepositInitiated({ - chainId: eraChainId, + chainId: ERA_CHAIN_ID, l2DepositTxHash: l2TxHash, from: _prevMsgSender, to: _l2Receiver, @@ -722,7 +734,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade bytes32[] calldata _merkleProof ) external override onlyLegacyBridge returns (address l1Receiver, address l1Token, uint256 amount) { (l1Receiver, l1Token, amount) = _finalizeWithdrawal({ - _chainId: eraChainId, + _chainId: ERA_CHAIN_ID, _l2BatchNumber: _l2BatchNumber, _l2MessageIndex: _l2MessageIndex, _l2TxNumberInBatch: _l2TxNumberInBatch, @@ -755,7 +767,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade ) external override onlyLegacyBridge { _claimFailedDeposit({ _checkedInLegacyBridge: true, - _chainId: eraChainId, + _chainId: ERA_CHAIN_ID, _depositSender: _depositSender, _l1Token: _l1Token, _amount: _amount, @@ -766,4 +778,18 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _merkleProof: _merkleProof }); } + + /*////////////////////////////////////////////////////////////// + PAUSE + //////////////////////////////////////////////////////////////*/ + + /// @notice Pauses all functions marked with the `whenNotPaused` modifier. + function pause() external onlyOwner { + _pause(); + } + + /// @notice Unpauses the contract, allowing all functions marked with the `whenNotPaused` modifier to be called again. + function unpause() external onlyOwner { + _unpause(); + } } diff --git a/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol index b0e2a6173..f7dd7b07b 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1ERC20Bridge.sol @@ -60,7 +60,7 @@ interface IL1ERC20Bridge { function l2TokenAddress(address _l1Token) external view returns (address); - function sharedBridge() external view returns (IL1SharedBridge); + function SHARED_BRIDGE() external view returns (IL1SharedBridge); function l2TokenBeacon() external view returns (address); diff --git a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol index 6a5c1b518..45db2d02a 100644 --- a/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/interfaces/IL1SharedBridge.sol @@ -120,9 +120,9 @@ interface IL1SharedBridge { uint256 _eraLegacyBridgeLastDepositTxNumber ) external; - function l1WethAddress() external view returns (address); + function L1_WETH_TOKEN() external view returns (address); - function bridgehub() external view returns (IBridgehub); + function BRIDGE_HUB() external view returns (IBridgehub); function legacyBridge() external view returns (IL1ERC20Bridge); diff --git a/l1-contracts/contracts/bridgehub/Bridgehub.sol b/l1-contracts/contracts/bridgehub/Bridgehub.sol index 40458aecc..539af6a0c 100644 --- a/l1-contracts/contracts/bridgehub/Bridgehub.sol +++ b/l1-contracts/contracts/bridgehub/Bridgehub.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; +import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import {L2TransactionRequestDirect, L2TransactionRequestTwoBridgesOuter, L2TransactionRequestTwoBridgesInner} from "./IBridgehub.sol"; import {IBridgehub, IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol"; @@ -13,7 +14,7 @@ import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE, BRIDGEHUB_MIN_SECOND_BRIDGE_ import {BridgehubL2TransactionRequest, L2Message, L2Log, TxStatus} from "../common/Messaging.sol"; import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; -contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { +contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, PausableUpgradeable { /// @notice all the ether is held by the weth bridge IL1SharedBridge public sharedBridge; @@ -48,6 +49,8 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { } /// @inheritdoc IBridgehub + /// @dev Please note, if the owner wants to enforce the admin change it must execute both `setPendingAdmin` and + /// `acceptAdmin` atomically. Otherwise `admin` can set different pending admin and so fail to accept the admin rights. function setPendingAdmin(address _newPendingAdmin) external onlyOwnerOrAdmin { // Save previous value into the stack to put it into the event later address oldPendingAdmin = pendingAdmin; @@ -73,7 +76,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { /// @notice return the state transition chain contract for a chainId function getHyperchain(uint256 _chainId) public view returns (address) { - return IStateTransitionManager(stateTransitionManager[_chainId]).hyperchain(_chainId); + return IStateTransitionManager(stateTransitionManager[_chainId]).getHyperchain(_chainId); } //// Registry @@ -119,7 +122,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { uint256 _salt, address _admin, bytes calldata _initData - ) external onlyOwnerOrAdmin nonReentrant returns (uint256 chainId) { + ) external onlyOwnerOrAdmin nonReentrant whenNotPaused returns (uint256) { require(_chainId != 0, "Bridgehub: chainId cannot be 0"); require(_chainId <= type(uint48).max, "Bridgehub: chainId too large"); @@ -212,7 +215,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { /// This means this is not ideal for contract calls, as the contract would have to handle token allowance of the base Token function requestL2TransactionDirect( L2TransactionRequestDirect calldata _request - ) external payable override nonReentrant returns (bytes32 canonicalTxHash) { + ) external payable override nonReentrant whenNotPaused returns (bytes32 canonicalTxHash) { { address token = baseToken[_request.chainId]; if (token == ETH_TOKEN_ADDRESS) { @@ -258,7 +261,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { /// @notice This function is great for contract calls to L2, the secondBridge can be any contract. function requestL2TransactionTwoBridges( L2TransactionRequestTwoBridgesOuter calldata _request - ) external payable override nonReentrant returns (bytes32 canonicalTxHash) { + ) external payable override nonReentrant whenNotPaused returns (bytes32 canonicalTxHash) { { address token = baseToken[_request.chainId]; uint256 baseTokenMsgValue; @@ -320,4 +323,18 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable { canonicalTxHash ); } + + /*////////////////////////////////////////////////////////////// + PAUSE + //////////////////////////////////////////////////////////////*/ + + /// @notice Pauses all functions marked with the `whenNotPaused` modifier. + function pause() external onlyOwner { + _pause(); + } + + /// @notice Unpauses the contract, allowing all functions marked with the `whenNotPaused` modifier to be called again. + function unpause() external onlyOwner { + _unpause(); + } } diff --git a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol index db99d76c4..b13050318 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManager.sol @@ -2,18 +2,22 @@ pragma solidity 0.8.24; +import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + import {StateTransitionManager} from "../../state-transition/StateTransitionManager.sol"; /// @title DummyExecutor /// @notice A test smart contract implementing the IExecutor interface to simulate Executor behavior for testing purposes. contract DummyStateTransitionManager is StateTransitionManager { + using EnumerableMap for EnumerableMap.UintToAddressMap; + // add this to be excluded from coverage report function test() internal virtual {} /// @notice Constructor - constructor() StateTransitionManager(address(0)) {} + constructor() StateTransitionManager(address(0), type(uint256).max) {} function setHyperchain(uint256 _chainId, address _hyperchain) external { - hyperchain[_chainId] = _hyperchain; + hyperchainMap.set(_chainId, _hyperchain); } } diff --git a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerForValidatorTimelock.sol b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerForValidatorTimelock.sol index d10027025..f2944d3a8 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerForValidatorTimelock.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerForValidatorTimelock.sol @@ -20,7 +20,7 @@ contract DummyStateTransitionManagerForValidatorTimelock { return chainAdmin; } - function hyperchain(uint256) external view returns (address) { + function getHyperchain(uint256) external view returns (address) { return hyperchainAddress; } } diff --git a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol index 570d005b0..883d74ca1 100644 --- a/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol +++ b/l1-contracts/contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol @@ -2,15 +2,19 @@ pragma solidity 0.8.24; +import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + import {StateTransitionManager} from "../../state-transition/StateTransitionManager.sol"; /// @title DummyExecutor /// @notice A test smart contract implementing the IExecutor interface to simulate Executor behavior for testing purposes. contract DummyStateTransitionManagerWBH is StateTransitionManager { + using EnumerableMap for EnumerableMap.UintToAddressMap; + /// @notice Constructor - constructor(address bridgeHub) StateTransitionManager(bridgeHub) {} + constructor(address bridgeHub) StateTransitionManager(bridgeHub, type(uint256).max) {} function setHyperchain(uint256 _chainId, address _hyperchain) external { - hyperchain[_chainId] = _hyperchain; + hyperchainMap.set(_chainId, _hyperchain); } } diff --git a/l1-contracts/contracts/dev-contracts/test/L1SharedBridgeTest.sol b/l1-contracts/contracts/dev-contracts/test/L1SharedBridgeTest.sol deleted file mode 100644 index 7070efccc..000000000 --- a/l1-contracts/contracts/dev-contracts/test/L1SharedBridgeTest.sol +++ /dev/null @@ -1,58 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; - -import {L1SharedBridge} from "../../bridge/L1SharedBridge.sol"; -import {IL1ERC20Bridge, IBridgehub} from "../../bridge/interfaces/IL1SharedBridge.sol"; -import {ETH_TOKEN_ADDRESS} from "../../common/Config.sol"; - -/// @author Matter Labs -contract L1SharedBridgeTest is L1SharedBridge { - // add this to be excluded from coverage report - function test() internal virtual {} - - constructor( - address _diamondProxyAddress, - address payable _l1WethAddress, - IBridgehub _bridgehub, - IL1ERC20Bridge _legacyBridge, - uint256 _eraChainId - ) L1SharedBridge(_l1WethAddress, _bridgehub, _eraChainId, _diamondProxyAddress) { - legacyBridge = IL1ERC20Bridge(_legacyBridge); - } - - /// @notice Checks that the message sender is the bridgehub or Era - modifier onlyBridgehubOrTestEra(uint256 _chainId) { - require( - (msg.sender == address(bridgehub)) || (_chainId == eraChainId && msg.sender == eraDiamondProxy), - "L1SharedBridge: not bridgehub or era chain" - ); - _; - } - - /// @notice used by bridgehub to acquire mintValue. If l2Tx fails refunds are sent to refund recipient on L2 - /// we also use it to keep to track each chain's assets - function bridgehubDepositBaseToken( - uint256 _chainId, - address _prevMsgSender, - address _l1Token, - uint256 _amount - ) external payable override onlyBridgehubOrTestEra(_chainId) { - if (_l1Token == ETH_TOKEN_ADDRESS) { - require(msg.value == _amount, "L1SharedBridge: msg.value not equal to amount"); - } else { - // The Bridgehub also checks this, but we want to be sure - require(msg.value == 0, "ShB m.v > 0 b d.it"); - - uint256 amount = _depositFunds(_prevMsgSender, IERC20(_l1Token), _amount); // note if _prevMsgSender is this contract, this will return 0. This does not happen. - require(amount == _amount, "3T"); // The token has non-standard transfer logic - } - - if (!hyperbridgingEnabled[_chainId]) { - chainBalance[_chainId][_l1Token] += _amount; - } - // Note we don't save the deposited amount, as this is for the base token, which gets sent to the refundRecipient if the tx fails - } -} diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index cac217448..d201c8333 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -57,13 +57,17 @@ interface IStateTransitionManager { /// @notice new ProtocolVersion event NewProtocolVersion(uint256 indexed oldProtocolVersion, uint256 indexed newProtocolVersion); - function bridgehub() external view returns (address); + function BRIDGE_HUB() external view returns (address); function setPendingAdmin(address _newPendingAdmin) external; function acceptAdmin() external; - function hyperchain(uint256 _chainId) external view returns (address); + function getAllHyperchains() external view returns (address[] memory); + + function getAllHyperchainChainIDs() external view returns (uint256[] memory); + + function getHyperchain(uint256 _chainId) external view returns (address); function storedBatchZero() external view returns (bytes32); @@ -95,7 +99,7 @@ interface IStateTransitionManager { bytes calldata _diamondCut ) external; - function registerAlreadyDeployedHyperchain(uint256 _chainId, address _hyperchainContract) external; + function registerAlreadyDeployedHyperchain(uint256 _chainId, address _hyperchain) external; function setNewVersionUpgrade( Diamond.DiamondCutData calldata _cutData, diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index ffb6bb68e..7271b253d 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; + import {Diamond} from "./libraries/Diamond.sol"; import {DiamondProxy} from "./chain-deps/DiamondProxy.sol"; import {IAdmin} from "./chain-interfaces/IAdmin.sol"; @@ -20,15 +22,21 @@ import {ReentrancyGuard} from "../common/ReentrancyGuard.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, L2_TO_L1_LOG_SERIALIZE_SIZE, DEFAULT_L2_LOGS_TREE_ROOT_HASH, EMPTY_STRING_KECCAK, SYSTEM_UPGRADE_L2_TX_TYPE, PRIORITY_TX_MAX_GAS_LIMIT} from "../common/Config.sol"; import {VerifierParams} from "./chain-interfaces/IVerifier.sol"; -/// @title StateTransition contract +/// @title State Transition Manager contract /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Ownable2StepUpgradeable { + using EnumerableMap for EnumerableMap.UintToAddressMap; + /// @notice Address of the bridgehub - address public immutable bridgehub; + address public immutable BRIDGE_HUB; + + /// @notice The total number of hyperchains can be created/connected to this STM. + /// This is the temporary security measure. + uint256 public immutable MAX_NUMBER_OF_HYPERCHAINS; - /// @notice The mapping from chainId => hyperchain contract - mapping(uint256 chainId => address chainContract) public hyperchain; + /// @notice The map from chainId => hyperchain contract + EnumerableMap.UintToAddressMap internal hyperchainMap; /// @dev The batch zero hash, calculated at initialization bytes32 public storedBatchZero; @@ -59,13 +67,14 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @dev Contract is expected to be used as proxy implementation. /// @dev Initialize the implementation to prevent Parity hack. - constructor(address _bridgehub) reentrancyGuardInitializer { - bridgehub = _bridgehub; + constructor(address _bridgehub, uint256 _maxNumberOfHyperchains) reentrancyGuardInitializer { + BRIDGE_HUB = _bridgehub; + MAX_NUMBER_OF_HYPERCHAINS = _maxNumberOfHyperchains; } /// @notice only the bridgehub can call modifier onlyBridgehub() { - require(msg.sender == bridgehub, "STM: only bridgehub"); + require(msg.sender == BRIDGE_HUB, "STM: only bridgehub"); _; } @@ -75,8 +84,29 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own _; } + /// @notice Returns all the registered hyperchain addresses + function getAllHyperchains() public view override returns (address[] memory chainAddresses) { + uint256[] memory keys = hyperchainMap.keys(); + chainAddresses = new address[](keys.length); + for (uint256 i = 0; i < keys.length; i++) { + chainAddresses[i] = hyperchainMap.get(i); + } + } + + /// @notice Returns all the registered hyperchain chainIDs + function getAllHyperchainChainIDs() public view override returns (uint256[] memory) { + return hyperchainMap.keys(); + } + + /// @notice Returns the address of the hyperchain with the corresponding chainID + function getHyperchain(uint256 _chainId) public view override returns (address chainAddress) { + // slither-disable-next-line unused-return + (, chainAddress) = hyperchainMap.tryGet(_chainId); + } + + /// @notice Returns the address of the hyperchain admin with the corresponding chainID function getChainAdmin(uint256 _chainId) external view override returns (address) { - return IZkSyncHyperchain(hyperchain[_chainId]).getAdmin(); + return IZkSyncHyperchain(hyperchainMap.get(_chainId)).getAdmin(); } /// @dev initialize @@ -113,6 +143,8 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one. /// @notice New admin can accept admin rights by calling `acceptAdmin` function. /// @param _newPendingAdmin Address of the new admin + /// @dev Please note, if the owner wants to enforce the admin change it must execute both `setPendingAdmin` and + /// `acceptAdmin` atomically. Otherwise `admin` can set different pending admin and so fail to accept the admin rights. function setPendingAdmin(address _newPendingAdmin) external onlyOwnerOrAdmin { // Save previous value into the stack to put it into the event later address oldPendingAdmin = pendingAdmin; @@ -172,7 +204,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own } /// @dev set the protocol version timestamp - function setprotocolVersionDeadline(uint256 _protocolVersion, uint256 _timestamp) external onlyOwner { + function setProtocolVersionDeadline(uint256 _protocolVersion, uint256 _timestamp) external onlyOwner { protocolVersionDeadline[_protocolVersion] = _timestamp; } @@ -188,17 +220,17 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @dev freezes the specified chain function freezeChain(uint256 _chainId) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).freezeDiamond(); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).freezeDiamond(); } /// @dev freezes the specified chain function unfreezeChain(uint256 _chainId) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).unfreezeDiamond(); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).unfreezeDiamond(); } /// @dev reverts batches on the specified chain function revertBatches(uint256 _chainId, uint256 _newLastBatch) external onlyOwnerOrAdmin { - IZkSyncHyperchain(hyperchain[_chainId]).revertBatches(_newLastBatch); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).revertBatches(_newLastBatch); } /// @dev execute predefined upgrade @@ -207,37 +239,37 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own uint256 _oldProtocolVersion, Diamond.DiamondCutData calldata _diamondCut ) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).upgradeChainFromVersion(_oldProtocolVersion, _diamondCut); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).upgradeChainFromVersion(_oldProtocolVersion, _diamondCut); } /// @dev executes upgrade on chain function executeUpgrade(uint256 _chainId, Diamond.DiamondCutData calldata _diamondCut) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).executeUpgrade(_diamondCut); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).executeUpgrade(_diamondCut); } /// @dev setPriorityTxMaxGasLimit for the specified chain function setPriorityTxMaxGasLimit(uint256 _chainId, uint256 _maxGasLimit) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).setPriorityTxMaxGasLimit(_maxGasLimit); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).setPriorityTxMaxGasLimit(_maxGasLimit); } /// @dev setTokenMultiplier for the specified chain function setTokenMultiplier(uint256 _chainId, uint128 _nominator, uint128 _denominator) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).setTokenMultiplier(_nominator, _denominator); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).setTokenMultiplier(_nominator, _denominator); } /// @dev changeFeeParams for the specified chain function changeFeeParams(uint256 _chainId, FeeParams calldata _newFeeParams) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).changeFeeParams(_newFeeParams); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).changeFeeParams(_newFeeParams); } /// @dev setValidator for the specified chain - function setValidator(uint256 _chainId, address _validator, bool _active) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).setValidator(_validator, _active); + function setValidator(uint256 _chainId, address _validator, bool _active) external onlyOwnerOrAdmin { + IZkSyncHyperchain(hyperchainMap.get(_chainId)).setValidator(_validator, _active); } /// @dev setPorterAvailability for the specified chain function setPorterAvailability(uint256 _chainId, bool _zkPorterIsAvailable) external onlyOwner { - IZkSyncHyperchain(hyperchain[_chainId]).setPorterAvailability(_zkPorterIsAvailable); + IZkSyncHyperchain(hyperchainMap.get(_chainId)).setPorterAvailability(_zkPorterIsAvailable); } /// registration @@ -298,11 +330,11 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @dev used to register already deployed hyperchain contracts /// @param _chainId the chain's id - /// @param _hyperchainContract the chain's contract - function registerAlreadyDeployedHyperchain(uint256 _chainId, address _hyperchainContract) external onlyOwner { - require(_hyperchainContract != address(0), "STM: hyperchain zero"); - hyperchain[_chainId] = _hyperchainContract; - emit NewHyperchain(_chainId, _hyperchainContract); + /// @param _hyperchain the chain's contract address + function registerAlreadyDeployedHyperchain(uint256 _chainId, address _hyperchain) external onlyOwner { + require(_hyperchain != address(0), "STM: hyperchain zero"); + + _registerNewHyperchain(_chainId, _hyperchain); } /// @notice called by Bridgehub when a chain registers @@ -318,7 +350,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own address _admin, bytes calldata _diamondCut ) external onlyBridgehub { - if (hyperchain[_chainId] != address(0)) { + if (getHyperchain(_chainId) != address(0)) { // Hyperchain already registered return; } @@ -337,7 +369,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own initData = bytes.concat( IDiamondInit.initialize.selector, bytes32(_chainId), - bytes32(uint256(uint160(bridgehub))), + bytes32(uint256(uint160(BRIDGE_HUB))), bytes32(uint256(uint160(address(this)))), bytes32(uint256(protocolVersion)), bytes32(uint256(uint160(_admin))), @@ -355,11 +387,17 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own // save data address hyperchainAddress = address(hyperchainContract); - hyperchain[_chainId] = hyperchainAddress; + _registerNewHyperchain(_chainId, hyperchainAddress); // set chainId in VM _setChainIdUpgrade(_chainId, hyperchainAddress); + } - emit NewHyperchain(_chainId, hyperchainAddress); + /// @dev This internal function is used to register a new hyperchain in the system. + function _registerNewHyperchain(uint256 _chainId, address _hyperchain) internal { + // slither-disable-next-line unused-return + hyperchainMap.set(_chainId, _hyperchain); + require(hyperchainMap.length() <= MAX_NUMBER_OF_HYPERCHAINS, "STM: Hyperchain limit reached"); + emit NewHyperchain(_chainId, _hyperchain); } } diff --git a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol index 786abd21e..d793783d6 100644 --- a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol +++ b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol @@ -210,7 +210,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { /// @dev Call the hyperchain diamond contract with the same calldata as this contract was called. /// Note: it is called the hyperchain diamond contract, not delegatecalled! function _propagateToZkSyncHyperchain(uint256 _chainId) internal { - address contractAddress = stateTransitionManager.hyperchain(_chainId); + address contractAddress = stateTransitionManager.getHyperchain(_chainId); assembly { // Copy function signature and arguments from calldata at zero position into memory at pointer position calldatacopy(0, 0, calldatasize()) diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol index 9f13d920a..7eb6e7904 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol @@ -135,7 +135,7 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { //////////////////////////////////////////////////////////////*/ /// @inheritdoc IAdmin - function freezeDiamond() external onlyAdminOrStateTransitionManager { + function freezeDiamond() external onlyStateTransitionManager { Diamond.DiamondStorage storage diamondStorage = Diamond.getDiamondStorage(); require(!diamondStorage.isFrozen, "a9"); // diamond proxy is frozen already @@ -145,7 +145,7 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { } /// @inheritdoc IAdmin - function unfreezeDiamond() external onlyAdminOrStateTransitionManager { + function unfreezeDiamond() external onlyStateTransitionManager { Diamond.DiamondStorage storage diamondStorage = Diamond.getDiamondStorage(); require(diamondStorage.isFrozen, "a7"); // diamond proxy is not frozen diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol index 71e15035b..752913b3f 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -34,19 +34,19 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { string public constant override getName = "MailboxFacet"; /// @dev Era's chainID - uint256 immutable eraChainId; + uint256 immutable ERA_CHAIN_ID; constructor(uint256 _eraChainId) { - eraChainId = _eraChainId; + ERA_CHAIN_ID = _eraChainId; } /// @inheritdoc IMailbox function transferEthToSharedBridge() external onlyBaseTokenBridge { - require(s.chainId == eraChainId, "Mailbox: transferEthToSharedBridge only available for Era on mailbox"); + require(s.chainId == ERA_CHAIN_ID, "Mailbox: transferEthToSharedBridge only available for Era on mailbox"); uint256 amount = address(this).balance; address baseTokenBridgeAddress = s.baseTokenBridge; - IL1SharedBridge(baseTokenBridgeAddress).receiveEth{value: amount}(eraChainId); + IL1SharedBridge(baseTokenBridgeAddress).receiveEth{value: amount}(ERA_CHAIN_ID); } /// @notice when requesting transactions through the bridgehub @@ -191,9 +191,9 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { bytes calldata _message, bytes32[] calldata _merkleProof ) external nonReentrant { - require(s.chainId == eraChainId, "Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); + require(s.chainId == ERA_CHAIN_ID, "Mailbox: finalizeEthWithdrawal only available for Era on mailbox"); IL1SharedBridge(s.baseTokenBridge).finalizeWithdrawal({ - _chainId: eraChainId, + _chainId: ERA_CHAIN_ID, _l2BatchNumber: _l2BatchNumber, _l2MessageIndex: _l2MessageIndex, _l2TxNumberInBatch: _l2TxNumberInBatch, @@ -212,7 +212,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { bytes[] calldata _factoryDeps, address _refundRecipient ) external payable returns (bytes32 canonicalTxHash) { - require(s.chainId == eraChainId, "Mailbox: legacy interface only available for Era"); + require(s.chainId == ERA_CHAIN_ID, "Mailbox: legacy interface only available for Era"); canonicalTxHash = _requestL2TransactionSender( BridgehubL2TransactionRequest({ sender: msg.sender, diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index db1187e94..78e148f5f 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -279,7 +279,7 @@ export class Deployer { ethTxOptions.gasLimit ??= 10_000_000; const contractAddress = await this.deployViaCreate2( "StateTransitionManager", - [this.addresses.Bridgehub.BridgehubProxy], + [this.addresses.Bridgehub.BridgehubProxy, getNumberFromEnv("CONTRACTS_MAX_NUMBER_OF_HYPERCHAINS")], create2Salt, ethTxOptions ); diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol index 5fff72f85..3dcc863fc 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol @@ -366,7 +366,7 @@ contract ExperimentalBridgeTest is Test { // bridgeHub.createNewChain => stateTransitionManager.createNewChain => this function sets the stateTransition mapping // of `chainId`, let's emulate that using foundry cheatcodes or let's just use the extra function we introduced in our mockSTM mockSTM.setHyperchain(chainId, address(mockChainContract)); - assertTrue(mockSTM.hyperchain(chainId) == address(mockChainContract)); + assertTrue(mockSTM.getHyperchain(chainId) == address(mockChainContract)); vm.startPrank(deployerAddress); vm.mockCall( diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeBase.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeBase.t.sol index 86869a5f4..c16ab2898 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeBase.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeBase.t.sol @@ -90,23 +90,9 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { function test_claimFailedDeposit_Erc() public { token.mint(address(sharedBridge), amount); bytes32 txDataHash = keccak256(abi.encode(alice, address(token), amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(chainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); require(sharedBridge.depositHappened(chainId, txHash) == txDataHash, "Deposit not set"); - - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); vm.mockCall( bridgehubAddress, @@ -144,23 +130,9 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { vm.deal(address(sharedBridge), amount); bytes32 txDataHash = keccak256(abi.encode(alice, ETH_TOKEN_ADDRESS, amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(chainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); require(sharedBridge.depositHappened(chainId, txHash) == txDataHash, "Deposit not set"); - - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, @@ -202,16 +174,7 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { function test_finalizeWithdrawal_EthOnEth() public { vm.deal(address(sharedBridge), amount); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -255,16 +218,7 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { function test_finalizeWithdrawal_ErcOnEth() public { token.mint(address(sharedBridge), amount); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -313,16 +267,7 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { function test_finalizeWithdrawal_EthOnErc() public { vm.deal(address(sharedBridge), amount); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -371,16 +316,7 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { function test_finalizeWithdrawal_BaseErcOnErc() public { token.mint(address(sharedBridge), amount); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -429,16 +365,7 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { function test_finalizeWithdrawal_NonBaseErcOnErc() public { token.mint(address(sharedBridge), amount); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); bytes memory message = abi.encodePacked( IL1ERC20Bridge.finalizeWithdrawal.selector, @@ -496,16 +423,7 @@ contract L1SharedBridgeTestBase is L1SharedBridgeTest { abi.encode(false) ); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(eraChainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(eraChainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol index dcb7dd165..15ef94080 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeFails.t.sol @@ -15,8 +15,6 @@ import {IL1ERC20Bridge} from "contracts/bridge/interfaces/IL1ERC20Bridge.sol"; import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol"; import {IGetters} from "contracts/state-transition/chain-interfaces/IGetters.sol"; -// import "forge-std/console.sol"; - /// We are testing all the specified revert and require cases. contract L1SharedBridgeFailTest is L1SharedBridgeTest { function test_initialize_wrongOwner() public { @@ -156,11 +154,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { function test_bridgehubConfirmL2Transaction_depositAlreadyHappened() public { bytes32 txDataHash = keccak256(abi.encode(alice, address(token), amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(chainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); vm.prank(bridgehubAddress); vm.expectRevert("ShB tx hap"); sharedBridge.bridgehubConfirmL2Transaction(chainId, txDataHash, txHash); @@ -259,11 +253,7 @@ contract L1SharedBridgeFailTest is L1SharedBridgeTest { vm.deal(address(sharedBridge), amount); bytes32 txDataHash = keccak256(abi.encode(alice, ETH_TOKEN_ADDRESS, amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(chainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); require(sharedBridge.depositHappened(chainId, txHash) == txDataHash, "Deposit not set"); vm.mockCall( diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeHyperEnabled.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeHyperEnabled.t.sol index 6b9447e65..b5e8e5467 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeHyperEnabled.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeHyperEnabled.t.sol @@ -107,27 +107,10 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { // storing depositHappened[chainId][l2TxHash] = txDataHash. bytes32 txDataHash = keccak256(abi.encode(alice, address(token), amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(chainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); require(sharedBridge.depositHappened(chainId, txHash) == txDataHash, "Deposit not set"); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); - - // Bridgehub bridgehub = new Bridgehub(); - // vm.store(address(bridgehub), bytes32(uint256(5 +2)), bytes32(uint256(31337))); - // require(address(bridgehub.deployer()) == address(31337), "Bridgehub: deployer wrong"); + _setSharedBridgeChainBalance(chainId, address(token), amount); vm.mockCall( bridgehubAddress, @@ -167,24 +150,11 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { // storing depositHappened[chainId][l2TxHash] = txDataHash. bytes32 txDataHash = keccak256(abi.encode(alice, ETH_TOKEN_ADDRESS, amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(chainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(chainId, txHash, txDataHash); require(sharedBridge.depositHappened(chainId, txHash) == txDataHash, "Deposit not set"); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, ETH_TOKEN_ADDRESS, amount); // Bridgehub bridgehub = new Bridgehub(); // vm.store(address(bridgehub), bytes32(uint256(5 +2)), bytes32(uint256(31337))); @@ -227,16 +197,7 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { vm.deal(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -281,16 +242,8 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { token.mint(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); + vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -340,16 +293,7 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { vm.deal(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -399,16 +343,8 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { token.mint(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); + vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -458,16 +394,7 @@ contract L1SharedBridgeHyperEnabledTest is L1SharedBridgeTest { token.mint(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(chainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(chainId, address(token), amount); bytes memory message = abi.encodePacked( IL1ERC20Bridge.finalizeWithdrawal.selector, diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeLegacy.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeLegacy.t.sol index db033ecfb..83e83df9c 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeLegacy.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/L1SharedBridgeLegacy.t.sol @@ -50,16 +50,7 @@ contract L1SharedBridgeLegacyTest is L1SharedBridgeTest { vm.deal(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(ETH_TOKEN_ADDRESS)), - keccak256(abi.encode(eraChainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(eraChainId, ETH_TOKEN_ADDRESS, amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -104,16 +95,7 @@ contract L1SharedBridgeLegacyTest is L1SharedBridgeTest { token.mint(address(sharedBridge), amount); /// storing chainBalance - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(eraChainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(eraChainId, address(token), amount); vm.mockCall( bridgehubAddress, abi.encodeWithSelector(IBridgehub.baseToken.selector), @@ -165,23 +147,10 @@ contract L1SharedBridgeLegacyTest is L1SharedBridgeTest { // storing depositHappened[chainId][l2TxHash] = txDataHash. bytes32 txDataHash = keccak256(abi.encode(alice, address(token), amount)); - vm.store( - address(sharedBridge), - keccak256(abi.encode(txHash, keccak256(abi.encode(eraChainId, depositLocationInStorage)))), - txDataHash - ); + _setSharedBridgeDepositHappened(eraChainId, txHash, txDataHash); require(sharedBridge.depositHappened(eraChainId, txHash) == txDataHash, "Deposit not set"); - vm.store( - address(sharedBridge), - keccak256( - abi.encode( - uint256(uint160(address(token))), - keccak256(abi.encode(eraChainId, chainBalanceLocationInStorage)) - ) - ), - bytes32(amount) - ); + _setSharedBridgeChainBalance(eraChainId, address(token), amount); // Bridgehub bridgehub = new Bridgehub(); // vm.store(address(bridgehub), bytes32(uint256(5 +2)), bytes32(uint256(31337))); diff --git a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol index 503a89799..cad8482fb 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridges/L1SharedBridge/_L1SharedBridge_Shared.t.sol @@ -1,16 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; +import {StdStorage, stdStorage} from "forge-std/Test.sol"; import {Test} from "forge-std/Test.sol"; import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; -// import {IL1ERC20Bridge} from "contracts/bridge/interfaces/IL1ERC20Bridge.sol"; import {TestnetERC20Token} from "contracts/dev-contracts/TestnetERC20Token.sol"; contract L1SharedBridgeTest is Test { + using stdStorage for StdStorage; + event BridgehubDepositBaseTokenInitiated( uint256 indexed chainId, address indexed from, @@ -83,10 +85,7 @@ contract L1SharedBridgeTest is Test { uint16 l2TxNumberInBatch; bytes32[] merkleProof; - // storing depositHappened[chainId][l2TxHash] = txDataHash. DepositHappened is 3rd so 3 -1 + dependency storage slots - uint256 depositLocationInStorage = uint256(7 - 1 + (1 + 49) + 0 + (1 + 49) + 50 + 1); // DepositHappened is 3rd so 3 -1 + dependency storage slots - uint256 isWithdrawalFinalizedStorageLocation = uint256(8 - 1 + (1 + 49) + 0 + (1 + 49) + 50 + 1); - uint256 chainBalanceLocationInStorage = uint256(10 - 1 + (1 + 49) + 0 + (1 + 49) + 50 + 1); + uint256 isWithdrawalFinalizedStorageLocation = uint256(8 - 1 + (1 + 49) + 0 + (1 + 49) + 50 + 1 + 50); function setUp() public { owner = makeAddr("owner"); @@ -96,7 +95,6 @@ contract L1SharedBridgeTest is Test { alice = makeAddr("alice"); // bob = makeAddr("bob"); l1WethAddress = makeAddr("weth"); - address l1WethAddress = makeAddr("weth"); l1ERC20BridgeAddress = makeAddr("l1ERC20Bridge"); l2SharedBridge = makeAddr("l2SharedBridge"); @@ -138,4 +136,22 @@ contract L1SharedBridgeTest is Test { vm.prank(owner); sharedBridge.initializeChainGovernance(eraChainId, l2SharedBridge); } + + function _setSharedBridgeDepositHappened(uint256 _chainId, bytes32 _txHash, bytes32 _txDataHash) internal { + stdstore + .target(address(sharedBridge)) + .sig(sharedBridge.depositHappened.selector) + .with_key(_chainId) + .with_key(_txHash) + .checked_write(_txDataHash); + } + + function _setSharedBridgeChainBalance(uint256 _chainId, address _token, uint256 _value) internal { + stdstore + .target(address(sharedBridge)) + .sig(sharedBridge.chainBalance.selector) + .with_key(_chainId) + .with_key(_token) + .checked_write(_value); + } } diff --git a/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol index 36c0f607c..41c07d9a2 100644 --- a/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol @@ -119,12 +119,12 @@ contract UpgradeLogicTest is DiamondCutTest { function test_RevertWhen_EmergencyFreezeWhenUnauthorizedGovernor() public { vm.startPrank(randomSigner); - vm.expectRevert(abi.encodePacked("Hyperchain: Only by admin or state transition manager")); + vm.expectRevert(abi.encodePacked("Hyperchain: not state transition manager")); proxyAsAdmin.freezeDiamond(); } - function test_RevertWhen_DoubleFreezingByGovernor() public { - vm.startPrank(admin); + function test_RevertWhen_DoubleFreezingBySTM() public { + vm.startPrank(stateTransitionManager); proxyAsAdmin.freezeDiamond(); @@ -133,7 +133,7 @@ contract UpgradeLogicTest is DiamondCutTest { } function test_RevertWhen_UnfreezingWhenNotFrozen() public { - vm.startPrank(admin); + vm.startPrank(stateTransitionManager); vm.expectRevert(abi.encodePacked("a7")); proxyAsAdmin.unfreezeDiamond(); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol index c3be7dc8c..dc66d38b9 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/CreateNewChain.t.sol @@ -31,7 +31,7 @@ contract createNewChainTest is StateTransitionManagerTest { createNewChain(getDiamondCutData(diamondInit)); address admin = chainContractAddress.getChainAdmin(chainId); - address newChainAddress = chainContractAddress.hyperchain(chainId); + address newChainAddress = chainContractAddress.getHyperchain(chainId); assertEq(newChainAdmin, admin); assertNotEq(newChainAddress, address(0)); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol index 2875c55c1..590d5d4ab 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/FreezeChain.t.sol @@ -8,7 +8,7 @@ contract freezeChainTest is StateTransitionManagerTest { function test_FreezingChain() public { createNewChain(getDiamondCutData(diamondInit)); - address newChainAddress = chainContractAddress.hyperchain(chainId); + address newChainAddress = chainContractAddress.getHyperchain(chainId); GettersFacet gettersFacet = GettersFacet(newChainAddress); bool isChainFrozen = gettersFacet.isDiamondStorageFrozen(); assertEq(isChainFrozen, false); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol index c1734d379..7e277c1ec 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol @@ -29,7 +29,7 @@ contract revertBatchesTest is StateTransitionManagerTest { function test_SuccessfulBatchReverting() public { createNewChain(getDiamondCutData(diamondInit)); - address newChainAddress = chainContractAddress.hyperchain(chainId); + address newChainAddress = chainContractAddress.getHyperchain(chainId); executorFacet = ExecutorFacet(address(newChainAddress)); gettersFacet = GettersFacet(address(newChainAddress)); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol index da67fcabe..cb7251185 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol @@ -41,7 +41,7 @@ contract StateTransitionManagerTest is Test { newChainAdmin = makeAddr("chainadmin"); vm.startPrank(bridgehub); - stateTransitionManager = new StateTransitionManager(bridgehub); + stateTransitionManager = new StateTransitionManager(bridgehub, type(uint256).max); diamondInit = address(new DiamondInit()); genesisUpgradeContract = new GenesisUpgrade(); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol index faa1bae67..8e79f4fc3 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/FreezeDiamond.t.sol @@ -3,17 +3,17 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; contract FreezeDiamondTest is AdminTest { event Freeze(); - function test_revertWhen_calledByNonAdminOrStateTransitionManager() public { - address nonAdminOrStateTransitionManager = makeAddr("nonAdminOrStateTransitionManager"); + function test_revertWhen_calledByNonStateTransitionManager() public { + address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); - vm.expectRevert(ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER); + vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - vm.startPrank(nonAdminOrStateTransitionManager); + vm.startPrank(nonStateTransitionManager); adminFacet.freezeDiamond(); } } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol index 4b24ad4a6..b7f1fa124 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/UnfreezeDiamond.t.sol @@ -3,22 +3,22 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; -import {ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; contract UnfreezeDiamondTest is AdminTest { event Unfreeze(); - function test_revertWhen_calledByNonAdminOrStateTransitionManager() public { - address nonAdminOrStateTransitionManager = makeAddr("nonAdminOrStateTransitionManager"); + function test_revertWhen_calledByNonStateTransitionManager() public { + address nonStateTransitionManager = makeAddr("nonStateTransitionManager"); - vm.expectRevert(ERROR_ONLY_ADMIN_OR_STATE_TRANSITION_MANAGER); + vm.expectRevert(ERROR_ONLY_STATE_TRANSITION_MANAGER); - vm.startPrank(nonAdminOrStateTransitionManager); + vm.startPrank(nonStateTransitionManager); adminFacet.unfreezeDiamond(); } function test_revertWhen_diamondIsNotFrozen() public { - address admin = utilsFacet.util_getAdmin(); + address admin = utilsFacet.util_getStateTransitionManager(); utilsFacet.util_setIsFrozen(false); diff --git a/l1-contracts/test/unit_tests/initial_deployment_test.spec.ts b/l1-contracts/test/unit_tests/initial_deployment_test.spec.ts index a466e3b44..a70594304 100644 --- a/l1-contracts/test/unit_tests/initial_deployment_test.spec.ts +++ b/l1-contracts/test/unit_tests/initial_deployment_test.spec.ts @@ -59,7 +59,7 @@ describe("Initial deployment", function () { expect(stateTransitionManagerAddress1.toLowerCase()).equal(stateTransitionManagerAddress2.toLowerCase()); const stateTransitionAddress1 = deployer.addresses.StateTransition.DiamondProxy; - const stateTransitionAddress2 = await stateTransition.hyperchain(chainId); + const stateTransitionAddress2 = await stateTransition.getHyperchain(chainId); expect(stateTransitionAddress1.toLowerCase()).equal(stateTransitionAddress2.toLowerCase()); const stateTransitionAddress3 = await bridgehub.getHyperchain(chainId); diff --git a/l1-contracts/test/unit_tests/legacy_era_test.spec.ts b/l1-contracts/test/unit_tests/legacy_era_test.spec.ts index f12c2028d..92a86dc7d 100644 --- a/l1-contracts/test/unit_tests/legacy_era_test.spec.ts +++ b/l1-contracts/test/unit_tests/legacy_era_test.spec.ts @@ -94,22 +94,19 @@ describe("Legacy Era tests", function () { await erc20TestToken.mint(await randomSigner.getAddress(), ethers.utils.parseUnits("10000", 18)); await erc20TestToken.connect(randomSigner).approve(l1ERC20BridgeAddress, ethers.utils.parseUnits("10000", 18)); - // The L1SharedBridge is compiled with the ERA_DIAMOND_PROXY address in hardhat config, so we update the shared bridge - // because all the variables are already set in the proxy, this is upgrade works. - const sharedBridgeTestFactory = await hardhat.ethers.getContractFactory("L1SharedBridgeTest"); + const sharedBridgeFactory = await hardhat.ethers.getContractFactory("L1SharedBridge"); const l1WethToken = tokens.find((token: { symbol: string }) => token.symbol == "WETH")!.address; - const sharedBridgeTest = await sharedBridgeTestFactory.deploy( - deployer.addresses.StateTransition.DiamondProxy, + const sharedBridge = await sharedBridgeFactory.deploy( l1WethToken, deployer.addresses.Bridgehub.BridgehubProxy, - deployer.addresses.Bridges.ERC20BridgeProxy, - deployer.chainId + deployer.chainId, + deployer.addresses.StateTransition.DiamondProxy ); const proxyAdminInterface = new Interface(hardhat.artifacts.readArtifactSync("ProxyAdmin").abi); const calldata = proxyAdminInterface.encodeFunctionData("upgrade(address,address)", [ deployer.addresses.Bridges.SharedBridgeProxy, - sharedBridgeTest.address, + sharedBridge.address, ]); await deployer.executeUpgrade(deployer.addresses.TransparentProxyAdmin, 0, calldata); diff --git a/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts b/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts index f39af1c62..119cae7cc 100644 --- a/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts +++ b/l1-contracts/test/unit_tests/validator_timelock_test.spec.ts @@ -80,7 +80,7 @@ describe("ValidatorTimelock tests", function () { expect(await validatorTimelock.executionDelay()).equal(0); expect(await validatorTimelock.validators(chainId, ethers.constants.AddressZero)).equal(false); expect(await validatorTimelock.stateTransitionManager()).equal(dummyStateTransitionManager.address); - expect(await dummyStateTransitionManager.hyperchain(chainId)).equal(dummyExecutor.address); + expect(await dummyStateTransitionManager.getHyperchain(chainId)).equal(dummyExecutor.address); expect(await dummyStateTransitionManager.getChainAdmin(chainId)).equal(await owner.getAddress()); expect(await dummyExecutor.getAdmin()).equal(await owner.getAddress()); }); diff --git a/yarn.lock b/yarn.lock index d12b9a84f..2c64e92e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1787,21 +1787,11 @@ antlr4@^4.11.0: resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== -antlr4@~4.8.0: - version "4.8.0" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.8.0.tgz#f938ec171be7fc2855cd3a533e87647185b32b6a" - integrity sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg== - antlr4ts@^0.5.0-alpha.4: version "0.5.0-alpha.4" resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -2095,14 +2085,6 @@ blakejs@^1.1.0: resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== -bn-str-256@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/bn-str-256/-/bn-str-256-1.9.1.tgz#898cebee70a3edc3968f97b4cebbc4771025aa82" - integrity sha512-u3muv3WO5sYv9nUQsPnDGLg731yNt/MOlKPK5pmBVqClcl7tY97tyfKxw8ed44HVrpi+7dkgJgQpbXP47a3GoQ== - dependencies: - decimal.js-light "^2.5.0" - lodash "^4.17.11" - bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" @@ -2535,11 +2517,6 @@ commander@^10.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== -commander@^2.19.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@^6.0.0: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" @@ -2742,11 +2719,6 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== -decimal.js-light@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - deep-eql@^4.0.1, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -5382,15 +5354,6 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - nan@^2.17.0, nan@^2.18.0: version "2.19.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" @@ -5491,7 +5454,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -6802,20 +6765,6 @@ then-request@^6.0.0: promise "^8.0.0" qs "^6.4.0" -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - "through@>=2.2.7 <3": version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" From b04dcaf2256a9b2626eeaefbf1b281f0119d30ab Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Fri, 19 Apr 2024 11:56:30 +0100 Subject: [PATCH 05/60] fix: l2 bridge script fix apr 19 (#380) --- .../contracts/bridge/L1SharedBridge.sol | 2 +- .../deploy-shared-bridge-on-l2-through-l1.ts | 18 +++++++++++------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index 8f02dd146..d2a9f4b0d 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -402,7 +402,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade { // Deposits that happened before the upgrade cannot be checked here, they have to be claimed and checked in the legacyBridge bool weCanCheckDepositHere = !_isEraLegacyDeposit(_chainId, _l2BatchNumber, _l2TxNumberInBatch); - // Double claims are not possible, as we this check except for legacy bridge withdrawals + // Double claims are not possible, as depositHappened is checked here for all except legacy deposits (which have to happen through the legacy bridge) // Funds claimed before the update will still be recorded in the legacy bridge // Note we double check NEW deposits if they are called from the legacy bridge notCheckedInLegacyBridgeOrWeCanCheckDeposit = (!_checkedInLegacyBridge) || weCanCheckDepositHere; diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index 930283932..e431bc344 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -20,7 +20,7 @@ import * as hre from "hardhat"; export const L2_SHARED_BRIDGE_ABI = hre.artifacts.readArtifactSync("L2SharedBridge").abi; export const L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE = hre.artifacts.readArtifactSync("L2SharedBridge").bytecode; -export const BEACON_PROXY_BYTECODE = hre.artifacts.readArtifactSync("BeaconProxy").bytecode; +export const L2_STANDARD_TOKEN_PROXY_BYTECODE = hre.artifacts.readArtifactSync("BeaconProxy").bytecode; export async function publishL2SharedBridgeDependencyBytecodesOnL2( deployer: Deployer, @@ -37,7 +37,11 @@ export async function publishL2SharedBridgeDependencyBytecodesOnL2( await publishBytecodeFromL1( chainId, deployer.deployWallet, - [L2_STANDARD_ERC20_PROXY_FACTORY_BYTECODE, L2_STANDARD_ERC20_IMPLEMENTATION_BYTECODE], + [ + L2_STANDARD_ERC20_PROXY_FACTORY_BYTECODE, + L2_STANDARD_ERC20_IMPLEMENTATION_BYTECODE, + L2_STANDARD_TOKEN_PROXY_BYTECODE, + ], gasPrice ); @@ -50,7 +54,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch if (deployer.verbose) { console.log("Deploying L2SharedBridge Implementation"); } - + const eraChainId = process.env.CONTRACTS_ERA_CHAIN_ID; if (!L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE) { throw new Error("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE not found"); } @@ -62,7 +66,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch const l2SharedBridgeImplAddress = computeL2Create2Address( deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [chainId]), + defaultAbiCoder.encode(["uint256"], [eraChainId]), ethers.constants.HashZero ); deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress; @@ -80,7 +84,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch chainId, deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [chainId]), + defaultAbiCoder.encode(["uint256"], [eraChainId]), ethers.constants.HashZero, priorityTxMaxGasLimit, gasPrice, @@ -108,8 +112,8 @@ export async function deploySharedBridgeProxyOnL2ThroughL1( const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("L2SharedBridge").abi); const proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initialize", [ l1SharedBridge.address, - ethers.constants.AddressZero, - hashL2Bytecode(BEACON_PROXY_BYTECODE), + deployer.addresses.Bridges.ERC20BridgeProxy, + hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE), l2GovernorAddress, ]); From b0c1aa5466b3ff531a318a89101a3f270bf886ef Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Mon, 22 Apr 2024 13:13:35 +0200 Subject: [PATCH 06/60] Debug dev CI (#385) --- l1-contracts-foundry/script/DeployErc20.s.sol | 4 ---- 1 file changed, 4 deletions(-) diff --git a/l1-contracts-foundry/script/DeployErc20.s.sol b/l1-contracts-foundry/script/DeployErc20.s.sol index 82f11b848..4a2046ec7 100644 --- a/l1-contracts-foundry/script/DeployErc20.s.sol +++ b/l1-contracts-foundry/script/DeployErc20.s.sol @@ -8,10 +8,6 @@ import {stdToml} from "forge-std/StdToml.sol"; import {Utils} from "./Utils.sol"; -// solhint-disable no-unused-import -import {TestnetERC20Token} from "contracts/dev-contracts/TestnetERC20Token.sol"; -import {WETH9} from "contracts/dev-contracts/WETH9.sol"; - contract DeployErc20Script is Script { using stdToml for string; From 06d4311dda56d0b0b7284bb045b2c80fa9b8f0aa Mon Sep 17 00:00:00 2001 From: Lyova Potyomkin Date: Mon, 22 Apr 2024 14:19:24 +0300 Subject: [PATCH 07/60] feat: allow using era's legacy interface for testing (#384) Co-authored-by: Stanislav Breadless --- .../dev-contracts/DummyL1ERC20Bridge.sol | 16 +++++ .../scripts/upgrade-shared-bridge-era.ts | 70 ++++++++++++++++++- l1-contracts/src.ts/deploy.ts | 8 ++- l1-contracts/test/unit_tests/utils.ts | 3 +- l1-contracts/tsconfig.json | 3 +- .../deploy-shared-bridge-on-l2-through-l1.ts | 23 ++++-- 6 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 l1-contracts/contracts/dev-contracts/DummyL1ERC20Bridge.sol diff --git a/l1-contracts/contracts/dev-contracts/DummyL1ERC20Bridge.sol b/l1-contracts/contracts/dev-contracts/DummyL1ERC20Bridge.sol new file mode 100644 index 000000000..8155ddf6b --- /dev/null +++ b/l1-contracts/contracts/dev-contracts/DummyL1ERC20Bridge.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +import {L1ERC20Bridge} from "../bridge/L1ERC20Bridge.sol"; +import {IL1SharedBridge} from "../bridge/interfaces/IL1SharedBridge.sol"; + +contract DummyL1ERC20Bridge is L1ERC20Bridge { + constructor(IL1SharedBridge _l1SharedBridge) L1ERC20Bridge(_l1SharedBridge) {} + + function setValues(address _l2Bridge, address _l2TokenBeacon, bytes32 _l2TokenProxyBytecodeHash) external { + l2Bridge = _l2Bridge; + l2TokenBeacon = _l2TokenBeacon; + l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; + } +} diff --git a/l1-contracts/scripts/upgrade-shared-bridge-era.ts b/l1-contracts/scripts/upgrade-shared-bridge-era.ts index e29c1172c..659005b80 100644 --- a/l1-contracts/scripts/upgrade-shared-bridge-era.ts +++ b/l1-contracts/scripts/upgrade-shared-bridge-era.ts @@ -7,7 +7,10 @@ import { Deployer } from "../src.ts/deploy"; import { formatUnits, parseUnits, Interface } from "ethers/lib/utils"; import { web3Provider, GAS_MULTIPLIER } from "./utils"; import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; -import { ethTestConfig } from "../src.ts/utils"; +import { ethTestConfig, getAddressFromEnv } from "../src.ts/utils"; +import { hashL2Bytecode } from "../../l2-contracts/src/utils"; +import { Provider } from "zksync-web3"; +import beaconProxy = require("../../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json"); const provider = web3Provider(); @@ -18,7 +21,6 @@ async function main() { program .option("--private-key ") - .option("--chain-id ") .option("--gas-price ") .option("--nonce ") .option("--owner-address ") @@ -57,12 +59,56 @@ async function main() { await deployer.deploySharedBridgeImplementation(create2Salt, { nonce }); const proxyAdminInterface = new Interface(hardhat.artifacts.readArtifactSync("ProxyAdmin").abi); - const calldata = proxyAdminInterface.encodeFunctionData("upgrade(address,address)", [ + let calldata = proxyAdminInterface.encodeFunctionData("upgrade(address,address)", [ deployer.addresses.Bridges.SharedBridgeProxy, deployer.addresses.Bridges.SharedBridgeImplementation, ]); await deployer.executeUpgrade(deployer.addresses.TransparentProxyAdmin, 0, calldata); + + // deploy a dummy erc20 bridge to set the storage values + await deployer.deployERC20BridgeImplementation(create2Salt, {}, true); + + // upgrade to dummy bridge + calldata = proxyAdminInterface.encodeFunctionData("upgrade(address,address)", [ + deployer.addresses.Bridges.ERC20BridgeProxy, + deployer.addresses.Bridges.ERC20BridgeImplementation, + ]); + + await deployer.executeUpgrade(deployer.addresses.TransparentProxyAdmin, 0, calldata); + console.log("Upgraded ERC20Bridge to 'dummy' implementation"); + + const dummyBridgeAbi = hardhat.artifacts.readArtifactSync("DummyL1ERC20Bridge").abi; + const dummyBridge = new ethers.Contract( + deployer.addresses.Bridges.ERC20BridgeProxy, + dummyBridgeAbi, + deployWallet + ); + + const l2SharedBridgeAddress = getAddressFromEnv("CONTRACTS_L2_SHARED_BRIDGE_ADDR"); + const l2TokenBytecodeHash = hashL2Bytecode(beaconProxy.bytecode); + const l2Provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + // For the server to start up. + console.log("Waiting for server to start up"); + await waitForServer(l2Provider); + + const l2SharedBridge = new ethers.Contract( + l2SharedBridgeAddress, + ["function l2TokenBeacon() view returns (address)"], + l2Provider + ); + const l2TokenBeacon = await l2SharedBridge.l2TokenBeacon(); + + console.log("Retrieved storage values for TestERC20Bridge:"); + console.log("l2SharedBridgeAddress:", l2SharedBridgeAddress); + console.log("l2TokenBeacon:", l2TokenBeacon); + console.log("l2TokenBytecodeHash:", ethers.utils.hexlify(l2TokenBytecodeHash)); + + // set storage values + const tx = await dummyBridge.setValues(l2SharedBridgeAddress, l2TokenBeacon, l2TokenBytecodeHash); + await tx.wait(); + + console.log("Set storage values for TestERC20Bridge"); }); await program.parseAsync(process.argv); @@ -74,3 +120,21 @@ main() console.error("Error:", err); process.exit(1); }); + +async function waitForServer(provider: Provider) { + let iter = 0; + while (iter < 60) { + try { + await provider.getBlockNumber(); + return; + } catch (_) { + await sleep(2); + iter += 1; + } + } + throw new Error("Server didn't start up in time. Exiting."); +} + +async function sleep(seconds: number) { + return new Promise((resolve) => setTimeout(resolve, seconds * 1000)); +} diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 78e148f5f..3039e2c49 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -401,10 +401,14 @@ export class Deployer { this.addresses.StateTransition.Verifier = contractAddress; } - public async deployERC20BridgeImplementation(create2Salt: string, ethTxOptions: ethers.providers.TransactionRequest) { + public async deployERC20BridgeImplementation( + create2Salt: string, + ethTxOptions: ethers.providers.TransactionRequest, + dummy: boolean = false + ) { ethTxOptions.gasLimit ??= 10_000_000; const contractAddress = await this.deployViaCreate2( - "L1ERC20Bridge", + dummy ? "DummyL1ERC20Bridge" : "L1ERC20Bridge", [this.addresses.Bridges.SharedBridgeProxy], create2Salt, ethTxOptions diff --git a/l1-contracts/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts index 5edd03e81..fd34a0e7f 100644 --- a/l1-contracts/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -380,7 +380,7 @@ export async function depositERC20( const neededValue = await bridgehubContract.l2TransactionBaseCost(chainId, gasPrice, l2GasLimit, gasPerPubdata); const ethIsBaseToken = (await bridgehubContract.baseToken(chainId)) == ADDRESS_ONE; - await bridge["deposit(address,address,uint256,uint256,uint256,address)"]( + const deposit = await bridge["deposit(address,address,uint256,uint256,uint256,address)"]( l2Receiver, l1Token, amount, @@ -391,6 +391,7 @@ export async function depositERC20( value: ethIsBaseToken ? neededValue : 0, } ); + await deposit.wait(); } export function buildL2CanonicalTransaction(tx: Partial): L2CanonicalTransaction { diff --git a/l1-contracts/tsconfig.json b/l1-contracts/tsconfig.json index 72a5bef45..41d8e3fa8 100644 --- a/l1-contracts/tsconfig.json +++ b/l1-contracts/tsconfig.json @@ -1,6 +1,7 @@ { "compilerOptions": { "types": ["node", "mocha"], - "downlevelIteration": true + "downlevelIteration": true, + "resolveJsonModule": true } } diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index e431bc344..226f1a505 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -50,7 +50,12 @@ export async function publishL2SharedBridgeDependencyBytecodesOnL2( } } -export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, chainId: string, gasPrice: BigNumberish) { +export async function deploySharedBridgeImplOnL2ThroughL1( + deployer: Deployer, + chainId: string, + gasPrice: BigNumberish, + chainIdHack: boolean = false +) { if (deployer.verbose) { console.log("Deploying L2SharedBridge Implementation"); } @@ -66,7 +71,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch const l2SharedBridgeImplAddress = computeL2Create2Address( deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [eraChainId]), + defaultAbiCoder.encode(["uint256"], [chainIdHack ? 0 : eraChainId]), ethers.constants.HashZero ); deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress; @@ -84,7 +89,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch chainId, deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [eraChainId]), + defaultAbiCoder.encode(["uint256"], [chainIdHack ? 0 : eraChainId]), ethers.constants.HashZero, priorityTxMaxGasLimit, gasPrice, @@ -174,9 +179,14 @@ export async function initializeChainGovernance(deployer: Deployer, chainId: str } } -export async function deploySharedBridgeOnL2ThroughL1(deployer: Deployer, chainId: string, gasPrice: BigNumberish) { +export async function deploySharedBridgeOnL2ThroughL1( + deployer: Deployer, + chainId: string, + gasPrice: BigNumberish, + chainIdHack: boolean = false +) { await publishL2SharedBridgeDependencyBytecodesOnL2(deployer, chainId, gasPrice); - await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice); + await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice, chainIdHack); await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice); await initializeChainGovernance(deployer, chainId); } @@ -189,6 +199,7 @@ async function main() { program .option("--private-key ") .option("--chain-id ") + .option("--chain-id-hack") .option("--gas-price ") .option("--nonce ") .option("--erc20-bridge ") @@ -216,7 +227,7 @@ async function main() { : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - await deploySharedBridgeOnL2ThroughL1(deployer, chainId, gasPrice); + await deploySharedBridgeOnL2ThroughL1(deployer, chainId, gasPrice, cmd.chainIdHack); }); await program.parseAsync(process.argv); From 9cf72821dc08cd0304964ea822ff95de930f8b6e Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Tue, 23 Apr 2024 10:34:44 +0200 Subject: [PATCH 08/60] Upgrade system context before any operation (#390) --- system-contracts/SystemContractsHashes.json | 20 +++--- system-contracts/bootloader/bootloader.yul | 65 +++++++++++++++++-- .../scripts/preprocess-bootloader.ts | 7 +- 3 files changed, 75 insertions(+), 17 deletions(-) diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index eb676d6b3..e39d8c95b 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb88c0c8d16ad34f53bd86690d54fc53700b36e2c6d96e80daeefae6a3", - "sourceCodeHash": "0x53b98a0403413cd08e6834cc993f9f69bfa7da11ef2d6f7f914ee0b07ebf7dc5" + "bytecodeHash": "0x010003cb170488b0d4f5a250d546364414eb07572fc0ea9fc4ee3ea5d3126487", + "sourceCodeHash": "0x87e09808464eec5c25e958743ab8ead8cdb81b0c3948341c1e8c312d28b66121" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x0100092f806054e0b58e70d8ac5030dc4376aba2f668abecf5ec91dd43b27e6a", - "sourceCodeHash": "0x843d4ee2f2db1b56b1912ca89a5c8f8b9f06ab067910d373887837cb6ca03c89" + "bytecodeHash": "0x010009517d943eabe605fba79edc8997a57ceeccc00e84d38b9a14f6995c4e9b", + "sourceCodeHash": "0x0f486544f7211215c60f1dc28576fa6c8771d05b8233894f0519b5d0d2c9bc48" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008b5af8f59a628061beed2bb0dd1a370f3fa751f8e680228ed4360c45604", - "sourceCodeHash": "0x49303331266334a2b21158e4b67553c9dfb0fd1992528749d0e46231cbabee70" + "bytecodeHash": "0x010008d765df2e281933e54276469a1bb780df7be2d77d766e8fd3f916368090", + "sourceCodeHash": "0xc25205451d83055646e4106e1915228969a6872f07f2edbec819c0cc3bd6bf49" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000935a1af83558bb816350d875200539be27751493ce8615afeabb39ad118", - "sourceCodeHash": "0x7381bb6c147956ec0d99d4b369ad736ff50ee9482b66b74bfab0226895bddb52" + "bytecodeHash": "0x01000957f5258bb8028a4f7843221c4efd6a1d9ff414c318a5cdadd60d1cf060", + "sourceCodeHash": "0x2549576b59baa5a9dd9e25455cc8e66c7f9a7bb6020f63f22e2f0a1cb79e89ee" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008c5683b01d785f46d7a4237432c3898b0a2c421d362a0729e2ccaa1c076", - "sourceCodeHash": "0xdd44e44795688eaa0176fcd3378b5bdef949e4f6cd1ef7c76bc412dfb77eaf77" + "bytecodeHash": "0x010008e7e76ac18ea5e49634399ec7062152c224259c85f4fa88690e5447d2e7", + "sourceCodeHash": "0xcb7bffd9535fdad708cbb3fab9a566fb8852fa3edf3ae7dbe2b47d43f9bfb52f" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index 685c9d616..96b4e70e2 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -499,10 +499,6 @@ object "Bootloader" { ret := 0x000000000000000000000000000000000000800e } - function KECCAK256_ADDR() -> ret { - ret := 0x0000000000000000000000000000000000008010 - } - function MAX_SYSTEM_CONTRACT_ADDR() -> ret { ret := 0x000000000000000000000000000000000000ffff } @@ -695,6 +691,63 @@ object "Bootloader" { ret := mload(0) } + /// @dev The function that is temporarily needed to upgrade the SystemContext system contract. This function is to be removed + /// once the upgrade is complete. + /// @dev Checks whether the code hash of the SystemContext contract is correct and updates it if needed. + /// @dev The bootloader calls `setPubdataInfo` before each transaction, including the upgrade one. + /// However, the old SystemContext does not have this method. So the bootloader should invoke this function + /// before starting any transaction. + function upgradeSystemContextIfNeeded() { + let expectedCodeHash := {{SYSTEM_CONTEXT_EXPECTED_CODE_HASH}} + + let actualCodeHash := getRawCodeHash(SYSTEM_CONTEXT_ADDR(), true) + if iszero(eq(expectedCodeHash, actualCodeHash)) { + // Now, we need to encode the call to the `ContractDeployer.forceDeployOnAddresses()` function. + + // The `mimicCallOnlyResult` requires that the first word of the data + // contains its length. Here it is 292 bytes. + mstore(0, 292) + mstore(32, {{PADDED_FORCE_DEPLOY_ON_ADDRESSES_SELECTOR}}) + + // The 0x20 offset, for the array of forced deployments + mstore(36, 0x0000000000000000000000000000000000000000000000000000000000000020) + // Only one force deployment + mstore(68, 0x0000000000000000000000000000000000000000000000000000000000000001) + + // Now, starts the description of the forced deployment itself. + // Firstly, the offset. + mstore(100, 0x0000000000000000000000000000000000000000000000000000000000000020) + // The new hash of the SystemContext contract. + mstore(132, expectedCodeHash) + // The address of the system context + mstore(164, SYSTEM_CONTEXT_ADDR()) + // The constructor must be called to reset the `blockGasLimit` variable + mstore(196, 0x0000000000000000000000000000000000000000000000000000000000000001) + // The value should be 0. + mstore(228, 0x0000000000000000000000000000000000000000000000000000000000000000) + // The offset of the input array. + mstore(260, 0x00000000000000000000000000000000000000000000000000000000000000a0) + // No input is provided, the array is empty. + mstore(292, 0x0000000000000000000000000000000000000000000000000000000000000000) + + // We'll use a mimicCall to simulate the correct sender. + let success := mimicCallOnlyResult( + CONTRACT_DEPLOYER_ADDR(), + FORCE_DEPLOYER(), + 0, + 0, + 0, + 0, + 0, + 0 + ) + + if iszero(success) { + assertionError("system context upgrade fail") + } + } + } + /// @dev Calculates the canonical hash of the L1->L2 transaction that will be /// sent to L1 as a message to the L1 contract that a certain operation has been processed. function getCanonicalL1TxHash(txDataOffset) -> ret { @@ -3965,6 +4018,8 @@ object "Bootloader" { assertionError("baseFee inconsistent") } + upgradeSystemContextIfNeeded() + setNewBatch(PREV_BATCH_HASH, NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) @@ -3973,6 +4028,8 @@ object "Bootloader" { let SHOULD_SET_NEW_BATCH := mload(224) + upgradeSystemContextIfNeeded() + switch SHOULD_SET_NEW_BATCH case 0 { unsafeOverrideBatch(NEW_BATCH_TIMESTAMP, NEW_BATCH_NUMBER, EXPECTED_BASE_FEE) diff --git a/system-contracts/scripts/preprocess-bootloader.ts b/system-contracts/scripts/preprocess-bootloader.ts index 8b5b4a3d8..4dbf145da 100644 --- a/system-contracts/scripts/preprocess-bootloader.ts +++ b/system-contracts/scripts/preprocess-bootloader.ts @@ -39,8 +39,8 @@ function getPaddedSelector(contractName: string, method: string): string { return padZeroRight(result, PADDED_SELECTOR_LENGTH); } -function getKeccak256ExpectedHash() { - const bytecode = readFileSync("contracts-preprocessed/precompiles/artifacts/Keccak256.yul.zbin"); +function getSystemContextCodeHash() { + const bytecode = hre.artifacts.readArtifactSync("SystemContext").bytecode; return ethers.utils.hexlify(utils.hashBytecode(bytecode)); } @@ -90,7 +90,8 @@ const params = { COMPRESSED_BYTECODES_SLOTS: 196608, ENSURE_RETURNED_MAGIC: 1, FORBID_ZERO_GAS_PER_PUBDATA: 1, - KECCAK256_EXPECTED_CODE_HASH: getKeccak256ExpectedHash(), + SYSTEM_CONTEXT_EXPECTED_CODE_HASH: getSystemContextCodeHash(), + PADDED_FORCE_DEPLOY_ON_ADDRESSES_SELECTOR: getPaddedSelector("ContractDeployer", "forceDeployOnAddresses"), // One of "worst case" scenarios for the number of state diffs in a batch is when 780kb of pubdata is spent // on repeated writes, that are all zeroed out. In this case, the number of diffs is 780kb / 5 = 156k. This means that they will have // accoomdate 42432000 bytes of calldata for the uncompressed state diffs. Adding 780kb on top leaves us with From 4d6def2f8f8a3fdeb2a4a521ba52108e825b8ce7 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Tue, 23 Apr 2024 12:44:23 +0200 Subject: [PATCH 09/60] Rename local legacy bridge setup (#394) --- l1-contracts/package.json | 2 +- ...ed-bridge-era.ts => setup-legacy-bridge-era.ts} | 6 ++++++ .../src/deploy-shared-bridge-on-l2-through-l1.ts | 14 +++++++------- 3 files changed, 14 insertions(+), 8 deletions(-) rename l1-contracts/scripts/{upgrade-shared-bridge-era.ts => setup-legacy-bridge-era.ts} (92%) diff --git a/l1-contracts/package.json b/l1-contracts/package.json index 4259b0a50..51e702943 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -78,7 +78,7 @@ "hyperchain-upgrade-1": "ts-node scripts/hyperchain-upgrade-1.ts", "hyperchain-upgrade-2": "ts-node scripts/hyperchain-upgrade-2.ts", "hyperchain-upgrade-3": "ts-node scripts/hyperchain-upgrade-3.ts", - "upgrade-shared-bridge-era": "ts-node scripts/upgrade-shared-bridge-era.ts" + "setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts" }, "dependencies": { "dotenv": "^16.0.3", diff --git a/l1-contracts/scripts/upgrade-shared-bridge-era.ts b/l1-contracts/scripts/setup-legacy-bridge-era.ts similarity index 92% rename from l1-contracts/scripts/upgrade-shared-bridge-era.ts rename to l1-contracts/scripts/setup-legacy-bridge-era.ts index 659005b80..cc471dfc5 100644 --- a/l1-contracts/scripts/upgrade-shared-bridge-era.ts +++ b/l1-contracts/scripts/setup-legacy-bridge-era.ts @@ -1,3 +1,9 @@ +/// This script is needed for testing the behavior of the shared bridge on Era chain. +/// Unlike other chains, Era also contains a legacy ERC20 bridge, which is also supported by the corresponding L2SharedBridge. +/// +/// This script ensures that the LegacyBridge is set up correctly and that the L2SharedBridge references it correctly too. +/// IMPORTANT: this script should be only used for local testing. + // hardhat import should be the first import in the file // eslint-disable-next-line @typescript-eslint/no-unused-vars import * as hardhat from "hardhat"; diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index 226f1a505..d24fe38f4 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -54,7 +54,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1( deployer: Deployer, chainId: string, gasPrice: BigNumberish, - chainIdHack: boolean = false + localLegacyBridgeTesting: boolean = false ) { if (deployer.verbose) { console.log("Deploying L2SharedBridge Implementation"); @@ -71,7 +71,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1( const l2SharedBridgeImplAddress = computeL2Create2Address( deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [chainIdHack ? 0 : eraChainId]), + defaultAbiCoder.encode(["uint256"], [localLegacyBridgeTesting ? 0 : eraChainId]), ethers.constants.HashZero ); deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress; @@ -89,7 +89,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1( chainId, deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [chainIdHack ? 0 : eraChainId]), + defaultAbiCoder.encode(["uint256"], [localLegacyBridgeTesting ? 0 : eraChainId]), ethers.constants.HashZero, priorityTxMaxGasLimit, gasPrice, @@ -183,10 +183,10 @@ export async function deploySharedBridgeOnL2ThroughL1( deployer: Deployer, chainId: string, gasPrice: BigNumberish, - chainIdHack: boolean = false + localLegacyBridgeTesting: boolean = false ) { await publishL2SharedBridgeDependencyBytecodesOnL2(deployer, chainId, gasPrice); - await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice, chainIdHack); + await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting); await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice); await initializeChainGovernance(deployer, chainId); } @@ -199,7 +199,7 @@ async function main() { program .option("--private-key ") .option("--chain-id ") - .option("--chain-id-hack") + .option("--local-legacy-bridge-testing") .option("--gas-price ") .option("--nonce ") .option("--erc20-bridge ") @@ -227,7 +227,7 @@ async function main() { : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - await deploySharedBridgeOnL2ThroughL1(deployer, chainId, gasPrice, cmd.chainIdHack); + await deploySharedBridgeOnL2ThroughL1(deployer, chainId, gasPrice, cmd.localLegacyBridgeTesting); }); await program.parseAsync(process.argv); From 467565d11500e0ed7c1d7c0c0300616dcbadef1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Rodr=C3=ADguez=20Chatruc?= <49622509+jrchatruc@users.noreply.github.com> Date: Tue, 23 Apr 2024 12:30:33 -0300 Subject: [PATCH 10/60] feat: Add EcPairing precompile (#383) Co-authored-by: Nacho Avecilla Co-authored-by: Stanislav Bezkorovainyi Co-authored-by: Lyova Potyomkin --- system-contracts/SystemContractsHashes.json | 59 +- system-contracts/contracts/Constants.sol | 1 + .../contracts/precompiles/EcPairing.yul | 1745 +++++++++++++++++ system-contracts/scripts/constants.ts | 6 + .../test/precompiles/EcPairing.spec.ts | 415 ++++ 5 files changed, 2200 insertions(+), 26 deletions(-) create mode 100644 system-contracts/contracts/precompiles/EcPairing.yul create mode 100644 system-contracts/test/precompiles/EcPairing.spec.ts diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index e39d8c95b..eeb4a80f3 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,49 +3,49 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x01000075e8397f3d02eddfe166a8324a2ac31a6da0db8eeebfa8739d3f31aad6", + "bytecodeHash": "0x0100007549287362e4263ea5b204f01fc3c7f2ac09d71e6eb21029698220f01a", "sourceCodeHash": "0xfbf66e830201c4b7fda14f0ddf28a53beb7fbb48a8406392bcfd0ef7ea9265c8" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007d1a4fc820cffd43ee10a7cec7ddba49e3e4bffb93f490c56ad76029187", + "bytecodeHash": "0x010007d1e53f2dca05f7e27ae5b7062291ed3a1470ca511140b8e786aae7eb77", "sourceCodeHash": "0x9ff5a2da00acfa145ee4575381ad386587d96b6a0309d05015974f4726881132" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x010000559e18a99ccbb6b1d3460baa9fbc44c68254335c4476d9dc74ff1828cf", + "bytecodeHash": "0x01000055c1f27b8316ba61bf07959b11cf3b2a418aa357ccc5531c0914a2da27", "sourceCodeHash": "0x0aa5d7ed159e783acde47856b13801b7f2268ba39b2fa50807fe3d705c506e96" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x01000179af9c195ca2588ae3034175586cec77ba5d95ead095851c042873d785", + "bytecodeHash": "0x01000179842b5aa1c76036f5b90652fe614dacb28438a89649d6ca48131bd402", "sourceCodeHash": "0xd43ac120a50398e0d6bdcfcf807154bfeece0c231509a0eb2e00bcad744e60cd" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010005212b10d9ee47071bcd4ad45f5c8c773faec7505bc27d82a2109001e9f2", + "bytecodeHash": "0x010005215fda00bfbf95847a13078bd16cdcb1b875534261c1dda9940c7754fe", "sourceCodeHash": "0x635301b824f927b4d17b3d9974cf6abbf979dda49e610805637db7c677d5f522" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x0100004b1ac12a1a5fa649f97aea9257952e07fcc27f86a5ce537013eaf726c5", + "bytecodeHash": "0x0100004bc85f45ebf0f0bf004752bcbff1bb99792d6cc6494227970ec77fe53b", "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x01000563dc93ec6220498801ccef18c8e667fe26b7fdd9fb9a8d8e01796144ff", + "bytecodeHash": "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32", "sourceCodeHash": "0xa42423712ddaa8f357d26e46825fda80a9a870d0ac7ff52c98884355f1173ec7" }, { @@ -59,63 +59,63 @@ "contractName": "GasBoundCaller", "bytecodePath": "artifacts-zk/contracts-preprocessed/GasBoundCaller.sol/GasBoundCaller.json", "sourceCodePath": "contracts-preprocessed/GasBoundCaller.sol", - "bytecodeHash": "0x010000b50991299ed474c996afdd521b9ba50ff8da1ae58d0ded14747f6bd441", + "bytecodeHash": "0x010000b5e930829f22bd5df4fac3cb37b599cf9733554124bfb7e717fa4a726b", "sourceCodeHash": "0x68db837d79ab575450f9123d97c7e566f311fb2e8d91c0d43dc9769ca895ccd3" }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003d95fede326bfa4034abb2ad310b88549cca833123f14a9d2b42e4625b", + "bytecodeHash": "0x0100003de00c5ceaa3fdf4566a9822ce94abe676f68b17a6ae11c453e14455fd", "sourceCodeHash": "0x30df621c72cb35b8820b902b91057f72d0214a0e4a6b7ad4c0847e674e8b9df8" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100007dc7756ea428ae2f0d238b6015adbcb47a25ac433ca8275b0e2a2a20c8", + "bytecodeHash": "0x0100007d82d4a2eb62e539e3c89cc641f507132b247022ba05ef1ddfed2b0073", "sourceCodeHash": "0x51d388adc58f67ef975a94a7978caa60ed8a0df9d3bd9ac723dfcfc540286c70" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002b90c71cc691211147a9c28f9325083785d0b4bda935234deb5b9744e77", + "bytecodeHash": "0x010002b97ebf3c481ead775617590ffca139bee428e443aa49eb38b6a5b83657", "sourceCodeHash": "0x35c189f3babf5c7a9ce2590bed9eb62b59766e358b7733fdb1bc33f4c232f765" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x010001035ba7b7620a3fa7e2d4443131a29bf9dcbcaf1bc4d44951f8044acf71", + "bytecodeHash": "0x010001039329e4bb55b24531c7e7d27ed40d2c82ad145033fdd5ed5b8ea86cf3", "sourceCodeHash": "0x76ac95c12820d9a02cd1f177eab59092d99463816f2616e1e0f44637bf791a43" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x010000694b6afab8a82dad8330a0489a7fb7021429168dd0fe21e5167ff19cf4", + "bytecodeHash": "0x010000695a1e821b6d5fcb25e25793b81de0bdca3ff8277e3ac93a38e729e0a1", "sourceCodeHash": "0x3f9e0af527875bebcdc20ca4ecb6822305877fd6038e4c4c58854d000b9ac115" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000e55a75bd4aa370257d02878df356132e99d206932f2c86c71afe06fe0a", + "bytecodeHash": "0x010000e563d4ad7b4822cc19d8f74f2c41ee3d3153379be4b02b27d4498d52b6", "sourceCodeHash": "0x91847512344ac5026e9fd396189c23ad9e253f22cb6e2fe65805c20c915797d4" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x01000049f4e028a9434cf0293f01080534b4dc2cb030696e82aaa5ee9ac57c99", + "bytecodeHash": "0x01000049eb6d79244e74e5286ed4d3f6eef2b5eb746b67d98691dbc28fa16984", "sourceCodeHash": "0xbc62d673c2cf9ba2d2148e5e2f99ea577cd357c6fd3ad7d248f670c750050faa" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001b3e077b7fdc663b698442e88daa71e51115aa801dd0829faf1ec44f59e", + "bytecodeHash": "0x010001b3f2c3a6bdd5ad00ae29a7cbbb32dca3c31fb608b5cd52f8f3056a3847", "sourceCodeHash": "0xb90284d78f48a958d082c4c877fc91ec292d05f0e388c6c78e6cce6d3b069a63" }, { @@ -146,6 +146,13 @@ "bytecodeHash": "0x010000bd8bd7ab008f76e359dc296ff5fe0e8a95fedce1d570943e90143acdfd", "sourceCodeHash": "0xb142465167a02139087fda7640ff859489b33081dcc7c2a8089da5b480bcb58c" }, + { + "contractName": "EcPairing", + "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcPairing.yul.zbin", + "sourceCodePath": "contracts-preprocessed/precompiles/EcPairing.yul", + "bytecodeHash": "0x01000f1b3432a32f9fba2115f5dd3b0ee8127e7bf2c609d57d3e231f19119c43", + "sourceCodeHash": "0x149f025b222369ab65b9995a6d61df8b557b23f8b52a05f21dc2164839befb18" + }, { "contractName": "Ecrecover", "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Ecrecover.yul.zbin", @@ -178,35 +185,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb170488b0d4f5a250d546364414eb07572fc0ea9fc4ee3ea5d3126487", - "sourceCodeHash": "0x87e09808464eec5c25e958743ab8ead8cdb81b0c3948341c1e8c312d28b66121" + "bytecodeHash": "0x010003cb722f6b3ac4928fadcb3ad05bb76a7e2497a5635efffb7bbc40f23d29", + "sourceCodeHash": "0x818032f314539edf7b5569c70099f27e2336199ce24313a3f1968e27082c18ae" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x010009517d943eabe605fba79edc8997a57ceeccc00e84d38b9a14f6995c4e9b", - "sourceCodeHash": "0x0f486544f7211215c60f1dc28576fa6c8771d05b8233894f0519b5d0d2c9bc48" + "bytecodeHash": "0x01000951a10ba35cd1fd7ea05039e53a06037213a162e6a3cfddf81ff6e54ad5", + "sourceCodeHash": "0x2cadacf92b4db89ecd699426b769526e5482e565d6d86ed287c9cc36cfe2cc2f" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d765df2e281933e54276469a1bb780df7be2d77d766e8fd3f916368090", - "sourceCodeHash": "0xc25205451d83055646e4106e1915228969a6872f07f2edbec819c0cc3bd6bf49" + "bytecodeHash": "0x010008d750d8f3fa01d99a747a5113d133594b72f26f0dce3243b225f5b91f9a", + "sourceCodeHash": "0x9a3aead2fe745861da43b8f43028821f7d592ffd16da70f38af19d3b24ae5ef7" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000957f5258bb8028a4f7843221c4efd6a1d9ff414c318a5cdadd60d1cf060", - "sourceCodeHash": "0x2549576b59baa5a9dd9e25455cc8e66c7f9a7bb6020f63f22e2f0a1cb79e89ee" + "bytecodeHash": "0x010009579942207c3a46a48ad0e66d9f73b6141bb5a2435a8fdce6ee8dfdd17d", + "sourceCodeHash": "0x2302636e39803befa5438f557bfc24b7e1587cfd8edead02dc41a0bb4002f15f" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e7e76ac18ea5e49634399ec7062152c224259c85f4fa88690e5447d2e7", - "sourceCodeHash": "0xcb7bffd9535fdad708cbb3fab9a566fb8852fa3edf3ae7dbe2b47d43f9bfb52f" + "bytecodeHash": "0x010008e7f0f15ed191392960117f88fe371348982b28a033c7207ed2c09bc0f4", + "sourceCodeHash": "0x55ce91a28b1d143ecba38dfe1b64d4877ad8f510256f47e5155fd4fd138840ea" } ] diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index d166127e5..0f8e2307f 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -32,6 +32,7 @@ address constant ECRECOVER_SYSTEM_CONTRACT = address(0x01); address constant SHA256_SYSTEM_CONTRACT = address(0x02); address constant ECADD_SYSTEM_CONTRACT = address(0x06); address constant ECMUL_SYSTEM_CONTRACT = address(0x07); +address constant ECPAIRING_SYSTEM_CONTRACT = address(0x08); /// @dev The number of ergs that need to be spent for a single byte of pubdata regardless of the pubdata price. diff --git a/system-contracts/contracts/precompiles/EcPairing.yul b/system-contracts/contracts/precompiles/EcPairing.yul new file mode 100644 index 000000000..6ea6e92de --- /dev/null +++ b/system-contracts/contracts/precompiles/EcPairing.yul @@ -0,0 +1,1745 @@ +object "EcPairing" { + code { + return(0, 0) + } + object "EcPairing_deployed" { + code { + // CONSTANTS + + /// @notice Constant function for value one in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return m_one The value one in Montgomery form. + function MONTGOMERY_ONE() -> m_one { + m_one := 6350874878119819312338956282401532409788428879151445726012394534686998597021 + } + + /// @notice Constant function for value three in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return m_three The value three in Montgomery form. + function MONTGOMERY_THREE() -> m_three { + m_three := 19052624634359457937016868847204597229365286637454337178037183604060995791063 + } + + /// @notice Constant function for the inverse of two on the alt_bn128 group in Montgomery form. + /// @dev This value was precomputed using Python. + /// @return two_inv The value of the inverse of two on the alt_bn128 group in Montgomery form. + function MONTGOMERY_TWO_INV() -> two_inv { + two_inv := 14119558874979547267292681013829403749242370018224634694350716214666112402802 + } + /// @notice constant function for the coeffitients of the sextic twist of the BN256 curve. + /// @dev E': y' ** 2 = x' ** 3 + 3 / (9 + u) + /// @dev the curve E' is defined over Fp2 elements. + /// @dev See https://hackmd.io/@jpw/bn254#Twists for further details. + /// @return coefficients of the sextic twist of the BN256 curve + function MONTGOMERY_TWISTED_CURVE_COEFFS() -> z0, z1 { + z0 := 16772280239760917788496391897731603718812008455956943122563801666366297604776 + z1 := 568440292453150825972223760836185707764922522371208948902804025364325400423 + } + + /// @notice Constant function for the alt_bn128 group order. + /// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @return ret The alt_bn128 group order. + function P() -> ret { + ret := 21888242871839275222246405745257275088696311157297823662689037894645226208583 + } + + /// @notice Constant function for the twisted curve subgroup order. + /// @dev See https://hackmd.io/@jpw/bn254#Parameter-for-BN254 for further details. + /// @return ret The twisted curve subgroup orde. + function TWISTED_SUBGROUP_ORDER() -> ret { + ret := 21888242871839275222246405745257275088548364400416034343698204186575808495617 + } + + /// @notice Constant function for the pre-computation of R^2 % N for the Montgomery REDC algorithm. + /// @dev R^2 is the Montgomery residue of the value 2^512. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details. + /// @dev This value was precomputed using Python. + /// @return ret The value R^2 modulus the curve group order. + function R2_MOD_P() -> ret { + ret := 3096616502983703923843567936837374451735540968419076528771170197431451843209 + } + + /// @notice Constant function for the pre-computation of N' for the Montgomery REDC algorithm. + /// @dev N' is a value such that NN' = -1 mod R, with N being the curve group order. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details. + /// @dev This value was precomputed using Python. + /// @return ret The value N'. + function N_PRIME() -> ret { + ret := 111032442853175714102588374283752698368366046808579839647964533820976443843465 + } + + /// @notice Constant function for the alt_bn128 curve seed (parameter `x`). + /// @dev See https://eips.ethereum.org/EIPS/eip-196 for further details. + /// @return ret The alt_bn128 curve seed. + function X() -> ret { + ret := 4965661367192848881 + } + + /// @notice Constant function for decimal representation of the NAF for the Millers Loop. + /// @dev Millers loop uses to iterate the NAF representation of the value t = 6x^2. Where x = 4965661367192848881 is a parameter of the BN 256 curve. + /// @dev For details of the x parameter: https://hackmd.io/@jpw/bn254#Barreto-Naehrig-curves. + /// @dev A NAF representation uses values: -1, 0 and 1. https://en.wikipedia.org/wiki/Non-adjacent_form. + /// @dev For iterating between this values we represent the 0 as 00, the 1 as 01 and the -1 as 10. + /// @dev Then we concatenate all and represent the result as a decimal. E.g. [0,-1,0,1] -> 00 10 00 01 -> 33 + /// @dev In each step of the iteration we just need to compute the operation AND between the number and 1 and 2 to check the original value. + /// @dev Finally we shift 2 bits to the right to get the next value. + /// @dev For this implementation, the first two iterations of the Miller loop are skipped, so the last two digits of the NAF representation of t are not used. + /// @dev This value was precomputed using Python. + /// @return ret The value of the decimal representation of the NAF. + function NAF_REPRESENTATIVE() -> ret { + // NAF rep in binary form + // 000000010001001000001000000001000010001000000001001000000000100000010010000001000000000010000010000100100000001000100000000100 + ret := 355712981487968141245753120442583044 + } + + /// @notice Constant function for the zero element in Fp6 representation. + /// @return z00, z01, z10, z11, z20, z21 The values of zero in Fp6. + function FP6_ZERO() -> z00, z01, z10, z11, z20, z21 { + z00 := 0 + z01 := 0 + z10 := 0 + z11 := 0 + z20 := 0 + z21 := 0 + } + + /// @notice Constant function for the zero element in the twisted curve on affine representation. + /// @return z00, z01, z10, z11, z20, z21 The values of infinity point on affine representation. + function G2_INFINITY() -> z00, z01, z02, z10, z11, z12 { + z00 := 0 + z01 := 0 + z02 := 0 + z10 := 0 + z11 := 0 + z12 := 0 + } + + /// @notice Constant function for element one in Fp12 representation. + /// @return the values of one in Fp12. + function FP12_ONE() -> z000, z001, z010, z011, z100, z101, z110, z111, z200, z201, z210, z211 { + z000 := MONTGOMERY_ONE() + z001 := 0 + z010 := 0 + z011 := 0 + z100 := 0 + z101 := 0 + z110 := 0 + z111 := 0 + z200 := 0 + z201 := 0 + z210 := 0 + z211 := 0 + } + + /// @notice Constant function for the length of the input of a single pair of points to compute the pairing. + /// @return ret The length of a pair of points input. + function PAIR_LENGTH() -> ret { + ret := 0xc0 + } + + // HELPER FUNCTIONS + + /// @dev Executes the `precompileCall` opcode. + function precompileCall(precompileParams, gasToBurn) -> ret { + // Compiler simulation for calling `precompileCall` opcode + ret := verbatim_2i_1o("precompile", precompileParams, gasToBurn) + } + + /// @notice Burns remaining gas until revert. + /// @dev This function is used to burn gas in the case of a failed precompile call. + function burnGas() { + // Precompiles that do not have a circuit counterpart + // will burn the provided gas by calling this function. + precompileCall(0, gas()) + } + + /// @notice Calculate the bit length of a number. + /// @param x The number to calculate the bit length of. + /// @return ret The bit length of the number. + function bitLen(x) -> ret { + ret := 0 + for {} x {} { + ret := add(ret, 1) + x := shr(1, x) + } + } + + /// @notice Checks if the bit of a number at a given index is 1. + /// @dev The index is counted from the right, starting at 0. + /// @param index The index of the bit to check. + /// @param n The number to check the bit of. + /// @return ret The value of the bit at the given index. + function checkBit(index, n) -> ret { + ret := and(shr(index, n), 1) + } + + // MONTGOMERY + + /// @notice Computes the inverse in Montgomery Form of a number in Montgomery Form. + /// @dev Reference: https://github.com/lambdaclass/lambdaworks/blob/main/math/src/field/fields/montgomery_backed_prime_fields.rs#L169 + /// @dev Let `base` be a number in Montgomery Form, then base = a*R mod P() being `a` the base number (not in Montgomery Form) + /// @dev Let `inv` be the inverse of a number `a` in Montgomery Form, then inv = a^(-1)*R mod P() + /// @dev The original binary extended euclidean algorithms takes a number a and returns a^(-1) mod N + /// @dev In our case N is P(), and we'd like the input and output to be in Montgomery Form (a*R mod P() + /// @dev and a^(-1)*R mod P() respectively). + /// @dev If we just pass the input as a number in Montgomery Form the result would be a^(-1)*R^(-1) mod P(), + /// @dev but we want it to be a^(-1)*R mod P(). + /// @dev For that, we take advantage of the algorithm's linearity and multiply the result by R^2 mod P() + /// @dev to get R^2*a^(-1)*R^(-1) mod P() = a^(-1)*R mod P() as the desired result in Montgomery Form. + /// @dev `inv` takes the value of `b` or `c` being the result sometimes `b` and sometimes `c`. In paper + /// @dev multiplying `b` or `c` by R^2 mod P() results on starting their values as b = R2_MOD_P() and c = 0. + /// @param base A number `a` in Montgomery Form, then base = a*R mod P(). + /// @return inv The inverse of a number `a` in Montgomery Form, then inv = a^(-1)*R mod P(). + function binaryExtendedEuclideanAlgorithm(base) -> inv { + let modulus := P() + let u := base + let v := modulus + // Avoids unnecessary reduction step. + let b := R2_MOD_P() + let c := 0 + + for {} and(iszero(eq(u, 1)), iszero(eq(v, 1))) {} { + for {} iszero(and(u, 1)) {} { + u := shr(1, u) + let current := b + switch and(current, 1) + case 0 { + b := shr(1, b) + } + case 1 { + b := shr(1, add(b, modulus)) + } + } + + for {} iszero(and(v, 1)) {} { + v := shr(1, v) + let current := c + switch and(current, 1) + case 0 { + c := shr(1, c) + } + case 1 { + c := shr(1, add(c, modulus)) + } + } + + switch gt(v, u) + case 0 { + u := sub(u, v) + if lt(b, c) { + b := add(b, modulus) + } + b := sub(b, c) + } + case 1 { + v := sub(v, u) + if lt(c, b) { + c := add(c, modulus) + } + c := sub(c, b) + } + } + + switch eq(u, 1) + case 0 { + inv := c + } + case 1 { + inv := b + } + } + + /// @notice Computes an addition and checks for overflow. + /// @param augend The value to add to. + /// @param addend The value to add. + /// @return sum The sum of the two values. + /// @return overflowed True if the addition overflowed, false otherwise. + function overflowingAdd(augend, addend) -> sum, overflowed { + sum := add(augend, addend) + overflowed := lt(sum, augend) + } + + /// @notice Retrieves the highest half of the multiplication result. + /// @param multiplicand The value to multiply. + /// @param multiplier The multiplier. + /// @return ret The highest half of the multiplication result. + function getHighestHalfOfMultiplication(multiplicand, multiplier) -> ret { + ret := verbatim_2i_1o("mul_high", multiplicand, multiplier) + } + + /// @notice Implementation of the Montgomery reduction algorithm (a.k.a. REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm + /// @param lowestHalfOfT The lowest half of the value T. + /// @param higherHalfOfT The higher half of the value T. + /// @return S The result of the Montgomery reduction. + function REDC(lowest_half_of_T, higher_half_of_T) -> S { + let q := mul(lowest_half_of_T, N_PRIME()) + let a_high := add(higher_half_of_T, getHighestHalfOfMultiplication(q, P())) + let a_low, overflowed := overflowingAdd(lowest_half_of_T, mul(q, P())) + if overflowed { + a_high := add(a_high, 1) + } + S := a_high + if iszero(lt(a_high, P())) { + S := sub(a_high, P()) + } + } + + /// @notice Encodes a field element into the Montgomery form using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on transforming a field element into the Montgomery form. + /// @param a The field element to encode. + /// @return ret The field element in Montgomery form. + function intoMontgomeryForm(a) -> ret { + let hi := getHighestHalfOfMultiplication(a, R2_MOD_P()) + let lo := mul(a, R2_MOD_P()) + ret := REDC(lo, hi) + } + + /// @notice Decodes a field element out of the Montgomery form using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on transforming a field element out of the Montgomery form. + /// @param m The field element in Montgomery form to decode. + /// @return ret The decoded field element. + function outOfMontgomeryForm(m) -> ret { + let higher_half_of_m := 0 + let lowest_half_of_m := m + ret := REDC(lowest_half_of_m, higher_half_of_m) + } + + /// @notice Computes the Montgomery addition. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param augend The augend in Montgomery form. + /// @param addend The addend in Montgomery form. + /// @return ret The result of the Montgomery addition. + function montgomeryAdd(augend, addend) -> ret { + ret := add(augend, addend) + if iszero(lt(ret, P())) { + ret := sub(ret, P()) + } + } + + /// @notice Computes the Montgomery subtraction. + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param minuend The minuend in Montgomery form. + /// @param subtrahend The subtrahend in Montgomery form. + /// @return ret The result of the Montgomery addition. + function montgomerySub(minuend, subtrahend) -> ret { + ret := sub(minuend, subtrahend) + if lt(minuend, subtrahend) { + ret := add(ret, P()) + } + } + + /// @notice Computes the Montgomery multiplication using the Montgomery reduction algorithm (REDC). + /// @dev See https://en.wikipedia.org/wiki/Montgomery_modular_multiplication#The_REDC_algorithm for further details on the Montgomery multiplication. + /// @param multiplicand The multiplicand in Montgomery form. + /// @param multiplier The multiplier in Montgomery form. + /// @return ret The result of the Montgomery multiplication. + function montgomeryMul(multiplicand, multiplier) -> ret { + let higher_half_of_product := getHighestHalfOfMultiplication(multiplicand, multiplier) + let lowest_half_of_product := mul(multiplicand, multiplier) + ret := REDC(lowest_half_of_product, higher_half_of_product) + } + + /// @notice Computes the Montgomery modular inverse skipping the Montgomery reduction step. + /// @dev The Montgomery reduction step is skipped because a modification in the binary extended Euclidean algorithm is used to compute the modular inverse. + /// @dev See the function `binaryExtendedEuclideanAlgorithm` for further details. + /// @param a The field element in Montgomery form to compute the modular inverse of. + /// @return invmod The result of the Montgomery modular inverse (in Montgomery form). + function montgomeryModularInverse(a) -> invmod { + invmod := binaryExtendedEuclideanAlgorithm(a) + } + + // CURVE ARITHMETIC + + /// @notice Checks if a coordinate is on the curve group order. + /// @dev A coordinate is on the curve group order if it is on the range [0, curveFieldOrder). + /// @param coordinate The coordinate to check. + /// @return ret True if the coordinate is in the range, false otherwise. + function coordinateIsOnFieldOrder(coordinate) -> ret { + ret := lt(coordinate, P()) + } + + // G1 + + /// @notice Checks if a point of the G1 curve is infinity. + /// @dev In affine coordinates the infinity is represented by the point (0,0). + /// @param x The x coordinate to check. + /// @param y The y coordinate to check. + /// @return ret True if the point is infinity, false otherwise. + function g1AffinePointIsInfinity(x, y) -> ret { + ret := iszero(or(x, y)) + } + + /// @notice Checks if a point in affine coordinates in Montgomery form is on the curve. + /// @dev The curve in question is the alt_bn128 curve. + /// @dev The Short Weierstrass equation of the curve is y^2 = x^3 + 3. + /// @param x The x coordinate of the point in Montgomery form. + /// @param y The y coordinate of the point in Montgomery form. + /// @return ret True if the point is on the curve, false otherwise. + function g1AffinePointIsOnCurve(x, y) -> ret { + let ySquared := montgomeryMul(y, y) + let xSquared := montgomeryMul(x, x) + let xQubed := montgomeryMul(xSquared, x) + let xQubedPlusThree := montgomeryAdd(xQubed, MONTGOMERY_THREE()) + + ret := eq(ySquared, xQubedPlusThree) + } + + // G2 + + /// @notice Converts a G2 point in affine coordinates to projective coordinates. + /// @dev Both input and output coordinates are encoded in Montgomery form. + /// @dev If x or y differ from 0, just add z = (1,0). + /// @dev If x and y are equal to 0, then P is the infinity point, and z = (0,0). + /// @param xp0, xp1 The x coordinate to transform. + /// @param yp0, yp1 The y coordinate to transform. + /// @return xr0, xr1, yr0, yr1, zr0, zr1 The projective coordinates of the given G2 point. + function g2ProjectiveFromAffine(xp0, xp1, yp0, yp1) -> xr0, xr1, yr0, yr1, zr0, zr1 { + xr0 := xp0 + xr1 := xp1 + yr0 := yp0 + yr1 := yp1 + zr0 := MONTGOMERY_ONE() + zr1 := 0 + } + + /// @notice Checks if a G2 point in affine coordinates is the point at infinity. + /// @dev The coordinates are encoded in Montgomery form. + /// @dev in Affine coordinates the point represents the infinity if both coordinates are 0. + /// @param x0, x1 The x coordinate to check. + /// @param y0, y1 The y coordinate to check. + /// @return ret True if the point is the point at infinity, false otherwise. + function g2AffinePointIsInfinity(x0, x1, y0, y1) -> ret { + ret := iszero(or(or(x0, x1), or(y0, y1))) + } + + /// @notice Checks if a G2 point in affine coordinates belongs to the twisted curve. + /// @dev The coordinates are encoded in Montgomery form. + /// @dev in Affine coordinates the point belongs to the curve if it satisfies the equation: y^2 = x^3 + 3. + /// @dev See https://hackmd.io/@jpw/bn254#Twists for further details. + /// @param x0, x1 The x coordinate to check. + /// @param y0, y1 The y coordinate to check. + /// @return ret True if the point is in the curve, false otherwise. + function g2AffinePointIsOnCurve(x0, x1, y0, y1) -> ret { + let a0, a1 := MONTGOMERY_TWISTED_CURVE_COEFFS() + let b0, b1 := fp2Mul(x0, x1, x0, x1) + b0, b1 := fp2Mul(b0, b1, x0, x1) + b0, b1 := fp2Add(b0, b1, a0, a1) + let c0, c1 := fp2Mul(y0, y1, y0, y1) + ret := and(eq(b0, c0), eq(b1, c1)) + } + + /// @notice Checks if a G2 point in projective coordinates is the point at infinity. + /// @dev The coordinates are encoded in Montgomery form. + /// @dev A projective point is at infinity if the z coordinate is (0, 0). + /// @param x0, x1 The x coordinate of the point. + /// @param y0, y1 The y coordinate of the point. + /// @param z0, z1 The z coordinate of the point. + /// @return ret True if the point is the point at infinity, false otherwise. + function g2ProjectivePointIsInfinity(x0, x1, y0, y1, z0, z1) -> ret { + ret := iszero(or(z0, z1)) + } + + /// @notice Negates a G2 point in affine coordinates. + /// @dev The coordinates are encoded in Montgomery form. + /// @dev The negation of a point (x, y) is (x, -y). + /// @param x0, x1 The x coordinate of the point. + /// @param y0, y1 The y coordinate of the point. + /// @return nx0, nx1, ny0, ny1 The coordinates of the negated point. + function g2AffineNeg(x0, x1, y0, y1) -> nx0, nx1, ny0, ny1 { + nx0 := x0 + nx1 := x1 + ny0, ny1 := fp2Neg(y0, y1) + } + + /// @notice Constant function for the alt_bn128 returning `(xi)^ ((N - 1) // 2)`. Where `xi` is D-type twist param. + /// @dev See https://eprint.iacr.org/2022/352.pdf (2 Preliminaries) for further details. + /// @return ret Twisted curve `xi2 = (xi)^ ((N - 1) // 2)` value in Montgomery form. + function xi2() -> xi0, xi1 { + xi0 := intoMontgomeryForm(2821565182194536844548159561693502659359617185244120367078079554186484126554) + xi1 := intoMontgomeryForm(3505843767911556378687030309984248845540243509899259641013678093033130930403) + } + + /// @notice Constant function for the alt_bn128 returning `(xi)^ ((N - 1) // 2)`. Where `xi` is D-type twist param. + /// @dev See https://eprint.iacr.org/2022/352.pdf (2 Preliminaries) for further details. + /// @return ret Twisted curve `xi2 = (xi)^ ((N - 1) // 2)` value in Montgomery form. + function xi3() -> xi0, xi1 { + xi0 := intoMontgomeryForm(21575463638280843010398324269430826099269044274347216827212613867836435027261) + xi1 := intoMontgomeryForm(10307601595873709700152284273816112264069230130616436755625194854815875713954) + } + + /// @notice Frobenius endomophism used to G2 sub group check for twisted curve. + /// @dev For more datail see https://eprint.iacr.org/2022/348.pdf + /// @param xp0, xp1 The x coordinate of the point on twisted curve. + /// @param yp0, yp1 The y coordinate of the point on twisted curve. + /// @param zp0, zp1 The z coordinate of the point on twisted curve. + /// @return Point on twisted curve transformed by the phi endomorphism + function endomorphism(xp0, xp1, yp0, yp1, zp0, zp1) -> xr0, xr1, yr0, yr1, zr0, zr1 { + let xp0_c, xp1_c := fp2Conjugate(xp0, xp1) + let yp0_c, yp1_c := fp2Conjugate(yp0, yp1) + + let xi2_0, xi2_1 := xi2() + let xi3_0, xi3_1 := xi3() + + xr0, xr1 := fp2Mul(xp0_c, xp1_c, xi3_0, xi3_1) + yr0, yr1 := fp2Mul(yp0_c, yp1_c, xi2_0, xi2_1) + zr0, zr1 := fp2Conjugate(zp0, zp1) + } + /// @notice Check if a G2 point in jacobian coordinates is in the subgroup of the twisted curve. + /// @dev The coordinates are encoded in Montgomery form. + /// @param xp0, xp1 The x coordinate of the point. + /// @param yp0, yp1 The y coordinate of the point. + /// @param zp0, zp1 The z coordinate of the point. + /// @return ret True if the point is in the subgroup, false otherwise. + function g2IsInSubGroup(xp0, xp1, yp0, yp1, zp0, zp1) -> ret { + // P * X + let px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1 := g2ScalarMul(xp0, xp1, yp0, yp1, zp0, zp1, X()) + // P * (X + 1) + let px1_xp0, px1_xp1, px1_yp0, px1_yp1, px1_zp0, px1_zp1 := g2JacobianAdd(px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1, xp0, xp1, yp0, yp1, zp0, zp1) + // P * 2X + let p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1 := g2JacobianDouble(px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1) + + // phi(P * X) + let e_px_xp0, e_px_xp1, e_px_yp0, e_px_yp1, e_px_zp0, e_px_zp1 := endomorphism(px_xp0, px_xp1, px_yp0, px_yp1, px_zp0, px_zp1) + // phi(phi(P * X)) + let e2_px_xp0, e2_px_xp1, e2_px_yp0, e2_px_yp1, e2_px_zp0, e2_px_zp1 := endomorphism(e_px_xp0, e_px_xp1, e_px_yp0, e_px_yp1, e_px_zp0, e_px_zp1) + + // phi(phi(phi(P * 2X))) + p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1 := endomorphism(p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1) + p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1 := endomorphism(p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1) + p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1 := endomorphism(p2x_xp0, p2x_xp1, p2x_yp0, p2x_yp1, p2x_zp0, p2x_zp1) + + let l1x0, l1x2, l1y0, l1y2, l1z0, l1z2 := g2JacobianAdd(px1_xp0, px1_xp1, px1_yp0, px1_yp1, px1_zp0, px1_zp1, e_px_xp0, e_px_xp1, e_px_yp0, e_px_yp1, e_px_zp0, e_px_zp1) + l1x0, l1x2, l1y0, l1y2, l1z0, l1z2 := g2JacobianAdd(l1x0, l1x2, l1y0, l1y2, l1z0, l1z2, e2_px_xp0, e2_px_xp1, e2_px_yp0, e2_px_yp1, e2_px_zp0, e2_px_zp1) + + let l1z0_square, l1z2_square := fp2Mul(l1z0, l1z2, l1z0, l1z2) + let p2x_zp0_square, p2x_zp1_square := fp2Mul(p2x_zp0, p2x_zp1, p2x_zp0, p2x_zp1) + + let r00, r01 := fp2Mul(p2x_xp0, p2x_xp1, l1z0_square, l1z2_square) + let r10, r11 := fp2Mul(l1x0, l1x2, p2x_zp0_square, p2x_zp1_square) + + let l1z0_cube, l1z2_cube := fp2Mul(l1z0_square, l1z2_square, l1z0, l1z2) + let p2x_zp0_cube, p2x_zp1_cube := fp2Mul(p2x_zp0_square, p2x_zp1_square, p2x_zp0, p2x_zp1) + + let l00, l01 := fp2Mul(p2x_yp0, p2x_yp1, l1z0_cube, l1z2_cube) + let l10, l11 := fp2Mul(l1y0, l1y2, p2x_zp0_cube, p2x_zp1_cube) + + let r1 := and(eq(r00, r10), eq(r01, r11)) + let r2 := and(eq(l00, l10), eq(l01, l11)) + ret := and(r1, r2) + } + + + /// @notice Check if a G2 point in jacobian coordinates is in the subgroup of the twisted curve. + /// @dev The coordinates are encoded in Montgomery form. + /// @param xp0, xp1 The x coordinate of the point. + /// @param yp0, yp1 The y coordinate of the point. + /// @param zp0, zp1 The z coordinate of the point. + /// @return ret True if the point is in the subgroup, false otherwise. + function g2IsInSubGroupNaive(xp0, xp1, yp0, yp1, zp0, zp1) -> ret { + let xr0, xr1, yr0, yr1, zr0, zr1 := g2ScalarMul(xp0, xp1, yp0, yp1, zp0, zp1, TWISTED_SUBGROUP_ORDER()) + ret := and(iszero(zr0), iszero(zr1)) + } + + /// @notice Double a g2 point represented in jacobian coordinates. + /// @dev The coordinates must be encoded in Montgomery form. + /// @param xp0, xp1 The x coordinate of the point. + /// @param yp0, yp1 The y coordinate of the point. + /// @param zp0, zp1 The z coordinate of the point. + /// @return xr0, xr1, yr0, yr1, zr0, zr1 The coordinates of the doubled point. + function g2JacobianDouble(xp0, xp1, yp0, yp1, zp0, zp1) -> xr0, xr1, yr0, yr1, zr0, zr1 { + let a00, a01 := fp2Mul(xp0, xp1, xp0, xp1) // A = X1^2 + let b00, b01 := fp2Mul(yp0, yp1, yp0, yp1) // B = Y1^2 + let c00, c01 := fp2Mul(b00, b01, b00, b01) // C = B^2 + let t00, t01 := fp2Add(xp0, xp1, b00, b01) // t0 = X1+B + let t10, t11 := fp2Mul(t00, t01, t00, t01) // t1 = t0^2 + let t20, t21 := fp2Sub(t10, t11, a00, a01) // t2 = t1-A + let t30, t31 := fp2Sub(t20, t21, c00, c01) // t3 = t2-C + let d00, d01 := fp2Add(t30, t31, t30, t31) // D = 2*t3 + let e00, e01 := fp2Add(a00, a01, a00, a01) // E = 3*A + e00, e01 := fp2Add(e00, e01, a00, a01) + let f00, f01 := fp2Mul(e00, e01, e00, e01) // F = E^2 + let t40, t41 := fp2Add(d00, d01, d00, d01) // t4 = 2*D + xr0, xr1 := fp2Sub(f00, f01, t40, t41) // X3 = F-t4 + let t50, t51 := fp2Sub(d00, d01, xr0, xr1) // t5 = D-X3 + let t60, t61 := fp2Add(c00, c01, c00, c01) // t6 = 8*C + t60, t61 := fp2Add(t60, t61, t60, t61) + t60, t61 := fp2Add(t60, t61, t60, t61) + let t70, t71 := fp2Mul(e00, e01, t50, t51) // t7 = E*t5 + yr0, yr1 := fp2Sub(t70, t71, t60, t61) // Y3 = t7-t6 + let t80, t81 := fp2Mul(yp0, yp1, zp0, zp1) // t8 = Y1*Z1 + zr0, zr1 := fp2Add(t80, t81, t80, t81) // Z3 = 2*t8 + } + + /// @notice Add two g2 points represented in jacobian coordinates. + /// @dev The coordinates must be encoded in Montgomery form. + /// @dev The points to be added must be different, if not the function will return infinity. The function `g2JacobianDouble` should be used in that case. + /// @param xq0, xq1 The x coordinate of the first point. + /// @param yq0, yq1 The y coordinate of the first point. + /// @param zq0, zq1 The z coordinate of the first point. + /// @param xr0, xr1 The x coordinate of the second point. + /// @param yr0, yr1 The y coordinate of the second point. + /// @param zr0, zr1 The z coordinate of the second point. + /// @return c00, c01, c10, c11, c20, c21 The coordinates of the added points. + function g2JacobianAdd(xq0, xq1, yq0, yq1, zq0, zq1, xr0, xr1, yr0, yr1, zr0, zr1) -> c00, c01, c10, c11, c20, c21 { + // Check for infinity in projective coordinates is the same as jacobian + let qIsInfinity := g2ProjectivePointIsInfinity(xq0, xq1, yq0, yq1, zq0, zq1) + let rIsInfinity := g2ProjectivePointIsInfinity(xr0, xr1, yr0, yr1, zr0, zr1) + if rIsInfinity { + // Infinity + P = P + c00 := xq0 + c01 := xq1 + c10 := yq0 + c11 := yq1 + c20 := zq0 + c21 := zq1 + leave + } + if qIsInfinity { + // P + Infinity = P + c00 := xr0 + c01 := xr1 + c10 := yr0 + c11 := yr1 + c20 := zr0 + c21 := zr1 + leave + } + + // Z1Z1 = Z1^2 + let zqzq0, zqzq1 := fp2Mul(zq0, zq1, zq0, zq1) + // Z2Z2 = Z2^2 + let zrzr0, zrzr1 := fp2Mul(zr0, zr1, zr0, zr1) + // U1 = X1*Z2Z2 + let u0, u1 := fp2Mul(xq0, xq1, zrzr0, zrzr1) + // U2 = X2*Z1Z1 + let u2, u3 := fp2Mul(xr0, xr1, zqzq0, zqzq1) + // t0 = Z2*Z2Z2 + let t0, t1 := fp2Mul(zr0, zr1, zrzr0, zrzr1) + // S1 = Y1*t0 + let s0, s1 := fp2Mul(yq0, yq1, t0, t1) + // t1 = Z1*Z1Z1 + let t2, t3 := fp2Mul(zq0, zq1, zqzq0, zqzq1) + // S2 = Y2*t1 + let s2, s3 := fp2Mul(yr0, yr1, t2, t3) + // H = U2-U1 + let h0, h1 := fp2Sub(u2, u3, u0, u1) + // t2 = 2*H + let t4, t5 := fp2Add(h0, h1, h0, h1) + // I = t2^2 + let i0, i1 := fp2Mul(t4, t5, t4, t5) + // J = H*I + let j0, j1 := fp2Mul(h0, h1, i0, i1) + // t3 = S2-S1 + let t6, t7 := fp2Sub(s2, s3, s0, s1) + // r = 2*t3 + let r0, r1 := fp2Add(t6, t7, t6, t7) + // V = U1*I + let v0, v1 := fp2Mul(u0, u1, i0, i1) + // t4 = r^2 + let t8, t9 := fp2Mul(r0, r1, r0, r1) + // t5 = 2*V + let t10, t11 := fp2Add(v0, v1, v0, v1) + // t6 = t4-J + let t12, t13 := fp2Sub(t8, t9, j0, j1) + // X3 = t6-t5 + c00, c01 := fp2Sub(t12, t13, t10, t11) + // t7 = V-X3 + let t14, t15 := fp2Sub(v0, v1, c00, c01) + // t8 = S1*J + let t16, t17 := fp2Mul(s0, s1, j0, j1) + // t9 = 2*t8 + let t18, t19 := fp2Add(t16, t17, t16, t17) + // t10 = r*t7 + let t20, t21 := fp2Mul(r0, r1, t14, t15) + // Y3 = t10-t9 + c10, c11 := fp2Sub(t20, t21, t18, t19) + // t11 = Z1+Z2 + let t22, t23 := fp2Add(zq0, zq1, zr0, zr1) + // t12 = t11^2 + let t24, t25 := fp2Mul(t22, t23, t22, t23) + // t13 = t12-Z1Z1 + let t26, t27 := fp2Sub(t24, t25, zqzq0, zqzq1) + // t14 = t13-Z2Z2 + let t28, t29 := fp2Sub(t26, t27, zrzr0, zrzr1) + // Z3 = t14*H + c20, c21 := fp2Mul(t28, t29, h0, h1) + } + + /// @notice Multiplies a G2 point represented in jacobian coordinates by a scalar. + /// @dev The coordinates must be encoded in Montgomery form. + /// @dev The scalar must not be encoded in Montgomery form. + /// @param xp0, xp1 The x coordinate of the point. + /// @param yp0, yp1 The y coordinate of the point. + /// @param zp0, zp1 The z coordinate of the point. + /// @param scalar The scalar to multiply the point by. + /// @return xr0, xr1, yr0, yr1, zr0, zr1 The coordinates of the multiplied point. + function g2ScalarMul(xp0, xp1, yp0, yp1, zp0, zp1, scalar) -> xr0, xr1, yr0, yr1, zr0, zr1 { + let scalarBitIndex := bitLen(scalar) + switch scalar + case 0x02 { + xr0, xr1, yr0, yr1, zr0, zr1 := g2JacobianDouble(xp0, xp1, yp0, yp1, zp0, yp1) + } + default { + xr0 := 0 + xr1 := 0 + yr0 := MONTGOMERY_ONE() + yr1 := 0 + zr0 := 0 + zr1 := 0 + for {} scalarBitIndex {} { + scalarBitIndex := sub(scalarBitIndex, 1) + xr0, xr1, yr0, yr1, zr0, zr1 := g2JacobianDouble(xr0, xr1, yr0, yr1, zr0, zr1) + let bitindex := checkBit(scalarBitIndex, scalar) + if bitindex { + xr0, xr1, yr0, yr1, zr0, zr1 := g2JacobianAdd(xp0, xp1, yp0, yp1, zp0, zp1, xr0, xr1, yr0, yr1, zr0, zr1) + } + + } + } + } + + // FP2 ARITHMETHICS + + /// @notice Computes the sum of two Fp2 elements. + /// @dev Algorithm 5 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01 The coefficients of the A element to sum. + /// @param b00, b01 The coefficients of the B element to sum. + /// @return c00, c01 The coefficients of the element C = A + B. + function fp2Add(a00, a01, b00, b01) -> c00, c01 { + c00 := montgomeryAdd(a00, b00) + c01 := montgomeryAdd(a01, b01) + } + + /// @notice Computes the subtraction of two Fp2 elements. + /// @dev Algorithm 6 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01 The coefficients of the minuend A. + /// @param b00, b01 The coefficients of the subtrahend B. + /// @return c00, c01 The coefficients of the element C = A - B. + function fp2Sub(a00, a01, b00, b01) -> c00, c01 { + c00 := montgomerySub(a00, b00) + c01 := montgomerySub(a01, b01) + } + + /// @notice Computes the multiplication between a Fp2 element a Fp element. + /// @dev Algorithm 7 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01 The coefficients of the Fp2 element A. + /// @param scalar The value of the Fp element k. + /// @return c00, c01 The coefficients of the element C = k * A. + function fp2ScalarMul(a00, a01, scalar) -> c00, c01 { + c00 := montgomeryMul(a00, scalar) + c01 := montgomeryMul(a01, scalar) + } + + /// @notice Computes the multiplication between two Fp2 elements. + /// @dev Algorithm 7 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01 The coefficients of the Fp2 element A. + /// @param a00, a01 The coefficients of the Fp2 element B. + /// @return c00, c01 The coefficients of the element C = A * B. + function fp2Mul(a00, a01, b00, b01) -> c00, c01 { + c00 := montgomerySub(montgomeryMul(a00, b00), montgomeryMul(a01, b01)) + c01 := montgomeryAdd(montgomeryMul(a00, b01), montgomeryMul(a01, b00)) + } + + /// @notice Computes the negative of a Fp2 elements. + /// @param a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = -A. + function fp2Neg(a00, a01) -> c00, c01 { + c00, c01 := fp2Sub(0, 0, a00, a01) + } + + /// @notice Computes the inverse of a Fp2 element. + /// @dev Algorithm 8 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = A^(-1). + function fp2Inv(a00, a01) -> c00, c01 { + let t0 := montgomeryMul(a00, a00) + let t1 := montgomeryMul(a01, a01) + t0 := montgomeryAdd(t0, t1) + t1 := montgomeryModularInverse(t0) + + c00 := montgomeryMul(a00, t1) + c01 := montgomerySub(0, montgomeryMul(a01, t1)) + } + + /// @notice Computes the multiplication of a Fp2 element with xi. + /// @dev Where xi = u in Fp + /// @dev See https://hackmd.io/@jpw/bn254#Field-extension-towers for further details. + /// @param a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = A * xi. + function mulByXi(a00, a01) -> c00, c01 { + let t0, t1 := fp2ScalarMul(a00, a01, intoMontgomeryForm(8)) + c00 := montgomerySub(montgomeryAdd(t0, a00), a01) + c01 := montgomeryAdd(montgomeryAdd(t1, a00), a01) + } + + /// @notice Computes the conjugation of a Fp2 element. + /// @param a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = A'. + function fp2Conjugate(a00, a01) -> c00, c01 { + c00 := a00 + c01 := montgomerySub(0, a01) + } + + // FP6 ARITHMETHICS + + /// @notice Computes the sum of two Fp6 elements. + /// @dev Algorithm 10 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the A element to sum. + /// @param b00, b01, b10, b11, b20, b21 The coefficients of the B element to sum. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = A + B. + function fp6Add(a00, a01, a10, a11, a20, a21, b00, b01, b10, b11, b20, b21) -> c00, c01, c10, c11, c20, c21 { + c00, c01 := fp2Add(a00, a01, b00, b01) + c10, c11 := fp2Add(a10, a11, b10, b11) + c20, c21 := fp2Add(a20, a21, b20, b21) + } + + /// @notice Computes the subtraction of two Fp6 elements. + /// @dev Algorithm 11 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the minuend A. + /// @param b00, b01, b10, b11, b20, b21 The coefficients of the subtrahend B. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = A - B. + function fp6Sub(a00, a01, a10, a11, a20, a21, b00, b01, b10, b11, b20, b21) -> c00, c01, c10, c11, c20, c21 { + c00, c01 := fp2Sub(a00, a01, b00, b01) + c10, c11 := fp2Sub(a10, a11, b10, b11) + c20, c21 := fp2Sub(a20, a21, b20, b21) + } + + /// @notice Computes the multiplication of a Fp6 element with g. + /// @dev Algorithm 12 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the Fp6 element A. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = A * g. + function mulByGamma(a00, a01, a10, a11, a20, a21) -> c00, c01, c10, c11, c20, c21 { + c00, c01 := mulByXi(a20, a21) + c10 := a00 + c11 := a01 + c20 := a10 + c21 := a11 + } + + /// @notice Computes the multiplication between two Fp6 elements. + /// @dev Algorithm 13 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the Fp6 element A. + /// @param b00, b01, b10, b11, b20, b21 The coefficients of the Fp6 element B. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = A * B. + function fp6Mul(a00, a01, a10, a11, a20, a21, b00, b01, b10, b11, b20, b21) -> c00, c01, c10, c11, c20, c21 { + let t00, t01 := fp2Mul(a00, a01, b00, b01) + let t10, t11 := fp2Mul(a10, a11, b10, b11) + let t20, t21 := fp2Mul(a20, a21, b20, b21) + + let tmp0, temp1 := fp2Add(a10, a11, a20, a21) + let tmp2, tmp3 := fp2Add(b10, b11, b20, b21) + let tmp4, tmp5 := fp2Mul(tmp0, temp1, tmp2, tmp3) + let tmp6, tmp7 := fp2Sub(tmp4, tmp5, t10, t11) + let tmp8, tmp9 := fp2Sub(tmp6, tmp7, t20, t21) + let tmp10, tmp11 := mulByXi(tmp8, tmp9) + c00, c01 := fp2Add(tmp10, tmp11, t00, t01) + + tmp0, temp1 := fp2Add(a00, a01, a10, a11) + tmp2, tmp3 := fp2Add(b00, b01, b10, b11) + tmp4, tmp5 := fp2Mul(tmp0, temp1, tmp2, tmp3) + tmp6, tmp7 := fp2Sub(tmp4, tmp5, t00, t01) + tmp8, tmp9 := fp2Sub(tmp6, tmp7, t10, t11) + tmp10, tmp11 := mulByXi(t20, t21) + c10, c11 := fp2Add(tmp8, tmp9, tmp10, tmp11) + + tmp0, temp1 := fp2Add(a00, a01, a20, a21) + tmp2, tmp3 := fp2Add(b00, b01, b20, b21) + tmp4, tmp5 := fp2Mul(tmp0, temp1, tmp2, tmp3) + tmp6, tmp7 := fp2Sub(tmp4, tmp5, t00, t01) + tmp8, tmp9 := fp2Sub(tmp6, tmp7, t20, t21) + c20, c21 := fp2Add(tmp8, tmp9, t10, t11) + } + + /// @notice Computes the negative of a Fp6 element. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the Fp2 element A. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = -A. + function fp6Neg(a00, a01, a10, a11, a20, a21) -> c00, c01, c10, c11, c20, c21 { + c00, c01 := fp2Neg(a00, a01) + c10, c11 := fp2Neg(a10, a11) + c20, c21 := fp2Neg(a20, a21) + } + + /// @notice Computes the square of a Fp6 element. + /// @dev Algorithm 16 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the Fp6 element A. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = A^2. + function fp6Square(a00, a01, a10, a11, a20, a21) -> c00, c01, c10, c11, c20, c21 { + let tmp0, tmp1 := fp2Mul(a00, a01, a10, a11) + tmp0, tmp1 := fp2Add(tmp0, tmp1, tmp0, tmp1) + + let tmp2, tmp3 := fp2Mul(a20, a21, a20, a21) + let tmp4, tmp5 := mulByXi(tmp2, tmp3) + c10, c11 := fp2Add(tmp4, tmp5, tmp0, tmp1) + + c20, c21 := fp2Sub(tmp0, tmp1, tmp2, tmp3) + + let tmp6, tmp7 := fp2Mul(a00, a01, a00, a01) + let tmp8, tmp9 := fp2Sub(a00, a01, a10, a11) + tmp0, tmp1 := fp2Add(tmp8, tmp9, a20, a21) + + let tmp10, tmp11 := fp2Mul(a10, a11, a20, a21) + tmp2, tmp3 := fp2Add(tmp10, tmp11, tmp10, tmp11) + tmp0, tmp1 := fp2Mul(tmp0, tmp1, tmp0, tmp1) + + let tmp12, tmp13 := mulByXi(tmp2, tmp3) + c00, c01 := fp2Add(tmp12, tmp13, tmp6, tmp7) + + let tmp14, tmp15 := fp2Add(c20, c21, tmp0, tmp1) + tmp14, tmp15 := fp2Add(tmp14, tmp15, tmp2, tmp3) + c20, c21 := fp2Sub(tmp14, tmp15, tmp6, tmp7) + + } + + /// @notice Computes the inverse of a Fp6 element. + /// @dev Algorithm 17 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a00, a01, a10, a11, a20, a21 The coefficients of the Fp6 element A. + /// @return c00, c01, c10, c11, c20, c21 The coefficients of the element C = A^(-1). + function fp6Inv(a00, a01, a10, a11, a20, a21) -> c00, c01, c10, c11, c20, c21 { + let t00, t01 := fp2Mul(a00, a01, a00, a01) + let t10, t11 := fp2Mul(a10, a11, a10, a11) + let t20, t21 := fp2Mul(a20, a21, a20, a21) + let t30, t31 := fp2Mul(a00, a01, a10, a11) + let t40, t41 := fp2Mul(a00, a01, a20, a21) + let t50, t51 := fp2Mul(a20, a21, a10, a11) + let t50Xi, t51Xi := mulByXi(t50, t51) + c00, c01 := fp2Sub(t00, t01, t50Xi, t51Xi) + let t20Xi, t21Xi := mulByXi(t20, t21) + c10, c11 := fp2Sub(t20Xi, t21Xi, t30, t31) + c20, c21 := fp2Sub(t10, t11, t40, t41) + let t60, t61 := fp2Mul(a00, a01, c00, c01) + let a20Xi, a21Xi := mulByXi(a20, a21) + let a20XiC10, a21XiC11 := fp2Mul(a20Xi, a21Xi, c10, c11) + t60, t61 := fp2Add(t60, t61, a20XiC10, a21XiC11) + let a10Xi, a11Xi := mulByXi(a10, a11) + let a10XiC20, a11XiC21 := fp2Mul(a10Xi, a11Xi, c20, c21) + t60, t61 := fp2Add(t60, t61, a10XiC20, a11XiC21) + t60, t61 := fp2Inv(t60, t61) + c00, c01 := fp2Mul(c00, c01, t60, t61) + c10, c11 := fp2Mul(c10, c11, t60, t61) + c20, c21 := fp2Mul(c20, c21, t60, t61) + } + + // FP12 ARITHMETHICS + + /// @notice Computes the sum of two Fp12 elements. + /// @dev Algorithm 18 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the A element to sum. + /// @param b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121 The coefficients of the B element to sum. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A + B. + function fp12Add(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121, b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + c000, c001, c010, c011, c020, c021 := fp6Add(a000, a001, a010, a011, a020, a021, b000, b001, b010, b011, b020, b021) + c100, c101, c110, c111, c120, c121 := fp6Add(a100, a101, a110, a111, a120, a121, b100, b101, b110, b111, b120, b121) + } + + /// @notice Computes the subtraction of two Fp12 elements. + /// @dev Algorithm 19 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the minuend A. + /// @param b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121 The coefficients of the subtrahend B. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A - B. + function fp12Sub(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121, b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + c000, c001, c010, c011, c020, c021 := fp6Sub(a000, a001, a010, a011, a020, a021, b000, b001, b010, b011, b020, b021) + c100, c101, c110, c111, c120, c121 := fp6Sub(a100, a101, a110, a111, a120, a121, b100, b101, b110, b111, b120, b121) + } + + /// @notice Computes the multiplication between two Fp12 elements. + /// @dev Algorithm 20 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @param b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121 The coefficients of the Fp12 element B. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A * B. + function fp12Mul(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121, b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + let t000, t001, t010, t011, t020, t021 := fp6Mul(a000, a001, a010, a011, a020, a021, b000, b001, b010, b011, b020, b021) + let t100, t101, t110, t111, t120, t121 := fp6Mul(a100, a101, a110, a111, a120, a121, b100, b101, b110, b111, b120, b121) + let t200, t201, t210, t211, t220, t221 := mulByGamma(t100, t101, t110, t111, t120, t121) + c000, c001, c010, c011, c020, c021 := fp6Add(t000, t001, t010, t011, t020, t021, t200, t201, t210, t211, t220, t221) + let t300, t301, t310, t311, t320, t321 := fp6Add(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) + let t400, t401, t410, t411, t420, t421 := fp6Add(b000, b001, b010, b011, b020, b021, b100, b101, b110, b111, b120, b121) + c100, c101, c110, c111, c120, c121 := fp6Mul(t300, t301, t310, t311, t320, t321, t400, t401, t410, t411, t420, t421) + c100, c101, c110, c111, c120, c121 := fp6Sub(c100, c101, c110, c111, c120, c121, t000, t001, t010, t011, t020, t021) + c100, c101, c110, c111, c120, c121 := fp6Sub(c100, c101, c110, c111, c120, c121, t100, t101, t110, t111, t120, t121) + } + + /// @notice Computes the square of a Fp12 element. + /// @dev Algorithm 22 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^2. + function fp12Square(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + let t100, t101, t110, t111, t120, t121 := fp6Sub(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) + let t200, t201, t210, t211, t220, t221 := mulByGamma(a100, a101, a110, a111, a120, a121) + let t300, t301, t310, t311, t320, t321 := fp6Sub(a000, a001, a010, a011, a020, a021, t200, t201, t210, t211, t220, t221) + let t400, t401, t410, t411, t420, t421 := fp6Mul(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) + let t500, t501, t510, t511, t520, t521 := fp6Mul(t100, t101, t110, t111, t120, t121, t300, t301, t310, t311, t320, t321) + let t600, t601, t610, t611, t620, t621 := fp6Add(t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + c100, c101, c110, c111, c120, c121 := fp6Add(t400, t401, t410, t411, t420, t421, t400, t401, t410, t411, t420, t421) + let t700, t701, t710, t711, t720, t721 := mulByGamma(t400, t401, t410, t411, t420, t421) + c000, c001, c010, c011, c020, c021 := fp6Add(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721) + } + + /// @notice Computes the inverse of a Fp12 element. + /// @dev Algorithm 23 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^(-1). + function fp12Inv(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + let t000, t001, t010, t011, t020, t021 := fp6Square(a000, a001, a010, a011, a020, a021) + let t100, t101, t110, t111, t120, t121 := fp6Square(a100, a101, a110, a111, a120, a121) + let t200, t201, t210, t211, t220, t221 := mulByGamma(t100, t101, t110, t111, t120, t121) + t000, t001, t010, t011, t020, t021 := fp6Sub(t000, t001, t010, t011, t020, t021, t200, t201, t210, t211, t220, t221) + t100, t101, t110, t111, t120, t121 := fp6Inv(t000, t001, t010, t011, t020, t021) + c000, c001, c010, c011, c020, c021 := fp6Mul(a000, a001, a010, a011, a020, a021, t100, t101, t110, t111, t120, t121) + let z00, z01, z10, z11, z20, z21 := FP6_ZERO() + c100, c101, c110, c111, c120, c121 := fp6Mul(a100, a101, a110, a111, a120, a121,t100, t101, t110, t111, t120, t121) + c100, c101, c110, c111, c120, c121 := fp6Sub(z00, z01, z10, z11, z20, z21, c100, c101, c110, c111, c120, c121) + } + + /// @notice Computes the exponentiation of a Fp12 element in the cyclotomic subgroup to t = 4965661367192848881. + /// @dev We make use of an addition chain to optimize the operation. + /// @dev See https://eprint.iacr.org/2015/192.pdf for further details. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^t. + function fp12Expt(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + let t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121 := fp12CyclotomicSquare(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) + let t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321 := fp12CyclotomicSquare(t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121) + c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 := fp12CyclotomicSquare(t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321) + let t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521 := fp12CyclotomicSquare(c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121) + + let t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := fp12Mul(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121, t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521 := fp12Mul(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121) + let t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921 := fp12Mul(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121, t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + let t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := fp12Mul(c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121, t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721) + let t1200, t1201, t1210, t1211, t1220, t1221, t1300, t1301, t1310, t1311, t1320, t1321 := fp12CyclotomicSquare(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721) + t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921 := fp12Mul(t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921, t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521 := fp12Mul(t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921, t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121) + t1200, t1201, t1210, t1211, t1220, t1221, t1300, t1301, t1310, t1311, t1320, t1321 := nSquare(t1200, t1201, t1210, t1211, t1220, t1221, t1300, t1301, t1310, t1311, t1320, t1321, 6) + t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321 := fp12Mul(t1200, t1201, t1210, t1211, t1220, t1221, t1300, t1301, t1310, t1311, t1320, t1321, t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321) + t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321 := fp12Mul(t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321, t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121) + t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321 := nSquare(t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321, 7) + t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := fp12Mul(t200, t201, t210, t211, t220, t221, t300, t301, t310, t311, t320, t321, t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121) + t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := nSquare(t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121, 8) + t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := fp12Mul(t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121, t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121 := fp12Mul(t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121, t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121) + t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121 := nSquare(t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121, 6) + t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := fp12Mul(t000, t001, t010, t011, t020, t021, t100, t101, t110, t111, t120, t121, t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721) + t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := nSquare(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, 8) + t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := fp12Mul(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := nSquare(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, 6) + t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := fp12Mul(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521) + t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721 := nSquare(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, 10) + t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921 := fp12Mul(t600, t601, t610, t611, t620, t621, t700, t701, t710, t711, t720, t721, t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921) + t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921 := nSquare(t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921, 6) + t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521 := fp12Mul(t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521, t800, t801, t810, t811, t820, t821, t900, t901, t910, t911, t920, t921) + c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 := fp12Mul(t400, t401, t410, t411, t420, t421, t500, t501, t510, t511, t520, t521, c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121) + } + + /// @notice Computes the conjugation of a Fp12 element. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A'. + function fp12Conjugate(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + c000 := a000 + c001 := a001 + c010 := a010 + c011 := a011 + c020 := a020 + c021 := a021 + c100, c101, c110, c111, c120, c121 := fp6Neg(a100, a101, a110, a111, a120, a121) + } + + /// @notice Computes the square of a Fp12 element in the cyclotomic subgroup. + /// @dev See https://eprint.iacr.org/2010/354.pdf for further details. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^2. + function fp12CyclotomicSquare(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + let t00, t01 := fp2Mul(a110, a111, a110, a111) + let t10, t11 := fp2Mul(a000, a001, a000, a001) + let t20, t21 := fp2Add(a110, a111, a000, a001) + t20, t21 := fp2Mul(t20, t21, t20, t21) + t20, t21 := fp2Sub(t20, t21, t00, t01) + t20, t21 := fp2Sub(t20, t21, t10, t11) + let t30, t31 := fp2Mul(a020, a021, a020, a021) + let t40, t41 := fp2Mul(a100, a101, a100, a101) + let t50, t51 := fp2Add(a020, a021, a100, a101) + t50, t51 := fp2Mul(t50, t51, t50, t51) + t50, t51 := fp2Sub(t50, t51, t30, t31) + t50, t51 := fp2Sub(t50, t51, t40, t41) + let t60, t61 := fp2Mul(a120, a121, a120, a121) + let t70, t71 := fp2Mul(a010, a011, a010, a011) + let t80, t81 := fp2Add(a120, a121, a010, a011) + t80, t81 := fp2Mul(t80, t81, t80, t81) + t80, t81 := fp2Sub(t80, t81, t60, t61) + t80, t81 := fp2Sub(t80, t81, t70, t71) + t80, t81 := mulByXi(t80, t81) + t00, t01 := mulByXi(t00, t01) + t00, t01 := fp2Add(t00, t01, t10, t11) + t30, t31 := mulByXi(t30, t31) + t30, t31 := fp2Add(t30, t31, t40, t41) + t60, t61 := mulByXi(t60, t61) + t60, t61 := fp2Add(t60, t61, t70, t71) + + c000, c001 := fp2Sub(t00, t01, a000, a001) + c000, c001 := fp2Add(c000, c001, c000, c001) + c000, c001 := fp2Add(c000, c001, t00, t01) + + c010, c011 := fp2Sub(t30, t31, a010, a011) + c010, c011 := fp2Add(c010, c011, c010, c011) + c010, c011 := fp2Add(c010, c011, t30, t31) + + c020, c021 := fp2Sub(t60, t61, a020, a021) + c020, c021 := fp2Add(c020, c021, c020, c021) + c020, c021 := fp2Add(c020, c021, t60, t61) + + c100, c101 := fp2Add(t80, t81, a100, a101) + c100, c101 := fp2Add(c100, c101, c100, c101) + c100, c101 := fp2Add(c100, c101, t80, t81) + + c110, c111 := fp2Add(t20, t21, a110, a111) + c110, c111 := fp2Add(c110, c111, c110, c111) + c110, c111 := fp2Add(c110, c111, t20, t21) + + c120, c121 := fp2Add(t50, t51, a120, a121) + c120, c121 := fp2Add(c120, c121, c120, c121) + c120, c121 := fp2Add(c120, c121, t50, t51) + } + + /// @notice Computes the exponentiation of a Fp12 element in the cyclotomic subgroup to 2n. + /// @dev We compute A^2n as n cyclotomic squares. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^2n. + function nSquare(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121, n) -> c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 { + c000 := a000 + c001 := a001 + c010 := a010 + c011 := a011 + c020 := a020 + c021 := a021 + c100 := a100 + c101 := a101 + c110 := a110 + c111 := a111 + c120 := a120 + c121 := a121 + for { let i := 0 } lt(i, n) { i := add(i, 1) } { + c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 := fp12CyclotomicSquare(c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121) + } + } + + // FROBENIUS + + + /// @notice Computes the exponentiation of a Fp12 element to p. + /// @dev Algorithm 28 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^p. + function frobenius(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c00, c01, c10, c11, c20, c21, c30, c31, c40, c41, c50, c51 { + let t10, t11 := fp2Conjugate(a000, a001) + let t20, t21 := fp2Conjugate(a100, a101) + let t30, t31 := fp2Conjugate(a010, a011) + let t40, t41 := fp2Conjugate(a110, a111) + let t50, t51 := fp2Conjugate(a020, a021) + let t60, t61 := fp2Conjugate(a120, a121) + + t20, t21 := mulByGamma11(t20, t21) + t30, t31 := mulByGamma12(t30, t31) + t40, t41 := mulByGamma13(t40, t41) + t50, t51 := mulByGamma14(t50, t51) + t60, t61 := mulByGamma15(t60, t61) + + c00 := t10 + c01 := t11 + c10 := t30 + c11 := t31 + c20 := t50 + c21 := t51 + c30 := t20 + c31 := t21 + c40 := t40 + c41 := t41 + c50 := t60 + c51 := t61 + } + + /// @notice Computes the exponentiation of a Fp12 element to p^2. + /// @dev Algorithm 29 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^(p^2). + function frobeniusSquare(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c00, c01, c10, c11, c20, c21, c30, c31, c40, c41, c50, c51 { + let t10 := a000 + let t11 := a001 + let t20, t21 := mulByGamma21(a100, a101) + let t30, t31 := mulByGamma22(a010, a011) + let t40, t41 := mulByGamma23(a110, a111) + let t50, t51 := mulByGamma24(a020, a021) + let t60, t61 := mulByGamma25(a120, a121) + + c00 := t10 + c01 := t11 + c10 := t30 + c11 := t31 + c20 := t50 + c21 := t51 + c30 := t20 + c31 := t21 + c40 := t40 + c41 := t41 + c50 := t60 + c51 := t61 + } + + /// @notice Computes the exponentiation of a Fp12 element to p^3. + /// @dev @dev Algorithm 29 in: https://eprint.iacr.org/2010/354.pdf. + /// @param a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return c000, c001, c010, c011, c020, c021, c100, c101, c110, c111, c120, c121 The coefficients of the element C = A^(p^3). + function frobeniusCube(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> c00, c01, c10, c11, c20, c21, c30, c31, c40, c41, c50, c51 { + let t10, t11 := fp2Conjugate(a000, a001) + let t20, t21 := fp2Conjugate(a100, a101) + let t30, t31 := fp2Conjugate(a010, a011) + let t40, t41 := fp2Conjugate(a110, a111) + let t50, t51 := fp2Conjugate(a020, a021) + let t60, t61 := fp2Conjugate(a120, a121) + + t20, t21 := mulByGamma31(t20, t21) + t30, t31 := mulByGamma32(t30, t31) + t40, t41 := mulByGamma33(t40, t41) + t50, t51 := mulByGamma34(t50, t51) + t60, t61 := mulByGamma35(t60, t61) + + c00 := t10 + c01 := t11 + c10 := t30 + c11 := t31 + c20 := t50 + c21 := t51 + c30 := t20 + c31 := t21 + c40 := t40 + c41 := t41 + c50 := t60 + c51 := t61 + } + + // GAMMA_1_i + /// @notice Computes the multiplication between a fp2 element by the constants g_1,i. + /// @dev Where g_1,i = u^(i(p-1)/6) + /// @dev This value was precomputed using Python. Already in montgomery form. + /// @dev See https://eprint.iacr.org/2010/354.pdf for further details. + /// @params a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = A*g_1,i. + + function mulByGamma11(a00, a01) -> c00, c01 { + let g00 := 1334504125441109323775816677333762124980877086439557453392802825656291576071 + let g01 := 7532670101108748540749979597679923402841328813027773483599019704565791010162 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma12(a00, a01) -> c00, c01 { + let g00 := 11461073415658098971834280704587444395456423268720245247603935854280982113072 + let g01 := 17373957475705492831721812124331982823197004514106338927670775596783233550167 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma13(a00, a01) -> c00, c01 { + let g00 := 16829996427371746075450799880956928810557034522864196246648550205375670302249 + let g01 := 20140510615310063345578764457068708762835443761990824243702724480509675468743 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma14(a00, a01) -> c00, c01 { + let g00 := 9893659366031634526915473325149983243417508801286144596494093251884139331218 + let g01 := 16514792769865828027011044701859348114858257981779976519405133026725453154633 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma15(a00, a01) -> c00, c01 { + let g00 := 8443299194457421137480282511969901974227997168695360756777672575877693116391 + let g01 := 21318636632361225103955470331868462398471880609949088574192481281746934874025 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + // GAMMA_2_i + /// @notice Computes the multiplication between a fp2 element by the constants g_2,i. + /// @dev Where g_2,i = g_1,i * g'_1,i + /// @dev This value was precomputed using Python. Already in montgomery form. + /// @dev See https://eprint.iacr.org/2010/354.pdf for further details. + /// @params a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = A*g_2,i. + + function mulByGamma21(a00, a01) -> c00, c01 { + let g0 := 1881798392815877688876180778159931906057091683336018750908411925848733129714 + c00, c01 := fp2ScalarMul(a00, a01, g0) + } + + function mulByGamma22(a00, a01) -> c00, c01 { + let g0 := 17419166386535333598783630241015674584964973961482396687585055285806960741276 + c00, c01 := fp2ScalarMul(a00, a01, g0) + } + + function mulByGamma23(a00, a01) -> c00, c01 { + let g0 := 15537367993719455909907449462855742678907882278146377936676643359958227611562 + c00, c01 := fp2ScalarMul(a00, a01, g0) + } + + function mulByGamma24(a00, a01) -> c00, c01 { + let g0 := 20006444479023397533370224967097343182639219473961804911780625968796493078869 + c00, c01 := fp2ScalarMul(a00, a01, g0) + } + + function mulByGamma25(a00, a01) -> c00, c01 { + let g0 := 4469076485303941623462775504241600503731337195815426975103982608838265467307 + c00, c01 := fp2ScalarMul(a00, a01, g0) + } + + // GAMMA_3_i + /// @notice Computes the multiplication between a fp2 element by the constants g_3,i. + /// @dev Where g_3,i = g_1,i * g_2,i + /// @dev This value was precomputed using Python. Already in montgomery form. + /// @dev See https://eprint.iacr.org/2010/354.pdf for further details. + /// @params a00, a01 The coefficients of the Fp2 element A. + /// @return c00, c01 The coefficients of the element C = A*g_3,i. + + function mulByGamma31(a00, a01) -> c00, c01 { + let g00 := 3649295186494431467217240962842301358951278585756714214031945394966344685949 + let g01 := 17372117152826387298350653207345606612066102743297871578090761045572893546809 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma32(a00, a01) -> c00, c01 { + let g00 := 14543349330631744552586812320441124107441202078168618766450326117520897829805 + let g01 := 4646831431411403714092965637071058625728899792817054432901795759277546050476 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma33(a00, a01) -> c00, c01 { + let g00 := 5058246444467529146795605864300346278139276634433627416040487689269555906334 + let g01 := 1747732256529211876667641288188566325860867395306999418986313414135550739840 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma34(a00, a01) -> c00, c01 { + let g00 := 3025265262868802913511075437173590487338001780554453930995247874855578067679 + let g01 := 10425289180741305073643362413949631488281652900778689227251281048515799234257 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + function mulByGamma35(a00, a01) -> c00, c01 { + let g00 := 9862576063628467829192720579684130652367741026604221989510773554027227469215 + let g01 := 16681752610922605480353377694363181135019829138759259603037557916788351015335 + c00, c01 := fp2Mul(a00, a01, g00, g01) + } + + // PAIRING FUNCTIONS + + /// @notice Computes the double of a G2 point and its tangent line. + /// @dev The point is in projective coordinates. + /// @dev See https://eprint.iacr.org/2013/722.pdf for further details. + /// @params xq0, xq1 The coefficients of the Fp2 X coordinate of the Q point. + /// @params yq0, yq1 The coefficients of the Fp2 X coordinate of the Q point. + /// @params zq0, zq1 The coefficients of the Fp2 X coordinate of the Q point. + /// @return xt0, xt1 The coefficients of the Fp2 X coordinate of T = 2Q. + /// @return yt0, yt1 The coefficients of the Fp2 X coordinate of T = 2Q. + /// @return zt0, zt1 The coefficients of the Fp2 X coordinate of T = 2Q. + /// @return l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 The coefficients of the tangent line to Q. + function doubleStep(xq0, xq1, yq0, yq1, zq0, zq1) -> l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, xt0, xt1, yt0, yt1, zt0, zt1 { + let zero := 0 + let twoInv := MONTGOMERY_TWO_INV() + let t00, t01 := fp2Mul(xq0, xq1, yq0, yq1) + let t10, t11 := fp2ScalarMul(t00, t01, twoInv) + let t20, t21 := fp2Mul(yq0, yq1, yq0, yq1) + let t30, t31 := fp2Mul(zq0, zq1, zq0, zq1) + let t40, t41 := fp2Add(t30, t31, t30, t31) + t40, t41 := fp2Add(t40, t41, t30, t31) + let t50, t51 := MONTGOMERY_TWISTED_CURVE_COEFFS() + t50, t51 := fp2Mul(t40, t41, t50, t51) + let t60, t61 :=fp2Add(t50, t51, t50, t51) + t60, t61 := fp2Add(t60, t61, t50, t51) + let t70, t71 := fp2Add(t20, t21, t60, t61) + t70, t71 := fp2ScalarMul(t70, t71, twoInv) + let t80, t81 := fp2Add(yq0, yq1, zq0, zq1) + t80, t81 := fp2Mul(t80, t81, t80, t81) + let t90, t91 := fp2Add(t30, t31, t20, t21) + t80, t81 := fp2Sub(t80, t81, t90, t91) + let t100, t101 := fp2Sub(t50, t51, t20, t21) + let t110, t111 := fp2Mul(xq0, xq1, xq0, xq1) + let t120, t121 := fp2Mul(t50, t51, t50, t51) + let t130, t131 := fp2Add(t120, t121, t120, t121) + t130, t131 := fp2Add(t130, t131, t120, t121) + + // l0 + l00 := t80 + l01 := t81 + l10 := zero + l11 := zero + l20 := zero + l21 := zero + + // l1 + l30, l31 := fp2Add(t110, t111, t110, t111) + l30, l31 := fp2Add(l30, l31, t110, t111) + + // l2 + l40 := t100 + l41 := t101 + + l50 := zero + l51 := zero + + // Tx + xt0, xt1 := fp2Sub(t20, t21, t60, t61) + xt0, xt1 := fp2Mul(xt0, xt1, t10, t11) + + // Ty + yt0, yt1 := fp2Mul(t70, t71, t70, t71) + yt0, yt1 := fp2Sub(yt0, yt1, t130, t131) + + // Tz + zt0, zt1 := fp2Mul(t20, t21, t80, t81) + } + + /// @notice Computes the addition of two G2 points and the line through them. + /// @dev It's called mixed addition because Q is in affine coordinates and T in projective coordinates. + /// @dev The two points must be different, in this Q, which is G2 group generator of an order of 21888242871839275222246405745257275088548364400416034343698204186575808495617, is doubled and added. So will never reach Q. + /// @dev See https://eprint.iacr.org/2013/722.pdf for further details. + /// @dev Disclaimer: The algorithm described in the paper is has a typo, the (`l00`,`l01`) coefficients should not be negated. + /// @params xq0, xq1 The coefficients of the Fp2 X coordinate of the Q point. + /// @params yq0, yq1 The coefficients of the Fp2 Y coordinate of the Q point. + /// @params xt0, xt1 The coefficients of the Fp2 X coordinate of the T point. + /// @params yt0, yt1 The coefficients of the Fp2 Y coordinate of the T point. + /// @params zt0, zt1 The coefficients of the Fp2 Z coordinate of the T point. + /// @return xc0, xc1 The coefficients of the Fp2 X coordinate of C = Q + T. + /// @return yc0, yc1 The coefficients of the Fp2 X coordinate of C = Q + T. + /// @return zc0, zc1 The coefficients of the Fp2 X coordinate of C = Q + T. + /// @return l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 The coefficients of the line through T and Q. + function mixedAdditionStep(xq0, xq1, yq0, yq1, xt0, xt1, yt0, yt1, zt0, zt1) -> l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, xc0, xc1, yc0, yc1, zc0, zc1 { + let zero := 0 + let t00, t01 := fp2Mul(yq0,yq1,zt0,zt1) + let t10, t11 := fp2Sub(yt0, yt1, t00, t01) + t00, t01 := fp2Mul(xq0, xq1, zt0, zt1) + let t20, t21 := fp2Sub(xt0, xt1, t00, t01) + let t30, t31 := fp2Mul(t10, t11, t10, t11) + let t40, t41 := fp2Mul(t20, t21, t20, t21) + let t50, t51 := fp2Mul(t20, t21, t40, t41) + let t60, t61 := fp2Mul(zt0, zt1, t30, t31) + let t70, t71 := fp2Mul(xt0, xt1, t40, t41) + t00, t01 := fp2Add(t70, t71, t70, t71) + let t80, t81 := fp2Add(t50, t51, t60, t61) + t80, t81 := fp2Sub(t80, t81, t00, t01) + t00, t01 := fp2Mul(yt0, yt1, t50, t51) + + // Xc0 + xc0, xc1 := fp2Mul(t20, t21, t80, t81) + + // Yc0 + yc0, yc1 := fp2Sub(t70, t71, t80, t81) + yc0, yc1 := fp2Mul(yc0, yc1, t10, t11) + yc0, yc1 := fp2Sub(yc0, yc1, t00, t01) + + // Zc0 + zc0, zc1 := fp2Mul(t50, t51, zt0, zt1) + t00, t01 := fp2Mul(t20, t21, yq0, yq1) + let t90, t91 := fp2Mul(xq0, xq1, t10, t11) + t90, t91 := fp2Sub(t90, t91, t00, t01) + + // l0 + l00 := t20 + l01 := t21 + l10 := zero + l11 := zero + l20 := zero + l21 := zero + + // l1 + l30 := t10 + l31 := t11 + + // l2 + l40 := t90 + l41 := t91 + l50 := zero + l51 := zero + } + + /// @notice Computes the line through two G2 points. + /// @dev Like in the mixedAdditionStep, Q is in affine coordinates and T in projective coordinates. + /// @dev The two points must be different, in this Q, which is G2 group generator of an order of 21888242871839275222246405745257275088548364400416034343698204186575808495617, is doubled and added. So will never reach Q. + /// @params xq0, xq1 The coefficients of the Fp2 X coordinate of the Q point. + /// @params yq0, yq1 The coefficients of the Fp2 Y coordinate of the Q point. + /// @params xt0, xt1 The coefficients of the Fp2 X coordinate of the T point. + /// @params yt0, yt1 The coefficients of the Fp2 Y coordinate of the T point. + /// @params zt0, zt1 The coefficients of the Fp2 Z coordinate of the T point. + /// @return l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 The coefficients of the line through T and Q. + function computeLine(xq0, xq1, yq0, yq1, xt0, xt1, yt0, yt1, zt0, zt1) -> l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 { + let zero := 0 + let t00, t01 := fp2Mul(yq0,yq1,zt0,zt1) + let t10, t11 := fp2Sub(yt0, yt1, t00, t01) + t00, t01 := fp2Mul(xq0, xq1, zt0, zt1) + let t20, t21 := fp2Sub(xt0, xt1, t00, t01) + let t30, t31 := fp2Mul(t20, t21, yq0, yq1) + let t40, t41 := fp2Mul(xq0, xq1, t10, t11) + t40, t41 := fp2Sub(t40, t41, t30, t31) + + // l0 + l00 := t20 + l01 := t21 + l10 := zero + l11 := zero + l20 := zero + l21 := zero + + // l1 + l30, l31 := fp2Neg(t10, t11) + + // l2 + l40 := t40 + l41 := t41 + l50 := zero + l51 := zero + } + + /// @notice Computes the final exponentiation to the result given by the Millers Loop. + /// @dev It computes the exponentiation of a Fp12 elemento to e, with e = (p^12 -1)/r + /// @dev We can split this exponentitation in three parts: e = (p^6 - 1)(p^2 + 1)((p^4 - p^2 + 1)/r) + /// @dev The first 2 parts are easy to compute using the Frobenius operator. + /// @dev To calculate this we use the first 5 lines of Algorithm 31 in: https://eprint.iacr.org/2010/354.pdf + /// @dev For the hard part we use the Fuentes et al. method. Algorithm 6 in: https://eprint.iacr.org/2015/192.pdf + /// @params a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121 The coefficients of the Fp12 element A. + /// @return f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 The coefficients of A^(s*((p^12 -1)/r)) where s is not divisible by r. + function finalExponentiation(a000, a001, a010, a011, a020, a021, a100, a101, a110, a111, a120, a121) -> f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 { + f000 := a000 + f001 := a001 + f010 := a010 + f011 := a011 + f020 := a020 + f021 := a021 + f100 := a100 + f101 := a101 + f110 := a110 + f111 := a111 + f120 := a120 + f121 := a121 + + // Easy Part + let t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Conjugate(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Inv(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Mul(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121, f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + let t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := frobeniusSquare(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121, t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + + // Hard Part + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Expt(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Conjugate(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12CyclotomicSquare(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := fp12CyclotomicSquare(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := fp12Mul(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121, t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121) + let t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := fp12Expt(t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121) + t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := fp12Conjugate(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121) + let t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121 := fp12Conjugate(t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121) + t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121 := fp12Mul(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121, t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121) + t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121 := fp12CyclotomicSquare(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121) + let t4000, t4001, t4010, t4011, t4020, t4021, t4100, t4101, t4110, t4111, t4120, t4121 := fp12Expt(t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121) + t4000, t4001, t4010, t4011, t4020, t4021, t4100, t4101, t4110, t4111, t4120, t4121 := fp12Mul(t4000, t4001, t4010, t4011, t4020, t4021, t4100, t4101, t4110, t4111, t4120, t4121, t1000, t1001, t1010, t1011, t1020, t1021, t1100, t1101, t1110, t1111, t1120, t1121) + t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121 := fp12Mul(t4000, t4001, t4010, t4011, t4020, t4021, t4100, t4101, t4110, t4111, t4120, t4121, t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Mul(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121, t4000, t4001, t4010, t4011, t4020, t4021, t4100, t4101, t4110, t4111, t4120, t4121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Mul(t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121, f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := frobenius(t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Mul(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121, t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := frobeniusSquare(t4000, t4001, t4010, t4011, t4020, t4021, t4100, t4101, t4110, t4111, t4120, t4121) + t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121 := fp12Mul(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121, t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := fp12Conjugate(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := fp12Mul(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121, t3000, t3001, t3010, t3011, t3020, t3021, t3100, t3101, t3110, t3111, t3120, t3121) + t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121 := frobeniusCube(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(t2000, t2001, t2010, t2011, t2020, t2021, t2100, t2101, t2110, t2111, t2120, t2121, t0000, t0001, t0010, t0011, t0020, t0021, t0100, t0101, t0110, t0111, t0120, t0121) + } + + /// @notice Computes the Millers Loop for the optimal ate pairing. + /// @dev Algorithm 1 in: https://eprint.iacr.org/2010/354.pdf + /// @dev It takes two points: P that belongs to the curve G1, in affine coordinates (Fp elements) + /// @dev Point Q belongs to the twisted G2 curve, in affine coordinates (Fp2 elements) + /// @params xp, yp The coordinates of the point P. + /// @params xq0, xq1 The coefficients of the X coordinate of point Q. + /// @params yq0, yq1 The coefficients of the Y coordinate of point Q. + /// @return f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 The Fp12 element result of the Miller Loop + function millerLoop(xq0, xq1, yq0, yq1, xp, yp) -> f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 { + let t00, t01, t10, t11, t20, t21 := g2ProjectiveFromAffine(xq0, xq1, yq0, yq1) + let mq00, mq01, mq10, mq11 := g2AffineNeg(xq0, xq1, yq0, yq1) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := FP12_ONE() + let naf := NAF_REPRESENTATIVE() + let n_iter := 63 + let l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 + let myp := montgomerySub(0, yp) + let mxp := montgomerySub(0, xp) + + // Computes the first iteration of Millers loop outside to avoid unecesariy square + // NAF[64] == 0 + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := doubleStep(t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, myp) + l30, l31 := fp2ScalarMul(l30, l31, xp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + + // Computes the second iteration of Millers loop outside + // NAF[63] == -1. + // Here T = 2Q, so doing a double step and a mixed addition step with -Q looks like: (2(2Q)-Q) = 3Q. + // This is equivalent to a mixed addition step with Q: (2Q + Q) = 3Q + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121,f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 := computeLine(mq00, mq01, mq10, mq11, t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, yp) + l30, l31 := fp2ScalarMul(l30, l31, xp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := mixedAdditionStep(xq0, xq1, yq0, yq1, t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, yp) + l30, l31 := fp2ScalarMul(l30, l31, mxp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + + for {let i := 0} lt(i, n_iter) { i := add(i, 1) } { + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Square(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := doubleStep(t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, myp) + l30, l31 := fp2ScalarMul(l30, l31, xp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + + // naf digit = 1 + if and(naf, 1) { + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := mixedAdditionStep(xq0, xq1, yq0, yq1, t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, yp) + l30, l31 := fp2ScalarMul(l30, l31, mxp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + } + + // naf digit = -1 + if and(naf, 2) { + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := mixedAdditionStep(mq00, mq01, mq10, mq11, t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, yp) + l30, l31 := fp2ScalarMul(l30, l31, mxp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + } + + naf := shr(2, naf) + } + + let r00, r01 := fp2Conjugate(xq0, xq1) + let r10, r11 := fp2Conjugate(yq0, yq1) + r00, r01 := mulByGamma12(r00, r01) + r10, r11 := mulByGamma13(r10, r11) + + let r20, r21 := mulByGamma22(xq0, xq1) + let r30, r31 := mulByGamma23(yq0, yq1) + r30, r31 := fp2Neg(r30, r31) + + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51, t00, t01, t10, t11, t20, t21 := mixedAdditionStep(r00, r01, r10, r11, t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, yp) + l30, l31 := fp2ScalarMul(l30, l31, mxp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + + l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51 := computeLine(r20, r21, r30, r31, t00, t01, t10, t11, t20, t21) + l00, l01 := fp2ScalarMul(l00, l01, yp) + l30, l31 := fp2ScalarMul(l30, l31, xp) + f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := fp12Mul(f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121, l00, l01, l10, l11, l20, l21, l30, l31, l40, l41, l50, l51) + } + + // FALLBACK + + let inputSize := calldatasize() + + // Empty input is valid and results in returning one. + if eq(inputSize, 0) { + mstore(0, 1) + return(0, 32) + } + + // If the input length is not a multiple of 192, the call fails. + if mod(inputSize, PAIR_LENGTH()) { + // Bad pairing input + burnGas() + } + + let r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121 := FP12_ONE() + + // Calldata "parsing" + for { let i := 0 } lt(i, inputSize) { i := add(i, PAIR_LENGTH()) } { + /* G1 */ + calldatacopy(i, i, 32) // x + calldatacopy(add(i, 32), add(i, 32), 32) // y + + let g1_x := mload(i) + let g1_y := mload(add(i, 32)) + + if iszero(and(coordinateIsOnFieldOrder(g1_x), coordinateIsOnFieldOrder(g1_y))) { + burnGas() + } + + g1_x := intoMontgomeryForm(g1_x) + g1_y := intoMontgomeryForm(g1_y) + + let g1IsInfinity := g1AffinePointIsInfinity(g1_x, g1_y) + + if and(iszero(g1IsInfinity), iszero(g1AffinePointIsOnCurve(g1_x, g1_y))) { + burnGas() + } + + /* G2 */ + let g2_x1_offset := add(i, 64) + let g2_x0_offset := add(i, 96) + let g2_y1_offset := add(i, 128) + let g2_y0_offset := add(i, 160) + + calldatacopy(g2_x1_offset, g2_x1_offset, 32) + calldatacopy(g2_x0_offset, g2_x0_offset, 32) + calldatacopy(g2_y1_offset, g2_y1_offset, 32) + calldatacopy(g2_y0_offset, g2_y0_offset, 32) + + let g2_x1 := mload(g2_x1_offset) + let g2_x0 := mload(g2_x0_offset) + let g2_y1 := mload(g2_y1_offset) + let g2_y0 := mload(g2_y0_offset) + + if iszero(and(coordinateIsOnFieldOrder(g2_x0), coordinateIsOnFieldOrder(g2_x1))) { + burnGas() + } + + if iszero(and(coordinateIsOnFieldOrder(g2_y0), coordinateIsOnFieldOrder(g2_y1))) { + burnGas() + } + + if g2AffinePointIsInfinity(g2_x0, g2_x1, g2_y0, g2_y1) { + continue + } + + g2_x0 := intoMontgomeryForm(g2_x0) + g2_x1 := intoMontgomeryForm(g2_x1) + g2_y0 := intoMontgomeryForm(g2_y0) + g2_y1 := intoMontgomeryForm(g2_y1) + + if iszero(g2IsInSubGroup(g2_x0,g2_x1, g2_y0, g2_y1, MONTGOMERY_ONE(), 0)) { + burnGas() + } + + if iszero(g2AffinePointIsOnCurve(g2_x0, g2_x1, g2_y0, g2_y1)) { + burnGas() + } + + // We must continue if g1 is the point at infinity after validating both g1 and g2 + // That's why although knowing this before parsing and validating g2 we check it later. + if g1IsInfinity { + continue + } + + + let f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121 := millerLoop(g2_x0, g2_x1, g2_y0, g2_y1, g1_x, g1_y) + + r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121 := fp12Mul(r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121, f000, f001, f010, f011, f020, f021, f100, f101, f110, f111, f120, f121) + } + + r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121 := finalExponentiation(r000, r001, r010, r011, r020, r021, r100, r101, r110, r111, r120, r121) + + // Pair check + if and(eq(r000, MONTGOMERY_ONE()), iszero(or(r001, or(r010, r011)))) { + if iszero(or(or(r020, r021), or(r100, r101))) { + if iszero(or(or(r110, r111), or(r120, r121))) { + mstore(0, 1) + return(0, 32) + } + } + } + + mstore(0, 0) + return(0, 32) + } + } +} diff --git a/system-contracts/scripts/constants.ts b/system-contracts/scripts/constants.ts index 88f8e0dd7..406b4cb6e 100644 --- a/system-contracts/scripts/constants.ts +++ b/system-contracts/scripts/constants.ts @@ -65,6 +65,12 @@ export const SYSTEM_CONTRACTS: ISystemContracts = { lang: Language.Yul, path: "precompiles", }, + ecPairing: { + address: "0x0000000000000000000000000000000000000008", + codeName: "EcPairing", + lang: Language.Yul, + path: "precompiles", + }, bootloader: { // Bootloader has EmptyContract code address: "0x0000000000000000000000000000000000008001", diff --git a/system-contracts/test/precompiles/EcPairing.spec.ts b/system-contracts/test/precompiles/EcPairing.spec.ts new file mode 100644 index 000000000..f938a14b9 --- /dev/null +++ b/system-contracts/test/precompiles/EcPairing.spec.ts @@ -0,0 +1,415 @@ +import { expect } from "chai"; +import type { Contract } from "zksync-ethers"; +import { callFallback, deployContractYul } from "../shared/utils"; + +describe("EcPairing tests", function () { + let ecPairing: Contract; + + before(async () => { + ecPairing = await deployContractYul("EcPairing", "precompiles"); + }); + + describe("Ethereum tests", function () { + it("ecpairing_empty_data_insufficient_gas", async () => { + const returnData = await callFallback(ecPairing, ""); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_perturb_g2_by_curve_order", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c248652d61f350be9ffaba461cdfdd9cd68f770b1d71184b6e8ac0b2f0c992f6ee090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_bad_length_191", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7d00" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_perturb_zeropoint_by_one", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_one_point_with_g1_zero", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_perturb_g2_by_field_modulus", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed396ad8433991909fa4eedf63ea8d8bf353cc9bc4d925598091cd66f3a99f94a212c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_one_point_with_g2_zero_and_g1_invalid", async () => { + const call = callFallback( + ecPairing, + "0x000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_two_point_match_1", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_two_point_fail_1", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + + it("ecpairing_two_point_oog", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_three_point_fail_1", async () => { + const returnData = await callFallback( + ecPairing, + "0x105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f00cacf3523caf879d7d05e30549f1e6fdce364cbb8724b0329c6c2a39d4f018e0692e55db067300e6e3fe56218fa2f940054e57e7ef92bf7d475a9d8a8502fd200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + + it("ecpairing_one_point_insufficient_gas", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + + it("ecpairing_two_point_match_4", async () => { + const returnData = await callFallback( + ecPairing, + "0x105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_perturb_g2_by_one", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c31800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_three_point_match_1", async () => { + const returnData = await callFallback( + ecPairing, + "0x105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_two_point_match_5", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_two_point_match_2", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_two_point_fail_2", async () => { + const returnData = await callFallback( + ecPairing, + "0x105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd03042700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002105384b6dd6c48634b9fe89cb3e19667c1fe6736c69df070d674c95a42b3b8242c0d8e67f0f2c14c43734b430d8be4265af8c4f7a67deb0b029fd2dff99cc6b9015eaec465d922580c7de5d4a5c26de75eaf2af6841b7412ef2eebd1e051076f1b4c21849e48de12d1bae2bad3299717aa8664ade430e19dec72a6e10a39b0ab" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + + it("ecpairing_two_points_with_one_g2_zero", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + + it("ecpairing_perturb_g2_by_field_modulus_again", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b432cad18bcbe0e1502fbb7370f4c98ed7b5351fa74b59e08890758183f777af1" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_perturb_zeropoint_by_field_modulus", async () => { + const call = callFallback( + ecPairing, + "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd470000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_perturb_zeropoint_by_curve_order", async () => { + const call = callFallback( + ecPairing, + "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_one_point_with_g2_zero", async () => { + const returnData = await callFallback( + ecPairing, + "0x000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_one_point_not_in_subgroup", async () => { + const call = callFallback( + ecPairing, + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800d3270b7da683f988d3889abcdad9776ecd45abaca689f1118c3fd33404b4392588360d269af2cd3e0803839ea274c2b8f062a6308e8da85fd774c26f1bcb87" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_bad_length_193", async () => { + const call = callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa0000000000000000000000000000000000000000000000000000000000000000" + ); + await expect(call).to.be.reverted; + }); + + it("ecpairing_two_point_match_3", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + + it("ecpairing_one_point_fail", async () => { + const returnData = await callFallback( + ecPairing, + "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa" + ); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + + it("ecpairing_fuzz_positive", async () => { + const positive_inputs = [ + "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e104316c97997c17267a1bb67365523b4388e1306d66ea6e4d8f4a4a4b65f5c7d06e286b49c56f6293b2cea30764f0d5eabe5817905468a41f09b77588f692e8b081070efe3d4913dde35bba2513c426d065dee815c478700cef07180fb6146182432428b1490a4f25053d4c20c8723a73de6f0681bd3a8fca41008a6c3c288252d50f18403272e96c10135f96db0f8d0aec25033ebdffb88d2e7956c9bb198ec072462211ebc0a2f042f993d5bd76caf4adb5e99610dcf7c1d992595e6976aa3", + "0084c3136563609ce6d7218719af3024e2163ea8124130cfb61c2521379b00672e775227ccd46bb5bd8b9f9714ecae9e037f8e91246b2a7e171337cf1332e3411fee9eea81af0f92485cb60cec6fdd90385b3f390c67d0885520bea38a07bb081242a8a318ba046cd7f4b87b4ede31c0c19f823ce0ab3192f36acc7683a9170411d50fa9a8a15815baf103030117065601aff6b54f4242d2a5a14e3147e89e25133ca084be363f41cb3886eed01fa8d896a609c22e099c4c9f5bb5a4363a57ad2f9b2caf0345e3ec3eccbc16af5713bbf15eaf2a17cd9f7a02966bd5e7ccd6fe185a77dfe45c4c1c9042c67fdb65d25bbd8b6f79dfdde27458a35792653443f3198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "00898cc97b5a1f95221e7272c6ea8ceb56e702d678ac6c24275a4f6147d2b27916f336255e3f8970fd79a12281e6a6bee510e7d2ce5117214f4dd8c764e00ef312580b380ddf94a3370e6842e68b260a12012ab02c883678abf3f0f37606f55c268f02e60dfc36a40bb1fa3dba22bba44953358031876c21748d5d57dfb39ef407c890d2b747cb1e0456c9c1b30c03badffb8cde540704104b016976d0a374472a3e2918076d66622d7d6014299b77850a74b2691dda1dadcd0232fbbfe2a9e02781b3ace921b11d98193720d1493609c4d47f607a2266d608185c6382b5d23519797c215563c8b73cc7f0041d1f5fe1ce017b36afbeffe56683e3ffccb9380b198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "082a5b0eb620c491dc7cfbf269ea3e9db35fdaf6c7c4baa25a829127a56f63c41c49e6c57c3c0ddca035138e5aadb79ac638f67a918e6a4377200ebfa80ed1880bf4734681e3030e126c2a595de85f80b46bd327bae8a860a3ed5f5be7318037116c5e07de19e858eb720604f6e2935bf0f5e40d9194cfba05bfea0ab69f1d82263ee7293c68743b04034a5b63e1d2b65261f7c6758d8084a50419cc65d02ad214189e61084d61cf2ad9b6140b951ca35ae18a008cb3c1c4904e59f462e66b0428ec2c3d544a901ad85af62e1ec02aac643e707a3a45983ef168877b6901a19d108e7a47061fd472bd715c35b71b842fc1914a8972e472a2a4faa4880e0d2787198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "09148ba3625b1d4862ecfed71970e395d22bc4dafaa4a662546e4fb39141d8ba0a8f563782b2b31347c9e7ced5a21d959a38f4ae4bbc7cd37b1180a0d491cad617f32b902d2096a48b25f94ad6c692a99c68e937a4bae3c820f25093cf2786ab155c57d2b7f4aefc0e1a44a78c7d59d2cac917546717c665dc001fa43cf5775317b81fe685dd2e24a14899ef74821d1d147b88fe0c63d0921eb45c191146e7e41c9ae775eba85ea225258c9bafdf5cbad6106cd79194f4b0f8e7814068370daf302ac8191cd6d55b858891d05b919ad95f5e2f16b78c5b0ad2ecc72c3fe238421a924fa7e779ad503830c25838c2489d9bbc21fd519ceb3f4a10f4dc3e3b72be198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "0ee7f0252e8210eaa3ee452c8731ad6864d8506ba61836f48c99a16a03d59b0d2ba1ddc868f452ef0cfdcac410e9d38d726557b05edc84f8d4f62203acc1f9f029aa08ecade2c1d537c14baf6cf62758c02e6f3c4eeb0b621ad3ab941b1559de11eac12aaf058f799ee8146f36a0bbbf8e67a0aa0f9e2c192bafd05ff8da45d303b7bd661becfa6ff5092b36f1768c815434f3b7f4254fb4b8abf68e36086cd3196caa297895d4a1d58a5fe388416fbac2a74fb9beb835dbbbaa8f6b63bf9cab29a00816ed140fc36e515f43fb054c891b4b07f013c9e6d5c3f284c8528c71ae2f060699e8f54b1028b78e5f016d8142563947adcac5a5857137b6958ddc995e141dd828af529924148912360fd71ef6a365a707173aa2c06c8290d54fae458e1cf61d5e9ceced0c662c6e2df96d63adc7d84e182fa0f62e08b9afdd5c90545e01f3e8049b7934995dee28faa0e401289b92ccd1a2f408c85383f5312f528c9e2c6aaa06b56e9d6c98a701b4a9cf2f8cfddbfa93d7104d5eafbad9a84b5174e5", + "0f740d88de760df099674c96dd2d476b42673d0f2972e6d5d1f9dba95a29d26a04a44d72c2a82088da663ff162fe2d3ddd4a139e1ef6c0bbb1124d8de75f7c68196346d9774f017c351dbbdd99960e834b188b3347b92fac7f83cc6453617fe11e3ba24a0848096a0d6484133af97b7487ca9a4309cb5574d8bb96cfd7f22678235603772d0e9cf9503d05742962b07cd0af71a7c7b757960ced6fcfa74d3ded1ceed193f30fbbe5e9a9438e82bac927a0977b49f6e476aee20923e1a230f2c4201af9371c7cea66800f961d6a7219da9c27fbe61b5df43fccb275d8c034bf8e1f0e7c5a1143b0f8e850d9516ea2c836b0331521829dc2b71dbf775078c770f4198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "107b8a2cb6318aabd95763c0cafc3b24d8a9acdf8dd967176f05c400951b3e0613a1c9847bf87c8cc79ef1120ed6e3e98412f0dd4e9c8c8c421057a2353279e6198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa2fb5b7e464a0a76d9aca8698e73802782da01fce50384f459be1427855c0eb502e6c7af07418cd0203fad6a1abde95e745c41a78c6ad1ae7b1b2ada2e643fd37260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c10118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b004fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe422febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55", + "117196c7ea11e6362bca58533a55de3deadc441b18b0a7ca68557f374dfed6a629b1b63f1d649480aa9655406c454b55cbbf8d29f3aedc30de3b0745bed3be52226ad93c0a164e73d8d9161f9d0206ab232fa5a08cb349f7df3633096cd04e920de4a56223ee43aa3c4a18bf4c84be1879dd9182fd4a03318a4bebd642627d1e142a0ed74ba11936e27101a43db8e16f6a603953c3ea4b14eaebbe117970268a2abced69ffbce2e34440530111050a4d72282dd5f4faa7703d5762d04327175619eedb06c5d1f53510f7f7464b39730659eccf0e9dfeec2cc131fd0d27c4f8e3043aaea131d0e69b79a816b675ac0dd21b4796046c149ca16df5884d615025c5238f967690e26443e6f5207b5c2af7fedb837d534282c7db1ca926a9bc06a7390ec4c043a606711a021205ef7d97785d9ae246ba06b2912e24ff9e669fb700b42714a2e42c4bd73a79cd7b2243d1b784cadb22a58e6360be1af873424efd420c12f54bdcf07ff30854629a0531065973197e685193051f2fa11a7761b0cc39f6", + "13b076f9e2ddf66bd1e9ec7509945ec37289d9ad65f210ed35e78ba2b02e7e3d2c6d9689097e79c4227b7b8519e4850be2d795f9496a70ae8607a3172208371a0774089b1be2375b269ac0cd913803af1e8e967c7a12ded9e38bbfe816cb6b2b25e481bf589a76e531e3cbaee9b47a07fb832b052a71029665a5ca89f1eb6d6b0f10223646f0d0f8f79189c456f40295fa02708a2629b8a88d7ae36caab470552b4bf562f83ed28edf524edc1646b4c4cd538bec5d544d8071f0c73406339b2e2043a8194e50b9ff3b93d13873035fee0ccc3b4a0fda33d34ac7a4771c9b884d291b24054553ecab7eb9a6807281a895bdcf29e95d8d3a2552749b7fc0932637198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "15d6eaaa18c5737e7bd229c2900f8deddf6da9c0e20e7e905e7b7491d041eaba2ab7d1b2a259b85054253da8947c2fd38b04a4ede3bfa6e258e22f668dcb5a63092a62b029973fcd9ec18db33eb4c7b6b649a2e6196561761789e39bc84f11ac0a59f2672462be814a277f495d53244691c40da85d39b210ed3e099b397a4cf92ad603022931e8c20c927fa114866ca26b305156336511a9224d6bd88e5ba7fb2b44dd02df7f7a846f546c77f3330cc171abeea7747ec03607c4b754a07101421f4b96b82bd3631447045f1bb66198fa6a904e48092750762efd419fb5ff52b51fac61c1a7265d0e1a6433e9767cb51c71e9ac5a119be9894f509bf92b0fb1b4198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "16f5d1473d8a9012df4efc624ae3b5fc3b1c1742bb73b9b62aa50c0dec9848ad1b2381a593f0a661db10b659329907fb62b4f5fd196092ef235f0775463b11f3054f9c54b1560a307e173c70fce534a2e4c7b248ec342f968a9db905fb31ba362513859b9c3a196e357d5d4f34e17f5cb2d78f4160103ecae86cb57a3e48ef7715e96b3ad7bfbccc491029f30be0ced0654c6c2600b49bfafc70af802b305a09154bb828c71576e1809723e3bbb5d459ece5bdccb9bcdff733761fe908e1e1d52f91cec7b5d03d4c5930875239f825c55849b352fa27b4e20581fc4a68950c752ee478820a0dc3f22866e7c5111d6fd1f057c18b7c9c1568173916ce67555c47198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "18dd52daaa11ff5dbb97c8776924d95b1bb86bf16481ba52519674873e0279ea0b32f4758cc18142794358e62b9c29951d3cb7e705d97e4cefd8422fa340ed5804cbac0707b92f59b87024017aae6941a3d8f42c6b93c619fa85cd54a3f0596325ef128bd051c44f95f7aa6122a390666691c2ec8a328f5302605f0aaae670db14a3194db0c978125b0212d2dbcf3639650e40f8acaeff5a5c20ba700de3966f004d3f0a629eb1456685db5a1b94d4b2f8dc0a9cdc5d29cccc5b596d88ba29fe0bcf53d38a1b0732fd90b73149559e0ee767f525875ebdb26f7f123136282afa28e440620ea4064d1f0190c75e2a36003f18643507a927926130eb54ecc1004d198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "1b6e4577cc71df5e856ed88d2d14a464343f140b07693e3b08308570b28fd55b24198aa6ee0f5bfec020ad2ff15729434439e4af7554fa0f7395ee20cb926346246b8e8c771c3db7226a8066537632923d7d5a542f8e0d600e7f0195240f1ec513cbe706f9ba436dd4a781fab85fa2e9d82854446cf91182dcfa66eb68c4b7e72533a60b837f9cf4838c4c38f4f9c8988fee10c9895753e7925a86330e925db702f47f10f7da957cfcc613361ab6aaeb67f14d22c06eec14e47e36988c4ee06705a596bd22bbb13dc898acfdd420c88893dd09f7fd4875e8b3fb65b54ad9643f2847ab3c7d853e89cfdf520de28e1092c1955b7e17d9cba5808f047a3d6898fd2f64f057deda8bbb646d5b9864d9789a696abf2a42218f7af28baae517f5e45723bd3952d332068086b2079260b285896cb84c73ece3647094fac90d8b1374c21eebb3f8ea3c3d9147fa09e4506bcff1c222a02ea8b4904fc6df3bca1cc0505e133d9a4794eb099e9bdf82a6fecdb2e2e29b0867bf0fe557475dc758d796714e", + "1ee2af29808bc7baad8eb3e87bf55588ef59763ae59585453aa57222a60409141756d11b0679f2e3c44a95592d270f55f76670c2d248fe2c0b391a11aa90d0ec0ea16e33157b6d0f197ed197ce3ad5b93ac91458632464dd5e4aa23ec628e6cb03c160eb0d2ab47566d495f1a53b7b1cdb659cb64e26c848c74267bc74ffeec81d5ee181514337f685e60ba02daccded24ea3122fb04d9da37790f3dce54587803087c55d223005ff8ad78f6f417b19caff564e8b8cb820d0eadb6bec43f0cf902b88f6e24920bd60dbbf082df1cd200abf141b6c01e7fcb262525364c14c20502958d26f4e6ad2d9b1db8a6b23e7fa5dc4d0e4c6673b0f840c000eeac001988198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "1f357db2cd961c374f81a4ae374f5306787361c3aea270815962003c0915b5d2044c12e4c6321f0a73b09480c1d7a84ce30ee9219b3b649ff36ec7553150428f1b789c458e1e033db933f65230c01f173dc581494d23407494818cbc70c5e4eb05685001b0f48e5191bc50797f1330beb69d7dabe58b9b7d0c9c86c61c8d2a3301c8dc500074bc4207038e94f028d954405d8b6ff8b3f1b52a7ce67c97382c0b0a9c7d7844ca3f0a571b04211c021dc96a29628119b067364a06fea760698a060452283eefd9b336e591f37119aa473f03932c9c6d7cb0256c93e2bb7ebc214024a87b7afbb4143434a5aecbec2c38e02c7e01e8b056b812c80deab761bd942906b4a2cadf0c0d14e9015f1dd1833e1a71bdecfcc8d400f0c96c309dd8f3f30e243fddb630078af3593c50273c6fbc2c33f2fc6e208ad1e6dd537079f569cd5f25e6c61eb8d52bfe15205fb66a6e90da703a7cb8b441023f90ae987e35c72f800e8e708e896b7ba90163f4dd87bb6660359ca5558473831dea4aac4d222fe443", + "21b1479be2a88d421d6aa893a59fe4966322436bcd047e610f90929a5823188a2feb0baed066808be65012e37e364243877a4d47b75cd9ffe4a5df3011a68f90198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa1aa2ba0e64e80047d931df5931420de2d4dc0b7b6fc83121a9f155ddf9d6577520108e265338e3f2bdcc276bf69d955d60c73419d7ba24c25a40e9efd4cb24b80dbbd035ab913dc40917c815e66941eef6529d94ecbaaee8f77efe9aac45aab22ff4691bd3aa5f5bbb6067c1a4392dc87bb7a9997f7a660dd960df462203c18f2d4e9ee9f56967d24826884a2473b374d24b5afef1cb8d11555a2a62249b44a907a93f02c17da88bbef2e8b41a34ee1137aa7edb0459e06be0bd88ef68a876b0", + "2371e7d92e9fc444d0e11526f0752b520318c80be68bf0131704b36b7976572e2dca8f05ed5d58e0f2e13c49ae40480c0f99dfcd9268521eea6c81c6387b66c4051a93d697db02afd3dcf8414ecb906a114a2bfdb6b06c95d41798d1801b3cbd2e275fef7a0bdb0a2aea77d8ec5817e66e199b3d55bc0fa308dcdda74e85060b1c7e33c2a72d6e12a31eababad3dbc388525135628102bb64742d9e325f43410115dc41fa10b2dbf99036f252ad6f00e8876b22f02cb4738dc4413b22ea9b2df09a760ea8f9bd87dc258a949395a03f7d2500c6e72c61f570986328a096b610a148027063c072345298117eb2cb980ad79601db31cc69bba6bcbe4937ada6720198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "23e6648726d779a5e9943a9cb2c3d89cc966f0ca965bbe7bbdc1bd93df6429302a1e299a0d2c7fb74af9e086c19b07b357c55e76d2c65fba3b122c8158ee2b76071a0694c6a785ae2ff2553f4c06e2d24d031b86a4023a0d41a095b9d35ec8d30c1ab42b9a9d852e0901c708a5a0dfa9920e0ba08828620a5ebbdf1ffb8f9d851741332dcd8798b695edf6be41e0e58803ab926516d0d600514c4572575b29241a64993ddd9be2bab46a7190024de9e051862f46ac3130db54ede8c322e604a22e198a9651f4d48dc87f0ebc9fba1061d49962668790edc37948681da728a79f1649dc12a9101ad7e6c1631c1290bec29720bf5617ee6b5afa720733748bc3fe2ae647da926e44cc8e5476a15ffc62f11eafc89cb7d1d9ea1107403e1773c49a2408eaaabd36aa0a8dc6db3fb091f3c8b4df202714f74ae8d8cca11a216a301725ef6bf83c607781e9c1696e31cb5baa60b9e2deb0856479b342737592c0961211d363f2f2fc286d903a1e94c6673714464530bdb734ded5608b4654466d3f35", + "24ab69f46f3e3333027d67d51af71571141bd5652b9829157a3c5d12684619840f0e1495665bccf97d627b714e8a49e9c77c21e8d5b383ad7dde7e50040d0f622cab595b9d579f8b82e433249b83ae1d7b62d7073a4f67cb3aeb9b316988907f1326d1905ffde0c77e8ebd98257aa239b05ae76c8ec7723ec19bbc8282b0debe130502106676b537e01cc356765e91c005d6c4bd1a75f5f6d41d2556c73e56ac2dc4cb08068b4aa5f14b7f1096ab35d5c13d78319ec7e66e9f67a1ff20cbbf031459f4140b271cbc8746de9dfcb477d5b72d50ef95bec5fef4a68dd69ddfdb2e2c589584551d16a9723b5d356d1ee2066d10381555cdc739e39efca2612fc544229ab0abdb0a7d1a5f0d93fb36ce41e12a31ba52fd9e3c27bebce524ab6c4e9b00f8756832b244377d06e2d00eeb95ec8096dcfd81f4e4931b50fea23c04a2fe29605352ce973ec48d1ab2c8355643c999b70ff771946078b519c556058c3d56059a65ae6e0189d4e04a966140aa40f781a1345824a90a91bb035e12ad29af1d", + "2b5154892605b4b57c6f309a1f39d91a89d985264f9dc47342470b5605532939153954f4ac012e3d5860731081c59b0b5d9df76eeeca47c1ede99d0a73a8d1351b7962c4f91943b75bfa71d26698f33807c0a82c4aff43116e6b0e97e087d64e0337b7f3f182a6241093041180e874062c10467e0147e1abd93857dda7e6aa34153cac48663d8de0c9f23d1a2cecf0bd14f6d7cf877ef833751f8a524d0f4c1c1ff902721cd414e4c564c569143a0356d3b6cb7b1970067365c0a0f8ecb4976b0da26ca39baccc3b276b50cbd06db50b1c544055c0c636256fa35afdafee49bf2238e1b69bc5e674c9351b702c26021f8eb254e0f890595f5f22ca04b205748003d0a15ac5814b86f5463c48d5f7d398da010569d67f979b2af9381802b485fd2d3de1b5338ac2222d3d1bfca2e20f7c1a280780ba9abd54b46d42380fda599c243c33dbb5c54e9566fdda8567e059b596fba1e9afef57deb1703f27cd93ce7419779141bb51eaa0ea4f1fd39efc61aee4e6b40316248277599c599ec30c8dd4", + "2cc6c9acabc199e21be075d6d7885acfa1f38fec18999d78105c87e55a5d8eb7238e3f5edea71116b4905645df360589eed6e69ff4145a28c6ae29599ccb590e0e8248a6ccd8770c3cdbbd6d7f247c76f189978508b6f3514877833b00a7c593261d44028c3119ad2707a456739918ad10b51e7257b539a34e7f479f2e76707a2b359c070959c19eb7bb2bf1dbbb2cc060558f6dd682965535cba0f2392d13b818a023e2b4d60c38c7c0ab6af9ff0887dd192ac88b5070851f4d0e7495a1144d0ed1531303f89b56ebe6e9a39e7b7c4b5f2385d774ab00ab0b3c32c9b110552a0794c8d242f2aa6f638a597e53d8f236c780fcac4a7e2cabcb688896a84046c713532c71aeac024eea1bbccb01b45ceb4ad91e106200b7e25b0e30bc588d783520692d41373a18914e163949fa765d49dbaa5999b1d606300a469555da182b591fe664fc1dc73f67d3261d81477fd5b43e9b7d9a376a09e4a2b82f935ce0ef730abd60b3b4ca1e15eae3dd484e5e22f0f8f50dfbc756b40cb2406e6a1d86c07c", + "2e565cd418929c3795adf3ea378f2616af24a1d7a93962c5be375e7fbdfe3d731197465669e70fd0793c00fb922d25dd53c8c35d4d686985e4e04741569497d1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003a781e0964591a816d07c8d6aa23d23b2ad50ae3acc529f877abf4d13e3f35e0fc25d443ba88ff661c914498d09f6c47bd3db7f8768c13ac2602e02250c34d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "2e5e8d67b60e1d06acd7a490f8394be4aab0eca89eac6738fff6664263500f2b23a1b85312f58351b078bfabd3ab8517e383900cc23a4d9a8fdb0a5ae691bd0023751d707cd5ababe78100ade4bcc1691182ef8a6086be7af4a0a62b52d7a5940dea3332f3c63c37814cba5afb4380c5c3ee3920ef5de5484c1961a98430c2820c10e66f5bd143c35562d6b5f1bd6d0a256f4afb69641a3d8c871f5caa98fa6a1c8f31e252726f5fb9f5f444f60b32fcf94ba5e077c9724d36246ec666d767cc1f0befe534aa028faf6181644d6774e4e14f600a5657b3e2f6287115317f678c13357844009932b0b873101c362a9ee9fea643412da278256377c345e3f409dc1db60e215fc52c5af9d1b5045473f2f06bb20399de3cde3ce877ba545b994f3327c359cd987e9f2d05f015974e1b18b98b8f9684a24b0a50441244333bf5a35a023036aeb27f556ca1e93dd351651594c723239a7c0cb15b8ab7a0446ba789ff17e4fcbe1d017009100203f39e446d7b686e30fce3323ef61d46bc956143947c", + "30618669fa4f387a7e9fcbf763bc0dc9908cf927d1f92b585ca17d46b7e97fd902acc05526844e174394b69b1e0b78d24f7b5bd0cfadcb6a33aa6dc090d9028f160c5af4494850ee7590972d0efda781e2879e76c807a16dd60ede657e0be6a8230f495774d31e8b73bf7ce73e6f87826d7a59e1c47b508d5f953a61c2b4939f0492560c98f9feab356c744c09f1ec80f5fc9cc579f9929a3c7d9046585431b7273a1175635e2ab1f1b63838c13bd9d1daf4dad2620a0e72beae5f66ab88acab0f0887388fbcfeed9d128b7324b47676549d378c55d6d28b80cc179258a2801711423de6d1555acffe946eebaee182f8d007d5bafea10c7e00236552de1c68b32b74c50fe814021736df034cfe502673b483baa8f12825b9c7f74c59943ca53516196e1e69cee3dc1a0ceebcd6163c57f0155afb41d78aac57966a2681fccd0229b85e084727db2843d66cc73e163875ae0cdf5ce9386bd6b2be7018476d460625bb91869e1c2453109ba45cda0fa3f4ba9b8186df72098e81ca6f131140d8b0", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000103aa4b2aeff1bc7afc5cd39952c872c8f29d64188e8d18c1b65e526d6277a33209854e0ac153a98eff0fd08a0c73d46dbbe4209f8a6a4f2aad914e40686f4720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ef4aac9b7954d5fc6eafae7f4f4c2a732ab05b45f8d50d102cee4973f36eb2c23db7d30c99e0a2a7f3bb5cd1f04635aaea58732b58887df93d9239c28230d282bd99d31a5054f2556d226f2e5ef0e075423d8604178b2e2c08006311caee54f0f11afb0c6073d12d21b13f4f78210e8ca9a66729206d3fcc2c1b04824c425f200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "06236320cf783a01e2b8be7816a84671de9e8bebda0e8f957809ee1253565bae0a4ce1ac405b9974e4eaf9342c2a43bd1fdc4edc2bd18235249bf51ec43287440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "24ab69f46f3e3333027d67d51af71571141bd5652b9829157a3c5d12684619840f0e1495665bccf97d627b714e8a49e9c77c21e8d5b383ad7dde7e50040d0f622cab595b9d579f8b82e433249b83ae1d7b62d7073a4f67cb3aeb9b316988907f1326d1905ffde0c77e8ebd98257aa239b05ae76c8ec7723ec19bbc8282b0debe130502106676b537e01cc356765e91c005d6c4bd1a75f5f6d41d2556c73e56ac2dc4cb08068b4aa5f14b7f1096ab35d5c13d78319ec7e66e9f67a1ff20cbbf031459f4140b271cbc8746de9dfcb477d5b72d50ef95bec5fef4a68dd69ddfdb2e2c589584551d16a9723b5d356d1ee2066d10381555cdc739e39efca2612fc544229ab0abdb0a7d1a5f0d93fb36ce41e12a31ba52fd9e3c27bebce524ab6c4e9b00f8756832b244377d06e2d00eeb95ec8096dcfd81f4e4931b50fea23c04a2fe29605352ce973ec48d1ab2c8355643c999b70ff771946078b519c556058c3d56059a65ae6e0189d4e04a966140aa40f781a1345824a90a91bb035e12ad29af1d1459f4140b271cbc8746de9dfcb477d5b72d50ef95bec5fef4a68dd69ddfdb2e2c589584551d16a9723b5d356d1ee2066d10381555cdc739e39efca2612fc544229ab0abdb0a7d1a5f0d93fb36ce41e12a31ba52fd9e3c27bebce524ab6c4e9b00f8756832b244377d06e2d00eeb95ec8096dcfd81f4e4931b50fea23c04a2fe29605352ce973ec48d1ab2c8355643c999b70ff771946078b519c556058c3d56059a65ae6e0189d4e04a966140aa40f781a1345824a90a91bb035e12ad29af1d24ab69f46f3e3333027d67d51af71571141bd5652b9829157a3c5d12684619840f0e1495665bccf97d627b714e8a49e9c77c21e8d5b383ad7dde7e50040d0f622cab595b9d579f8b82e433249b83ae1d7b62d7073a4f67cb3aeb9b316988907f1326d1905ffde0c77e8ebd98257aa239b05ae76c8ec7723ec19bbc8282b0debe130502106676b537e01cc356765e91c005d6c4bd1a75f5f6d41d2556c73e56ac2dc4cb08068b4aa5f14b7f1096ab35d5c13d78319ec7e66e9f67a1ff20cbbf03", + "1147057b17237df94a3186435acf66924e1d382b8c935fdd493ceb38c38def7303cd046286139915160357ce5b29b9ea28bfb781b71734455d20ef1a64be76ca0daa7cc4983cf74c94607519df747f61e317307c449bafb6923f6d6a65299a7e1d48db8f275830859fd61370addbc5d5ef3f0ce7491d16918e065f7e3727439d1ca8ac2f4a0f540e5505edbe1d15d13899a2a0dfccb012d068134ac66edec6252162c315417d1d12c9d7028c5619015391003a9006d4d8979784c7af2c4537a30d221a19ca86dafa8cb804daff78fd3d1bed30aa32e7d4029b1aa69afda2d750018628c766a98de1d0cca887a6d90303e68a7729490f25f937b76b57624ba0be14550ccf7139312da6fa9eb1259c6365b0bd688a27473ccb42bc5cd6f14c8abd165f8721ee9f614382c8c7edb103c941d3a55c1849c9787f34317777d5d9365b0d19da7439edb573a1b3e357faade63d5d68b6031771fd911459b7ab0bda9d3f25a50a44d10c99c5f107e3b3874f717873cb2d4674699a468204df27c0c50a9a0d7136c59b907615e1b45cf730fbfd6cf38b7e126e85e52be804620a23ace4fb03e80c29d24ed5cc407329ae093bb1be00f9e3c9332f532bc3658937110d76072129813bd7247065ac58eac42c81e874044e199f48c12aa749a9fe6bb6e4bddc1b72b9ab4579283e62445555d5b2921424213d09a776152361c46988b82be8a7111bc8198f932e379b8f9825f01af0f5e5cacbf8bfe274bf674f6eaa6e338e04259f58d438fd6391e158c991e155966218e6a432703a84068a325439657498571ba47a91d487cce77aa78390a295df54d9351637d67810c400415fb374278e3f24318bbc05a4e4d779b9498075841c360c6973c1c51dea254281829bbc9aef33198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa1e219772c16eee72450bbf43e9cadae7bf6b2e6ae6637cfeb1d1e8965287acfb0347e7bf4245debd3d00b6f51d2d50fd718e6769352f4fe1db0efe492fed2fc324fdcc7d4ed0953e3dad500c7ef9836fc61ded44ba454ec76f0a6d0687f4c1b4282b18f7e59c1db4852e622919b2ce9aa5980ca883eac312049c19a3deb79f6d0c9d6ce303b7811dd7ea506c8fa124837405bd209b8731bda79a66eb7206277b1ac5dac62d2332faa8069faca3b0d27fcdf95d8c8bafc9074ee72b5c1f33aa70", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + ]; + positive_inputs.forEach(async (input) => { + const returnData = callFallback(ecPairing, input); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000001"); + }); + }); + + it("ecpairing_fuzz_negative", async () => { + const negative_inputs = [ + "142c9123c08a0d7f66d95f3ad637a06b95700bc525073b75610884ef45416e1610104c796f40bfeef3588e996c040d2a88c0b4b85afd2578327b99413c6fe820198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000092a62b029973fcd9ec18db33eb4c7b6b649a2e6196561761789e39bc84f11ac0a59f2672462be814a277f495d53244691c40da85d39b210ed3e099b397a4cf92ad603022931e8c20c927fa114866ca26b305156336511a9224d6bd88e5ba7fb2b44dd02df7f7a846f546c77f3330cc171abeea7747ec03607c4b754a07101421f4b96b82bd3631447045f1bb66198fa6a904e48092750762efd419fb5ff52b51fac61c1a7265d0e1a6433e9767cb51c71e9ac5a119be9894f509bf92b0fb1b4198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "104f6d8507d6a112e8fd516d70bfe3d2474539948276d36eee987be127a9e3ab199eef24146007e80386f391edc886f5ddba22b5cf131efa3b6ae71a673fc88e198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa2642f046ad222f094c9282816131317b8d52fc0fee64f26898232432d34fdae605a5f2a2e8f15ba27e90f54faff78391b307b402a0ae995d1c12f92c0b574593198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "1f0ab114f50077d71a195869dd8c07e2a031a55a8dac07c522ee7ac74136c50c229c9d498f5ca70a27612a244743773fe22668370a91410b645fe22f2e6eb78c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000284869d750e478e4b09637f7ae55bcce23bd622f04e986e1cba0f64b59b023200a88bc2898a2930aee2b92055ca2f97360a79c598f5e8998fed7add43a692d1021f4f3ddd5250962baaefc6ef587f464c8fdad1bb7812b292dce48d5462039df14044ca96015f3c6666f98d756fbf7bd0e12c3e884db4100391da8a47deff16e00b30c250f71db58eb20e14d67cd98ebb47790a7e7d45d30a90ce707175f295b1e45eca08667a7cfe06158fae4a38cac01a37853e730eaa28b2f7167fd74c22d", + "0624d2c76767981fadc8f74f29c034f7ae0522585e1e0201308109c40d1d5420251ba3c545339bbe22da0fe90692a099384c435ec0902c99be7e7a84d62bb49c0c0b524584214b17414a25236e4e2b6f4bf398ec62e9abeb7ea1f158d89df05b0e05f600bf1408ab25c0f3dbb98ff26c4d85a6ce6a63bebc3b2e360de77cf6062488eb90497d64621124420825abd353268fe00bd90726991d0ce623e59da9c62340b1fb006017382cb76606a873f48de8f31434cc243c8f465cb908d8cc734618cde0d7bde7e1da88fb8192ce94bea754f24a53f1f000f15b4c5c151c12df4f0066b16bf4229edf5375b78a5c7469ddf68f7d5c7577642ed2c90d5d42c231ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa2948734db775bb41a29257214b19a6356e6640894c2a48f201addce62de7b41e1bb87bddbe46d75809751232405928c3314934082052131a64574ff5a59c7db7198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa09c91a687e6c44f2917682dc5d0a34be7c77fff361aa36610effab6f6d2d87ac13849277ed76b58020ab993f1847ebcc0f1bcf711fba15f4a7a80ab72b4fe9642f0c63d0c53b3dfbca27b6b43ae7fbf55a38d78a21470996485b03128accc20800556502356e37ed150db2e36531b0f275fd6835c0fc1945922e270b48c48a8602644c27b5dbd793592a70b735e22c798a5e309fa17a992a7dc2a050e01b298f194776b6a53439d7336f389d2a8f6651e40885f5ca2538b0dc9cb534fb23f7fa1e379e19dbffba1edf0a04505f67229e707a4b82f19285d3c186964e83e1553608ee58baa16641b1513f007da7d3cf58b503b80f73c7d8e792db63def167e0d82b1f95d6aa6fd6f5e6978d0135c206079770d5c3ba001967c5d94c5902f95fe9264ad64952cb1d30a7230bca35b3907b2457abdcd6052e14e2a132d76822222514f79ce35164acfdb802551e02a9aebdb20bf4248c0ccf5c6cf5e576908778410f8dfb99aaa272bbaa49012da81dfafa1a3c07eba89355602143c58f63df2939117a8203a67ab052af18032434b61fe6b33e0a6ad5ab70d57aef4444478b42ba123a80e91f77c135f657e2dbf5af0d07e9a4fb63585b88e5439ddab7741c0961198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + ]; + negative_inputs.forEach(async (input) => { + const returnData = callFallback(ecPairing, input); + await expect(returnData).to.be.equal("0x0000000000000000000000000000000000000000000000000000000000000000"); + }); + }); + + it("ecpairing_fuzz_invalid_g1_point", async () => { + const invalid_inputs = [ + "00000000000000000000000000000000000000000000000000000000000000000000000000be00be00bebebebebebe00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000ffffffff0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca71ca8d3c16d87cfd450000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000ffff7d7d7d7d7d7d7d7d7d7d7d7d30644e72e131a0297d7d7d7dffffffffff00000000000000000000000000000000000000000000000000000000ff7d7d7d7d7d817d7d7d7d7dffffffffffa100000000000000ffffffffffffffffffffffffffff7d7d7d7d7d7d7d7d7d7d7d7d30644e72e131a0297d7d7d7dffffffffff00000000000000000000000000000000000000000000000000000000ff7d7d7d7d7d817d7d7d7d7d827d7d7d7d7d7d", + "0000000000002900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffff80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000fffffffffdfffffe2e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "30644e72e131a029b85045ac81ec585dffffffffffffffffffffffffffffffffffff7d7dffff7d817f827d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d767d7d7d7d7d7d797d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7f7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d8d7d7d7d7d7d7d7dffffffffffffffffffffff01ffffffffffffffffffffff747d7d7d7d7d7d7d7d7dfd7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7d7dffffffffffffffffffffffff29ffffff0affffff0a", + "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f00000010000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47000000000000000000000000000000000000000000000000000000000000000000000000ffffff000060bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad0c693395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "25a78fa05de3e5f7c69f35ab209d6595697e8664c3572a57ea0c971fe33532ed0bc38b0a2d9961cf8d392de63be18471ffaaa192111cd8adccc98b7d790b61140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008013e823575500fffffffffffffffa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "2dec711c75595613e8f7e4723c19f6e69be2ebafe07e965a001f4fa00a41eecc10246180d145035dfe0e334a8e1f4274a189b8dde0b2cc683cddfd9cae9b634b198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffff0f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "30644e72e131a029b85045b68181585d97816a916871ca8d3c208d16d87cfd4700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "0a12d3fb2743836bbbb51414a351e5e70429a5de70c0fe7cec084e47d6027709006a8c414196abf21da0b3f6944846c77a1032b519baa1abf125f4f84010c47a250f9cf43675bc1077753c607600f3e51b627a10f3aa68a7e462d89a6bd2a21312ae5d695c4f9792cf70228a1ba07e5e0c2cb47d7aecbae923a84a3734a94ff10bdcd3d0b8e47a925f98bad0184dfe81967aaff8db8f0dfae31afccbcb8c4bd6148dff646f2764243ba9100a930eb7cc8c766b58e0d9953256698da5dbe66cc31f372b78747db898121455853a5672e71977957f134615fd0dd1fab4938b65e7201458c7d8ec49141bd3289f8cc4d19bb52041d51187432579e2e67cab27c847198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa2110e6d9f2378c1c1cd070a3f1507c3aa924a60f67259abe487621b0d3c5c38f0c26130b8aaa54109a5d82fbb2782b9ed461a4b8faa69341ccf652d2f73e188722f1acbb03c4508760c2430af35865e7cdf9f3eb1224504fdcc3708ddb954a482a344fad01c2ed0ed73142ae1752429eaea515c6f3f6b941103cc21c2308e1cb159f15b842ba9c8449aa3268f981010d4c7142e5193473d80b464e964845c3f80efd30ac7b6f8d0d3ccbc2207587c2acbad1532dc0293f0d034cf8258cd428b300710c68e1b8b73a72a289422d2b6f841cc56fe8c51105021c56ae30c3ae1aca0b2ff392a2fc535427ec9b7e1ae1c35a7961986788cf648349190dd92e182f05198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daabebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebefdbebebebeabc689bebebebe43be92be5fbebebebebebebebebebebebebebebebebebebebebebebe9ebebebe2abebebebebebebebebebebebebebebebebebe", + ]; + invalid_inputs.forEach(async (input) => { + const call = callFallback(ecPairing, input); + await expect(call).to.be.reverted; + }); + }); + + it("ecpairing_fuzz_invalid_g2_point", async () => { + const invalid_inputs = [ + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffff0000000000000000ffffffffffffffffffff", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d00e9ff0000000000000000ffffffffffffffffbfffffffffffffffffffa120000000000000fffffffffff7ffffffffffff000000000000000000000000000000000000000000000000000000002d0002ff0000000000000000ffffffffffffffffbfffffffffffffffffffa120000000000000ff007d7d7d7d7d7d7d7d7d7d", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a0294fafba497e1ec6d18c48814a69000000010000000030000000cd71ec682d26313681ea8a1a9a410c862cc44a5d0000000000000000000001158d600a2d8411f2e9bd1a1b51eac64e43b0c511f2e9bd1a1b51eac64e43b0c511fc9ba8b80b727a2c28ee454fc286fd659262c510a3e7f11a4b0e4b74bebafc", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d00e9ff0000000000000000ffffffffffffffffbfb2ffffffffffffffffa120000000000000fffffffffff7ffffffffffff000000000000000000000000000000000000000000000000000000002d0002ff0000000000000000ffffffffffffffffbfffffffffffffffffffa120000000000000ff007d7d7d7d7d7d7d7d7d7d", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f8ffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffa10000000000ffffffffffffffffffa100000000000000000000000000000000000000000000000000000000000000000016c46ebe0077418d002f28e20236919ad92313729f18578ba8547626478ea52c2b5b688b4d8078d1e1acd7acc7be7f9e0e30812ce2925b35559213646c93237f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000fb55bf7df894a746fbe20b6f8c54d0dc0d9fd4ed005174a42fc3c45e6e27f912a20d63d446eb175733853b88dd36708eb7a81f5c79e7659c3a6e2b2c470077005ed60ba723a2dd3a5fc35520f982963de61e3b563636fe6996cc2c3008035720ad16f835a46faca48c6d39ae00a10d3514e93ae3b946ee2f009ea2dccff97e198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed09068950585ff0759e99ecad6903000000000000000000000000000000002c000000000000000000000085b7aef328c21800deef5e0000aa426a00665e0000aa", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8329a0d6d5e7d14a774c3abff1435361da2ee5d8b4f3ee62085ce779f248b41d4a2fd37ae5468f6a17b7f9a0bcca02ee128bdced61402a566e4eee2d0fa825f03d198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47000000000000004500000000000000000000000000000000000000000000000107b55de1642362d16b8fc4dccfec9e794d24968511cf8e252ed27afc4d72ca1e0301cb4d7e0b7b52a6a8f78613c403ead1543fedb0d3f28c77685fdb9eaa27420cdc335fa81dff303b71cffb0256d7097c2b4c6715ca7b1589ea9386a41c2f851223d6bb1f3e68ddfb08f4c95f590f99227fb681a3b0abdf685cf12bde37d8ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000001f1cd7f247f2ae1ba9a1aeb4b32ed4c8c13c70c8861b6ab5340e276c58e1046b13d7de2b557e0ae2b53380ad596ba79f07c037c9d9aa17cf407e9ed86201436e", + "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed95bc4b313370b38ef355acdadcd122975b4b313370b38ef355acdadcd122975b120000c8db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1", + "2a4f1dbc9fe6d2882462fb11afeae7b7f2a0cf213b1f19c45cb222336283f3801141763c897c9a90e387ea80f68eb88c2d79aab680196d9538cd2ca632a5e81b0e540f5b5be91f82ed05349750761224f543068ce30d2d5e838bf66866f345200fa5ac8c46f725e54505019bda3356ef6e35b0a89b9b4f79bb0c62211235c9312e6d97a1f7e0428fc0be6be02c811095f5166710dcbe869c36a8ef89cac63e012657bbaf3bcfd106dd677eef03172f693a6c919776f441dc0fd47a4bd91d0487225fdab8fe6cd876363d27075cdf0d01c209da61b1634b574a5d811cfae407001216b7c3e2adc07c3bef31771c7bb9e1d02f07ff3a5b74953c4fd5bf9a7a6dff25f63fcc543337b8f6275f97d6479633b921541a96ac1bc2aff2e0905db7407c206776f9480168741eca625c06e5526b4664a02ce664bc656f39664d96278b6e1e40e8084fd648ba315f691e8367be1d4c13844421c87223d84829c31a0d7afe24b8042d4cb604ae66c0dc97ca8a9c2d22c743335d92bc401700f6b00d5cdc5b", + "2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc0203d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db841213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f06967a1237ebfeca9aaae0d6d0bab8e28c198c5a339ef8a2407e31cdac516db922160fa257a5fd5b280642ff47b65eca77e626cb685c84fa6d3b6882a283ddd1198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2e8ff2110ede0e189426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd216da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb314a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee2459000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000b4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + ]; + invalid_inputs.forEach(async (input) => { + const call = callFallback(ecPairing, input); + await expect(call).to.be.reverted; + }); + }); + + it("ecpairing_fuzz_invalid_g2_subgroup", async () => { + const invalid_inputs = [ + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000070a77c19a07df2e666ea36f7879462c0a78ebbdf5c70b3dd35d438dc58f0d9d0a2dd5b476a606a8243e7e879bddaa8086ba658087aacc4d986a10c74dd9e7742d46618f9d516e0f07a59d3c97f5e167a1b49ebe9fb30dd05bded8185a545420", + "000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb43", + "0a96696a78e6818da746c504a8b83f7a3faea0dfee0a2c52751f3cfae5fe979b017a319dce2d1976671eddd5b909781c102e5eed5c40db00bdbd19a14397b889198e9393920daef312c20b9f1099ecefa8b45575d349b0a6f04c16d0d58af9001800deef121f1e76426a00665e5c4479674322d4f75edaddde46bd5cd992f6ed05a7a5759338c23ca603c1c4adf979e004c2f3e3c5bad6f07693c59a85d600a922376289c558493c1d6cc413a5f07dcb54526a964e4e687b65a881aa9752faa2", + "111f95e1632a3624dd29bbc012e6462b7836eb9c80e281b9381e103aebe632372b38b76d492b3af692eb99d03cd8dcfd8a8c3a6e4a161037c42f542af5564c41198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b924933879", + "17956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800104e75a20b641566a0c71c9069a5256391aa31e22021d36c037c108dfb79c66200bf257ae3d66a589214f980a2ae34f9544be2fcbcc13b21f4c1642f31aa4d200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800104e75a20b641566a0c71c9069a5256391aa31e22021d36c037c108dfb79c66200bf257ae3d66a589214f980a2ae34f9544be2fcbcc13b21f4c1642f31aa4d20", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000012ab9bb0c853fb1d884197cdefdf654c01a289b677094fe609c835d2b249dcc51460243cc357281001b8b257c6396865c729761ac575a85b2f8f0e58af439c84000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000fb1b0e8c8b85ec99ebedae0880006b0809f5151890cca524eea2c0b3ad87f3229d3e6bc7f0886b75e186b10564dc990258855e0311e3e2e72f9d9c0dfab4f0d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000fb1b0e8c8b85ec99ebedae0880006b0809f5151890cca524eea2c0b3ad87f3229d3e6bc7f0886b75e186b10564dc990258855e0311e3e2e72f9d9c0dfab4f0d", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000114cc34c5044c87540b942287d555ce935499ce155202081ca5ce495c356896009fd9490a6f214b7729f9574d53fce82a2d46b3ccf7499ab5616b2c4f36582d7000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000192b7e3a0ca8b63592989fe8b2589465703315272bc730644e72e131a029b85045b68181585d00001b86b77538000000000100000000128a694e7017ae1db6a312c9ef648b1a4910a41e684cb554302044a2065f04680df2d76a91278279cf401d431c31876ee9c8ad35070694552ccbd368755413830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000192b7e3a0ca8b63592989fe8b2589465703315272bc730644e72e131a029b85045b68181585d00001b86b77538000000000100000000128a694e7017ae1db6a312c9ef648b1a4910a41e684cb554302044a2065f04680df2d76a91278279cf401d431c31876ee9c8ad35070694552ccbd36875541383", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005b000000000045000000002a00000000008000000000000000000130644e72e131a029b65045b68181585d2b0d3025c6abdbaa75ef4d163a7cfd4017c66e1806ece8d631d792f8cbd8bdf7514a9058c183a3b2fcda7e86c44b7752301a6a722cdc812165b619f3cd2b21250d7f7083d0b984fdaf8636202e4ae0470000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d2b0d3025c6ab2eb4fbef4d16d87cfd4000000000005b004500000000000000002a000000000000000000000000000001109beddbaa84026c8f71d34a485af27fe418028129b55b0a0df51e3dba2310021aea54403ce01876467152aa79ca1f227b6b1e0f95b56cb0537583190252556d", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000fb55bf7df894a746fbe20b6f8c54d5dc0d9fd4eda4742fc35100c45e6e27f912a20d63d446eb175733853b88dd36708eb7a81f5c79e7659c3a6e2b2c470077000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff00000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000fb55bf7df894a746fbe20b6f8c549feddc0dd0d4005174a42fc3c45e6e27f912a20d63d446eb175733853b88dd36708eb7a81f5c79e7659c3a6e2b2c470077", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ea1146af1a0c4df0000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000015d42e5a1c18703100bef65a743007bead1fc389b7d8f0a8ccda34b7d30620cb1c4156d243211b733af4f4fff11b9c0928308bf3c3102415e3105b986166d0cd00000000000000000000000000000000000000000000f8ffffffffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000249409822e0000000000000000000000000000000000000001154baf30644e72e131a029b85045b66ac4175696816a916871ca8d3c208c161a46c432126f44fab27034ba2832173059ebf31a96607ada20f006b4f12d4a8bad410d8f02eee77897359cfc599b6ca4e8c2a47f641fc0cd6d4146d8eca263a85c7aa36500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b92493387900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b924933879", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb43000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb43", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb431a3cf0c503b2dbc6e1b0f8aea605de20d8612fe14627c6f4d3706f8272a1cf842a0bb098018ca4392a1ddc08b9605602aed954308944ac729e2f99bfdd0166dd0000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000024b364d16400886c82900af060fd117cb2f4e0b93590cbf6ec34ed97f4c391ec26a10e3233aeff776d578de9178a9b7bb919e6eb6cf2cf924eb16ec8dc659af9", + "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b05040ff00000000000000000000000000000000000000002e00d573b028b22b9d347da8044a53c94b6c3aee7d9bfb00ab2c0a10eb4775e619e1a75be1c5d39a105504a0e5d16c949524742dde6bbb6e831668fef921a1430000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b050ffffffff585d97816a86b77537dafbef4d16d87cfd4500000000005b00450000f400000000002a00647d903b504c1a020000000000012db3d49da56012cf4f73cbf19fdb59ef41356cebb4f4b6f692f9a38fb282a9ff2d96db5d24dcea418a44feae6052fbc7788e65e521b17232666818386252176a", + "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000107b55de1642362d16b8f25dccf30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d800000009eae594f627b7ccf496d680f0266e7364f51d2d99ccd69801f29137d889e1e006ea1409d3f9bb38bd40e8da0701d122e059a02fc3c3c4a99a8cbf6e4290bdc0000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd450000000000000000000000000000000000000107b55de1642362d16b8f25dccf30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d800000009eae594f627b7ccf496d680f0266e7364f51d2d99ccd69801f29137d889e1e006ea1409d3f9bb38bd40e8da0701d122e059a02fc3c3c4a99a8cbf6e4290bdc0", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000005b00450000000000da76b36b83c72830000000000000000000000830644e72e131a029b85045b68181585d97816a916871ca8d104d5b2baf5734631b8765e7f5163862fcd3bc29f751af42d869a0c8a329f5a53472d3c977038bb7068cd6bc298bd1ec695a49e1db0620332f26e03a4a0ed9076973c1fea43099f2000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000005b00450000fc00000000002a00647d903b504c1a0200000000000130644e72e131a029b85045b68181585d97816a86b77537dafbef4d16d87cfd450125b8edede9e4f320e4dbfd7ee46d23a82508c3b44dbb99cb29724daaa5c5602d663cc48c6d7469cc9df0e861f3a9b93239af8001f8ecf28b4572f201ef1369000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a86b77538dafbef4d16d87cfd4500000000005b004500000000000000002a00647d903b504c1a02000000000001247f1f6fbf2fe1fff7e28d816724080774979f57692c2fa8569ea1a3ce52dfc51f5c96f77d84ae24b701a32ff1b8d95b982c76bf5ab02e605c9ba4fa9f45b958", + "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002012cd187faae3648a35e12cc197ddb26d9d3a44a625d97816a86b77537dafbef30644e72e131a029b050ffffffff5802086325c1129ad4a34ebb48ee9634016008aef33d9388c8f993f0af340e047c1c9519d222062186f7b025291b6f6f4ef2293f1064b0e3345895dc4968bc8bb52fcbe960621c1f15cd7c693c7347078e32000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45012cd187faae3648a35e12cc197ddb26d9d3a44a625d97816a86b77537dafbef30644e72e131a029b050ffffffff5802086325c1129ad4a34ebb48ee9634016008aef33d9388c8f993f0af340e047c1c9519d222062186f7b025291b6f6f4ef2293f1064b0e3345895dc4968bc8bb52fcbe960621c1f15cd7c693c7347078e32", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b05045b68181585d97816a86b77537dafbef4d16d87cfd4500000000005b00450000fc00000000002a00647d903b504c1a020000000000012c32d7465b0607cfaebe0b13577b25e42fe6d9e49eeb9d5c0ca78cc17e114cbc2cd71c8288ebbd272a784c5b4921128cb68e9e2ddaaec0595b266126c4e526bd000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b05045b68181585d97816a86b77537dafbef4d16d87cfd4500000000005b00450000fc00000000002a00647d903b504c1a020000000000012c32d7465b0607cfaebe0b13577b25e42fe6d9e49eeb9d5c0ca78cc17e114cbc2cd71c8288ebbd272a784c5b4921128cb68e9e2ddaaec0595b266126c4e526bd", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d97816a86b77538dafbef4d16d87cfd4500000000005b004500000000000000002a000000000000000000000000000001124ca5dc43ed1e22d1c616b50a7d4249a012c1d65330ae8e4cad70567c8231bb23f9415fa570e58e0ac61e4e6e7a6bd02a564f6b206a9d4645401b1d677bf3ab000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a86b77538dafbef4d16d87cfd4500000000005b004500000000000000002a000000000000000000000000000001124ca5dc43ed1e22d1c616b50a7d4249a012c1d65330ae8e4cad70567c8231bb23f9415fa570e58e0ac61e4e6e7a6bd02a564f6b206a9d4645401b1d677bf3ab", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d97816a86b77538dafbef4d16d87cfd4500000000005b004500000000000000002a00647d903b504c1a02000000000001247f1f6fbf2fe1fff7e28d816724080774979f57692c2fa8569ea1a3ce52dfc51f5c96f77d84ae24b701a32ff1b8d95b982c76bf5ab02e605c9ba4fa9f45b958000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a86b77538dafbef4d16d87cfd4500000000005b004500000000000000002a00647d903b504c1a02000000000001247f1f6fbf2fe1fff7e28d816724080774979f57692c2fa8569ea1a3ce52dfc51f5c96f77d84ae24b701a32ff1b8d95b982c76bf5ab02e605c9ba4fa9f45b958", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d97816a916871ca8d30140b193f92396c00000000005b0045000000000000000000000000000000080000000000000001301a8b8043356b83c4341d5e9cfc67071c61c0b053ec979b59ad8c0455b71c9815f88e8c709168c1ab898ca5288423b585331497f16b2c074dcbf76c2480e8c9000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d30140b193f92396c00000000005b0045000000000000000000000000000000080000000000000001301a8b8043356b83c4341d5e9cfc67071c61c0b053ec979b59ad8c0455b71c9815f88e8c709168c1ab898ca5288423b585331497f16b2c074dcbf76c2480e8c9", + "000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd452b0d3f819fd0046aee4d0e54cc759ad714c473bd5f86a0d68df977f7450390f730644e72e131a029b85045ae0000000000000107b55de1642362d16b8fc4dccf2a5c3a27c4a417ea34f627b9481b9004e3b0ef59619daa16e846d8a152d6bf771301a8bb9c71966a4b557a21eea89447294e8a9cc1308f0c8eecb16dfbf5d53b000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45000000000000004500000000000000000000000000000000000000000000000107b55de1642362d16b8fc4dccfec9e794d24968511cf8e252ed27afc4d72ca1e0301cb4d7e0b7b52a6a8f78613c403ead1543fedb0d3f28c77685fdb9eaa2742", + "000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd0000000000005b0045000000000000000000000000000000000000000000000001112006831f3f0e121585c21cdf0aaf63f09728bcfee141bb4cd407caae7715e319df1e217ad7b1f874726c6683ab87b423c1737f46a54dc5356a9b617c6b9e28000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1", + "003db26a0b244fb3fd47f7f5f0f8a289e088fd932d340f0592696503fc62124824c9b9423ef04336563adc35604ba729a4c9e6104bfcb55517e3198b8edbdf981800deef121f1e76426a00665e5c4479674322d4f75edaddde46bd5cd992f6ed198e9393920d483a7260bfb731dd5d25f1aa493335a9e71297e485b7aef312c20b9f1099ecefa8b45575d349b0a6f04c16d0d58af9007f2c6d8bd7aa763a3b0e0b7c77862fe8d10d489a493a1a5c5d0f282c7d4e8148f340653c4b6297a1088f003db26a0b244fb3fd47f7f5f0f8a289e088fd932d340f0592696503fc62124824c9b9423ef04336563adc35604ba729a4c9e6104bfcb55517e3198b8edbdf98198e9393920d483a7260bfb731dd5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed2ba3e0cab22efbfef96e027f1a29ba7ec11a0f824024a3787d3cb8370b9eed71103ce48dac2e3ff691b61c7e4466adf35aa183aade7f15386bf7c789628b1b0e", + "0d1e4322f03fa0515f8ed6cb02b15e5a024b5092003dd7792d2ac055f14ac67d155c53a1daa56e3a5e9bd097cebfcd44038f2c606c8951310aae0ea01a44725300000000000000279573fbfe8e6c2300000000000030640472e131a029b85045255495ffba02a0ed6877a0a6ed4684235053c04cc3aaa05934e35bbb953673af0e1cec4c9d6d3921992e4c5c71523f5d097cde90f25b3e6c52c9c63e764a67870fe0cfe24e0b2f78d4f909c9131e3794fa911b1109df4a567b1423475cf409c1000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4700000000000000000000000000000000000000fcff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000212a3b4059e59d125dd17f662945170e1e13024fae97a401895690acac63cf681aecb67409d1d9c142ffd13375bd79fd0457deb278dfa91b5756378fb837fd60", + "0e474956b0fbc11ba65f3c7632afb3c66a98340871cee7c974db4461d8791b8d25410e545457af7bb0e9d2f1f8126180f11dec9bfcf69cd2934e6814741c9aa2231e75fddf7e2fa8b38b7dd6fd13eb4b7046000000000000000000000200650000000000000000000000000000000000000000000000002546ac8393e836a2970d312fc0ac642c207b5b36e17990b4f7d0ef39cfe6f0d46b9c556a0b7935714b1e4cd9fd726048138dcdea456203d4b7414f3ba5ef7b37817aa98874d71c191f2e5efcb149c6a4914b8d85be71e79254f9fdf19f62de2b2f6cc0822e578a420f07fd874051cb395ca999e596047a25fc6bc12cba97dab578f9f903612c1c757f198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "102c9afaa6ac9d2553d0f47e2a945816f56b10014ddcc00ef63f5cda3d1431020db583622c614b32310911623e2f71f7871413d13dc372ace97f1813d2622d590a0e124cd6005b33c8a16492b1b451897b1679f44f3d288585ec8f82b49f6f501579cd1aa3fb1bf108c6b7b5d1f4ae1fae44099a8bf5fddc74d87665e29812ba0d5db514ca1c318cc409bcbf9a75055b1a8e7b783127734d902b6118b518ee962f24a2abda945e843c6952a5f0632365146cfd4e2034b70e41a78772fc404bea102c9afaa6ac9d2553d0f47e2a945816f56b10014ddcc00ef63f5cda3d14310222aecb10b4d054f7874734544351e666106d56c02aae57e052a17403061acfee0a0e124cd6005b33c8a16492b1b451897b1679f44f3d288585ec8f82b49f6f501579cd1aa3fb1bf108c6b7b5d1f4ae1fae44099a8bf5fddc74d87665e29812ba0d5db514ca1c318cc409bcbf9a75055b1a8e7b783127734d902b6118b518ee962f24a2abda945e843c6952a5f0632365146cfd4e2034b70e41a78772fc404bea", + "11c8f0ea735e099781f852fb93256540c7c7611ba324f67680f3dbfc00bbdda12d7fb8d83e13afa4ea8a9d8817cd5b7c5b1804aa1006af2a8ab7e9c7757b300c040000002db3759aaff5357156bc2e8d52eacd11efb7d108d3b4034162839a9300000000003000000000000000000000000000000000000000000031000000000649ebc27a3909e089c6023c7ed952098a3e5547ce56e79953929ba4d718f1311c2c7e752e7947b506c14a8300a0d15d9022bd6fba67461cc8a0783dfeba77fb11c8f0ea735e099781f852fb93256540c7c7611ba324f67680f3dbfc00bbdda102e4959aa31df084cdc5a82e69b3fce13c6965e7586b1b62b168a24f6301cd3b040000002db3759aaff5357156bc2e8d52eacd11efb7d108d3b4034162839a9300000000003000000000000000000000000000000000000000000031000000000649ebc27a3909e089c6023c7ed952098a3e5547ce56e79953929ba4d718f1311c2c7e752e7947b506c14a8300a0d15d9022bd6fba67461cc8a0783dfeba77fb", + "12ca97e893996e5bb392c57abba4578276654d2856b336b640eafd84de31140e055370544625ea3c3e85a42831dcaf47353695b158149bc2d5bf4061326f089e0e80426227ce5fd647afba497e7ea7a2687e956e978e3572c3df73e9278302b9000000000000000000000000000000000000000000000000000000c451f8749a05602fde384569be9950c3466d0fb40a66a63f202c3a685856cd21c76cea2be70ed4f367e657bc59c785bf6bf6ac33fb4b653e8bd68d1d838e0416e8c47b5f5312ca97e893996e5bb392c57abba4578276654d2856b336b640eafd84de31140e2b10de1e9b0bb5ed79caa18e4fa4a916624ad4e0105d2eca66614bb5a60df4a90e80426227ce5fd647afba497e7ea7a2687e956e978e3572c3df73e9278302b9000000000000000000000000000000000000000000000000000000c451f8749a05602fde384569be9950c3466d0fb40a66a63f202c3a685856cd21c76cea2be70ed4f367e657bc59c785bf6bf6ac33fb4b653e8bd68d1d838e0416e8c47b5f53", + "1425b11b4fe47a394dbfc0ad3e99dc93c3e1c0980b9bcb68529ba9de33dbf585168b8cdff7ae7d084fd111608fa03e018b415fd4f0755f7e8f039a2d852bda0e0000000000000000000000000000000000000000000000000000000000005b00149bb18d1ece5fd647afba497e7ea7a2687e956e978e3072c4fc9ec579b809462061ebaffaedc532d8bb542f9d93cae5dc6c4b431833ee0a7be4d053e2e0d60d03c12e282e4442c88f5235d004e8edba3080754ca41c976d03cd332a9b6fa42d1425b11b4fe47a394dbfc0ad3e99dc93c3e1c0980b9bcb68529ba9de33dbf58519d8c192e9832321687f3455f1e11a5c0c400abc77fc6b0ead1cf1e953512339149bb18d1ece5fd647afba497e7ea7a2687e956e978e3572c4fc9ec579b809460000000000000000000000000000000000000000000000000000000000005b0029e864b516b661105d0a2708f21beaae1bf1636608ac53864c4d8f0ea2e7dc3805c3b957caa8f4c5f248e3e6e754304e9ba7e5b6dd3a4ece125f47811a525e65", + "1565586940bbb0e082639a1e2c9ecfe96bff6cbda25a93c4d462b8360230067219767d96dd90432f459bf8f6181c9fea507bf7bcd4063fd070fe8e72093e8bf900000000000000000000000000000000000000000000000000000000000000e8000000000000000000000000000000000000000000000000000000000000000023812d70e97cfd777c5cf0b64b18400f3ea88afb56146bfc1f34071eebb0599827352c710f0e1711b5d18e672b5cab3c369cd8d84b70ed159bb712c7d929c8e51565586940bbb0e082639a1e2c9ecfe96bff6cbda25a93c4d462b8360230067216edd0dc03a15cfa72b44cc06964b873470572d4946b8abccb21fda4cf3e714e252b5ec0e7df7df26d0cc46dd811ace847a4174aa634c8d9269ccebb52845d7829a0fe67466554bc0a6c97089dec1ebac672344bc3a69b8fc6904f9b83438cbb24c159cda85a7f7e04f7e128101e8fbe502fee784946ffce0a9174424f0254b22b0c8ac28082e97eae5ee175ae2c1a6e466c7dd693238a386ec80f7743ffc517", + "17ac723d48c98fce706845b61c254630acb6da96a9620fc6cd07276a4ef8936d1a515b7e403d2a46bb5387138f17d33c2b12e3d5051f9d22042921f35031035e000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d8ad25dc006eea79b9c052a6a367b209d5c9215c8a4c325555a7e1e608abed022dd54ed23382326a8df674c7be35d7ac181c9625a10f508dd7fbd109760d76217ac723d48c98fce706845b61c254630acb6da96a9620fc6cd07276a4ef8936d1612f2f4a0f475e2fcfcbea2f26985216c6e86bc63522d6b37f76a23884bf9e9062ca96b10a86be7bc151a74e01170193f2ad046c2f5eb3a25a95592cc3a17752043c18fe0a47868239575b1c3700be7308890370eb6982f4e3e36916ebc28f52b7d22180be2bdca69028c5bf32181d203b2350781d675098b320766f5dcd9b02a21aa3010f604fea531e9264671d546cc94d8a0ddab42b7146573f5c1ed26fb", + "1c4189bbfe590521da71e6834b73a622528fd923e9421f18df9a48e9123b16aa15c8e4948927f2e089accb33c8d51b4c83ca69505f4a7801399573273d7439910000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800023ad956e40f22f18bf59310f6d23055f2a3fdc2713f05cf1b099a18041cd498220b15bb64c3c6223098439e4fc7e9b2bd956ed94b2bf1f066c281d41c8560ee51c4189bbfe590521da71e6834b73a622528fd923e9421f18df9a48e9123b16aa1a9b69de5809ad492ea37a82b8ac3d1113b701410927528c028b18ef9b08c3b60000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800023ad956e40f22f18bf59310f6d23055f2a3fdc2713f05cf1b099a18041cd498220b15bb64c3c6223098439e4fc7e9b2bd956ed94b2bf1f066c281d41c8560ee5", + "1c934d642c245e76eb0c016b17e8eced3a1cf56ef6d787eace40bc0cb933dea902567d6e1141f67673e6f17a705f3d9764c6d5673f1f93e2ed5a21fd38e9a572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007700000000000000000000001f3953d0d836a44e15aebef16dd187ccf9493693379fe7d1c5a2cf2deb87f89c0dd737c063475fc587c1574a8ff4e9e4f933118d67bb7ba4a70c79c1ccb0d3441c934d642c245e76eb0c016b17e8eced3a1cf56ef6d787eace40bc0cb933dea92e0dd104cfefa9b34469543c11221ac632ba952a295236aa4ec66a199f9357d5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007700000000000000000000001f3953d0d836a44e15aebef16dd187ccf9493693379fe7d1c5a2cf2deb87f89c0dd737c063475fc587c1574a8ff4e9e4f933118d67bb7ba4a70c79c1ccb0d344", + "1ced814234531c29aa14f95e3a3f59657aacea69fa4c35dfa5b8e03c87e8075725c3327a2c4f61437d53abbb2bb75dc1dc4f2427c3e9d7714d5d83dae80697690ec85b4f8a9224b27145b3757b7bf6e7397bc04c8634404d924689e27bb8a261000000000000000000000000000000000000000000000000000000000000bf890e717255b589c7286f7bde23fe6ac9d838262d9e7ba5bc603e410abf27aada5b1760bbdb5183ae4e28f049cfe75fb9600b8fd03e63d9aa1a9bd709d23afbc12f1ced814234531c29aa14f95e3a3f59657aacea69fa4c35dfa5b8e03c87e807570aa11bf8b4e23ee63afc99fb55c9fa9bbb324669a487f31beec3083bf07665de0ec85b4f8a9224b27145b3757b7bf6e7397bc04c8634404d924689e27bb8a261000000000000000000000000000000000000000000000000000000000000bf890e717255b589c7286f7bde23fe6ac9d838262d9e7ba5bc603e410abf27aada5b1760bbdb5183ae4e28f049cfe75fb9600b8fd03e63d9aa1a9bd709d23afbc12f", + "1f9d02fa71d0ae244edc79709af68216d99a978a5e8fd92ebe793fff8317aad42cd6a493d88a0a87a6f6818c23fa87ff12fd84e5641e1081e849f6e88a488a4304bb53b8977e5f92a0bc372742c48309445cd3cfa9a62aee49f8130962b4b3b9203e205db4f19b37b60121b83a7333706db86431c6d835849957edf0509de1521f544b5e4ab6d13dcb7e89582aaee12a8410a7c6b2d8a5de7bd83e8cdb1fb1a82baef43e095caaf7c2aca272aee277d1da98d74656f2ca01b833c67dcc08ca5d000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1", + "225fdab8fe6cd876363d27075cdf0d01c209da61b1634b574a5d811cfae407001216b7c3e2adc07c3bef31771c7bb9e1d02f07ff3a5b74953c4fd5bf9a7a6dff25f63fcc543337b8f6275f97d6479633b921541a96e0f2acaf901bc25db7407c206776f9480168741eca625c06e5526b4664a02ce664bc656f39664d96278b6e1e40e8084fd648ba315f691e8367be1d4c13844421c87223d84829c31a0d7afe24b8042d4cb604ae66c0dc97ca8a9c2d22c743335d92bc401700f6b00d5cdc5b2a4f1dbc9fe6d2882462fb11afeae7b7f2a0cf213b1f19c45cb222336283f3801141763c897c9a90e387ea80f68eb88c2d79aab680196d9538cd2ca632a5e81b0e540f5b5be91f82ed05349750761224f543068ce30d2d5e838bf66866f345200fa5ac8c46f725e54505019bda3356ef6e35b0a89b9b4f79bb0c62211235c9312e6d97a1f7e0428fc0be6be02c811095f5166710dcbe869c36a8ef89cac63e012657bbaf3bcfd106dd677eef03172f693a6c919776f441dc0fd47a4bd91d0487", + "22847a3cd1cb28b60a51b54991d6dd86d206aa12b3873942c45a120b2e63a49226c3889c7b08d9288f13f64e6e3f166c59f57b5c014cbecf815a4aba4ebabbfb2e91f2b0f4f7a42c870fe8f6236ec1042bdeb2586a641808a5e09019514e83a02b078a1f12cb5426b6bcfeb9548566afb4bdf7454190eaf97f63e210f3a94ce1008a9ede8dde2c849793027433d90c626bc326bdc248dc223f537f7152955dac00b319b7060ad49091d9b52015b4ae8085bf6739b7f5a2c098c2f113ff33806a22847a3cd1cb28b60a51b54991d6dd86d206aa12b3873942c45a120b2e63a49226c3889c7b08d9288f13f64e6e3f166c59f57b5c014cbecf815a4aba4ebabbfb2e91f2b0f4f7a42c870fe8f6236ec1042bdeb2586a641808a5e09019514e83a02b078a1f12cb5426b6bcfeb9548566afb4bdf7454190eaf97f63e210f3a94ce1008a9ede8dde2c849793027433d90c626bc326bdc248dc223f537f7152955dac00b319b7060ad49091d9b52015b4ae8085bf6739b7f5a2c098c2f113ff33806a", + "26581613e6c802822867d2b3a0867fd7fd8cea503764ae1a9d01ec0d5364d1be0530ae3d4fe87ac76da4382835135ac0aec9b1ecd0705cf84c21b48327eade5407a13e1be6f9072893c0e5bb528c5cc22dd6370308dda1613068e064c6e5d15a067239c795d2ea27b85d93e54fc221d81e9de3ebc8e43c20d63608e7078fab6822fa7ea234e21aec74f4db0b365ae1e7cc6e7f4aac89bc460d0308b83399be8627705b19388ebeddbd35a5ce72830ec07e3f1bca3f4e9fdc0aebaab5a1fe91b126581613e6c802822867d2b3a0867fd7fd8cea503764ae1a9d01ec0d5364d1be2b33a035914925624aac0d8e4c6dfd9ce8b7b8a498016d94effed793b0921ef307a13e1be6f9072893c0e5bb528c5cc22dd6370308dda1613068e064c6e5d15a067239c795d2ea27b85d93e54fc221d81e9de3ebc8e43c20d63608e7078fab6822fa7ea234e21aec74f4db0b365ae1e7cc6e7f4aac89bc460d0308b83399be8627705b19388ebeddbd35a5ce72830ec07e3f1bca3f4e9fdc0aebaab5a1fe91b1", + "28100e22df4dc1c6bf8801f63ffdef2af6bfb80147994395be6dc792479ca4f517414e05ac69d56dec03e0af314645b463414a7d831aff54459b6d409351a5a400002851fd14fbaa7fd586e3039a2d9fa136c42685cb2b5904bf0591b95b52fc000000000000000000000000000000000000000000000000000000000000000024d852a54e2d52ffc43b2e4f1993fd159ae7ec19af2f3ad548f6daa33bd0de310b0fabbc2f33ea444e5f3c92269f11fc30c048463973a914a6787dbd616e703e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "299a5917adb7b45c30cea045edaa623f5036280df176f4a2c751ca728c2c9e3a2bedf30ba7d8bd0814e9d091913ea5bc6a4b60ee993e949507832df60190651900000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000213d689af09b7f52ac4a04c34bcdb2f90521b1cd213edcfe48fa3063520b6be22ef0f3110ea3051248e907221493e6c2943ebe8d70794188a515ec23df5d9b2b299a5917adb7b45c30cea045edaa623f5036280df176f4a2c751ca728c2c9e3a04765b673958e321a3667524f042b2a12d3609a2cf3335f8349d5e20d6ec982e00000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000213d689af09b7f52ac4a04c34bcdb2f90521b1cd213edcfe48fa3063520b6be22ef0f3110ea3051248e907221493e6c2943ebe8d70794188a515ec23df5d9b2b", + "2deb529e45720f20be41088dfd7489c315e9e18fe23dd1c8a8183295dc770dee1090b3fcd1898780c332b7d73a602cadd1b26029124db9da19941250eda890b500000000000000000000000000ff0a69a42c284614e3d7de26b3f9b2f3c71ff600000000000000000000000000000000000000000000000000000000000000001e2c7f9d6a525b6af5dad683c5e6408661da29780860c3209b2dddcad5a88795033123665850406fc2428227bbb3509fc71c911cf41623de1605cd3e0a281b902deb529e45720f20be41088dfd7489c315e9e18fe23dd1c8a8183295dc770dee1090b3fcd1898780c332b7d73a602cadd1b26029124db9da19941250eda890b5000000000000000000000000000000000000000000275680008ded35ba000000000000000000000000000000000000000000000000000000000000000000000019367fe97b92d85d7c29090c2313de1a85f030239cfa71f939a197249cb17b890465a8498153883aca20e4de66ac02b1b6957fab9b4bce71df334cd6bee5ff95", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b92493387900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b92493387900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b924933879", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000005b004500000000000000000000000000000000000000000000000830644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d81702c919c023ce224a0c0b121dd4f578b39e0ddf00a55580b03265cb32fcb623bbf778240f6bf16b9a25500a02b09fbe8abfa933f9ee09effb104d712baf573463ef8c000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000830644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d81702c919c023ce224a0c0b121dd4f578b39e0ddf00a55580b03265cb32fcb623bbf778240f6bf16b9a25500a02b09fbe8abfa933f9ee09effb104d712baf573463ef8c000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1", + "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd450d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000230644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5", + "000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45000000000000004500000000000000000000000000000000000000000000000107b55de1642362d16b8fc4dccfec9e794d24968511cf8e252ed27afc4d72ca1e0301cb4d7e0b7b52a6a8f78613c403ead1543fedb0d3f28c77685fdb9eaa2742000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45000000000000004500000000000000000000000000000000000000000000000107b55de1642362d16b8fc4dccfec9e794d24968511cf8e252ed27afc4d72ca1e0301cb4d7e0b7b52a6a8f78613c403ead1543fedb0d3f28c77685fdb9eaa2742000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45000000000000004500000000000000000000000000000000000000000000000107b55de1642362d16b8fc4dccfec9e794d24968511cf8e252ed27afc4d72ca1e0301cb4d7e0b7b52a6a8f78613c403ead1543fedb0d3f28c77685fdb9eaa2742", + "0272af94b7aeb772c1666db65ff3987fd8ec43b8454aad395232b5eef18ca2c51d5fc6b50ef577096ec2489356e8ecccd5ed5a144928c5338af5549701dbb40d255495ffba02a0ed6877a0a6ed658c93a1487a3319aaa05934e35bbb953673af00000000000000279573fbfe8e6c2300000000000030640472e131a029b85045090d17c2eaeda0d61dd0442997d161e176fb98a27091fe8b6b5746fe2f344a0f26f1f16556d24506af1fd1c8cb4b3b6dfa73e2ce958c50e3b937fd59a1df623f0272af94b7aeb772c1666db65ff3987fd8ec43b8454aad395232b5eef18ca2c5130487bdd23c2920498dfd232a986b90c194107d1f490559b12b377fd6a1493a255495ffba02a0ed6877a0a6ed658c93a1487a3319aaa05934e35bbb953673af00000000000000279573fbfe8e6c2300000000000030640472e131a029b85045090d17c2eaeda0d61dd0442997d161e176fb98a27091fe8b6b5746fe2f344a0f26f1f16556d24506af1fd1c8cb4b3b6dfa73e2ce958c50e3b937fd59a1df623f000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4700000000000000000000000000000000000000fcff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000212a3b4059e59d125dd17f662945170e1e13024fae97a401895690acac63cf681aecb67409d1d9c142ffd13375bd79fd0457deb278dfa91b5756378fb837fd60", + "17956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a17956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a17956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a", + "1bbefdb0536c0996d663a908adc2cae17180c53d971e73fe234a6927cd10da332481152785517c274b2dc4ab7b6cacbbdc7d7b8e4dd396faa05a119761130e5c039a49879c785fd647afba497e7ea7a2687e956e978e3572c3df73e9278302b9194b9757129492217d64c4b267e5e935137ae3859ec8b99cf6e6dc61ca90bdfd1c67b6b637c528053a25079e25734a67ffc5388209d11839b3ff1f92591c81ee09750d9bc6fdb71f16e6a69eea50e7288aac1c25a5cd674ca9c57d8ac06fac691bbefdb0536c0996d663a908adc2cae17180c53d971e73fe234a6927cd10da330be3394b5be024026d22810b0614aba1bb03ef031a9e33929bc67a7f7769eeeb039a49879c785fd647afba497e7ea7a2687e956e978e3572c3df73e9278302b9194b9757129492217d64c4b267e5e935137ae3859ec8b99cf6e6dc61ca90bdfd1c67b6b637c528053a25079e25734a67ffc5388209d11839b3ff1f92591c81ee09750d9bc6fdb71f16e6a69eea50e7288aac1c25a5cd674ca9c57d8ac06fac6929a0d6d5e7d14a774c3abff1435361da2ee5d8b4f3ee62085ce779f248b41d4a2fd37ae5468f6a17b7f9a0bcca02ee128bdced61402a566e4eee2d0fa825f03d198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa", + "299a5917adb7b45c30cea045edaa623f5036280df176f4a2c751ca728c2c9e3a2bedf30ba7d8bd0814e9d091913ea5bc6a4b60ee993e949507832df60190651900000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000213d689af09b7f52ac4a04c34bcdb2f90521b1cd213edcfe48fa3063520b6be22ef0f3110ea3051248e907221493e6c2943ebe8d70794188a515ec23df5d9b2b299a5917adb7b45c30cea045edaa623f5036280df176f4a2c751ca728c2c9e3a04765b673958e321a3667524f042b2a12d3609a2cf3335f8349d5e20d6ec982e00000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000213d689af09b7f52ac4a04c34bcdb2f90521b1cd213edcfe48fa3063520b6be22ef0f3110ea3051248e907221493e6c2943ebe8d70794188a515ec23df5d9b2b299a5917adb7b45c30cea045edaa623f5036280df176f4a2c751ca728c2c9e3a2bedf30ba7d8bd0814e9d091913ea5bc6a4b60ee993e949507832df60190651900000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000213d689af09b7f52ac4a04c34bcdb2f90521b1cd213edcfe48fa3063520b6be22ef0f3110ea3051248e907221493e6c2943ebe8d70794188a515ec23df5d9b2b", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080a77c09a07dfaf666ea36f7879462c0a78eb28f5c70b5ed35d438dc58f0d9d058bcabf53ccb1b6f2ad14e6bc531485dba856600b7941c8c5a4968940fba978210dc371bfd9736eb879d25be8a799eff45bea91130b9b2768689786235accd9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800104e7500000000000000000000000000000000000000000000000000000000000000000a535bc14c0f581a039d0bfb15e730b6bbb3d6e33ecda8c74ebd901deeb4ef8423e99eadcc72ced9221df2db154b36f6931270c3f21f4ec8c4206b9211924bb203a99966a8db46602ac05b8f0d7669c3bc066fb7b9a188cc79e5239e27e3580517e54f1fff192038a907711c8123997f785d2c2c9a214355466b60652ee53e4d00c662006274fb346e22eeb59635c82cb4e20e34da7230644e72e131c82cb4e2000000104e75a20b64000000000000000000150000000000000000006629c731270ef2ea6f8c3dad3832f95f309cb6a1591ad53af025c6e0809992f15234e5fe1b37771ce3bb5a62017c56c496e57673e2617634e900c587724d21f24e603a6303a99966a8db46602ac05b8f0d7669c3bc066fb7b9a188cc79e5239e27e35805187eff52e2187ff10f48d49a005dbede1f243e64ce508737f5b52bb1a997befa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf0000000000000000001284bdd8e69832b232222d3493a6abb523575be2a5af6e88f5501cef408aa5bb0ca4d5b3c58e0bc7be2c8885e53c673b54f3057cff97cb1020cb2f5a9f61affb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005908648c919b2bd65122716e5e4aa74fb342e22eeb59635c84bb4e20e34da7230644e72e131a0296427b6542e3a6a00ccfa1d43577c305499096bbd8414f16c0df67cf39cb400a898e9aa727937ca9e07d92185f3fba6aa42be45ddad4fdadb145da376a6ec6d77185df39edde6e9037e58065a054cda2796f4e669bcdcbf1f", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b92493387900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b92493387900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b92493387900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a8305b993046905746641a19b500ebbbd30cf0068a845bfbee9de55b8fe57d1dee8243ef33537f73ef4ace4279d86344d93a5dc8c20c69045865c0fa3b924933879", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a0290000000000000000000000000000000040000000000000000001000000000000000000000000000000000000000017f66b9111253405000006f2a18a982e6e9436f171f8bcdb4f60b9ea1dafaf115f9228e11ddd98ca9680304502b9c299712d0cf851e73adc8ce68c549a5b2ae712a44811db357d3bdb9717956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a17956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a17956b549321b92c524d191a62b90c81f08e694af4dceb00a80094e53120d39e2fd15d78815388959caa54affa2d7b2c8d52c528e6a1f6c0a50fcf0498fac7ee30644e72e131a0290000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000016b9e28a32ee61a7ad5bd4bad29d64fc35a8fb46b510be2067907069497ae1f0c3c07c40f41a731fe27d953f1154b4e9a8acf3ef44608817150de0df916503a", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d977f9597358c206e72c88c16e622b8b2000000000000004500000000000000000000000107b55de1642362d16b8fc4dc2a314eca6adb97bf3a3872a406ecf97bf2bdd210b6cba667eba043f71c1ffc200ba9caa5888ae7c0e6d2b54181905e66769d9ed9badc43da3d9f3e56b46cb43b0acfd59a153bdc736907cc4a640a2fb675cdaa8066a58616537ce4cd7145aa061b1d6bf901bda3c5e3df60e3741d6f5d6660f4034e2f99545e0dc71e9b53af2c30644e72e131a029b85045b68181585d977f956e978c3572c8208c166622b8b2000000000000004500000000000000000000000107b55de1642362d16b8fc4dc2ad9bb009c15bdc11d5ed75a805d5f24ba0e10e5b7953e281e241f72d208ce880d6f072450fd6ef76dd73ff2924238cbee09ea4c6281b867a897d85d8d091b330acfd59a153bdc736907cc4a640a2fb675cdaa8066a58616537ce4cd7145aa061b1d6bf901bda3c5e3df60e3741d6f5d6660f4034e2f99545e0dc71e9b53af2c30644e72e131a029b85045b68181585d977f956e978c3572c8208c166622b8b2000000000000004500000000000000000000000107b55de1642362d16b8fc4dc2ad9bb009c15bdc11d5ed75a805d5f24ba0e10e5b7953e281e241f72d208ce880d6f072450fd6ef76dd73ff2924238cbee09ea4c6281b867a897d85d8d091b330acfd59a153bdc736907cc4a640a2fb675cdaa8066a58616537ce4cd7145aa061546e279df73fc63d470e4d30d63e9003120768e1a423138de12c4f83d294e1b30644e72e131a029b85045b68181585d977f956e978c3572c8208c166622b8b2000000000000004500000000000000000000000107b55de1642362d16b8fc4dc2ad9bb009c15bdc11d5ed75a805d5f24ba0e10e5b7953e281e241f72d208ce880d6f072450fd6ef76dd73ff2924238cbee09ea4c6281b867a897d85d8d091b33", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb431a5d389ca17607c4b12d7f1c8463b960754dbbb74ee00f645ca559f5ee759ad5231fdb414002b25ebeed48fd799214f4db09a7dae25ac92c15b7e429e1800a70297861ced3673fa135f178751f203f13d8a4c9f15ad9fdbb4bb7468154af97f71698710af2efbde1687bc1530e7da2ca42c8e85baf594682890d36c8fb8d08f9106f1d083223bd63d1630baf008588ac9c0392c289c68afee37b013030a9f7d10128036f1a405f40bce08bc346f0f83cb8ca2fe81d18fdfffa984c97cef373580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb431c251d57a884434484d488b3fa5bb0b0d8566a251bfa57cdcfa452ee114a19601bcd6dec5e0b17fb9bb77b1145793cd6a99534de85911f41c37934fc6f1f508e203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c15393157ad3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e", + "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000005b004500000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45218c0cef2a606613357bfaa3c880e71ff8490195337fa26205a21ccd9a6949a313fed2c79add9d85b9949c5852ef8cccf02b69ea6fc4db0d1660ac7b50df39e1", + "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6", + "000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21cc9a9eb823f8d97adee0206828c9f19eaf8f536c23207d68ae3d056a1480bb21990ddb90388b94f31089d3b4ff594d5449c04fcdf2a3681017b5d7749367ba1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21cc9a9eb823f8d97adee0206828c9f19eaf8f536c23207d68ae3d056a1480bb21990ddb90388b94f31089d3b4ff594d5449c04fcdf2a3681017b5d7749367ba1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21cc9a9eb823f8d97adee0206828c9f19eaf8f536c23207d68ae3d056a1480bb21990ddb90388b94f31089d3b4ff594d5449c04fcdf2a3681017b5d7749367ba1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21cc9a9eb823f8d97adee0206828c9f19eaf8f536c23207d68ae3d056a1480bb21990ddb90388b94f31089d3b4ff594d5449c04fcdf2a3681017b5d7749367ba1", + "000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb43000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4500000000000000000000000000000000000000000000000000000000000000020833e47a2eaa8bbe12d33b2da1a4fa8d763f5c567fe0da6c5c9da2e246f2096f28dc125bf7443bc1826c69fe4c7bf30c26ec60882350e784c4848c822726eb43", + "01ea6e2eae2a2501d6830a3f5ea1353a5f920719aaeeea537dde0df31bec7a802b40433b22aaaec8f6d6d21dc04994ab99ba4a4b16545f63430a6ecf01881e090000000004000000000000000000000000000000000000000000000000000000196ec634c6397f591ebee925f9fa9e89a1fa55ba5e38d5cb0f7dcfa49e0c0ae4260377b5b8fed1c2f2a2f848038464ffc8c3bd1d71844fcc85f64b478248b21d0990a17d0f06d3bb026b17967cc55b2160d7570fde6a448502bd28e8192db67e01ea6e2eae2a2501d6830a3f5ea1353a5f920719aaeeea537dde0df31bec7a8005240b37be86f160c1797398c137c3b1fdc72046521d6b29f9161d47d6f4df3e0000000004000000000000000000000000000000000000000000000000000000196ec634c6397f591ebee925f9fa9e89a1fa55ba5e38d5cb0f7dcfa49e0c0ae4260377b5b8fed1c2f2a2f848038464ffc8c3bd1d71844fcc85f64b478248b21d0990a17d0f06d3bb026b17967cc55b2160d7570fde6a448502bd28e8192db67e000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020d7d3be95c6b1fc7d70f2edc7b7bf6e7397bc04bc6aaa0584b9e5bbc064de4fa30644e72e131a029b85045b68181585d97816a9168543fedb0d3f28c77685fdb10fb4e584f10053cba1117d920db188f54d1ab64e66e10b6177401a44c71e25020f50c6423205b18d96cdf7a832041d89076cf36dcde6700e62833186acd60b6", + "03a99966a8db46602ac05b8f0d7669c3bc066fb7b9a188cc79e5239e27e35805187eff52e2187ff10f48d49a005dbede1f243e64ce508737f5b52bb1a997befa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bf0000000000000000001284bdd8e69832b232222d3493a6abb523575be2a5af6e88f5501cef408aa5bb0ca4d5b3c58e0bc7be2c8885e53c673b54f3057cff97cb1020cb2f5a9f61affb03a99966a8db46602ac05b8f0d7669c3bc066fb7b9a188cc79e5239e27e3580517e54f1fff192038a907711c8123997f785d2c2c9a214355466b60652ee53e4d00c662006274fb346e22eeb59635c82cb4e20e34da7230644e72e131c82cb4e2000000104e75a20b64000000000000000000150000000000000000006629c731270ef2ea6f8c3dad3832f95f309cb6a1591ad53af025c6e0809992f15234e5fe1b37771ce3bb5a62017c56c496e57673e2617634e900c587724d21f24e603a630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800104e75a20b641566a0c71c9069a5256391aa31e22021d36c037c108dfb79c66200bf257ae3d66a589214f980a2ae34f9544be2fcbcc13b21f4c1642f31aa4d20000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000", + "0cdc335fa81dff303b71cffb0256d7097c2b4c6715ca7b1589ea9386a41c2f851e4077b7c1f3374bbd4750ed222848c47501b40fc4c11eadd3c39aeafa452459000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000001f1cd7f247f2ae1ba9a1aeb4b32ed4c8c13c70c8861b6ab5340e276c58e1046b13d7de2b557e0ae2b53380ad596ba79f07c037c9d9aa17cf407e9ed86201436e0cdc335fa81dff303b71cffb0256d7097c2b4c6715ca7b1589ea9386a41c2f851223d6bb1f3e68ddfb08f4c95f590f99227fb681a3b0abdf685cf12bde37d8ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000001f1cd7f247f2ae1ba9a1aeb4b32ed4c8c13c70c8861b6ab5340e276c58e1046b13d7de2b557e0ae2b53380ad596ba79f07c037c9d9aa17cf407e9ed86201436e000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd45000000000000004500000000000000000000000000000000000000000000000107b55de1642362d16b8fc4dccfec9e794d24968511cf8e252ed27afc4d72ca1e0301cb4d7e0b7b52a6a8f78613c403ead1543fedb0d3f28c77685fdb9eaa274212ee4836f908e5e39090a4124b75f3ec5b665a729997f55cdea80f76ab940c5902a12ba6400116479dcf5179e4d06471a65e72229fb444b34d8f07458a4a81570000000000ffffffff00000000000000000000000000000000000000000000000000000000ffffffff000000000000000000000000000000000000000000000000fb55bf7df894a746fbe20b6f8c54d5dc0d9fd4eda4742fc35100c45e6e27f912a20d63d446eb175733853b88dd36708eb7a81f5c79e7659c3a6e2b2c470077", + "1838ccf8d820349a8c38a57dc0a5495577898e422509e4c9636e9737fe0dcd9116f566a30b7d2579fd6109eb09d66c005fdccdc0d91b28f43be34c5668f34f812a9a64f273fa329bc9c98ff2083c627609e2219177b9c5df7286af31a3b27e8120d85101e1e6af0126c00a95c645b192b3ea69ed72297deac1fbb0e6bd1440c600ec155ab3cd58005b488308578aaeeaeae9c65939f785bf693fa5763c174dd624d3b2adb35ad17933d0317a00436d10f2d6908faf109e7fe3db77a39d5c1711175bcec7c4c77c612df588174dd44362722f7b8e588a0ef599129cf123f63b8d2e1ff6c569e5cb0d20fb28504057d4f7ed248900ac99bd0f31a853af5c10a806198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21cc9a9eb823f8d97adee0206828c9f19eaf8f536c23207d68ae3d056a1480bb21990ddb90388b94f31089d3b4ff594d5449c04fcdf2a3681017b5d7749367ba1000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd451800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21cc9a9eb823f8d97adee0206828c9f19eaf8f536c23207d68ae3d056a1480bb21990ddb90388b94f31089d3b4ff594d5449c04fcdf2a3681017b5d7749367ba1", + "1bbf3321bfdf76e22ca0e95089338a772a4a2982dbede2571c14a258bd9874ff2b5aa74efa3429cd77acc68bd2e487960f34074d3a725444b06a552c1be0ca442471fa6c0785556dacbe4d9570fa9e89a2fa55ba5e38d5cb0f7dcfa49e0c0ae4181b42bbb36f2bb465708c62b0bd12ae5d6922cf5c4f928a7097f8db8f0dfae3103e85ddefbe5900ded1384badbc32c907c50baa4282172d02562116005aecdf2cce8d04251b64ced66cc7b66a1c54000e17872b10b4793f5bd81052e5ef3e5c1bbf3321bfdf76e22ca0e95089338a772a4a2982dbede2571c14a258bd9874ff0509a723e6fd765c40a37f2aae9cd0c7884d63442dff76488bb636eabc9c33032471fa6c0785556dacbe4d9570fa9e89a2fa55ba5e38d5cb0f7dcfa49e0c0ae4181b42bbb36f2bb465708c62b0bd12ae5d6922cf5c4f928a7097f8db8f0dfae3103e85ddefbe5900ded1384badbc32c907c50baa4282172d02562116005aecdf2cce8d04251b64ced66cc7b66a1c54000e17872b10b4793f5bd81052e5ef3e5c00710c68e1b8b73a72a289422d2b6f841cc56fe8c51105021c56ae30c3ae1aca0b2ff392a2fc535427ec9b7e1ae1c35a7961986788cf648349190dd92e182f05198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daabebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebefdbebebebeabc689bebebebe43be92be5fbebebebebebebebebebebebebebebebebebebebebebebe9ebebebe2abebebebebebebebebebebebebebebebebebe", + "29c19b11665cbeb0fd496542e6115ceef9b628ab4bc7419802e7016cf1b2c931057cdbec3f7c2ad0f4da33b3cfd3234ea29f71c6c46b8b90eb2d4a5851adf74b00bb00b95e1b59fca2159a5f33f27f36b15fe6bcda0b1ee0381b0ef7dd804bd625ed3c1a0120b6531e39cca6f67f35f9a849cfbfe958cc1840d1c20cc6b3e1ad08cbba5815581dcea62fa0426dbff39c8f0e9fdc451b1fb127a4e7a4c058799619068e06466a9dd7543ac89d53a17a8beb6c11c59c3af32ea0c1bbc55e0fae7b2c52ab9e7e9296183b9695387e3ae3d06c9d11a98676e4e046914b36b636ddc4050abc3606826f8aeaac5aa7be9f44d15a55805037eb2b260c32d43bd32adef10763b017bc2777ac81ff30fff09f65381c24912bfc9d1490a23765b4830f0aae2b71c998abc367ad761da7e9900eb7e579989f82eee3338c17b8dc17e53e052b21e242369877673070a6b8b0307da6e84e32bdfb3eb09d514b25e8704bd55d431782c07d2d471af10469a13476a49ec51d1bc538d49bbaf85a63fdb6b412fb4a1bc85b155eee2e33bf5322810c7c0150158f373e998316edf821ae9804a2ac191899a5e18c57f4e6b5f736c2f21e95f4147a4235ed2c1f6e6615eb0e00979f0920568d8f3b2f2d0a6a596ea20b3e62191baf420de10125557f9a665900a82a5925a43a697ceaa9deba01a97d8722815e8185973a402e11fdca62fa908da409c4054081d5b9d0e3aa18a31cc5f9d0fa925205fd50a71edf4ca157a607587e24571c9cacf3b3d821146083f9e5fe6be23546643e3ad4540a1f02c02728010a4b9f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030644e72e131a029b85045b68181585d97816a916871ca8d3c208c166622b860000000000000004500000000000000000000000107b55de1642362d16b8fc4dc2215436159d2bdb4e084a6c63bd04f6b84d69bfad793da72c21b421f3f89b22f22b811a1a4fa51df281657f0b0a1add382fab768ac1ed8886bf979e2bf11402d", + "2deb529e45720f20be41088dfd7489c315e9e18fe23dd1c8a8183295dc770dee1090b3fcd1898780c332b7d73a602cadd1b26029124db9da19941250eda890b500000000000000000000000000ff0a69a42c284614e3d7de26b3f9b2f3c71ff600000000000000000000000000000000000000000000000000000000000000001e2c7f9d6a525b6af5dad683c5e6408661da29780860c3209b2dddcad5a88795033123665850406fc2428227bbb3509fc71c911cf41623de1605cd3e0a281b902deb529e45720f20be41088dfd7489c315e9e18fe23dd1c8a8183295dc770dee1090b3fcd1898780c332b7d73a602cadd1b26029124db9da19941250eda890b5000000000000000000000000000000000000000000275680008ded35ba000000000000000000000000000000000000000000000000000000000000000000000019367fe97b92d85d7c29090c2313de1a85f030239cfa71f939a197249cb17b890465a8498153883aca20e4de66ac02b1b6957fab9b4bce71df334cd6bee5ff952deb529e45720f20be41088dfd7489c315e9e18fe23dd1c8a8183295dc770dee1090b3fcd1898780c332b7d73a602cadd1b26029124db9da19941250eda890b5000000000000000000000000000000000000000000275680008ded35ba000000000000000000000000000000000000000000000000000000000000000000000019367fe97b92d85d7c29090c2313de1a85f030239cfa71f939a197249cb17b890465a8498153883aca20e4de66ac02b1b6957fab9b4bce71df334cd6bee5ff952deb529e45720f20be41088dfd7489c315e9e18fe23dd1c8a8183295dc770dee1090b3fcd1898780c332b7d73a602cadd1b26029124db9da19941250eda890b5000000000000000000000000000000000000000000275680008ded35ba000000000000000000000000000000000000000000000000000000000000000000000019367fe97b92d85d7c29090c2313de1a85f030239cfa71f939a197249cb17b890465a8498153883aca20e4de66ac02b1b6957fab9b4bce71df334cd6bee5ff95", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a36c98d1ece5fd647afba497e7ea7a2687e956e978e3572c3df75e9278302b9000000000000000000000000000000000000000000000000000000991b498795099a3faf27255b9542daf48d9588fc4d6927c7fcd88c5784a4245345474e1e4509a44ea53f191ddef8a32ec03a7e1a24e06588f8de364ba0024b3b8a062ca91a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a36c98d1ece5fd647afba497e7ea7a2687e956e978e3572c3df75e9278302b9000000000000000000000000000000000000000000000000000000991b498795099a3faf27255b9542daf48d9588fc4d6927c7fcd88c5784a4245345474e1e4509a44ea53f191ddef8a32ec03a7e1a24e06588f8de364ba0024b3b8a062ca91a000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5000000000000000000000000000000000000000000000000000000000000000130644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd4530644e72e131a029b85045b68181585d97816a68917120ca8d3c8c16d87cfd4500000000005b004500000000000000000000000000000000000000004000000111ee2be185fb562c979eeb452df376f91c7852bfb8a6d5727024444a2fc58c152825d78e66be7952503e9e1bf2d8aad4c39f4ce4095349043106508bab20d6e5", + "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000310000000000000000000000000ccc369050590000000000000000000000000000000000000000000000000000000000000000034e16015e4aeadb3c1c93fd54f496a6a75271f9e514b6c51782d145a1771a9827910e860d8264c87a784c364d78f117ca598153fc5947c915eb6e2e7e0ad6d5000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "06e42bc7eb32a979b39a77435202c2a062c8bef977f46500b040fa35b8a45b2315ca114b0522bdd5e928f9629ed2a283d36141f3307071cad74fb768721cbb0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006e42bc7eb32a979b39a77435202c2a062c8bef977f46500b040fa35b8a45b231a9a3d27dc0ee253cf274c53e2aeb5d9c420289e380158c264d0d4ae6660423900000000000000000000000000000000000000000000010000000000000000001611179006befd3749602129813bd7247045ac58ea0000000100000000000000202a170a4a4385bdcefbe36ade6cc7c0e9834b78fc6ca233e8de345a2d5782dc1699f57deaacb74e8b98bd8532c3f152570db884fc1755fbc0c8cb3ef54a537f26c6e104e6c30ed077379b1762d05ac66a6d8e1bb0699ff4f8e3fa52568f0f7709179c965e45c4f28e2ee2affb9b86744b8f29df08357dc80776ecede39adc7f221276dfff5b3a2b6a46ec6c0e0891aefd121170d8361187b73b46e1c6b1218f29255d7955576bba25241ec1edfdfc08c9b8d29379d4213025fa95b0dbdd16460ff9fdfcccda82fb0dd8f17931e05823321073a1a4e484699acdc9d0f14ea6f60c25b531fed0c7e8899296888cc0b27fbb6dbfc2041d482e21d908e240772a2326c6e104e6c30ed077379b1762d05ac66a6d8e1bb0699ff4f8e3fa52568f0f7709179c965e45c4f28e2ee2affb9b86744b8f29df08357dc80776ecede39adc7f221276dfff5b3a2b6a46ec6c0e0891aefd121170d8361187b73b46e1c6b1218f29255d7955576bba25241ec1edfdfc08c9b8d29379d4213025fa95b0dbdd16460ff9fdfcccda82fb0dd8f17931e05823321073a1a4e484699acdc9d0f14ea6f60c25b531fed0c7e8899296888cc0b27fbb6dbfc2041d482e21d908e240772a2326c6e104e6c30ed077379b1762d05ac66a6d8e1bb0699ff4f8e3fa52568f0f7709179c965e45c4f28e2ee2affb9b86744b8f29df08357dc80776ecede39adc7f221276dfff5b3a2b6a46ec6c0e0891aefd121170d8361187b73b46e1c6b1218f29255d7955576bba25241ec1edfdfc08c9b8d29379d4213025fa95b0dbdd16460ff9fdfcccda82fb0dd8f17931e05823321073a1a4e484699acdc9d0f14ea6f60c25b531fed0c7e8899296888cc0b27fbb6dbfc2041d482e21d908e240772a2326c6e104e6c30ed077379b1762d05ac66a6d8e1bb0699ff4f8e3fa52568f0f7709179c965e45c4f28e2ee2affb9b86744b8f29df08357dc80776ecede39adc7f221276dfff5b3a2b6a46ec6c0e0891aefd121170d8361187b73b46e1c6b1218f29255d7955576bba25241ec1edfdfc08c9b8d29379d4213025fa95b0dbdd16460ff9fdfcccda82fb0dd8f17931e05823321073a1a4e484699acdc9d0f14ea6f60c25b531fed0c7e8899296888cc0b27fbb6dbfc2041d482e21d908e240772a23", + ]; + invalid_inputs.forEach(async (input) => { + const call = callFallback(ecPairing, input); + await expect(call).to.be.reverted; + }); + }); + }); +}); From 1de39001c44e95dcd7c2919564b1c926f458f3d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Rodr=C3=ADguez=20Chatruc?= <49622509+jrchatruc@users.noreply.github.com> Date: Tue, 23 Apr 2024 16:56:39 -0300 Subject: [PATCH 11/60] Fix flaky loadtest (#398) Co-authored-by: Stanislav Breadless --- l1-contracts/scripts/setup-legacy-bridge-era.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/l1-contracts/scripts/setup-legacy-bridge-era.ts b/l1-contracts/scripts/setup-legacy-bridge-era.ts index cc471dfc5..ffea4ef2d 100644 --- a/l1-contracts/scripts/setup-legacy-bridge-era.ts +++ b/l1-contracts/scripts/setup-legacy-bridge-era.ts @@ -97,6 +97,10 @@ async function main() { // For the server to start up. console.log("Waiting for server to start up"); await waitForServer(l2Provider); + console.log("Server started up"); + + // Wait a bit more after the server is ready to ensure that all of its components are ready. + await sleep(2); const l2SharedBridge = new ethers.Contract( l2SharedBridgeAddress, From 6139b7217bbe30f753a82c43c864719b28dec1ad Mon Sep 17 00:00:00 2001 From: Marcin M <128217157+mm-zk@users.noreply.github.com> Date: Wed, 24 Apr 2024 09:58:58 +0200 Subject: [PATCH 12/60] updating verification keys to v1.5.0 (#400) --- .../contracts/state-transition/Verifier.sol | 8 ++--- tools/data/scheduler_key.json | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index e2ee9e5cb..861f7e850 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -283,8 +283,8 @@ contract Verifier is IVerifier { function _loadVerificationKey() internal pure virtual { assembly { // gate setup commitments - mstore(VK_GATE_SETUP_0_X_SLOT, 0x03efa4fe0a5d7aa3d98e8becb5058987dddca95ecbe29b624ad274553bf9dd8e) - mstore(VK_GATE_SETUP_0_Y_SLOT, 0x24fb07eb5f0e62013938eb1dcae0aba367a7150a40a9ab2e1ae15e06bbe43853) + mstore(VK_GATE_SETUP_0_X_SLOT, 0x2b344993e706c18427e96e2eefd8e89aaf4cd464814ed978b98793bf129a786c) + mstore(VK_GATE_SETUP_0_Y_SLOT, 0x123af72bf1c5e693516b037d16ba48711c3486823aec3772318b6737634575a4) mstore(VK_GATE_SETUP_1_X_SLOT, 0x04659caf7b05471ba5ba85b1ab62267aa6c456836e625f169f7119d55b9462d2) mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0ea63403692148d2ad22189a1e5420076312f4d46e62036a043a6b0b84d5b410) mstore(VK_GATE_SETUP_2_X_SLOT, 0x0e6696d09d65fce1e42805be03fca1f14aea247281f688981f925e77d4ce2291) @@ -295,8 +295,8 @@ contract Verifier is IVerifier { mstore(VK_GATE_SETUP_4_Y_SLOT, 0x22e404bc91350f3bc7daad1d1025113742436983c85eac5ab7b42221a181b81e) mstore(VK_GATE_SETUP_5_X_SLOT, 0x0d9b29613037a5025655c82b143d2b7449c98f3aea358307c8529249cc54f3b9) mstore(VK_GATE_SETUP_5_Y_SLOT, 0x15b3c4c946ad1babfc4c03ff7c2423fd354af3a9305c499b7fb3aaebe2fee746) - mstore(VK_GATE_SETUP_6_X_SLOT, 0x1c541b6423211b65e42c1a52d0c8a07bf631fbf24606a4135e9e486f2bb9bb06) - mstore(VK_GATE_SETUP_6_Y_SLOT, 0x057be8e4f2db0b66a9134809a33bae06d380c386fdce322e837d11a22ce0f9a9) + mstore(VK_GATE_SETUP_6_X_SLOT, 0x18e466aac9b830ea5417e1ba2e920acf041e3976d36fe891be80beac1d1696c7) + mstore(VK_GATE_SETUP_6_Y_SLOT, 0x025f89444627d09c7b1bf665dc6f58055bf729c683a4b3e815215758a7075602) mstore(VK_GATE_SETUP_7_X_SLOT, 0x283344a1ab3e55ecfd904d0b8e9f4faea338df5a4ead2fa9a42f0e103da40abc) mstore(VK_GATE_SETUP_7_Y_SLOT, 0x223b37b83b9687512d322993edd70e508dd80adb10bcf7321a3cc8a44c269521) diff --git a/tools/data/scheduler_key.json b/tools/data/scheduler_key.json index be6a0dc53..ab950921b 100644 --- a/tools/data/scheduler_key.json +++ b/tools/data/scheduler_key.json @@ -6,16 +6,16 @@ "gate_setup_commitments": [ { "x": [ - 5391499613343178126, - 15986839001871063906, - 15676621201688856967, - 283626712550177443 + 13368816467732756588, + 12631704582998645112, + 2875950984924293274, + 3113194142004855172 ], "y": [ - 1936932697761134675, - 7468961640795974446, - 4123303972047989667, - 2664732312013267457 + 3570060617207608740, + 2032397225743366002, + 5866786775367305329, + 1313634009443853971 ], "infinity": false }, @@ -96,16 +96,16 @@ }, { "x": [ - 6817966528197671686, - 17740237425164592147, - 16441545282615287931, - 2041286648005729125 + 13727181310656943815, + 296737807969282193, + 6059560013411781327, + 1793671435315065066 ], "y": [ - 9474748579292707241, - 15240396123572941358, - 12183160623197826566, - 395165462349679462 + 1522594187298952706, + 6626811309287846888, + 8870954808386738181, + 171006237191164060 ], "infinity": false }, From 501691051a745bdb03922e57f263497a866701dd Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Wed, 24 Apr 2024 09:02:58 +0100 Subject: [PATCH 13/60] fix: hyperchain migration fixes (#395) Co-authored-by: Stanislav Bezkorovainyi --- l1-contracts/src.ts/hyperchain-upgrade.ts | 64 +++++++++++++++++-- ...loy-shared-bridge-implementation-legacy.ts | 8 +-- 2 files changed, 63 insertions(+), 9 deletions(-) diff --git a/l1-contracts/src.ts/hyperchain-upgrade.ts b/l1-contracts/src.ts/hyperchain-upgrade.ts index 132c9a6a2..9b37db572 100644 --- a/l1-contracts/src.ts/hyperchain-upgrade.ts +++ b/l1-contracts/src.ts/hyperchain-upgrade.ts @@ -17,10 +17,10 @@ import type { Deployer } from "./deploy"; import type { ITransparentUpgradeableProxy } from "../typechain/ITransparentUpgradeableProxy"; import { ITransparentUpgradeableProxyFactory } from "../typechain/ITransparentUpgradeableProxyFactory"; -import { L1SharedBridgeFactory } from "../typechain"; +import { L1SharedBridgeFactory, StateTransitionManagerFactory } from "../typechain"; import { Interface } from "ethers/lib/utils"; -import { ADDRESS_ONE } from "./utils"; +import { ADDRESS_ONE, getAddressFromEnv } from "./utils"; import type { L2CanonicalTransaction, ProposedUpgrade, VerifierParams } from "./utils"; import { @@ -231,7 +231,7 @@ async function integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer: Dep const stateTransitionManager = deployer.stateTransitionManagerContract(deployer.deployWallet); if (deployer.verbose) { - console.log("registering Era in stateTransitionManager"); + console.log("Registering Era in stateTransitionManager"); } const registerData = stateTransitionManager.interface.encodeFunctionData("registerAlreadyDeployedHyperchain", [ deployer.chainId, @@ -240,7 +240,7 @@ async function integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer: Dep await deployer.executeUpgrade(deployer.addresses.StateTransition.StateTransitionProxy, 0, registerData); const bridgehub = deployer.bridgehubContract(deployer.deployWallet); if (deployer.verbose) { - console.log("registering Era in Bridgehub"); + console.log("Registering Era in Bridgehub"); } const tx = await bridgehub.createNewChain( deployer.chainId, @@ -253,7 +253,9 @@ async function integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer: Dep ); await tx.wait(); - + if (deployer.verbose) { + console.log("Setting L1Erc20Bridge data in shared bridge"); + } const sharedBridge = L1SharedBridgeFactory.connect( deployer.addresses.Bridges.SharedBridgeProxy, deployer.deployWallet @@ -262,6 +264,58 @@ async function integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer: Dep deployer.addresses.Bridges.ERC20BridgeProxy, ]); await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data1); + if (process.env.CHAIN_ETH_NETWORK != "hardhat") { + if (deployer.verbose) { + console.log("Initializing l2 bridge in shared bridge"); + } + const data2 = sharedBridge.interface.encodeFunctionData("initializeChainGovernance", [ + deployer.chainId, + deployer.addresses.Bridges.L2SharedBridgeProxy, + ]); + await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data2); + } + if (deployer.verbose) { + console.log("Setting validators in hyperchain"); + } + // we have to set it via the STM + const stm = StateTransitionManagerFactory.connect( + deployer.addresses.StateTransition.DiamondProxy, + deployer.deployWallet + ); + const data3 = stm.interface.encodeFunctionData("setValidator", [ + deployer.chainId, + deployer.addresses.ValidatorTimeLock, + true, + ]); + await deployer.executeUpgrade(deployer.addresses.StateTransition.StateTransitionProxy, 0, data3); + + if (deployer.verbose) { + console.log("Setting validators in validator timelock"); + } + + // adding to validator timelock + const validatorOneAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR"); + const validatorTwoAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR"); + const validatorTimelock = deployer.validatorTimelock(deployer.deployWallet); + const txRegisterValidator = await validatorTimelock.addValidator(deployer.chainId, validatorOneAddress, { + gasPrice, + }); + const receiptRegisterValidator = await txRegisterValidator.wait(); + if (deployer.verbose) { + console.log( + `Validator registered, gas used: ${receiptRegisterValidator.gasUsed.toString()}, tx hash: ${ + txRegisterValidator.hash + }` + ); + } + + const tx3 = await validatorTimelock.addValidator(deployer.chainId, validatorTwoAddress, { + gasPrice, + }); + const receipt3 = await tx3.wait(); + if (deployer.verbose) { + console.log(`Validator 2 registered, gas used: ${receipt3.gasUsed.toString()}`); + } } async function upgradeL2Bridge(deployer: Deployer) { diff --git a/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts b/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts index 6016f514e..84a7df17a 100644 --- a/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts +++ b/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts @@ -2,7 +2,7 @@ import { Command } from "commander"; import { artifacts } from "hardhat"; import type { BigNumberish } from "ethers"; import { ethers, Wallet } from "ethers"; -import { formatUnits, Interface, parseUnits } from "ethers/lib/utils"; +import { formatUnits, Interface, parseUnits, defaultAbiCoder } from "ethers/lib/utils"; import { computeL2Create2Address, provider, @@ -52,7 +52,7 @@ async function create2DeployFromL1( REQUIRED_L2_GAS_PRICE_PER_PUBDATA, factoryDeps, wallet.address, - { value: expectedCost, gasPrice } + { value: expectedCost.mul(5), gasPrice } ); } @@ -125,7 +125,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch const l2SharedBridgeImplAddress = computeL2Create2Address( deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - "0x", + defaultAbiCoder.encode(["uint256"], [deployer.chainId]), ethers.constants.HashZero ); deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress; @@ -143,7 +143,7 @@ export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, ch chainId, deployer.deployWallet, L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - "0x", + defaultAbiCoder.encode(["uint256"], [deployer.chainId]), ethers.constants.HashZero, priorityTxMaxGasLimit, gasPrice, From fcee799c3f794318551a76a9507013380164f091 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Wed, 24 Apr 2024 13:14:21 +0200 Subject: [PATCH 14/60] Script + safeTransferFromLegacy (#402) --- .../contracts/bridge/L1SharedBridge.sol | 24 +- l1-contracts/package.json | 1 + l1-contracts/scripts/token-migration.ts | 220 ++++++++++++++++++ l1-contracts/src.ts/hyperchain-upgrade.ts | 6 +- 4 files changed, 247 insertions(+), 4 deletions(-) create mode 100644 l1-contracts/scripts/token-migration.ts diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index d2a9f4b0d..d0b4898fe 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -110,6 +110,12 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade _; } + /// @notice Checks that the message sender is the shared bridge itself. + modifier onlySelf() { + require(msg.sender == address(this), "ShB not shared bridge"); + _; + } + /// @dev Contract is expected to be used as proxy implementation. /// @dev Initialize the implementation to prevent Parity hack. constructor( @@ -161,7 +167,7 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade } /// @dev transfer tokens from legacy erc20 bridge or mailbox and set chainBalance as part of migration process - function transferFundsFromLegacy(address _token, address _target, uint256 _targetChainId) external onlyOwner { + function transferFundsFromLegacy(address _token, address _target, uint256 _targetChainId) external onlySelf { if (_token == ETH_TOKEN_ADDRESS) { uint256 balanceBefore = address(this).balance; IMailbox(_target).transferEthToSharedBridge(); @@ -177,11 +183,25 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade require(legacyBridgeBalance > 0, "ShB: 0 amount to transfer"); IL1ERC20Bridge(_target).transferTokenToSharedBridge(_token); uint256 balanceAfter = IERC20(_token).balanceOf(address(this)); - require(balanceAfter - balanceBefore == legacyBridgeBalance, "ShB: wrong amount transferred"); + require(balanceAfter - balanceBefore >= legacyBridgeBalance, "ShB: wrong amount transferred"); chainBalance[_targetChainId][_token] = chainBalance[_targetChainId][_token] + legacyBridgeBalance; } } + /// @dev transfer tokens from legacy erc20 bridge or mailbox and set chainBalance as part of migration process. + /// @dev Unlike `transferFundsFromLegacy` is provides a concrete limit on the gas used for the transfer and even if it will fail, it will not revert the whole transaction. + function safeTransferFundsFromLegacy( + address _token, + address _target, + uint256 _targetChainId, + uint256 _gasPerToken + ) external onlyOwner { + try this.transferFundsFromLegacy{gas: _gasPerToken}(_token, _target, _targetChainId) {} catch { + // A reasonable amount of gas will be provided to transfer the token. + // If the transfer fails, we don't want to revert the whole transaction. + } + } + function receiveEth(uint256 _chainId) external payable { require(BRIDGE_HUB.getHyperchain(_chainId) == msg.sender, "receiveEth not state transition"); } diff --git a/l1-contracts/package.json b/l1-contracts/package.json index 51e702943..7363c96c6 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -78,6 +78,7 @@ "hyperchain-upgrade-1": "ts-node scripts/hyperchain-upgrade-1.ts", "hyperchain-upgrade-2": "ts-node scripts/hyperchain-upgrade-2.ts", "hyperchain-upgrade-3": "ts-node scripts/hyperchain-upgrade-3.ts", + "token-migration": "ts-node scripts/token-migration.ts", "setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts" }, "dependencies": { diff --git a/l1-contracts/scripts/token-migration.ts b/l1-contracts/scripts/token-migration.ts new file mode 100644 index 000000000..09413b529 --- /dev/null +++ b/l1-contracts/scripts/token-migration.ts @@ -0,0 +1,220 @@ +// hardhat import should be the first import in the file +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as hardhat from "hardhat"; +import { Command } from "commander"; +import { web3Url } from "./utils"; +import { ethers } from "ethers"; +import { Provider, utils } from "zksync-ethers"; + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("upgrade-shared-bridge-era").description("upgrade shared bridge for era diamond proxy"); + + program + .command("get-confirmed-tokens") + .description("Returns the list of tokens that are registered on the bridge and should be migrated") + .option("--use-l1") + .option("--start-from-block ") + .action(async (cmd) => { + const l2Provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + const l1Provider = new ethers.providers.JsonRpcProvider(web3Url()); + + let confirmedFromAPI; + + if (cmd.useL1) { + const block = cmd.startFromBlock; + if (!block) { + throw new Error("For L1 the starting block should be provided"); + } + + console.log("Fetching confirmed tokens from the L1"); + console.log("This will take a long time"); + + const bridge = (await l2Provider.getDefaultBridgeAddresses()).erc20L1; + console.log("Using L1 ERC20 bridge ", bridge); + + const confirmedFromL1 = await loadAllConfirmedTokensFromL1(l1Provider, bridge, +block); + console.log(JSON.stringify(confirmedFromL1, null, 2)); + } else { + console.log("Fetching confirmed tokens from the L2 API..."); + confirmedFromAPI = await loadAllConfirmedTokensFromAPI(l2Provider); + + console.log(JSON.stringify(confirmedFromAPI, null, 2)); + } + }); + + program + .command("merge-confirmed-tokens") + .description("Merges two lists of confirmed tokens") + .option("--from-l1 ") + .option("--from-l2 ") + .action(async (cmd) => { + const l2Provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + const bridge = (await l2Provider.getDefaultBridgeAddresses()).erc20L1; + console.log("Using L1 ERC20 bridge ", bridge); + + const allTokens = {}; + const tokensFromL1: string[] = JSON.parse(cmd.fromL1).map((token) => token.toLowerCase()); + const tokensFromL2: string[] = JSON.parse(cmd.fromL2).map((token) => token.toLowerCase()); + + tokensFromL1.forEach((token) => (allTokens[token] = true)); + tokensFromL2.forEach((token) => (allTokens[token] = true)); + + const erc20Abi = ["function balanceOf(address) view returns (uint256)"]; + + const result = []; + + const l1Provider = new ethers.providers.JsonRpcProvider(web3Url()); + for (const token of Object.keys(allTokens)) { + const contract = new ethers.Contract(token, erc20Abi, l1Provider); + const balanceL1 = await contract.balanceOf(bridge); + if (balanceL1.gt(0)) { + console.log("Token ", token, " has balance in the bridge ", balanceL1.toString()); + result.push(token); + } + } + + console.log(JSON.stringify(result, null, 2)); + }); + + program + .command("prepare-migration-calldata") + .description("Prepare the calldata to be signed by the governance to migrate the funds from the legacy bridge") + .option("--tokens-list ") + .option("--gas-per-token ") + .option("--tokens-per-signature ") + .option("--shared-bridge-addr ") + .option("--legacy-bridge-addr ") + .option("--era-chain-address ") + .option("--era-chain-id ") + .option("--delay ") + + .action(async (cmd) => { + const allTokens: string[] = JSON.parse(cmd.tokensList); + // Appending the ETH token to be migrated + allTokens.push("0x0000000000000000000000000000000000000001"); + + const tokensPerSignature = +cmd.tokensPerSignature; + + const scheduleCalldatas = []; + const executeCalldatas = []; + + for (let i = 0; i < allTokens.length; i += tokensPerSignature) { + const tokens = allTokens.slice(i, Math.min(i + tokensPerSignature, allTokens.length)); + const { scheduleCalldata, executeCalldata } = await prepareGovernanceTokenMigrationCall( + tokens, + cmd.sharedBridgeAddr, + cmd.legacyBridgeAddr, + cmd.eraChainAddress, + cmd.eraChainId, + +cmd.gasPerToken, + +cmd.delay + ); + + scheduleCalldatas.push(scheduleCalldata); + executeCalldatas.push(executeCalldata); + } + + console.log("Schedule operations to sign: "); + scheduleCalldatas.forEach((calldata) => console.log(calldata + "\n")); + + console.log("Execute operations to sign: "); + executeCalldatas.forEach((calldata) => console.log(calldata + "\n")); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); + +async function loadAllConfirmedTokensFromAPI(l2Provider: Provider) { + const limit = 50; + const result = []; + let offset = 0; + + // eslint-disable-next-line no-constant-condition + while (true) { + const tokens = await l2Provider.send("zks_getConfirmedTokens", [offset, limit]); + if (!tokens.length) { + return result; + } + + tokens.forEach((token) => result.push(token.l1Address)); + offset += limit; + } +} + +async function loadAllConfirmedTokensFromL1( + l1Provider: ethers.providers.JsonRpcProvider, + bridgeAddress: string, + startBlock: number +) { + const blocksRange = 50000; + const endBlock = await l1Provider.getBlockNumber(); + const abi = (await hardhat.artifacts.readArtifact("IL1ERC20Bridge")).abi; + const contract = new ethers.Contract(bridgeAddress, abi, l1Provider); + const filter = contract.filters.DepositInitiated(); + + const tokens = {}; + + while (startBlock <= endBlock) { + console.log("Querying blocks ", startBlock, " - ", Math.min(startBlock + blocksRange, endBlock)); + const logs = await l1Provider.getLogs({ + ...filter, + fromBlock: startBlock, + toBlock: Math.min(startBlock + blocksRange, endBlock), + }); + const deposits = logs.map((log) => contract.interface.parseLog(log)); + deposits.forEach((dep) => { + if (!tokens[dep.args.l1Token]) { + console.log(dep.args.l1Token, " found!"); + } + tokens[dep.args.l1Token] = true; + }); + + startBlock += blocksRange; + } + + return Object.keys(tokens); +} + +async function prepareGovernanceTokenMigrationCall( + tokens: string[], + l1SharedBridgeAddr: string, + l1LegacyBridgeAddr: string, + eraChainAddress: string, + eraChainId: number, + gasPerToken: number, + delay: number +) { + const governanceAbi = new ethers.utils.Interface((await hardhat.artifacts.readArtifact("IGovernance")).abi); + const sharedBridgeAbi = new ethers.utils.Interface((await hardhat.artifacts.readArtifact("L1SharedBridge")).abi); + const calls = tokens.map((token) => { + const target = token == utils.ETH_ADDRESS_IN_CONTRACTS ? eraChainAddress : l1LegacyBridgeAddr; + + return { + target: l1SharedBridgeAddr, + value: 0, + data: sharedBridgeAbi.encodeFunctionData("safeTransferFundsFromLegacy", [token, target, eraChainId, gasPerToken]), + }; + }); + const governanceOp = { + calls, + predecessor: ethers.constants.HashZero, + salt: ethers.constants.HashZero, + }; + + const scheduleCalldata = governanceAbi.encodeFunctionData("scheduleTransparent", [governanceOp, delay]); + const executeCalldata = governanceAbi.encodeFunctionData("execute", [governanceOp]); + + return { + scheduleCalldata, + executeCalldata, + }; +} diff --git a/l1-contracts/src.ts/hyperchain-upgrade.ts b/l1-contracts/src.ts/hyperchain-upgrade.ts index 9b37db572..578ed92f0 100644 --- a/l1-contracts/src.ts/hyperchain-upgrade.ts +++ b/l1-contracts/src.ts/hyperchain-upgrade.ts @@ -411,10 +411,11 @@ async function migrateAssets(deployer: Deployer) { console.log("transferring Eth"); } const sharedBridge = deployer.defaultSharedBridge(deployer.deployWallet); - const ethTransferData = sharedBridge.interface.encodeFunctionData("transferFundsFromLegacy", [ + const ethTransferData = sharedBridge.interface.encodeFunctionData("safeTransferFundsFromLegacy", [ ADDRESS_ONE, deployer.addresses.StateTransition.DiamondProxy, deployer.chainId, + 300_000, ]); await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, ethTransferData); @@ -433,10 +434,11 @@ async function migrateAssets(deployer: Deployer) { ); await mintTx.wait(); - const daiTransferData = sharedBridge.interface.encodeFunctionData("transferFundsFromLegacy", [ + const daiTransferData = sharedBridge.interface.encodeFunctionData("safeTransferFundsFromLegacy", [ altTokenAddress, deployer.addresses.Bridges.ERC20BridgeProxy, deployer.chainId, + 300_000, ]); // daiTransferData; await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, daiTransferData); From 4c0e566a9d6274c21d008e99374311ffac005c6e Mon Sep 17 00:00:00 2001 From: Raid5594 <52794079+Raid5594@users.noreply.github.com> Date: Wed, 24 Apr 2024 15:36:17 +0200 Subject: [PATCH 15/60] extend utils & update compilation process (#396) Co-authored-by: Raid Ateir --- .gitignore | 1 + system-contracts/package.json | 2 +- system-contracts/scripts/compile-yul.ts | 44 +++++++++-- .../scripts/preprocess-system-contracts.ts | 14 ++++ system-contracts/scripts/utils.ts | 73 +++++++++++++++++++ 5 files changed, 127 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index 356147e7b..6cb7fef4f 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ l1-contracts/out/* l1-contracts-foundry/broadcast/* l1-contracts-foundry/script-out/* !l1-contracts-foundry/script-out/.gitkeep +*.timestamp diff --git a/system-contracts/package.json b/system-contracts/package.json index aed76a397..ca1d7490e 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -62,7 +62,7 @@ "compile-zasm": "ts-node scripts/compile-zasm.ts", "deploy-preimages": "ts-node scripts/deploy-preimages.ts", "preprocess:bootloader": "rm -rf ./bootloader/build && yarn ts-node scripts/preprocess-bootloader.ts", - "preprocess:system-contracts": "rm -rf ./contracts-preprocessed && ts-node scripts/preprocess-system-contracts.ts", + "preprocess:system-contracts": "ts-node scripts/preprocess-system-contracts.ts", "test": "yarn build:test-system-contracts && hardhat test --network zkSyncTestNode", "test-node": "hardhat node-zksync --tag v0.0.1-vm1.5.0", "test:bootloader": "cd bootloader/test_infra && cargo run" diff --git a/system-contracts/scripts/compile-yul.ts b/system-contracts/scripts/compile-yul.ts index 589a3a8ea..6c75cf3ef 100644 --- a/system-contracts/scripts/compile-yul.ts +++ b/system-contracts/scripts/compile-yul.ts @@ -1,11 +1,23 @@ // hardhat import should be the first import in the file import type { CompilerPaths } from "./utils"; -import { spawn, compilerLocation, prepareCompilerPaths, getSolcLocation } from "./utils"; +import { + spawn, + compilerLocation, + prepareCompilerPaths, + getSolcLocation, + needsRecompilation, + setCompilationTime, +} from "./utils"; import * as fs from "fs"; import { Command } from "commander"; +import * as _path from "path"; const COMPILER_VERSION = "1.3.18"; const IS_COMPILER_PRE_RELEASE = true; +const CONTRACTS_DIR = "contracts-preprocessed"; +const BOOTLOADER_DIR = "bootloader"; +const TIMESTAMP_FILE_YUL = "last_compilation_yul.timestamp"; +const TIMESTAMP_FILE_BOOTLOADER = "last_compilation_bootloader.timestamp"; export async function compileYul(paths: CompilerPaths, file: string) { const solcCompilerPath = await getSolcLocation(); @@ -30,14 +42,34 @@ async function main() { program.version("0.1.0").name("compile yul").description("publish preimages for the L2 contracts"); program.command("compile-bootloader").action(async () => { - await compileYulFolder("bootloader/build"); - await compileYulFolder("bootloader/tests"); + const timestampFilePath = _path.join(process.cwd(), TIMESTAMP_FILE_BOOTLOADER); + const folderToCheck = _path.join(process.cwd(), BOOTLOADER_DIR); + + if (needsRecompilation(folderToCheck, timestampFilePath)) { + console.log("Compilation needed."); + await compileYulFolder("bootloader/build"); + await compileYulFolder("bootloader/tests"); + setCompilationTime(timestampFilePath); + } else { + console.log("Compilation not needed."); + return; + } }); program.command("compile-precompiles").action(async () => { - await compileYulFolder("contracts-preprocessed"); - await compileYulFolder("contracts-preprocessed/precompiles"); - await compileYulFolder("contracts-preprocessed/precompiles/test-contracts"); + const timestampFilePath = _path.join(process.cwd(), TIMESTAMP_FILE_YUL); + const folderToCheck = _path.join(process.cwd(), CONTRACTS_DIR); + + if (needsRecompilation(folderToCheck, timestampFilePath)) { + console.log("Compilation needed."); + await compileYulFolder("contracts-preprocessed"); + await compileYulFolder("contracts-preprocessed/precompiles"); + await compileYulFolder("contracts-preprocessed/precompiles/test-contracts"); + setCompilationTime(timestampFilePath); + } else { + console.log("Compilation not needed."); + return; + } }); await program.parseAsync(process.argv); diff --git a/system-contracts/scripts/preprocess-system-contracts.ts b/system-contracts/scripts/preprocess-system-contracts.ts index acecee1ac..0b3690a9e 100644 --- a/system-contracts/scripts/preprocess-system-contracts.ts +++ b/system-contracts/scripts/preprocess-system-contracts.ts @@ -3,9 +3,11 @@ import path from "path"; import { renderFile } from "template-file"; import { glob } from "fast-glob"; import { Command } from "commander"; +import { needsRecompilation, deleteDir, setCompilationTime, isFolderEmpty } from "./utils"; const CONTRACTS_DIR = "contracts"; const OUTPUT_DIR = "contracts-preprocessed"; +const TIMESTAMP_FILE = "last_compilation_preprocessing.timestamp"; // File to store the last compilation time const params = { SYSTEM_CONTRACTS_OFFSET: "0x8000", @@ -17,6 +19,18 @@ async function preprocess(testMode: boolean) { params.SYSTEM_CONTRACTS_OFFSET = "0x9000"; } + const timestampFilePath = path.join(process.cwd(), TIMESTAMP_FILE); + const folderToCheck = path.join(process.cwd(), CONTRACTS_DIR); + + if ((await isFolderEmpty(OUTPUT_DIR)) || needsRecompilation(folderToCheck, timestampFilePath) || testMode) { + console.log("Preprocessing needed."); + deleteDir(OUTPUT_DIR); + setCompilationTime(timestampFilePath); + } else { + console.log("Preprocessing not needed."); + return; + } + const contracts = await glob( [`${CONTRACTS_DIR}/**/*.sol`, `${CONTRACTS_DIR}/**/*.yul`, `${CONTRACTS_DIR}/**/*.zasm`], { onlyFiles: true } diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts index 3a4e7bad4..3314abb83 100644 --- a/system-contracts/scripts/utils.ts +++ b/system-contracts/scripts/utils.ts @@ -7,6 +7,7 @@ import type { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import type { BigNumberish, BytesLike } from "ethers"; import { BigNumber, ethers } from "ethers"; import * as fs from "fs"; +import * as fsPr from "fs/promises"; import { hashBytecode } from "zksync-web3/build/src/utils"; import type { YulContractDescription, ZasmContractDescription } from "./constants"; import { Language, SYSTEM_CONTRACTS } from "./constants"; @@ -253,3 +254,75 @@ export function prepareCompilerPaths(path: string): CompilerPaths { return new CompilerPaths(absolutePathSources, absolutePathArtifacts); } + +// Get the latest file modification time in the watched folder +function getLatestModificationTime(folder: string): Date | null { + const files = fs.readdirSync(folder); + let latestTime: Date | null = null; // Initialize to null to avoid uninitialized variable + + files.forEach((file) => { + const filePath = path.join(folder, file); + const stats = fs.statSync(filePath); + if (stats.isDirectory()) { + const dirLatestTime = getLatestModificationTime(filePath); + if (dirLatestTime && (!latestTime || dirLatestTime > latestTime)) { + latestTime = dirLatestTime; + } + } else if (stats.isFile()) { + if (!latestTime || stats.mtime > latestTime) { + latestTime = stats.mtime; + } + } + }); + + return latestTime; +} + +// Read the last compilation timestamp from the file +export function getLastCompilationTime(timestampFile: string): Date | null { + try { + if (fs.existsSync(timestampFile)) { + const timestamp = fs.readFileSync(timestampFile, "utf-8"); + return new Date(parseInt(timestamp, 10)); + } + } catch (error) { + const err = error as Error; // Cast `error` to `Error` + console.error(`Error reading timestamp: ${err.message}`); + } + return null; +} + +// Write the current time to the timestamp file +export function setCompilationTime(timestampFile: string) { + fs.writeFileSync(timestampFile, Date.now().toString()); +} + +// Determine if recompilation is needed +export function needsRecompilation(folder: string, timestampFile: string): boolean { + const lastCompilationTime = getLastCompilationTime(timestampFile); + const latestModificationTime = getLatestModificationTime(folder); + if (!lastCompilationTime) { + return true; // If there's no history, always recompile + } + + return latestModificationTime! > lastCompilationTime; +} + +export function deleteDir(path: string): void { + try { + fs.rmSync(path, { recursive: true, force: true }); // 'recursive: true' deletes all contents, 'force: true' prevents errors if the directory doesn't exist + console.log(`Directory '${path}' deleted successfully.`); + } catch (error) { + console.error(`Error deleting directory '${path}':`, error); + } +} + +export async function isFolderEmpty(folderPath: string): Promise { + try { + const files = await fsPr.readdir(folderPath); // Get a list of files in the folder + return files.length === 0; // If there are no files, the folder is empty + } catch (error) { + console.error("No target folder with artifacts."); + return true; // Return true if an error, as folder doesn't exist. + } +} From 381911ed4fb6397c87fa95615221ac1847af3cdc Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Wed, 24 Apr 2024 17:15:47 +0100 Subject: [PATCH 16/60] fix: get all hyperchains (#403) --- .../contracts/state-transition/StateTransitionManager.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index 7271b253d..c5367dd9b 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -89,7 +89,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own uint256[] memory keys = hyperchainMap.keys(); chainAddresses = new address[](keys.length); for (uint256 i = 0; i < keys.length; i++) { - chainAddresses[i] = hyperchainMap.get(i); + chainAddresses[i] = hyperchainMap.get(keys[i]); } } From 670434de8845f5128826e2166c083e4407c209d7 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Wed, 24 Apr 2024 13:53:49 -0400 Subject: [PATCH 17/60] chore(executor): remove constraint on pubdata hash for validiums (#404) --- .../contracts/state-transition/chain-deps/facets/Executor.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 506379eb4..b5c977879 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -51,7 +51,6 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { bytes32[] memory blobCommitments = new bytes32[](MAX_NUMBER_OF_BLOBS); if (pricingMode == PubdataPricingMode.Validium) { // skipping data validation for validium, we just check that the data is empty - require(logOutput.pubdataHash == 0x00, "v0h"); require(_newBatch.pubdataCommitments.length == 1, "EF: v0l"); } else if (pubdataSource == uint8(PubdataSource.Blob)) { // In this scenario, pubdataCommitments is a list of: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)) = 144 bytes From 809942502197ba8453a6c9af390bba5a13da4704 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Wed, 24 Apr 2024 21:48:48 +0200 Subject: [PATCH 18/60] Update L1SharedBridge.sol (#405) --- l1-contracts/contracts/bridge/L1SharedBridge.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index d0b4898fe..f74a771b0 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -37,10 +37,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade IBridgehub public immutable override BRIDGE_HUB; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 public immutable ERA_CHAIN_ID; /// @dev The address of zkSync Era diamond proxy contract. - address immutable ERA_DIAMOND_PROXY; + address public immutable ERA_DIAMOND_PROXY; /// @dev Stores the first batch number on the zkSync Era Diamond Proxy that was settled after Diamond proxy upgrade. /// This variable is used to differentiate between pre-upgrade and post-upgrade Eth withdrawals. Withdrawals from batches older From 78d339fecd0ffb48c7addb4627948a0c4f93de9b Mon Sep 17 00:00:00 2001 From: koloz193 Date: Wed, 24 Apr 2024 16:24:14 -0400 Subject: [PATCH 19/60] chore(scripts): update setValidium to setPubdataPricing (#406) --- l1-contracts/src.ts/deploy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 3039e2c49..b256d7e39 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -750,7 +750,7 @@ export class Deployer { } if (validiumMode) { - const tx5 = await diamondProxy.setValidiumMode(PubdataPricingMode.Validium); + const tx5 = await diamondProxy.setPubdataPricingMode(PubdataPricingMode.Validium); const receipt5 = await tx5.wait(); if (this.verbose) { console.log(`Validium mode set, gas used: ${receipt5.gasUsed.toString()}`); From f78faf0e0b1a75cda7aa55a12545a86c307c8fa3 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Thu, 25 Apr 2024 10:50:07 +0200 Subject: [PATCH 20/60] Accept ownership script (#409) --- l1-contracts/package.json | 3 +- .../scripts/governance-accept-ownership.ts | 134 ++++++++++++++++++ 2 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 l1-contracts/scripts/governance-accept-ownership.ts diff --git a/l1-contracts/package.json b/l1-contracts/package.json index 7363c96c6..bd0f75fac 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -79,7 +79,8 @@ "hyperchain-upgrade-2": "ts-node scripts/hyperchain-upgrade-2.ts", "hyperchain-upgrade-3": "ts-node scripts/hyperchain-upgrade-3.ts", "token-migration": "ts-node scripts/token-migration.ts", - "setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts" + "setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts", + "governance-accept-ownership": "ts-node scripts/governance-accept-ownership.ts" }, "dependencies": { "dotenv": "^16.0.3", diff --git a/l1-contracts/scripts/governance-accept-ownership.ts b/l1-contracts/scripts/governance-accept-ownership.ts new file mode 100644 index 000000000..e111f0ba3 --- /dev/null +++ b/l1-contracts/scripts/governance-accept-ownership.ts @@ -0,0 +1,134 @@ +/// This script is needed to migrate the ownership for key contracts to the governance multisig + +// hardhat import should be the first import in the file +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as hardhat from "hardhat"; +import { Command } from "commander"; +import { Wallet, ethers } from "ethers"; +import { formatUnits, parseUnits, Interface } from "ethers/lib/utils"; +import { web3Provider, GAS_MULTIPLIER } from "./utils"; +import { ethTestConfig } from "../src.ts/utils"; + +const ownable2StepInterface = new Interface(hardhat.artifacts.readArtifactSync("ValidatorTimelock").abi); +const governanceInterface = new Interface(hardhat.artifacts.readArtifactSync("Governance").abi); + +const provider = web3Provider(); + +async function main() { + const program = new Command(); + + program.version("0.1.0").name("upgrade-shared-bridge-era").description("upgrade shared bridge for era diamond proxy"); + + program + .command("transfer-ownership") + .option("--private-key ") + .option("--gas-price ") + .option("--nonce ") + .option("--owner-address ") + .option("--validator-timelock-addr ") + .option("--stm-addr ") + .option("--l1-shared-bridge-addr ") + .option("--bridgehub-addr ") + .option("--proxy-admin-addr ") + .option("--only-verifier") + .action(async (cmd) => { + const deployWallet = cmd.privateKey + ? new Wallet(cmd.privateKey, provider) + : Wallet.fromMnemonic( + process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, + "m/44'/60'/0'/0/1" + ).connect(provider); + console.log(`Using deployer wallet: ${deployWallet.address}`); + + const ownerAddress = ethers.utils.getAddress(cmd.ownerAddress); + console.log(`Using owner address: ${ownerAddress}`); + + const gasPrice = cmd.gasPrice + ? parseUnits(cmd.gasPrice, "gwei") + : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); + console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); + + const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); + console.log(`Using nonce: ${nonce}`); + + // Moving ownership for ValidatorTimelock + const validatorTimelockAddr = ethers.utils.getAddress(cmd.validatorTimelockAddr); + console.log(`Using ValidatorTimelock address: ${validatorTimelockAddr}`); + const stmAddr = ethers.utils.getAddress(cmd.stmAddr); + console.log("Using STM address: ", stmAddr); + const l1SharedBridgeAddr = ethers.utils.getAddress(cmd.l1SharedBridgeAddr); + console.log("Using L1 Shared Bridge address: ", l1SharedBridgeAddr); + const bridgehubAddr = ethers.utils.getAddress(cmd.bridgehubAddr); + console.log("Using Bridgehub address: ", bridgehubAddr); + const proxyAdminAddr = ethers.utils.getAddress(cmd.proxyAdminAddr); + console.log("Using Proxy Admin address: ", proxyAdminAddr); + + await transferOwnership1StepTo(deployWallet, validatorTimelockAddr, ownerAddress); + await transferOwnership1StepTo(deployWallet, stmAddr, ownerAddress); + await transferOwnership1StepTo(deployWallet, l1SharedBridgeAddr, ownerAddress); + await transferOwnership1StepTo(deployWallet, bridgehubAddr, ownerAddress); + await transferOwnership1StepTo(deployWallet, proxyAdminAddr, ownerAddress); + }); + + program + .command("accept-ownership") + .option("--validator-timelock-addr ") + .option("--stm-addr ") + .option("--l1-shared-bridge-addr ") + .option("--bridgehub-addr ") + .action(async (cmd) => { + // Moving ownership for ValidatorTimelock + const validatorTimelockAddr = ethers.utils.getAddress(cmd.validatorTimelockAddr); + console.log(`Using ValidatorTimelock address: ${validatorTimelockAddr}`); + const stmAddr = ethers.utils.getAddress(cmd.stmAddr); + console.log("Using STM address: ", stmAddr); + const l1SharedBridgeAddr = ethers.utils.getAddress(cmd.l1SharedBridgeAddr); + console.log("Using L1 Shared Bridge address: ", l1SharedBridgeAddr); + const bridgehubAddr = ethers.utils.getAddress(cmd.bridgehubAddr); + console.log("Using Bridgehub address: ", bridgehubAddr); + + const addresses = [validatorTimelockAddr, stmAddr, l1SharedBridgeAddr, bridgehubAddr]; + + const govCalls = addresses.map(acceptOwnershipCall); + + const govOperation = { + calls: govCalls, + predecessor: ethers.constants.HashZero, + salt: ethers.constants.HashZero, + }; + + const scheduleData = governanceInterface.encodeFunctionData("scheduleTransparent", [govOperation, 0]); + const executeData = governanceInterface.encodeFunctionData("execute", [govOperation]); + + console.log("Calldata for scheduling: ", scheduleData); + console.log("Calldata for execution: ", executeData); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); + +async function transferOwnership1StepTo(wallet: ethers.Wallet, contractAddress: string, newOwner: string) { + const contract = new ethers.Contract(contractAddress, ownable2StepInterface, wallet); + console.log("Transferring ownership of contract: ", contractAddress, " to: ", newOwner); + const tx = await contract.transferOwnership(newOwner); + console.log("Tx hash", tx.hash); + await tx.wait(); + const newPendingOwner = await contract.pendingOwner(); + console.log("New pending owner: ", newPendingOwner); +} + +function acceptOwnershipCall(target: string) { + const data = ownable2StepInterface.encodeFunctionData("acceptOwnership", []); + return { + target, + value: 0, + data, + }; +} From f9ccb10d8a77db4f56941418cde82d5d5ccf02a1 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Fri, 26 Apr 2024 14:38:39 +0200 Subject: [PATCH 21/60] Script to cross check the contracts from the upgrade (#408) Co-authored-by: kelemeno Co-authored-by: kelemeno <34402761+kelemeno@users.noreply.github.com> Co-authored-by: koloz193 --- l1-contracts/package.json | 1 + .../scripts/upgrade-consistency-checker.ts | 550 ++++++++++++++++++ l1-contracts/src.ts/deploy-test-process.ts | 22 +- l1-contracts/src.ts/deploy.ts | 21 +- .../hyperchain_migration_test.spec.ts | 41 -- l2-contracts/package.json | 3 +- .../src/upgrade-consistency-checker.ts | 129 ++++ 7 files changed, 697 insertions(+), 70 deletions(-) create mode 100644 l1-contracts/scripts/upgrade-consistency-checker.ts delete mode 100644 l1-contracts/test/unit_tests/hyperchain_migration_test.spec.ts create mode 100644 l2-contracts/src/upgrade-consistency-checker.ts diff --git a/l1-contracts/package.json b/l1-contracts/package.json index bd0f75fac..e7dc65632 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -80,6 +80,7 @@ "hyperchain-upgrade-3": "ts-node scripts/hyperchain-upgrade-3.ts", "token-migration": "ts-node scripts/token-migration.ts", "setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts", + "upgrade-consistency-checker": "ts-node scripts/upgrade-consistency-checker.ts", "governance-accept-ownership": "ts-node scripts/governance-accept-ownership.ts" }, "dependencies": { diff --git a/l1-contracts/scripts/upgrade-consistency-checker.ts b/l1-contracts/scripts/upgrade-consistency-checker.ts new file mode 100644 index 000000000..ae2d994d1 --- /dev/null +++ b/l1-contracts/scripts/upgrade-consistency-checker.ts @@ -0,0 +1,550 @@ +/// This is the script to double check the consistency of the upgrade +/// It is yet to be refactored. + +// hardhat import should be the first import in the file +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as hardhat from "hardhat"; +import { Command } from "commander"; +import { web3Url } from "./utils"; +import { BigNumber, ethers } from "ethers"; +import { utils } from "zksync-ethers"; +import type { FacetCut } from "../src.ts/diamondCut"; +import { getCurrentFacetCutsForAdd } from "../src.ts/diamondCut"; + +// Things that still have to be manually double checked: +// 1. Contracts must be verified. +// 2. Getter methods in STM. + +// List the contracts that should become the upgrade targets +const genesisUpgrade = "0xDdc72e56A3b90793271FF0EA9a762294f163F992"; +const validatorTimelockDeployTx = "0x1ada4121db6e83bfe38f1f92e31c0931e2f0f2b830429841a7d264c56cceb8b0"; +const validatorTimelock = "0xc47CBbc601dbB65439e7b02B0d19bbA9Dba57442"; +const upgradeHyperchains = "0xc029cE1EB5C61C4a3B2a6EE920bb3B7b026bc00b"; + +const verifier = "0x82856fED36d36e1d4db24398bC2056C440cB45FC"; +const proxyAdmin = "0xCb7F8e556Ef02771eA32F54e767D6F9742ED31c2"; + +const bridgeHubImpl = "0x22c456Cb8E657bD48e14E9a54CE20169d78CB0F7"; +const bridgeHub = "0x236D1c3Ff32Bd0Ca26b72Af287E895627c0478cE"; + +const executorFacet = "0xd56f4696ecbE9ADc2e1539F5311ae6C92F4B2BAd"; +const adminFacet = "0x21924127192db478faDf6Ae07f57df928EBCA6AE"; +const mailboxFacetDeployTx = "0xad8028a8a1c7fe71e40fb6e32b80f5893b6b26af5475d9a014b9510faf460090"; +const mailboxFacet = "0x445aD49fC6d1845ec774783659aA5351381b0c49"; +const gettersFacet = "0xbF4C2dfBe9E722F0A87E104c3af5780d49872745"; + +const diamondInit = "0x17384Fd6Cc64468b69df514A940caC89B602d01c"; + +const stmImplDeployTx = "0x6dacf003368a922b9f916393f3c11c869c1f614c16345667cabd1d8b890ec0cb"; +const stmImpl = "0x91E088D2F36500c4826E5623c9C14Dd90912c23E"; +const stmDeployTx = "0x11ceebf3d0b95a4a49f798c937fd3e0085dc01a4e5d497b60b5072b13e58235a"; +const stm = "0x6F03861D12E6401623854E494beACd66BC46e6F0"; + +const sharedBridgeImplDeployTx = "0x6dacf003368a922b9f916393f3c11c869c1f614c16345667cabd1d8b890ec0cb"; +const sharedBridgeImpl = "0x91E088D2F36500c4826E5623c9C14Dd90912c23E"; +const sharedBridgeProxy = "0x6F03861D12E6401623854E494beACd66BC46e6F0"; + +const legacyBridgeImplDeployTx = "0xc0640213aa843f812c44d63723b5dc03064d8e5a32d85e94689e3273df6c3ef5"; +const legacyBridgeImpl = "0x8fE595B3f92AA34962d7A8aF106Fa50A3e4FC6fA"; + +const expectedL1WethAddress = "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9"; +const initialOwner = "0x343Ee72DdD8CCD80cd43D6Adbc6c463a2DE433a7"; +const expectedOwner = "0x343Ee72DdD8CCD80cd43D6Adbc6c463a2DE433a7"; +const expectedDelay = 0; +const eraChainId = 270; +const expectedSalt = "0x0000000000000000000000000000000000000000000000000000000000000005"; +const expectedHyperchainAddr = "0x6d6e010A2680E2E5a3b097ce411528b36d880EF6"; +const maxNumberOfHyperchains = 100; +const expectedStoredBatchHashZero = "0x53dc316f108d1b64412be840e0ab89193e94ba6c4af8b9ca57d39ad4d782e0f4"; +const expectedL2BridgeAddress = "0xCEB8d4888d2025aEaAD0272175281e0CaFC33152"; +const expectedL1LegacyBridge = "0x7303B5Ce64f1ADB0558572611a0b90620b6dd5F4"; +const expectedGenesisBatchCommitment = "0x49276362411c40c07ab01d3dfa9428abca95e361d8c980cd39f1ab6a9c561c0c"; +const expectedIndexRepeatedStorageChanges = BigNumber.from(54); +const expectedProtocolVersion = 23; +const expectedGenesisRoot = "0xabdb766b18a479a5c783a4b80e12686bc8ea3cc2d8a3050491b701d72370ebb5"; +const expectedRecursionNodeLevelVkHash = "0xf520cd5b37e74e19fdb369c8d676a04dce8a19457497ac6686d2bb95d94109c8"; +const expectedRecursionLeafLevelVkHash = "0x435202d277dd06ef3c64ddd99fda043fc27c2bd8b7c66882966840202c27f4f6"; +const expectedRecursionCircuitsSetVksHash = "0x0000000000000000000000000000000000000000000000000000000000000000"; +const expectedBootloaderHash = "0x010008e7f0f15ed191392960117f88fe371348982b28a033c7207ed2c09bc0f4"; +const expectedDefaultAccountHash = "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32"; + +const expectedGovernance = "0xEE73438083629026FAfA1f5F5bBE2bBD6Bad6331"; +const validatorOne = "0x0000000000000000000000000000000000000000"; // to do find +const validatorTwo = "0x0000000000000000000000000000000000000000"; // to do find + +const l1Provider = new ethers.providers.JsonRpcProvider(web3Url()); + +async function checkIdenticalBytecode(addr: string, contract: string) { + const correctCode = (await hardhat.artifacts.readArtifact(contract)).deployedBytecode; + const currentCode = await l1Provider.getCode(addr); + + if (ethers.utils.keccak256(currentCode) == ethers.utils.keccak256(correctCode)) { + console.log(contract, "bytecode is correct"); + } else { + throw new Error(contract + " bytecode is not correct"); + } +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +async function checkCorrectInitCode(txHash: string, contract: ethers.Contract, bytecode: string, params: any[]) { + const deployTx = await l1Provider.getTransaction(txHash); + const usedInitCode = await extractInitCode(deployTx.data); + const correctConstructorData = contract.interface.encodeDeploy(params); + const correctInitCode = ethers.utils.hexConcat([bytecode, correctConstructorData]); + if (usedInitCode.toLowerCase() !== correctInitCode.toLowerCase()) { + throw new Error("Init code is not correct"); + } +} + +async function extractInitCode(data: string) { + const create2FactoryAbi = (await hardhat.artifacts.readArtifact("SingletonFactory")).abi; + + const iface = new ethers.utils.Interface(create2FactoryAbi); + const initCode = iface.parseTransaction({ data }).args._initCode; + const salt = iface.parseTransaction({ data }).args._salt; + if (salt !== expectedSalt) { + throw new Error("Salt is not correct"); + } + + return initCode; +} + +async function extractProxyInitializationData(contract: ethers.Contract, data: string) { + const initCode = await extractInitCode(data); + + const artifact = await hardhat.artifacts.readArtifact("TransparentUpgradeableProxy"); + + // Deployment tx is a concatenation of the init code and the constructor data + // constructor has the following type `constructor(address _logic, address admin_, bytes memory _data)` + + const constructorData = "0x" + initCode.slice(artifact.bytecode.length); + + const [, , initializeCode] = ethers.utils.defaultAbiCoder.decode(["address", "address", "bytes"], constructorData); + + // Now time to parse the initialize code + const parsedData = contract.interface.parseTransaction({ data: initializeCode }); + const initializeData = { + ...parsedData.args._initializeData, + }; + + const usedInitialOwner = initializeData.owner; + if (usedInitialOwner.toLowerCase() !== initialOwner.toLowerCase()) { + throw new Error("Initial owner is not correct"); + } + + const usedValidatorTimelock = initializeData.validatorTimelock; + if (usedValidatorTimelock.toLowerCase() !== validatorTimelock.toLowerCase()) { + throw new Error("Validator timelock is not correct"); + } + const usedGenesisUpgrade = initializeData.genesisUpgrade; + if (usedGenesisUpgrade.toLowerCase() !== genesisUpgrade.toLowerCase()) { + throw new Error("Genesis upgrade is not correct"); + } + const usedGenesisBatchHash = initializeData.genesisBatchHash; + if (usedGenesisBatchHash.toLowerCase() !== expectedGenesisRoot.toLowerCase()) { + throw new Error("Genesis batch hash is not correct"); + } + const usedGenesisIndexRepeatedStorageChanges = initializeData.genesisIndexRepeatedStorageChanges; + if (!usedGenesisIndexRepeatedStorageChanges.eq(expectedIndexRepeatedStorageChanges)) { + throw new Error("Genesis index repeated storage changes is not correct"); + } + + const usedGenesisBatchCommitment = initializeData.genesisBatchCommitment; + if (usedGenesisBatchCommitment.toLowerCase() !== expectedGenesisBatchCommitment.toLowerCase()) { + throw new Error("Genesis batch commitment is not correct"); + } + + const usedProtocolVersion = initializeData.protocolVersion; + if (!usedProtocolVersion.eq(expectedProtocolVersion)) { + throw new Error("Protocol version is not correct"); + } + + const diamondCut = initializeData.diamondCut; + + if (diamondCut.initAddress.toLowerCase() !== diamondInit.toLowerCase()) { + throw new Error("Diamond init address is not correct"); + } + + const expectedFacetCuts: FacetCut[] = Object.values( + await getCurrentFacetCutsForAdd(adminFacet, gettersFacet, mailboxFacet, executorFacet) + ); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const usedFacetCuts = diamondCut.facetCuts.map((fc: any) => { + return { + facet: fc.facet, + selectors: fc.selectors, + action: fc.action, + isFreezable: fc.isFreezable, + }; + }); + + // Now sort to compare + expectedFacetCuts.sort((a, b) => a.facet.localeCompare(b.facet)); + usedFacetCuts.sort((a, b) => a.facet.localeCompare(b.facet)); + + if (expectedFacetCuts.length !== usedFacetCuts.length) { + throw new Error("Facet cuts length is not correct"); + } + + for (let i = 0; i < expectedFacetCuts.length; i++) { + const used = usedFacetCuts[i]; + const expected = expectedFacetCuts[i]; + + if (used.facet !== expected.facet) { + throw new Error(`Facet ${i} is not correct`); + } + + // For the array of selectors it is just easier to hexconcat them and compare + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const usedSelectors = ethers.utils.hexConcat(Array.from(used.selectors).sort() as any[]); + const expectedSelectors = ethers.utils.hexConcat(expected.selectors.sort()); + if (usedSelectors !== expectedSelectors) { + throw new Error(`Facet ${i} selectors are not correct`); + } + + if (used.action !== expected.action) { + throw new Error(`Facet ${i} action is not correct`); + } + + if (used.isFreezable !== expected.isFreezable) { + throw new Error(`Facet ${i} isFreezable is not correct`); + } + } + + const [ + usedVerifier, + + // We just unpack verifier params here + recursionNodeLevelVkHash, + recursionLeafLevelVkHash, + recursionCircuitsSetVksHash, + + l2BootloaderBytecodeHash, + l2DefaultAccountBytecodeHash, + // priorityTxMaxGasLimit, + + // // We unpack fee params + // pubdataPricingMode, + // batchOverheadL1Gas, + // maxPubdataPerBatch, + // priorityTxMaxPubdata, + // maxL2GasPerBatch, + // minimalL2GasPrice, + + // blobVersionedHashRetriever + ] = ethers.utils.defaultAbiCoder.decode( + [ + "address", + "bytes32", + "bytes32", + "bytes32", + "bytes32", + "bytes32", + "uint256", + "uint256", + "uint256", + "uint256", + "uint256", + "uint256", + "uint256", + "address", + ], + diamondCut.initCalldata + ); + + if (usedVerifier.toLowerCase() !== verifier.toLowerCase()) { + throw new Error("Verifier is not correct"); + } + + if (recursionNodeLevelVkHash.toLowerCase() !== expectedRecursionNodeLevelVkHash.toLowerCase()) { + throw new Error("Recursion node level vk hash is not correct"); + } + + if (recursionLeafLevelVkHash.toLowerCase() !== expectedRecursionLeafLevelVkHash.toLowerCase()) { + throw new Error("Recursion leaf level vk hash is not correct"); + } + + if (recursionCircuitsSetVksHash.toLowerCase() !== expectedRecursionCircuitsSetVksHash.toLowerCase()) { + throw new Error("Recursion circuits set vks hash is not correct"); + } + + if (l2BootloaderBytecodeHash.toLowerCase() !== expectedBootloaderHash.toLowerCase()) { + throw new Error("L2 bootloader bytecode hash is not correct"); + } + + if (l2DefaultAccountBytecodeHash.toLowerCase() !== expectedDefaultAccountHash.toLowerCase()) { + throw new Error("L2 default account bytecode hash is not correct"); + } + + console.log("STM init data correct!"); +} + +async function checkValidatorTimelock() { + const artifact = await hardhat.artifacts.readArtifact("ValidatorTimelock"); + const contract = new ethers.Contract(validatorTimelock, artifact.abi, l1Provider); + + const owner = await contract.owner(); + if (owner.toLowerCase() != expectedOwner.toLowerCase()) { + throw new Error("ValidatorTimelock owner is not correct"); + } + + const usedStm = await contract.stateTransitionManager(); + if (usedStm.toLowerCase() != stm.toLowerCase()) { + throw new Error("ValidatorTimelock stateTransitionManager is not correct"); + } + + const validatorOneIsSet = await contract.validators(eraChainId, validatorOne); + if (!validatorOneIsSet) { + throw new Error("ValidatorTimelock validatorOne is not correct"); + } + + const validatorTwoIsSet = await contract.validators(eraChainId, validatorTwo); + if (!validatorTwoIsSet) { + throw new Error("ValidatorTimelock validatorTwo is not correct"); + } + + await checkCorrectInitCode(validatorTimelockDeployTx, contract, artifact.bytecode, [ + initialOwner, + expectedDelay, + eraChainId, + ]); + + console.log("ValidatorTimelock is correct!"); +} + +async function checkBridgehub() { + const artifact = await hardhat.artifacts.readArtifact("Bridgehub"); + const contract = new ethers.Contract(bridgeHub, artifact.abi, l1Provider); + + const owner = await contract.owner(); + if (owner.toLowerCase() != expectedOwner.toLowerCase()) { + throw new Error("ValidatorTimelock owner is not correct"); + } + + const baseToken = await contract.baseToken(eraChainId); + if (baseToken.toLowerCase() != utils.ETH_ADDRESS_IN_CONTRACTS) { + throw new Error("Bridgehub baseToken is not correct"); + } + + const hyperchain = await contract.getHyperchain(eraChainId); + if (hyperchain.toLowerCase() != expectedHyperchainAddr.toLowerCase()) { + throw new Error("Bridgehub hyperchain is not correct"); + } + + const sharedBridge = await contract.sharedBridge(); + if (sharedBridge.toLowerCase() != sharedBridgeProxy.toLowerCase()) { + throw new Error("Bridgehub sharedBridge is not correct"); + } + + const usedSTM = await contract.stateTransitionManager(eraChainId); + if (usedSTM.toLowerCase() != stm.toLowerCase()) { + throw new Error("Bridgehub stateTransitionManager is not correct"); + } + + const isRegistered = await contract.stateTransitionManagerIsRegistered(usedSTM); + if (!isRegistered) { + throw new Error("Bridgehub stateTransitionManager is not registered"); + } + + const tokenIsRegistered = await contract.tokenIsRegistered(utils.ETH_ADDRESS_IN_CONTRACTS); + if (!tokenIsRegistered) { + throw new Error("Bridgehub token is not registered"); + } + + console.log("Bridgehub is correct!"); +} + +async function checkMailbox() { + const artifact = await hardhat.artifacts.readArtifact("MailboxFacet"); + const contract = new ethers.Contract(mailboxFacet, artifact.abi, l1Provider); + + await checkCorrectInitCode(mailboxFacetDeployTx, contract, artifact.bytecode, [eraChainId]); + console.log("Mailbox is correct!"); +} + +async function checkUpgradeHyperchainParams() { + const artifact = await hardhat.artifacts.readArtifact("GettersFacet"); + const contract = new ethers.Contract(expectedHyperchainAddr, artifact.abi, l1Provider); + + // Note: there is no getters for chainId + const setBridgehub = await contract.getBridgehub(); + if (setBridgehub != bridgeHub) { + throw new Error("Bridgehub is not set in Era correctly"); + } + const setStateTransitionManager = await contract.getStateTransitionManager(); + if (setStateTransitionManager != stm) { + throw new Error("Bridgehub is not set in Era correctly"); + } + const setBaseTokenBridge = await contract.getBaseTokenBridge(); + if (setBaseTokenBridge != sharedBridgeProxy) { + throw new Error("Bridgehub is not set in Era correctly"); + } + const setBaseToken = await contract.getBaseToken(); + if (setBaseToken != utils.ETH_ADDRESS_IN_CONTRACTS) { + throw new Error("Bridgehub is not set in Era correctly"); + } + const baseTokenGasPriceMultiplierNominator = await contract.baseTokenGasPriceMultiplierNominator(); + if (baseTokenGasPriceMultiplierNominator != 1) { + throw new Error("baseTokenGasPriceMultiplierNominator is not set in Era correctly"); + } + const baseTokenGasPriceMultiplierDenominator = await contract.baseTokenGasPriceMultiplierDenominator(); + if (baseTokenGasPriceMultiplierDenominator != 1) { + throw new Error("baseTokenGasPriceMultiplierDenominator is not set in Era correctly"); + } + const admin = await contract.getAdmin(); + if (admin != expectedGovernance) { + throw new Error("admin is not set in Era correctly"); + } + const validatorTimelockIsRegistered = await contract.isValidator(validatorTimelock); + if (!validatorTimelockIsRegistered) { + throw new Error("Bridgehub is not set in Era correctly"); + } + console.log("Validator timelock and admin is set correctly in Era!"); +} + +async function checkSTMImpl() { + const artifact = await hardhat.artifacts.readArtifact("StateTransitionManager"); + const contract = new ethers.Contract(stmImpl, artifact.abi, l1Provider); + + await checkCorrectInitCode(stmImplDeployTx, contract, artifact.bytecode, [bridgeHub, maxNumberOfHyperchains]); + + console.log("STM impl correct!"); +} + +async function checkSTM() { + const artifact = await hardhat.artifacts.readArtifact("StateTransitionManager"); + + const contract = new ethers.Contract(stm, artifact.abi, l1Provider); + + const usedBH = await contract.BRIDGE_HUB(); + if (usedBH.toLowerCase() != bridgeHub.toLowerCase()) { + throw new Error("STM bridgeHub is not correct"); + } + const usedMaxNumberOfHyperchains = (await contract.MAX_NUMBER_OF_HYPERCHAINS()).toNumber(); + if (usedMaxNumberOfHyperchains != maxNumberOfHyperchains) { + throw new Error("STM maxNumberOfHyperchains is not correct"); + } + + const genUpgrade = await contract.genesisUpgrade(); + if (genUpgrade.toLowerCase() != genesisUpgrade.toLowerCase()) { + throw new Error("STM genesisUpgrade is not correct"); + } + + const storedBatchHashZero = await contract.storedBatchZero(); + if (storedBatchHashZero.toLowerCase() != expectedStoredBatchHashZero.toLowerCase()) { + throw new Error("STM storedBatchHashZero is not correct"); + } + + const currentOwner = await contract.owner(); + if (currentOwner.toLowerCase() != expectedOwner.toLowerCase()) { + throw new Error("STM owner is not correct"); + } + + console.log("STM is correct!"); + + await extractProxyInitializationData(contract, (await l1Provider.getTransaction(stmDeployTx)).data); +} + +async function checkL1SharedBridgeImpl() { + const artifact = await hardhat.artifacts.readArtifact("L1SharedBridge"); + const contract = new ethers.Contract(sharedBridgeImpl, artifact.abi, l1Provider); + + await checkCorrectInitCode(sharedBridgeImplDeployTx, contract, artifact.bytecode, [ + expectedL1WethAddress, + bridgeHub, + eraChainId, + expectedHyperchainAddr, + ]); + + console.log("L1 shared bridge impl correct!"); +} + +async function checkSharedBridge() { + const artifact = await hardhat.artifacts.readArtifact("L1SharedBridge"); + const contract = new ethers.Contract(sharedBridgeProxy, artifact.abi, l1Provider); + + const l2BridgeAddr = await contract.l2BridgeAddress(eraChainId); + if (l2BridgeAddr.toLowerCase() != expectedL2BridgeAddress.toLowerCase()) { + throw new Error("Shared bridge l2BridgeAddress is not correct"); + } + + const usedLegacyBridge = await contract.legacyBridge(); + if (usedLegacyBridge.toLowerCase() != expectedL1LegacyBridge.toLowerCase()) { + throw new Error("Shared bridge legacyBridge is not correct"); + } + + const usedOwner = await contract.owner(); + if (usedOwner.toLowerCase() != expectedOwner.toLowerCase()) { + throw new Error("Shared bridge owner is not correct"); + } + + console.log("L1 shared bridge correct!"); +} + +async function checkLegacyBridge() { + const artifact = await hardhat.artifacts.readArtifact("L1ERC20Bridge"); + const contract = new ethers.Contract(legacyBridgeImpl, artifact.abi, l1Provider); + + await checkCorrectInitCode(legacyBridgeImplDeployTx, contract, artifact.bytecode, [sharedBridgeProxy]); + + console.log("L1 shared bridge impl correct!"); +} + +async function checkProxyAdmin() { + await checkIdenticalBytecode(proxyAdmin, "ProxyAdmin"); + + const artifact = await hardhat.artifacts.readArtifact("ProxyAdmin"); + const contract = new ethers.Contract(proxyAdmin, artifact.abi, l1Provider); + + const currentOwner = await contract.owner(); + if (currentOwner.toLowerCase() != expectedOwner.toLowerCase()) { + throw new Error("ProxyAdmin owner is not correct"); + } + + console.log("ProxyAdmin is correct!"); +} + +async function main() { + const program = new Command(); + + program + .version("0.1.0") + .name("upgrade-consistency-checker") + .description("upgrade shared bridge for era diamond proxy"); + + program.action(async () => { + await checkIdenticalBytecode(genesisUpgrade, "GenesisUpgrade"); + await checkIdenticalBytecode(upgradeHyperchains, "UpgradeHyperchains"); + await checkIdenticalBytecode(executorFacet, "ExecutorFacet"); + await checkIdenticalBytecode(gettersFacet, "GettersFacet"); + await checkIdenticalBytecode(adminFacet, "AdminFacet"); + await checkIdenticalBytecode(bridgeHubImpl, "Bridgehub"); + await checkIdenticalBytecode(verifier, "TestnetVerifier"); + await checkIdenticalBytecode(diamondInit, "DiamondInit"); + + await checkMailbox(); + await checkUpgradeHyperchainParams(); + + await checkProxyAdmin(); + + await checkValidatorTimelock(); + await checkBridgehub(); + + await checkL1SharedBridgeImpl(); + await checkSharedBridge(); + + await checkLegacyBridge(); + + await checkSTMImpl(); + await checkSTM(); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); diff --git a/l1-contracts/src.ts/deploy-test-process.ts b/l1-contracts/src.ts/deploy-test-process.ts index a831197b6..ac5665a3b 100644 --- a/l1-contracts/src.ts/deploy-test-process.ts +++ b/l1-contracts/src.ts/deploy-test-process.ts @@ -44,9 +44,8 @@ export async function loadDefaultEnvVarsForTests(deployWallet: Wallet) { process.env.CONTRACTS_GENESIS_BATCH_COMMITMENT = ethers.constants.HashZero; // process.env.CONTRACTS_GENESIS_UPGRADE_ADDR = ADDRESS_ONE; process.env.CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT = "72000000"; - process.env.CONTRACTS_RECURSION_NODE_LEVEL_VK_HASH = ethers.constants.HashZero; - process.env.CONTRACTS_RECURSION_LEAF_LEVEL_VK_HASH = ethers.constants.HashZero; - process.env.CONTRACTS_RECURSION_CIRCUITS_SET_VKS_HASH = ethers.constants.HashZero; + process.env.CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH = ethers.constants.HashZero; + process.env.CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH = ethers.constants.HashZero; // process.env.CONTRACTS_SHARED_BRIDGE_UPGRADE_STORAGE_SWITCH = "1"; process.env.ETH_CLIENT_CHAIN_ID = (await deployWallet.getChainId()).toString(); process.env.CONTRACTS_ERA_CHAIN_ID = "270"; @@ -261,18 +260,11 @@ export class EraDeployer extends Deployer { ); facetCuts = facetCuts.concat(extraFacets ?? []); - const verifierParams = - process.env["CONTRACTS_PROVER_AT_GENESIS"] == "fri" - ? { - recursionNodeLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH"), - recursionLeafLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH"), - recursionCircuitsSetVksHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - } - : { - recursionNodeLevelVkHash: getHashFromEnv("CONTRACTS_RECURSION_NODE_LEVEL_VK_HASH"), - recursionLeafLevelVkHash: getHashFromEnv("CONTRACTS_RECURSION_LEAF_LEVEL_VK_HASH"), - recursionCircuitsSetVksHash: getHashFromEnv("CONTRACTS_RECURSION_CIRCUITS_SET_VKS_HASH"), - }; + const verifierParams = { + recursionNodeLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH"), + recursionLeafLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH"), + recursionCircuitsSetVksHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + }; const priorityTxMaxGasLimit = getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT"); const DiamondInit = new Interface(hardhat.artifacts.readArtifactSync("DiamondInit").abi); diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index b256d7e39..43f9e3074 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -77,18 +77,11 @@ export class Deployer { ); facetCuts = facetCuts.concat(extraFacets ?? []); - const verifierParams = - process.env["CONTRACTS_PROVER_AT_GENESIS"] == "fri" - ? { - recursionNodeLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH"), - recursionLeafLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH"), - recursionCircuitsSetVksHash: "0x0000000000000000000000000000000000000000000000000000000000000000", - } - : { - recursionNodeLevelVkHash: getHashFromEnv("CONTRACTS_RECURSION_NODE_LEVEL_VK_HASH"), - recursionLeafLevelVkHash: getHashFromEnv("CONTRACTS_RECURSION_LEAF_LEVEL_VK_HASH"), - recursionCircuitsSetVksHash: getHashFromEnv("CONTRACTS_RECURSION_CIRCUITS_SET_VKS_HASH"), - }; + const verifierParams = { + recursionNodeLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH"), + recursionLeafLevelVkHash: getHashFromEnv("CONTRACTS_FRI_RECURSION_LEAF_LEVEL_VK_HASH"), + recursionCircuitsSetVksHash: "0x0000000000000000000000000000000000000000000000000000000000000000", + }; const priorityTxMaxGasLimit = getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT"); const DiamondInit = new Interface(hardhat.artifacts.readArtifactSync("DiamondInit").abi); @@ -233,8 +226,10 @@ export class Deployer { const rec = await proxyAdmin.deployTransaction.wait(); if (this.verbose) { + console.log( + `Proxy admin deployed, gasUsed: ${rec.gasUsed.toString()}, tx hash ${rec.transactionHash}, expected address: ${proxyAdmin.address}` + ); console.log(`CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR=${proxyAdmin.address}`); - console.log(`Proxy admin deployed, gasUsed: ${rec.gasUsed.toString()}`); } this.addresses.TransparentProxyAdmin = proxyAdmin.address; diff --git a/l1-contracts/test/unit_tests/hyperchain_migration_test.spec.ts b/l1-contracts/test/unit_tests/hyperchain_migration_test.spec.ts deleted file mode 100644 index 216bc6fbc..000000000 --- a/l1-contracts/test/unit_tests/hyperchain_migration_test.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as ethers from "ethers"; -import { Wallet } from "ethers"; -import * as hardhat from "hardhat"; - -import type { EraDeployer } from "../../src.ts/deploy-test-process"; -import { initialPreUpgradeContractsDeployment } from "../../src.ts/deploy-test-process"; -import { ethTestConfig } from "../../src.ts/utils"; - -import { upgradeToHyperchains } from "../../src.ts/hyperchain-upgrade"; - -// note this test presumes that it is ok to start out with the new contracts, and upgrade them to themselves -describe("Hyperchain migration test", function () { - let owner: ethers.Signer; - let deployer: EraDeployer; - let gasPrice; - - before(async () => { - [owner] = await hardhat.ethers.getSigners(); - - const deployWallet = Wallet.fromMnemonic(ethTestConfig.test_mnemonic3, "m/44'/60'/0'/0/1").connect(owner.provider); - const ownerAddress = await deployWallet.getAddress(); - - gasPrice = await owner.provider.getGasPrice(); - - const tx = { - from: await owner.getAddress(), - to: deployWallet.address, - value: ethers.utils.parseEther("1000"), - nonce: owner.getTransactionCount(), - gasLimit: 100000, - gasPrice: gasPrice, - }; - await owner.sendTransaction(tx); - - deployer = await initialPreUpgradeContractsDeployment(deployWallet, ownerAddress, gasPrice, []); - }); - - it("Start upgrade", async () => { - await upgradeToHyperchains(deployer, gasPrice); - }); -}); diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 16138754b..c7fecce29 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -45,7 +45,8 @@ "publish-bridge-preimages": "ts-node src/publish-bridge-preimages.ts", "deploy-l2-weth": "ts-node src/deploy-l2-weth.ts", "upgrade-bridge-contracts": "ts-node src/upgrade-bridge-impl.ts", - "update-l2-erc20-metadata": "ts-node src/update-l2-erc20-metadata.ts" + "update-l2-erc20-metadata": "ts-node src/update-l2-erc20-metadata.ts", + "upgrade-consistency-checker": "ts-node src/upgrade-consistency-checker.ts" }, "dependencies": { "dotenv": "^16.0.3" diff --git a/l2-contracts/src/upgrade-consistency-checker.ts b/l2-contracts/src/upgrade-consistency-checker.ts new file mode 100644 index 000000000..74f286eae --- /dev/null +++ b/l2-contracts/src/upgrade-consistency-checker.ts @@ -0,0 +1,129 @@ +/// This is the script to double check the consistency of the upgrade +/// It is yet to be refactored. + +// hardhat import should be the first import in the file +// eslint-disable-next-line @typescript-eslint/no-unused-vars +import * as hardhat from "hardhat"; +import { Command } from "commander"; +import { ethers } from "ethers"; +import { Provider } from "zksync-ethers"; + +// Things that still have to be manually double checked: +// 1. Contracts must be verified. +// 2. Getter methods in STM. + +// List the contracts that should become the upgrade targets +const l2BridgeImplAddr = "0xce0a8c005a73e35d95cec41a9e8b75668470fb8f"; + +const eraChainId = 270; + +const l2Provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); + +async function checkIdenticalBytecode(addr: string, contract: string) { + const correctCode = (await hardhat.artifacts.readArtifact(contract)).deployedBytecode; + const currentCode = await l2Provider.getCode(addr); + + if (ethers.utils.keccak256(currentCode) == ethers.utils.keccak256(correctCode)) { + console.log(contract, "bytecode is correct"); + } else { + throw new Error(contract + " bytecode is not correct"); + } +} + +async function checkL2SharedBridgeImpl() { + await checkIdenticalBytecode(l2BridgeImplAddr, "L2SharedBridge"); + + // In Era we can retrieve the immutable from the simulator + const contract = new ethers.Contract( + "0x0000000000000000000000000000000000008005", + immutableSimulatorAbi(), + l2Provider + ); + + const usedEraChainId = ethers.BigNumber.from(await contract.getImmutable(l2BridgeImplAddr, 0)); + if (!usedEraChainId.eq(ethers.BigNumber.from(eraChainId))) { + throw new Error("Era chain id is not correct"); + } + console.log("L2SharedBridge is correct!"); +} + +async function main() { + const program = new Command(); + + program + .version("0.1.0") + .name("upgrade-consistency-checker") + .description("upgrade shared bridge for era diamond proxy"); + + program.action(async () => { + await checkL2SharedBridgeImpl(); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err); + process.exit(1); + }); + +function immutableSimulatorAbi() { + return [ + { + inputs: [ + { + internalType: "address", + name: "_dest", + type: "address", + }, + { + internalType: "uint256", + name: "_index", + type: "uint256", + }, + ], + name: "getImmutable", + outputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [ + { + internalType: "address", + name: "_dest", + type: "address", + }, + { + components: [ + { + internalType: "uint256", + name: "index", + type: "uint256", + }, + { + internalType: "bytes32", + name: "value", + type: "bytes32", + }, + ], + internalType: "struct ImmutableData[]", + name: "_immutables", + type: "tuple[]", + }, + ], + name: "setImmutables", + outputs: [], + stateMutability: "nonpayable", + type: "function", + }, + ]; +} From b8247267877d2d140de35fa85d1160a0f945d7eb Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Fri, 26 Apr 2024 14:08:29 +0100 Subject: [PATCH 22/60] fix: upgrade hyperchain add missing fields (#415) --- .../contracts/upgrades/UpgradeHyperchains.sol | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol index ded2df649..16ce5f1ca 100644 --- a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol +++ b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol @@ -13,12 +13,20 @@ contract UpgradeHyperchains is BaseZkSyncUpgrade { /// @notice The main function that will be called by the upgrade proxy. /// @param _proposedUpgrade The upgrade to be executed. function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) { - (uint256 chainId, address bridgehubAddress, address stateTransitionManager, address sharedBridgeAddress) = abi - .decode(_proposedUpgrade.postUpgradeCalldata, (uint256, address, address, address)); + ( + uint256 chainId, + address bridgehubAddress, + address stateTransitionManager, + address sharedBridgeAddress, + address chainAdmin, + address validatorTimelock + ) = abi.decode(_proposedUpgrade.postUpgradeCalldata, (uint256, address, address, address, address, address)); require(chainId != 0, "UpgradeHyperchain: 1"); require(bridgehubAddress != address(0), "UpgradeHyperchain: 2"); require(stateTransitionManager != address(0), "UpgradeHyperchain: 3"); require(sharedBridgeAddress != address(0), "UpgradeHyperchain: 4"); + require(chainAdmin != address(0), "UpgradeHyperchains: 5"); + require(validatorTimelock != address(0), "UpgradeHyperchains: 6"); s.chainId = chainId; s.bridgehub = bridgehubAddress; @@ -27,6 +35,8 @@ contract UpgradeHyperchains is BaseZkSyncUpgrade { s.baseToken = ETH_TOKEN_ADDRESS; s.baseTokenGasPriceMultiplierNominator = 1; s.baseTokenGasPriceMultiplierDenominator = 1; + s.admin = chainAdmin; + s.validators[validatorTimelock] = true; super.upgrade(_proposedUpgrade); return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE; From b5314f657748bfa6313f1e43b5753475d59fa5ad Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Fri, 26 Apr 2024 16:55:44 +0200 Subject: [PATCH 23/60] Extend bootloader memory (#421) --- system-contracts/SystemContractsHashes.json | 20 +- system-contracts/bootloader/bootloader.yul | 2 +- .../bootloader/test_infra/Cargo.lock | 808 +++++++++++++----- .../bootloader/test_infra/Cargo.toml | 12 +- .../bootloader/test_infra/src/hook.rs | 4 +- .../bootloader/test_infra/src/main.rs | 6 +- 6 files changed, 626 insertions(+), 226 deletions(-) diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index eeb4a80f3..3944df256 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -185,35 +185,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb722f6b3ac4928fadcb3ad05bb76a7e2497a5635efffb7bbc40f23d29", - "sourceCodeHash": "0x818032f314539edf7b5569c70099f27e2336199ce24313a3f1968e27082c18ae" + "bytecodeHash": "0x010003cbf67ee7370dd2e77fb9ad39f718ded9354be174ea3009c6cb4fb8c06d", + "sourceCodeHash": "0x232e09be0ce4a92a3b77558e5724ab67e9deaf68e12e8be682a999655203b066" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x01000951a10ba35cd1fd7ea05039e53a06037213a162e6a3cfddf81ff6e54ad5", - "sourceCodeHash": "0x2cadacf92b4db89ecd699426b769526e5482e565d6d86ed287c9cc36cfe2cc2f" + "bytecodeHash": "0x01000951968c701c02714779299712d9da6e400e56c78d0d07acd984bfe7242a", + "sourceCodeHash": "0x9b2d51a24186af7ef58f7c8f53d77f6732f3a8d2dbde556fc8c1152957855fa5" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d750d8f3fa01d99a747a5113d133594b72f26f0dce3243b225f5b91f9a", - "sourceCodeHash": "0x9a3aead2fe745861da43b8f43028821f7d592ffd16da70f38af19d3b24ae5ef7" + "bytecodeHash": "0x010008d7dffe019f801bf2ee23b93f83afd80ea6d20c8efe82da71fd57cbcb5c", + "sourceCodeHash": "0xf6624fe716eec6bcd5d513f069f33d758271b304009d2bdf5c5b7d0573868a1c" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x010009579942207c3a46a48ad0e66d9f73b6141bb5a2435a8fdce6ee8dfdd17d", - "sourceCodeHash": "0x2302636e39803befa5438f557bfc24b7e1587cfd8edead02dc41a0bb4002f15f" + "bytecodeHash": "0x01000957420977a293aab097a368f36b123247d87d4695a6cd27ac62598ab171", + "sourceCodeHash": "0x23293faa6627f60f8b4d61657c615cb2327162dd1e33c0968e9ab4d5dd605a20" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e7f0f15ed191392960117f88fe371348982b28a033c7207ed2c09bc0f4", - "sourceCodeHash": "0x55ce91a28b1d143ecba38dfe1b64d4877ad8f510256f47e5155fd4fd138840ea" + "bytecodeHash": "0x010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e", + "sourceCodeHash": "0x8ac4971296d0546fc6366caa4089489177656cbc33cc21247947d98c28c6dee4" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index 96b4e70e2..85cc33dda 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -405,7 +405,7 @@ object "Bootloader" { /// for the sake of simplicity we will spend 32 bytes on each /// of those for now. function MAX_MEM_SIZE() -> ret { - ret := 59000000 + ret := 63800000 } function L1_TX_INTRINSIC_L2_GAS() -> ret { diff --git a/system-contracts/bootloader/test_infra/Cargo.lock b/system-contracts/bootloader/test_infra/Cargo.lock index 3a764c769..6fa43fd45 100644 --- a/system-contracts/bootloader/test_infra/Cargo.lock +++ b/system-contracts/bootloader/test_infra/Cargo.lock @@ -131,6 +131,51 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -214,7 +259,6 @@ dependencies = [ "num-bigint", "num-integer", "num-traits", - "serde", ] [[package]] @@ -354,7 +398,7 @@ dependencies = [ [[package]] name = "boojum" version = "0.2.0" -source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#30300f043c9afaeeb35d0f7bd3cc0acaf69ccde4" +source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -577,7 +621,7 @@ dependencies = [ [[package]] name = "circuit_encodings" version = "0.1.42" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2#012dcc678990c695f97e5dd1f136dfa8fe376c16" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2#3149a162a729581005fbad6dbcef027a3ee1b214" dependencies = [ "derivative", "serde", @@ -585,6 +629,17 @@ dependencies = [ "zkevm_circuits 1.4.1", ] +[[package]] +name = "circuit_encodings" +version = "0.1.50" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.5.0#394e1c7d1aec06d2f3abd63bdc2ddf0efef5ac49" +dependencies = [ + "derivative", + "serde", + "zk_evm 1.5.0", + "zkevm_circuits 1.5.0", +] + [[package]] name = "circuit_sequencer_api" version = "0.1.0" @@ -626,7 +681,7 @@ dependencies = [ [[package]] name = "circuit_sequencer_api" version = "0.1.42" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2#012dcc678990c695f97e5dd1f136dfa8fe376c16" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2#3149a162a729581005fbad6dbcef027a3ee1b214" dependencies = [ "bellman_ce", "circuit_encodings 0.1.42", @@ -636,6 +691,18 @@ dependencies = [ "zk_evm 1.4.1", ] +[[package]] +name = "circuit_sequencer_api" +version = "0.1.50" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.5.0#394e1c7d1aec06d2f3abd63bdc2ddf0efef5ac49" +dependencies = [ + "bellman_ce", + "circuit_encodings 0.1.50", + "derivative", + "rayon", + "serde", +] + [[package]] name = "clang-sys" version = "1.6.1" @@ -660,7 +727,8 @@ dependencies = [ [[package]] name = "compile-fmt" version = "0.1.0" -source = "git+https://github.com/slowli/compile-fmt.git?rev=c6a41c846c9a6f70cdba4b44c9f3922242ffcf12#c6a41c846c9a6f70cdba4b44c9f3922242ffcf12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed69047ed42e52c7e38d6421eeb8ceefb4f2a2b52eed59137f7bad7908f6800" [[package]] name = "const-oid" @@ -922,7 +990,7 @@ dependencies = [ [[package]] name = "cs_derive" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#30300f043c9afaeeb35d0f7bd3cc0acaf69ccde4" +source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" dependencies = [ "proc-macro-error", "proc-macro2", @@ -958,41 +1026,6 @@ dependencies = [ "syn 2.0.40", ] -[[package]] -name = "darling" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" -dependencies = [ - "darling_core", - "quote", - "syn 1.0.109", -] - [[package]] name = "dashmap" version = "5.5.3" @@ -1070,6 +1103,27 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7abbfc297053be59290e3152f8cbcd52c8642e0728b69ee187d991d4c1af08d" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bba3e9872d7c58ce7ef0fcf1844fcc3e23ef2a58377b50df35dd98e42a5726e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.40", + "unicode-xid", +] + [[package]] name = "digest" version = "0.9.0" @@ -1646,7 +1700,7 @@ dependencies = [ "futures-sink", "futures-util", "http", - "indexmap", + "indexmap 2.1.0", "slab", "tokio", "tokio-util", @@ -1714,6 +1768,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.3" @@ -1836,6 +1896,18 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -1872,12 +1944,6 @@ dependencies = [ "cc", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "0.4.0" @@ -1936,6 +2002,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + [[package]] name = "indexmap" version = "2.1.0" @@ -2111,6 +2187,8 @@ dependencies = [ "glob", "libc", "libz-sys", + "lz4-sys", + "zstd-sys", ] [[package]] @@ -2209,6 +2287,16 @@ dependencies = [ "logos-codegen", ] +[[package]] +name = "lz4-sys" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "match_cfg" version = "0.1.0" @@ -2224,6 +2312,12 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + [[package]] name = "maybe-uninit" version = "2.0.0" @@ -2264,28 +2358,6 @@ dependencies = [ "autocfg", ] -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash 0.8.6", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-macros" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", -] - [[package]] name = "miette" version = "5.10.0" @@ -2365,13 +2437,14 @@ checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" [[package]] name = "multivm" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "anyhow", "circuit_sequencer_api 0.1.0", "circuit_sequencer_api 0.1.40", "circuit_sequencer_api 0.1.41", "circuit_sequencer_api 0.1.42", + "circuit_sequencer_api 0.1.50", "hex", "itertools 0.10.5", "once_cell", @@ -2383,10 +2456,6 @@ dependencies = [ "zk_evm 1.4.0", "zk_evm 1.4.1", "zk_evm 1.5.0", - "zkevm_test_harness 1.3.3", - "zkevm_test_harness 1.4.0", - "zkevm_test_harness 1.4.1", - "zkevm_test_harness 1.4.2", "zksync_contracts", "zksync_state", "zksync_system_constants", @@ -2566,7 +2635,16 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" dependencies = [ - "num_enum_derive", + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", ] [[package]] @@ -2581,6 +2659,18 @@ dependencies = [ "syn 2.0.40", ] +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 2.0.1", + "proc-macro2", + "quote", + "syn 2.0.40", +] + [[package]] name = "object" version = "0.32.1" @@ -2646,6 +2736,110 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-http" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7594ec0e11d8e33faf03530a4c49af7064ebba81c1480e01be67d90b356508b" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry_api", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5e5a5c4135864099f3faafbe939eb4d7f9b80ebf68a8448da961b32a7c1275" +dependencies = [ + "async-trait", + "futures-core", + "http", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry-semantic-conventions", + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "reqwest", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e3f814aa9f8c905d0ee4bde026afd3b2577a97c10e1699912e3e44f0c4cbeb" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9f9340ad135068800e7f1b24e9e09ed9e7143f5bf8518ded3d3ec69789269" +dependencies = [ + "opentelemetry", +] + +[[package]] +name = "opentelemetry_api" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +dependencies = [ + "async-trait", + "crossbeam-channel 0.5.8", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "ordered-float 3.9.2", + "percent-encoding", + "rand 0.8.5", + "regex", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + [[package]] name = "ordered-float" version = "2.10.1" @@ -2655,6 +2849,15 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + [[package]] name = "os_info" version = "3.7.0" @@ -2710,7 +2913,7 @@ dependencies = [ [[package]] name = "pairing_ce" version = "0.28.5" -source = "git+https://github.com/matter-labs/pairing.git?rev=f55393fd366596eac792d78525d26e9c4d6ed1ca#f55393fd366596eac792d78525d26e9c4d6ed1ca" +source = "git+https://github.com/matter-labs/pairing.git?rev=d24f2c5871089c4cd4f54c0ca266bb9fef6115eb#d24f2c5871089c4cd4f54c0ca266bb9fef6115eb" dependencies = [ "byteorder", "cfg-if 1.0.0", @@ -2722,7 +2925,7 @@ dependencies = [ [[package]] name = "pairing_ce" version = "0.28.5" -source = "git+https://github.com/matter-labs/pairing.git#f55393fd366596eac792d78525d26e9c4d6ed1ca" +source = "git+https://github.com/matter-labs/pairing.git#d24f2c5871089c4cd4f54c0ca266bb9fef6115eb" dependencies = [ "byteorder", "cfg-if 1.0.0", @@ -2814,7 +3017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap", + "indexmap 2.1.0", ] [[package]] @@ -2892,12 +3095,6 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" -[[package]] -name = "portable-atomic" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7170ef9988bc169ba16dd36a7fa041e5c4cbeb6a35b76d4c03daded371eae7c0" - [[package]] name = "powerfmt" version = "0.2.0" @@ -2997,9 +3194,9 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.21.2" +version = "0.22.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2" +checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" dependencies = [ "dtoa", "itoa", @@ -3018,6 +3215,16 @@ dependencies = [ "syn 2.0.40", ] +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + [[package]] name = "prost" version = "0.12.3" @@ -3025,7 +3232,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" dependencies = [ "bytes", - "prost-derive", + "prost-derive 0.12.3", ] [[package]] @@ -3035,14 +3242,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" dependencies = [ "bytes", - "heck", + "heck 0.4.1", "itertools 0.11.0", "log", "multimap", "once_cell", "petgraph", "prettyplease", - "prost", + "prost 0.12.3", "prost-types", "regex", "syn 2.0.40", @@ -3050,6 +3257,19 @@ dependencies = [ "which", ] +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "prost-derive" version = "0.12.3" @@ -3073,7 +3293,7 @@ dependencies = [ "logos", "miette", "once_cell", - "prost", + "prost 0.12.3", "prost-types", "serde", "serde-value", @@ -3085,7 +3305,7 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" dependencies = [ - "prost", + "prost 0.12.3", ] [[package]] @@ -3096,7 +3316,7 @@ checksum = "00bb76c5f6221de491fe2c8f39b106330bbd9762c6511119c07940e10eb9ff11" dependencies = [ "bytes", "miette", - "prost", + "prost 0.12.3", "prost-reflect", "prost-types", "protox-parse", @@ -3812,7 +4032,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" dependencies = [ - "ordered-float", + "ordered-float 2.10.1", "serde", ] @@ -3851,26 +4071,29 @@ dependencies = [ ] [[package]] -name = "serde_with" -version = "1.14.0" +name = "serde_yaml" +version = "0.9.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +checksum = "a15e0ef66bf939a7c890a0bf6d5a733c70202225f9888a89ed5c62298b019129" dependencies = [ - "base64 0.13.1", + "indexmap 2.1.0", + "itoa", + "ryu", "serde", - "serde_with_macros", + "unsafe-libyaml", ] [[package]] -name = "serde_with_macros" -version = "1.5.2" +name = "sha-1" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 1.0.109", + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -3884,19 +4107,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - [[package]] name = "sha2" version = "0.10.6" @@ -4040,6 +4250,21 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] + [[package]] name = "spin" version = "0.5.2" @@ -4123,7 +4348,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap", + "indexmap 2.1.0", "ipnetwork", "log", "memchr", @@ -4166,7 +4391,7 @@ dependencies = [ "atomic-write-file", "dotenvy", "either", - "heck", + "heck 0.4.1", "hex", "once_cell", "proc-macro2", @@ -4320,12 +4545,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strum" version = "0.24.1" @@ -4341,7 +4560,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -4388,6 +4607,12 @@ dependencies = [ "syn 2.0.40", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "system-configuration" version = "0.5.1" @@ -4573,6 +4798,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-macros" version = "2.2.0" @@ -4623,6 +4858,7 @@ checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" dependencies = [ "bytes", "futures-core", + "futures-io", "futures-sink", "pin-project-lite", "tokio", @@ -4641,7 +4877,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap", + "indexmap 2.1.0", "toml_datetime", "winnow", ] @@ -4652,11 +4888,65 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" dependencies = [ - "indexmap", + "indexmap 2.1.0", "toml_datetime", "winnow", ] +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.5", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -4696,6 +4986,17 @@ dependencies = [ "valuable", ] +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + [[package]] name = "tracing-log" version = "0.2.0" @@ -4707,6 +5008,22 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-opentelemetry" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75327c6b667828ddc28f5e3f169036cb793c3f588d83bf0f262a7f062ffed3c8" +dependencies = [ + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log 0.1.4", + "tracing-subscriber", +] + [[package]] name = "tracing-serde" version = "0.1.3" @@ -4735,7 +5052,7 @@ dependencies = [ "time", "tracing", "tracing-core", - "tracing-log", + "tracing-log 0.2.0", "tracing-serde", ] @@ -4842,6 +5159,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + [[package]] name = "untrusted" version = "0.9.0" @@ -4909,7 +5232,7 @@ checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "vise" version = "0.1.0" -source = "git+https://github.com/matter-labs/vise.git?rev=1c9cc500e92cf9ea052b230e114a6f9cce4fb2c1#1c9cc500e92cf9ea052b230e114a6f9cce4fb2c1" +source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" dependencies = [ "compile-fmt", "elsa", @@ -4922,7 +5245,7 @@ dependencies = [ [[package]] name = "vise-macros" version = "0.1.0" -source = "git+https://github.com/matter-labs/vise.git?rev=1c9cc500e92cf9ea052b230e114a6f9cce4fb2c1#1c9cc500e92cf9ea052b230e114a6f9cce4fb2c1" +source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" dependencies = [ "proc-macro2", "quote", @@ -4932,12 +5255,16 @@ dependencies = [ [[package]] name = "vlog" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "chrono", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", "sentry", "serde_json", "tracing", + "tracing-opentelemetry", "tracing-subscriber", ] @@ -5051,7 +5378,7 @@ dependencies = [ "arrayvec 0.7.4", "base64 0.21.5", "bytes", - "derive_more", + "derive_more 0.99.17", "ethabi", "ethereum-types", "futures", @@ -5069,7 +5396,24 @@ dependencies = [ "secp256k1", "serde", "serde_json", + "soketto", "tiny-keccak 2.0.2", + "tokio", + "tokio-stream", + "tokio-util", + "url", + "web3-async-native-tls", +] + +[[package]] +name = "web3-async-native-tls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6d8d1636b2627fe63518d5a9b38a569405d9c9bc665c43c9c341de57227ebb" +dependencies = [ + "native-tls", + "thiserror", + "tokio", "url", ] @@ -5417,7 +5761,7 @@ dependencies = [ [[package]] name = "zk_evm" version = "1.5.0" -source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.5.0#912fbab463f6f010f824eb66844fe8c8ff240765" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.5.0#0448e26ffd8e2f1935ff8cd3303fe5a504cd5d7b" dependencies = [ "anyhow", "lazy_static", @@ -5434,7 +5778,7 @@ version = "0.1.0" source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git#32dd320953841aa78579d9da08abbc70bcaed175" dependencies = [ "anyhow", - "num_enum", + "num_enum 0.6.1", "serde", "static_assertions", "zkevm_opcode_defs 1.3.2", @@ -5446,7 +5790,7 @@ version = "1.4.1" source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git?branch=v1.4.1#0aac08c3b097ee8147e748475117ac46bddcdcef" dependencies = [ "anyhow", - "num_enum", + "num_enum 0.6.1", "serde", "static_assertions", "zkevm_opcode_defs 1.4.1", @@ -5455,10 +5799,10 @@ dependencies = [ [[package]] name = "zk_evm_abstractions" version = "1.5.0" -source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git?branch=v1.5.0#3e4253e2cb86cc0b51f230643571d9b387bca0c6" +source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git?branch=v1.5.0#e464b2cf2b146d883be80e7d690c752bf670ff05" dependencies = [ "anyhow", - "num_enum", + "num_enum 0.6.1", "serde", "static_assertions", "zkevm_opcode_defs 1.5.0", @@ -5488,7 +5832,7 @@ dependencies = [ [[package]] name = "zkevm_circuits" version = "1.4.1" -source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.4.1#3a973afb3cf2b50b7138c1af61cc6ac3d7d0189f" +source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.4.1#8bf24543ffc5bafab34182388394e887ecb37d17" dependencies = [ "arrayvec 0.7.4", "bincode", @@ -5506,6 +5850,25 @@ dependencies = [ "zkevm_opcode_defs 1.4.1", ] +[[package]] +name = "zkevm_circuits" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.5.0#861f81029bf3a916dae55afa5bd7f82b2eaca98b" +dependencies = [ + "arrayvec 0.7.4", + "boojum", + "cs_derive", + "derivative", + "hex", + "itertools 0.10.5", + "rand 0.4.6", + "rand 0.8.5", + "seq-macro", + "serde", + "smallvec", + "zkevm_opcode_defs 1.5.0", +] + [[package]] name = "zkevm_opcode_defs" version = "1.3.1" @@ -5548,7 +5911,7 @@ dependencies = [ [[package]] name = "zkevm_opcode_defs" version = "1.5.0" -source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.5.0#7bf8016f5bb13a73289f321ad6ea8f614540ece9" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.5.0#109d9f734804a8b9dc0531c0b576e2a0f55a40de" dependencies = [ "bitflags 2.4.1", "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -5561,49 +5924,23 @@ dependencies = [ "sha3 0.10.8", ] -[[package]] -name = "zkevm_test_harness" -version = "1.4.2" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2#d9da285c2e8a5fedddd2e9c2a893769ebd12a6ed" -dependencies = [ - "bincode", - "circuit_definitions 0.1.0 (git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2)", - "codegen", - "crossbeam 0.8.2", - "curl", - "derivative", - "env_logger 0.9.3", - "hex", - "lazy_static", - "rand 0.4.6", - "rayon", - "reqwest", - "rescue_poseidon 0.4.1 (git+https://github.com/matter-labs/rescue-poseidon.git?branch=poseidon2)", - "serde", - "serde_json", - "smallvec", - "snark_wrapper", - "structopt", - "test-log", - "tracing", - "walkdir", - "zkevm-assembly 1.4.1", -] - [[package]] name = "zksync_basic_types" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ + "chrono", + "num_enum 0.7.2", "serde", "serde_json", + "strum", "web3", ] [[package]] name = "zksync_concurrency" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ "anyhow", "once_cell", @@ -5621,25 +5958,27 @@ dependencies = [ [[package]] name = "zksync_config" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "anyhow", "rand 0.8.5", "serde", "zksync_basic_types", + "zksync_consensus_utils", + "zksync_crypto_primitives", ] [[package]] name = "zksync_consensus_crypto" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ "anyhow", "blst", "ed25519-dalek", "ff_ce", "hex", - "pairing_ce 0.28.5 (git+https://github.com/matter-labs/pairing.git?rev=f55393fd366596eac792d78525d26e9c4d6ed1ca)", + "pairing_ce 0.28.5 (git+https://github.com/matter-labs/pairing.git?rev=d24f2c5871089c4cd4f54c0ca266bb9fef6115eb)", "rand 0.4.6", "rand 0.8.5", "sha3 0.10.8", @@ -5650,12 +5989,12 @@ dependencies = [ [[package]] name = "zksync_consensus_roles" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ "anyhow", "bit-vec", "hex", - "prost", + "prost 0.12.3", "rand 0.8.5", "serde", "thiserror", @@ -5670,11 +6009,11 @@ dependencies = [ [[package]] name = "zksync_consensus_storage" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ "anyhow", "async-trait", - "prost", + "prost 0.12.3", "rand 0.8.5", "thiserror", "tracing", @@ -5688,8 +6027,9 @@ dependencies = [ [[package]] name = "zksync_consensus_utils" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ + "rand 0.8.5", "thiserror", "zksync_concurrency", ] @@ -5697,7 +6037,7 @@ dependencies = [ [[package]] name = "zksync_contracts" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "envy", "ethabi", @@ -5711,21 +6051,37 @@ dependencies = [ [[package]] name = "zksync_crypto" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", "hex", "once_cell", "serde", - "sha2 0.9.9", + "sha2 0.10.8", + "thiserror", + "zksync_basic_types", +] + +[[package]] +name = "zksync_crypto_primitives" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +dependencies = [ + "anyhow", + "hex", + "secp256k1", + "serde", + "serde_json", "thiserror", + "web3", "zksync_basic_types", + "zksync_utils", ] [[package]] name = "zksync_dal" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "anyhow", "bigdecimal", @@ -5733,8 +6089,7 @@ dependencies = [ "chrono", "hex", "itertools 0.10.5", - "once_cell", - "prost", + "prost 0.12.3", "rand 0.8.5", "serde", "serde_json", @@ -5743,12 +6098,11 @@ dependencies = [ "thiserror", "tokio", "tracing", - "url", "vise", "zksync_consensus_roles", "zksync_consensus_storage", "zksync_contracts", - "zksync_health_check", + "zksync_db_connection", "zksync_protobuf", "zksync_protobuf_build", "zksync_system_constants", @@ -5756,15 +6110,34 @@ dependencies = [ "zksync_utils", ] +[[package]] +name = "zksync_db_connection" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +dependencies = [ + "anyhow", + "rand 0.8.5", + "serde", + "serde_json", + "sqlx", + "thiserror", + "tokio", + "tracing", + "url", + "vise", + "zksync_health_check", +] + [[package]] name = "zksync_health_check" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "async-trait", "futures", "serde", "serde_json", + "thiserror", "tokio", "tracing", "vise", @@ -5773,7 +6146,7 @@ dependencies = [ [[package]] name = "zksync_mini_merkle_tree" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "once_cell", "zksync_basic_types", @@ -5783,28 +6156,30 @@ dependencies = [ [[package]] name = "zksync_protobuf" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ "anyhow", "bit-vec", "once_cell", - "prost", + "prost 0.12.3", "prost-reflect", "quick-protobuf", "rand 0.8.5", "serde", "serde_json", + "serde_yaml", "zksync_concurrency", + "zksync_consensus_utils", "zksync_protobuf_build", ] [[package]] name = "zksync_protobuf_build" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=5329a809cfc06d4939fb5ece26c9ad1e1741c50a#5329a809cfc06d4939fb5ece26c9ad1e1741c50a" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" dependencies = [ "anyhow", - "heck", + "heck 0.5.0", "prettyplease", "proc-macro2", "prost-build", @@ -5814,18 +6189,32 @@ dependencies = [ "syn 2.0.40", ] +[[package]] +name = "zksync_shared_metrics" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +dependencies = [ + "vise", + "zksync_dal", + "zksync_types", +] + [[package]] name = "zksync_state" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "anyhow", + "async-trait", + "chrono", "itertools 0.10.5", "mini-moka", + "once_cell", "tokio", "tracing", "vise", "zksync_dal", + "zksync_shared_metrics", "zksync_storage", "zksync_types", "zksync_utils", @@ -5834,11 +6223,12 @@ dependencies = [ [[package]] name = "zksync_storage" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "num_cpus", "once_cell", "rocksdb", + "thread_local", "tracing", "vise", ] @@ -5846,7 +6236,7 @@ dependencies = [ [[package]] name = "zksync_system_constants" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "once_cell", "zksync_basic_types", @@ -5856,27 +6246,28 @@ dependencies = [ [[package]] name = "zksync_types" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "anyhow", "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", "chrono", + "derive_more 1.0.0-beta.6", "hex", "itertools 0.10.5", "num", - "num_enum", + "num_enum 0.7.2", "once_cell", - "prost", + "prost 0.12.3", "rlp", "secp256k1", "serde", "serde_json", - "serde_with", "strum", "thiserror", "zksync_basic_types", "zksync_config", "zksync_contracts", + "zksync_crypto_primitives", "zksync_mini_merkle_tree", "zksync_protobuf", "zksync_protobuf_build", @@ -5887,14 +6278,13 @@ dependencies = [ [[package]] name = "zksync_utils" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=ce5743679f18d737b459635c4d0d7b07dbf6ee2d#ce5743679f18d737b459635c4d0d7b07dbf6ee2d" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" dependencies = [ "anyhow", "bigdecimal", "futures", "hex", "itertools 0.10.5", - "metrics", "num", "reqwest", "serde", @@ -5905,3 +6295,13 @@ dependencies = [ "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2)", "zksync_basic_types", ] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/system-contracts/bootloader/test_infra/Cargo.toml b/system-contracts/bootloader/test_infra/Cargo.toml index df3756e5d..cfcd2c9a3 100644 --- a/system-contracts/bootloader/test_infra/Cargo.toml +++ b/system-contracts/bootloader/test_infra/Cargo.toml @@ -7,12 +7,12 @@ edition = "2021" [dependencies] -multivm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "ce5743679f18d737b459635c4d0d7b07dbf6ee2d" } -zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "ce5743679f18d737b459635c4d0d7b07dbf6ee2d" } -zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "ce5743679f18d737b459635c4d0d7b07dbf6ee2d" } -zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "ce5743679f18d737b459635c4d0d7b07dbf6ee2d" } -zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", rev = "ce5743679f18d737b459635c4d0d7b07dbf6ee2d" } -vlog = { git = "https://github.com/matter-labs/zksync-era.git", rev = "ce5743679f18d737b459635c4d0d7b07dbf6ee2d" } +multivm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c4d1c49282a3710be5d491636ba26207efb1f9ce" } +zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c4d1c49282a3710be5d491636ba26207efb1f9ce" } +zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c4d1c49282a3710be5d491636ba26207efb1f9ce" } +zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c4d1c49282a3710be5d491636ba26207efb1f9ce" } +zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c4d1c49282a3710be5d491636ba26207efb1f9ce" } +vlog = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c4d1c49282a3710be5d491636ba26207efb1f9ce" } colored = "2.0" hex = "0.4" diff --git a/system-contracts/bootloader/test_infra/src/hook.rs b/system-contracts/bootloader/test_infra/src/hook.rs index ca30ae03b..04bacc90c 100644 --- a/system-contracts/bootloader/test_infra/src/hook.rs +++ b/system-contracts/bootloader/test_infra/src/hook.rs @@ -1,5 +1,5 @@ use multivm::vm_latest::{ - constants::{BOOTLOADER_HEAP_PAGE, VM_HOOK_PARAMS_START_POSITION}, + constants::{BOOTLOADER_HEAP_PAGE, get_vm_hook_start_position_latest}, HistoryMode, SimpleMemory, }; @@ -26,7 +26,7 @@ pub(crate) enum TestVmHook { // Number of 32-bytes slots that are reserved for test hooks (passing information between bootloader test code and the VM). const TEST_HOOKS: u32 = 5; -const TEST_HOOK_ENUM_POSITION: u32 = VM_HOOK_PARAMS_START_POSITION - 1; +const TEST_HOOK_ENUM_POSITION: u32 = get_vm_hook_start_position_latest() - 1; const TEST_HOOK_START: u32 = TEST_HOOK_ENUM_POSITION - TEST_HOOKS; pub fn get_vm_hook_params(memory: &SimpleMemory) -> Vec { diff --git a/system-contracts/bootloader/test_infra/src/main.rs b/system-contracts/bootloader/test_infra/src/main.rs index 33dae7ddd..3928200e4 100644 --- a/system-contracts/bootloader/test_infra/src/main.rs +++ b/system-contracts/bootloader/test_infra/src/main.rs @@ -21,7 +21,7 @@ use zksync_state::{ InMemoryStorage, StoragePtr, StorageView, IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID, }; use zksync_types::system_contracts::get_system_smart_contracts_from_dir; -use zksync_types::{block::MiniblockHasher, Address, L1BatchNumber, MiniblockNumber, U256}; +use zksync_types::{block::L2BlockHasher, Address, L1BatchNumber, L2BlockNumber, U256}; use zksync_types::{L2ChainId, Transaction}; use zksync_utils::bytecode::hash_bytecode; use zksync_utils::{bytes_to_be_words, u256_to_h256}; @@ -63,7 +63,7 @@ fn execute_internal_bootloader_test() { zk_porter_available: false, version: zksync_types::ProtocolVersionId::latest(), base_system_smart_contracts: base_system_contract, - gas_limit: u32::MAX, + bootloader_gas_limit: u32::MAX, execution_mode: TxExecutionMode::VerifyExecute, default_validation_computational_gas_limit: u32::MAX, chain_id: zksync_types::L2ChainId::from(299), @@ -80,7 +80,7 @@ fn execute_internal_bootloader_test() { first_l2_block: L2BlockEnv { number: 1, timestamp: 15, - prev_block_hash: MiniblockHasher::legacy_hash(MiniblockNumber(0)), + prev_block_hash: L2BlockHasher::legacy_hash(L2BlockNumber(0)), max_virtual_blocks_to_create: 1, }, }; From d89e406cd20c6d6e9052ba2321334b71ef53c54e Mon Sep 17 00:00:00 2001 From: Agustin Aon <21188659+aon@users.noreply.github.com> Date: Mon, 29 Apr 2024 08:33:47 -0300 Subject: [PATCH 24/60] feat: improve foundry l1 config deployment (#378) Co-authored-by: Danil --- .../workflows/l1-contracts-foundry-ci.yaml | 5 + .gitignore | 1 + .../config-deploy-erc20.toml | 7 +- .../config-deploy-l1.toml | 0 .../config-initialize-l2-weth-token.toml | 0 l1-contracts-foundry/script/DeployErc20.s.sol | 19 +-- l1-contracts-foundry/script/DeployL1.s.sol | 116 ++++++++++-------- .../script/InitializeL2WethToken.s.sol | 8 +- .../script/RegisterHyperchain.s.sol | 64 ++++++---- 9 files changed, 127 insertions(+), 93 deletions(-) rename l1-contracts-foundry/{script-config => script-config-template}/config-deploy-erc20.toml (51%) rename l1-contracts-foundry/{script-config => script-config-template}/config-deploy-l1.toml (100%) rename l1-contracts-foundry/{script-config => script-config-template}/config-initialize-l2-weth-token.toml (100%) diff --git a/.github/workflows/l1-contracts-foundry-ci.yaml b/.github/workflows/l1-contracts-foundry-ci.yaml index 367ea2977..729e66a69 100644 --- a/.github/workflows/l1-contracts-foundry-ci.yaml +++ b/.github/workflows/l1-contracts-foundry-ci.yaml @@ -6,6 +6,7 @@ env: on: pull_request: + jobs: build: runs-on: ubuntu-latest @@ -73,6 +74,10 @@ jobs: - name: Use Foundry uses: foundry-rs/foundry-toolchain@v1 + - name: Copy configs from template + working-directory: ./l1-contracts-foundry + run: cp -r script-config-template script-config + - name: Run anvil run: | anvil --silent & diff --git a/.gitignore b/.gitignore index 356147e7b..ab8dbb92c 100644 --- a/.gitignore +++ b/.gitignore @@ -23,5 +23,6 @@ l1-contracts/report/* l1-contracts/coverage/* l1-contracts/out/* l1-contracts-foundry/broadcast/* +l1-contracts-foundry/script-config/* l1-contracts-foundry/script-out/* !l1-contracts-foundry/script-out/.gitkeep diff --git a/l1-contracts-foundry/script-config/config-deploy-erc20.toml b/l1-contracts-foundry/script-config-template/config-deploy-erc20.toml similarity index 51% rename from l1-contracts-foundry/script-config/config-deploy-erc20.toml rename to l1-contracts-foundry/script-config-template/config-deploy-erc20.toml index b77417c0d..a22795b9b 100644 --- a/l1-contracts-foundry/script-config/config-deploy-erc20.toml +++ b/l1-contracts-foundry/script-config-template/config-deploy-erc20.toml @@ -1,14 +1,11 @@ -create2_factory_addr = "0x4e59b44847b379578588920cA78FbF26c0B4956C" -create2_factory_salt = "0x00000000000000000000000000000000000000000000000000000000000000ff" - -[tokens.dai] +[tokens.DAI] name = "DAI" symbol = "DAI" decimals = 18 implementation = "TestnetERC20Token.sol" mint = "10000000000" -[tokens.weth] +[tokens.WETH] name = "Wrapped Ether" symbol = "WETH" decimals = 18 diff --git a/l1-contracts-foundry/script-config/config-deploy-l1.toml b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml similarity index 100% rename from l1-contracts-foundry/script-config/config-deploy-l1.toml rename to l1-contracts-foundry/script-config-template/config-deploy-l1.toml diff --git a/l1-contracts-foundry/script-config/config-initialize-l2-weth-token.toml b/l1-contracts-foundry/script-config-template/config-initialize-l2-weth-token.toml similarity index 100% rename from l1-contracts-foundry/script-config/config-initialize-l2-weth-token.toml rename to l1-contracts-foundry/script-config-template/config-initialize-l2-weth-token.toml diff --git a/l1-contracts-foundry/script/DeployErc20.s.sol b/l1-contracts-foundry/script/DeployErc20.s.sol index 4a2046ec7..48bbddbc7 100644 --- a/l1-contracts-foundry/script/DeployErc20.s.sol +++ b/l1-contracts-foundry/script/DeployErc20.s.sol @@ -38,18 +38,24 @@ contract DeployErc20Script is Script { } function initializeConfig() internal { - // Grab config from output of l1 deployment + config.deployerAddress = msg.sender; + string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/script-config/config-deploy-erc20.toml"); - string memory toml = vm.readFile(path); - config.deployerAddress = msg.sender; + // Grab config from output of l1 deployment + string memory path = string.concat(root, "/script-out/output-deploy-l1.toml"); + string memory toml = vm.readFile(path); // Config file must be parsed key by key, otherwise values returned // are parsed alfabetically and not by key. // https://book.getfoundry.sh/cheatcodes/parse-toml config.create2FactoryAddr = vm.parseTomlAddress(toml, "$.create2_factory_addr"); config.create2FactorySalt = vm.parseTomlBytes32(toml, "$.create2_factory_salt"); + + // Grab config from custom config file + path = string.concat(root, "/script-config/config-deploy-erc20.toml"); + toml = vm.readFile(path); + string[] memory tokens = vm.parseTomlKeys(toml, "$.tokens"); for (uint256 i = 0; i < tokens.length; i++) { @@ -67,7 +73,7 @@ contract DeployErc20Script is Script { function deployTokens() internal { for (uint256 i = 0; i < config.tokens.length; i++) { - TokenDescription memory token = config.tokens[i]; + TokenDescription storage token = config.tokens[i]; console.log("Deploying token:", token.name); address tokenAddress = deployErc20({ name: token.name, @@ -110,9 +116,6 @@ contract DeployErc20Script is Script { } function saveOutput() internal { - vm.serializeAddress("root", "create2_factory_addr", config.create2FactoryAddr); - vm.serializeBytes32("root", "create2_factory_salt", config.create2FactorySalt); - string memory tokens = ""; for (uint256 i = 0; i < config.tokens.length; i++) { TokenDescription memory token = config.tokens[i]; diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 3768787de..7c8d62adf 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -563,116 +563,124 @@ contract DeployL1Script is Script { } function saveOutput() internal { - vm.serializeAddress("l1.bridgehub", "bridgehub_proxy_addr", addresses.bridgehub.bridgehubProxy); - string memory l1Bridgehub = vm.serializeAddress( - "l1.bridgehub", + vm.serializeAddress("bridgehub", "bridgehub_proxy_addr", addresses.bridgehub.bridgehubProxy); + string memory bridgehub = vm.serializeAddress( + "bridgehub", "bridgehub_implementation_addr", addresses.bridgehub.bridgehubImplementation ); vm.serializeAddress( - "l1.state_transition", + "state_transition", "state_transition_proxy_addr", addresses.stateTransition.stateTransitionProxy ); vm.serializeAddress( - "l1.state_transition", + "state_transition", "state_transition_implementation_addr", addresses.stateTransition.stateTransitionImplementation ); - vm.serializeAddress("l1.state_transition", "verifier_addr", addresses.stateTransition.verifier); - vm.serializeAddress("l1.state_transition", "admin_facet_addr", addresses.stateTransition.adminFacet); - vm.serializeAddress("l1.state_transition", "mailbox_facet_addr", addresses.stateTransition.mailboxFacet); - vm.serializeAddress("l1.state_transition", "executor_facet_addr", addresses.stateTransition.executorFacet); - vm.serializeAddress("l1.state_transition", "getters_facet_addr", addresses.stateTransition.gettersFacet); - vm.serializeAddress("l1.state_transition", "diamond_init_addr", addresses.stateTransition.diamondInit); - vm.serializeAddress("l1.state_transition", "genesis_upgrade_addr", addresses.stateTransition.genesisUpgrade); - vm.serializeAddress("l1.state_transition", "default_upgrade_addr", addresses.stateTransition.defaultUpgrade); - string memory l1StateTransition = vm.serializeAddress( - "l1.state_transition", + vm.serializeAddress("state_transition", "verifier_addr", addresses.stateTransition.verifier); + vm.serializeAddress("state_transition", "admin_facet_addr", addresses.stateTransition.adminFacet); + vm.serializeAddress("state_transition", "mailbox_facet_addr", addresses.stateTransition.mailboxFacet); + vm.serializeAddress("state_transition", "executor_facet_addr", addresses.stateTransition.executorFacet); + vm.serializeAddress("state_transition", "getters_facet_addr", addresses.stateTransition.gettersFacet); + vm.serializeAddress("state_transition", "diamond_init_addr", addresses.stateTransition.diamondInit); + vm.serializeAddress("state_transition", "genesis_upgrade_addr", addresses.stateTransition.genesisUpgrade); + vm.serializeAddress("state_transition", "default_upgrade_addr", addresses.stateTransition.defaultUpgrade); + string memory stateTransition = vm.serializeAddress( + "state_transition", "diamond_proxy_addr", addresses.stateTransition.diamondProxy ); + vm.serializeAddress("bridges", "erc20_bridge_implementation_addr", addresses.bridges.erc20BridgeImplementation); + vm.serializeAddress("bridges", "erc20_bridge_proxy_addr", addresses.bridges.erc20BridgeProxy); vm.serializeAddress( - "l1.bridges", - "erc20_bridge_implementation_addr", - addresses.bridges.erc20BridgeImplementation - ); - vm.serializeAddress("l1.bridges", "erc20_bridge_proxy_addr", addresses.bridges.erc20BridgeProxy); - vm.serializeAddress( - "l1.bridges", + "bridges", "shared_bridge_implementation_addr", addresses.bridges.sharedBridgeImplementation ); - string memory l1Bridges = vm.serializeAddress( - "l1.bridges", + string memory bridges = vm.serializeAddress( + "bridges", "shared_bridge_proxy_addr", addresses.bridges.sharedBridgeProxy ); vm.serializeUint( - "l1.config", + "contracts_config", "diamond_init_pubdata_pricing_mode", uint256(config.contracts.diamondInitPubdataPricingMode) ); vm.serializeUint( - "l1.config", + "contracts_config", "diamond_init_batch_overhead_l1_gas", config.contracts.diamondInitBatchOverheadL1Gas ); vm.serializeUint( - "l1.config", + "contracts_config", "diamond_init_max_pubdata_per_batch", config.contracts.diamondInitMaxPubdataPerBatch ); vm.serializeUint( - "l1.config", + "contracts_config", "diamond_init_max_l2_gas_per_batch", config.contracts.diamondInitMaxL2GasPerBatch ); vm.serializeUint( - "l1.config", + "contracts_config", "diamond_init_priority_tx_max_pubdata", config.contracts.diamondInitPriorityTxMaxPubdata ); vm.serializeUint( - "l1.config", + "contracts_config", "diamond_init_minimal_l2_gas_price", config.contracts.diamondInitMinimalL2GasPrice ); - vm.serializeBytes32("l1.config", "recursion_node_level_vk_hash", config.contracts.recursionNodeLevelVkHash); - vm.serializeBytes32("l1.config", "recursion_leaf_level_vk_hash", config.contracts.recursionLeafLevelVkHash); vm.serializeBytes32( - "l1.config", + "contracts_config", + "recursion_node_level_vk_hash", + config.contracts.recursionNodeLevelVkHash + ); + vm.serializeBytes32( + "contracts_config", + "recursion_leaf_level_vk_hash", + config.contracts.recursionLeafLevelVkHash + ); + vm.serializeBytes32( + "contracts_config", "recursion_circuits_set_vks_hash", config.contracts.recursionCircuitsSetVksHash ); - string memory l1Config = vm.serializeUint( - "l1.config", + string memory contractsConfig = vm.serializeUint( + "contracts_config", "priority_tx_max_gas_limit", config.contracts.priorityTxMaxGasLimit ); - vm.serializeAddress("l1", "transparent_proxy_admin_addr", addresses.transparentProxyAdmin); - vm.serializeAddress("l1", "governance_addr", addresses.governance); - vm.serializeAddress("l1", "blob_versioned_hash_retriever_addr", addresses.blobVersionedHashRetriever); - vm.serializeAddress("l1", "validator_timelock_addr", addresses.validatorTimelock); - vm.serializeAddress("l1", "create2_factory_addr", addresses.create2Factory); - vm.serializeBytes32("l1", "create2_factory_salt", config.contracts.create2FactorySalt); - vm.serializeAddress("l1", "multicall3_addr", config.contracts.multicall3Addr); - vm.serializeUint("l1", "l1_chain_id", config.l1ChainId); - vm.serializeUint("l1", "era_chain_id", config.eraChainId); - vm.serializeString("l1", "bridgehub", l1Bridgehub); - vm.serializeString("l1", "state_transition", l1StateTransition); - vm.serializeString("l1", "config", l1Config); - vm.serializeAddress("l1", "deployer_addr", config.deployerAddress); - vm.serializeAddress("l1", "owner_addr", config.ownerAddress); - string memory l1 = vm.serializeString("l1", "bridges", l1Bridges); - - string memory toml = vm.serializeString("toml", "l1", l1); - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/script-out/output-deploy-l1.toml"); + vm.serializeAddress("deployed_addresses", "transparent_proxy_admin_addr", addresses.transparentProxyAdmin); + vm.serializeAddress("deployed_addresses", "governance_addr", addresses.governance); + vm.serializeAddress( + "deployed_addresses", + "blob_versioned_hash_retriever_addr", + addresses.blobVersionedHashRetriever + ); + vm.serializeAddress("deployed_addresses", "validator_timelock_addr", addresses.validatorTimelock); + vm.serializeString("deployed_addresses", "bridgehub", bridgehub); + vm.serializeString("deployed_addresses", "state_transition", stateTransition); + string memory deployedAddresses = vm.serializeString("deployed_addresses", "bridges", bridges); + + vm.serializeAddress("root", "create2_factory_addr", addresses.create2Factory); + vm.serializeBytes32("root", "create2_factory_salt", config.contracts.create2FactorySalt); + vm.serializeAddress("root", "multicall3_addr", config.contracts.multicall3Addr); + vm.serializeUint("root", "l1_chain_id", config.l1ChainId); + vm.serializeUint("root", "era_chain_id", config.eraChainId); + vm.serializeAddress("root", "deployer_addr", config.deployerAddress); + vm.serializeString("root", "deployed_addresses", deployedAddresses); + vm.serializeString("root", "contracts_config", contractsConfig); + string memory toml = vm.serializeAddress("root", "owner_addr", config.ownerAddress); + + string memory path = string.concat(vm.projectRoot(), "/script-out/output-deploy-l1.toml"); vm.writeToml(toml, path); } diff --git a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol index 96828fbe6..792e83721 100644 --- a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol +++ b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol @@ -46,10 +46,10 @@ contract InitializeL2WethTokenScript is Script { string memory path = string.concat(root, "/script-out/output-deploy-l1.toml"); string memory toml = vm.readFile(path); - config.create2FactoryAddr = toml.readAddress("$.l1.create2_factory_addr"); - config.create2FactorySalt = toml.readBytes32("$.l1.create2_factory_salt"); - config.eraChainId = toml.readUint("$.l1.era_chain_id"); - config.bridgehubProxyAddr = toml.readAddress("$.l1.bridgehub.bridgehub_proxy_addr"); + config.create2FactoryAddr = toml.readAddress("$.create2_factory_addr"); + config.create2FactorySalt = toml.readBytes32("$.create2_factory_salt"); + config.eraChainId = toml.readUint("$.era_chain_id"); + config.bridgehubProxyAddr = toml.readAddress("$.deployed_addresses.bridgehub.bridgehub_proxy_addr"); // Parse some config from output of erc20 tokens deployment path = string.concat(root, "/script-out/output-deploy-erc20.toml"); diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 9429a472c..5d088e796 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -76,6 +76,8 @@ contract RegisterHyperchainScript is Script { registerHyperchain(); addValidators(); configureZkSyncStateTransition(); + + saveOutput(); } function initializeConfig() internal { @@ -89,37 +91,47 @@ contract RegisterHyperchainScript is Script { // Config file must be parsed key by key, otherwise values returned // are parsed alfabetically and not by key. // https://book.getfoundry.sh/cheatcodes/parse-toml - config.ownerAddress = toml.readAddress("$.l1.owner_addr"); - - config.addresses.bridgehub = toml.readAddress("$.l1.bridgehub.bridgehub_proxy_addr"); - config.addresses.stateTransitionProxy = toml.readAddress("$.l1.state_transition.state_transition_proxy_addr"); - config.addresses.adminFacet = toml.readAddress("$.l1.state_transition.admin_facet_addr"); - config.addresses.gettersFacet = toml.readAddress("$.l1.state_transition.getters_facet_addr"); - config.addresses.mailboxFacet = toml.readAddress("$.l1.state_transition.mailbox_facet_addr"); - config.addresses.executorFacet = toml.readAddress("$.l1.state_transition.executor_facet_addr"); - config.addresses.verifier = toml.readAddress("$.l1.state_transition.verifier_addr"); - config.addresses.blobVersionedHashRetriever = toml.readAddress("$.l1.blob_versioned_hash_retriever_addr"); - config.addresses.diamondInit = toml.readAddress("$.l1.state_transition.diamond_init_addr"); - config.addresses.validatorTimelock = toml.readAddress("$.l1.validator_timelock_addr"); + config.ownerAddress = toml.readAddress("$.owner_addr"); + + config.addresses.bridgehub = toml.readAddress("$.deployed_addresses.bridgehub.bridgehub_proxy_addr"); + config.addresses.stateTransitionProxy = toml.readAddress( + "$.deployed_addresses.state_transition.state_transition_proxy_addr" + ); + config.addresses.adminFacet = toml.readAddress("$.deployed_addresses.state_transition.admin_facet_addr"); + config.addresses.gettersFacet = toml.readAddress("$.deployed_addresses.state_transition.getters_facet_addr"); + config.addresses.mailboxFacet = toml.readAddress("$.deployed_addresses.state_transition.mailbox_facet_addr"); + config.addresses.executorFacet = toml.readAddress("$.deployed_addresses.state_transition.executor_facet_addr"); + config.addresses.verifier = toml.readAddress("$.deployed_addresses.state_transition.verifier_addr"); + config.addresses.blobVersionedHashRetriever = toml.readAddress( + "$.deployed_addresses.blob_versioned_hash_retriever_addr" + ); + config.addresses.diamondInit = toml.readAddress("$.deployed_addresses.state_transition.diamond_init_addr"); + config.addresses.validatorTimelock = toml.readAddress("$.deployed_addresses.validator_timelock_addr"); config.contracts.diamondInitPubdataPricingMode = PubdataPricingMode( - toml.readUint("$.l1.config.diamond_init_pubdata_pricing_mode") + toml.readUint("$.contracts_config.diamond_init_pubdata_pricing_mode") ); config.contracts.diamondInitBatchOverheadL1Gas = toml.readUint( - "$.l1.config.diamond_init_batch_overhead_l1_gas" + "$.contracts_config.diamond_init_batch_overhead_l1_gas" ); config.contracts.diamondInitMaxPubdataPerBatch = toml.readUint( - "$.l1.config.diamond_init_max_pubdata_per_batch" + "$.contracts_config.diamond_init_max_pubdata_per_batch" + ); + config.contracts.diamondInitMaxL2GasPerBatch = toml.readUint( + "$.contracts_config.diamond_init_max_l2_gas_per_batch" ); - config.contracts.diamondInitMaxL2GasPerBatch = toml.readUint("$.l1.config.diamond_init_max_l2_gas_per_batch"); config.contracts.diamondInitPriorityTxMaxPubdata = toml.readUint( - "$.l1.config.diamond_init_priority_tx_max_pubdata" + "$.contracts_config.diamond_init_priority_tx_max_pubdata" ); - config.contracts.diamondInitMinimalL2GasPrice = toml.readUint("$.l1.config.diamond_init_minimal_l2_gas_price"); - config.contracts.recursionNodeLevelVkHash = toml.readBytes32("$.l1.config.recursion_node_level_vk_hash"); - config.contracts.recursionLeafLevelVkHash = toml.readBytes32("$.l1.config.recursion_leaf_level_vk_hash"); - config.contracts.recursionCircuitsSetVksHash = toml.readBytes32("$.l1.config.recursion_circuits_set_vks_hash"); - config.contracts.priorityTxMaxGasLimit = toml.readUint("$.l1.config.priority_tx_max_gas_limit"); + config.contracts.diamondInitMinimalL2GasPrice = toml.readUint( + "$.contracts_config.diamond_init_minimal_l2_gas_price" + ); + config.contracts.recursionNodeLevelVkHash = toml.readBytes32("$.contracts_config.recursion_node_level_vk_hash"); + config.contracts.recursionLeafLevelVkHash = toml.readBytes32("$.contracts_config.recursion_leaf_level_vk_hash"); + config.contracts.recursionCircuitsSetVksHash = toml.readBytes32( + "$.contracts_config.recursion_circuits_set_vks_hash" + ); + config.contracts.priorityTxMaxGasLimit = toml.readUint("$.contracts_config.priority_tx_max_gas_limit"); // Grab config from l1 deployment config root = vm.projectRoot(); @@ -258,6 +270,7 @@ contract RegisterHyperchainScript is Script { revert("Diamond proxy address not found"); } config.addresses.newDiamondProxy = diamondProxyAddress; + console.log("Hyperchain diamond proxy deployed at:", diamondProxyAddress); } function addValidators() internal { @@ -288,4 +301,11 @@ contract RegisterHyperchainScript is Script { vm.stopBroadcast(); console.log("ZkSync State Transition configured"); } + + function saveOutput() internal { + string memory toml = vm.serializeAddress("root", "diamond_proxy_addr", config.addresses.newDiamondProxy); + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-out/output-register-hyperchain.toml"); + vm.writeToml(toml, path); + } } From d8e07b666f7115c6f77b509f5569e877b86aa550 Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Wed, 1 May 2024 21:31:01 +0100 Subject: [PATCH 25/60] Kl/l2 bridge fix l1 bridge names (#434) --- l1-contracts/src.ts/deploy.ts | 4 +++- .../contracts/bridge/L2SharedBridge.sol | 23 +++++++++++-------- .../bridge/interfaces/IL2SharedBridge.sol | 2 ++ 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 43f9e3074..7a1760762 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -227,7 +227,9 @@ export class Deployer { if (this.verbose) { console.log( - `Proxy admin deployed, gasUsed: ${rec.gasUsed.toString()}, tx hash ${rec.transactionHash}, expected address: ${proxyAdmin.address}` + `Proxy admin deployed, gasUsed: ${rec.gasUsed.toString()}, tx hash ${rec.transactionHash}, expected address: ${ + proxyAdmin.address + }` ); console.log(`CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR=${proxyAdmin.address}`); } diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index 82c5bc615..4c33b4b12 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -20,8 +20,8 @@ import {SystemContractsCaller} from "../SystemContractsCaller.sol"; /// @notice The "default" bridge implementation for the ERC20 tokens. Note, that it does not /// support any custom token logic, i.e. rebase tokens' functionality is not supported. contract L2SharedBridge is IL2SharedBridge, Initializable { - /// @dev The address of the L1 bridge counterpart. - address public override l1Bridge; + /// @dev The address of the L1 shared bridge counterpart. + address public override l1SharedBridge; /// @dev Contract that stores the implementation address for token. /// @dev For more details see https://docs.openzeppelin.com/contracts/3.x/api/proxy#UpgradeableBeacon. @@ -33,7 +33,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { /// @dev A mapping l2 token address => l1 token address mapping(address l2TokenAddress => address l1TokenAddress) public override l1TokenAddress; - address private l1LegacyBridge; + /// @dev The address of the legacy L1 erc20 bridge counterpart. + /// This is non-zero only on Era, and should not be renamed for backward compatibility with the SDKs. + address public override l1Bridge; /// @dev Contract is expected to be used as proxy implementation. /// @dev Disable the initialization to prevent Parity hack. @@ -45,20 +47,21 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { } /// @notice Initializes the bridge contract for later use. Expected to be used in the proxy. - /// @param _l1Bridge The address of the L1 Bridge contract. + /// @param _l1SharedBridge The address of the L1 Bridge contract. + /// @param _l1Bridge The address of the legacy L1 Bridge contract. /// @param _l2TokenProxyBytecodeHash The bytecode hash of the proxy for tokens deployed by the bridge. /// @param _aliasedOwner The address of the governor contract. function initialize( + address _l1SharedBridge, address _l1Bridge, - address _l1LegacyBridge, bytes32 _l2TokenProxyBytecodeHash, address _aliasedOwner ) external reinitializer(2) { - require(_l1Bridge != address(0), "bf"); + require(_l1SharedBridge != address(0), "bf"); require(_l2TokenProxyBytecodeHash != bytes32(0), "df"); require(_aliasedOwner != address(0), "sf"); - l1Bridge = _l1Bridge; + l1SharedBridge = _l1SharedBridge; if (block.chainid != ERA_CHAIN_ID) { address l2StandardToken = address(new L2StandardERC20{salt: bytes32(0)}()); @@ -66,8 +69,8 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; l2TokenBeacon.transferOwnership(_aliasedOwner); } else { - require(_l1LegacyBridge != address(0), "bf2"); - l1LegacyBridge = _l1LegacyBridge; + require(_l1Bridge != address(0), "bf2"); + l1Bridge = _l1Bridge; // l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy } } @@ -88,7 +91,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { // Only the L1 bridge counterpart can initiate and finalize the deposit. require( AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge || - AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1LegacyBridge, + AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1SharedBridge, "mq" ); diff --git a/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol b/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol index 0f16e2360..c1aa05102 100644 --- a/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/interfaces/IL2SharedBridge.sol @@ -33,4 +33,6 @@ interface IL2SharedBridge { function l2TokenAddress(address _l1Token) external view returns (address); function l1Bridge() external view returns (address); + + function l1SharedBridge() external view returns (address); } From 51c3b47937469108c443e95d4921a35bd78f86c0 Mon Sep 17 00:00:00 2001 From: Danil Date: Thu, 2 May 2024 13:38:06 +0200 Subject: [PATCH 26/60] remove redundant configs (#429) Signed-off-by: Danil Co-authored-by: aon <21188659+aon@users.noreply.github.com> --- .../workflows/l1-contracts-foundry-ci.yaml | 4 +- .../config-deploy-l1.toml | 10 - .../register-hyperchain.toml | 12 + l1-contracts-foundry/script/DeployL1.s.sol | 10 +- .../script/RegisterHyperchain.s.sol | 241 ++++++------------ 5 files changed, 98 insertions(+), 179 deletions(-) create mode 100644 l1-contracts-foundry/script-config-template/register-hyperchain.toml diff --git a/.github/workflows/l1-contracts-foundry-ci.yaml b/.github/workflows/l1-contracts-foundry-ci.yaml index 729e66a69..c02688546 100644 --- a/.github/workflows/l1-contracts-foundry-ci.yaml +++ b/.github/workflows/l1-contracts-foundry-ci.yaml @@ -105,7 +105,9 @@ jobs: - name: Run RegisterHyperchain script working-directory: ./l1-contracts-foundry - run: forge script ./script/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY + run: | + cat ./script-out/output-deploy-l1.toml >> ./script-config/register-hyperchain.toml + forge script ./script/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY - name: Run DeployErc20 script working-directory: ./l1-contracts-foundry diff --git a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml index ddcd9b27e..28fe6a68a 100644 --- a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml +++ b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml @@ -25,13 +25,3 @@ diamond_init_minimal_l2_gas_price = 250000000 [tokens] token_weth_address = "0x0000000000000000000000000000000000000000" - -[hyperchain] -hyperchain_chain_id = 9 -base_token_addr = "0x0000000000000000000000000000000000000001" -bridgehub_create_new_chain_salt = 0 -validium_mode = false -validator_sender_operator_commit_eth = "0x0000000000000000000000000000000000000000" -validator_sender_operator_blobs_eth = "0x0000000000000000000000000000000000000001" -base_token_gas_price_multiplier_nominator = 1 -base_token_gas_price_multiplier_denominator = 1 diff --git a/l1-contracts-foundry/script-config-template/register-hyperchain.toml b/l1-contracts-foundry/script-config-template/register-hyperchain.toml new file mode 100644 index 000000000..3d45e5b50 --- /dev/null +++ b/l1-contracts-foundry/script-config-template/register-hyperchain.toml @@ -0,0 +1,12 @@ +owner_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +[hyperchain] +hyperchain_chain_id = 9 +base_token_addr = "0x0000000000000000000000000000000000000001" +bridgehub_create_new_chain_salt = 0 +validium_mode = false +validator_sender_operator_commit_eth = "0x0000000000000000000000000000000000000000" +validator_sender_operator_blobs_eth = "0x0000000000000000000000000000000000000001" +base_token_gas_price_multiplier_nominator = 1 +base_token_gas_price_multiplier_denominator = 1 +governance_min_delay = 0 +governance_security_council_address = "0x0000000000000000000000000000000000000000" diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 7c8d62adf..9625dbba6 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -106,6 +106,7 @@ contract DeployL1Script is Script { address governanceSecurityCouncilAddress; uint256 governanceMinDelay; uint256 maxNumberOfHyperchains; + bytes diamondCutData; } struct TokensConfig { @@ -412,6 +413,8 @@ contract DeployL1Script is Script { initCalldata: abi.encode(initializeData) }); + config.contracts.diamondCutData = abi.encode(diamondCut); + StateTransitionManagerInitializeData memory diamondInitData = StateTransitionManagerInitializeData({ owner: config.ownerAddress, validatorTimelock: addresses.validatorTimelock, @@ -652,10 +655,11 @@ contract DeployL1Script is Script { "recursion_circuits_set_vks_hash", config.contracts.recursionCircuitsSetVksHash ); - string memory contractsConfig = vm.serializeUint( + vm.serializeUint("contracts_config", "priority_tx_max_gas_limit", config.contracts.priorityTxMaxGasLimit); + string memory contractsConfig = vm.serializeBytes( "contracts_config", - "priority_tx_max_gas_limit", - config.contracts.priorityTxMaxGasLimit + "diamond_cut_data", + config.contracts.diamondCutData ); vm.serializeAddress("deployed_addresses", "transparent_proxy_admin_addr", addresses.transparentProxyAdmin); diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 5d088e796..7f1a69026 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -7,14 +7,10 @@ import {Script, console2 as console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; import {stdToml} from "forge-std/StdToml.sol"; -import {Utils} from "./Utils.sol"; import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; -import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; -import {VerifierParams, IVerifier} from "contracts/state-transition/chain-interfaces/IVerifier.sol"; -import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; -import {InitializeDataNewChain as DiamondInitializeDataNewChain} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; +import {Governance} from "contracts/governance/Governance.sol"; contract RegisterHyperchainScript is Script { using stdToml for string; @@ -23,45 +19,24 @@ contract RegisterHyperchainScript is Script { bytes32 constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); struct Config { - ContractsConfig contracts; - AddressesConfig addresses; address deployerAddress; address ownerAddress; uint256 hyperchainChainId; - } - - struct ContractsConfig { - uint256 bridgehubCreateNewChainSalt; - PubdataPricingMode diamondInitPubdataPricingMode; - uint256 diamondInitBatchOverheadL1Gas; - uint256 diamondInitMaxPubdataPerBatch; - uint256 diamondInitMaxL2GasPerBatch; - uint256 diamondInitPriorityTxMaxPubdata; - uint256 diamondInitMinimalL2GasPrice; - bytes32 recursionNodeLevelVkHash; - bytes32 recursionLeafLevelVkHash; - bytes32 recursionCircuitsSetVksHash; - uint256 priorityTxMaxGasLimit; bool validiumMode; + uint256 bridgehubCreateNewChainSalt; address validatorSenderOperatorCommitEth; address validatorSenderOperatorBlobsEth; + address baseToken; uint128 baseTokenGasPriceMultiplierNominator; uint128 baseTokenGasPriceMultiplierDenominator; - } - - struct AddressesConfig { - address baseToken; address bridgehub; address stateTransitionProxy; - address adminFacet; - address gettersFacet; - address mailboxFacet; - address executorFacet; - address verifier; - address blobVersionedHashRetriever; - address diamondInit; address validatorTimelock; + bytes diamondCutData; + address governanceSecurityCouncilAddress; + uint256 governanceMinDelay; address newDiamondProxy; + address governance; } Config config; @@ -71,19 +46,33 @@ contract RegisterHyperchainScript is Script { initializeConfig(); + deployGovernance(); checkTokenAddress(); registerTokenOnBridgehub(); registerHyperchain(); addValidators(); configureZkSyncStateTransition(); + setPendingAdmin(); saveOutput(); } + // This function should be called by the owner to accept the admin role + function acceptAdmin() public { + console.log("Accept admin Hyperchain"); + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-config/accept-admin.toml"); + string memory toml = vm.readFile(path); + address diamondProxy = toml.readAddress("$.diamond_proxy_addr"); + IZkSyncHyperchain zkSyncStateTransition = IZkSyncHyperchain(diamondProxy); + vm.broadcast(); + zkSyncStateTransition.acceptAdmin(); + } + function initializeConfig() internal { // Grab config from output of l1 deployment string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/script-out/output-deploy-l1.toml"); + string memory path = string.concat(root, "/script-config/register-hyperchain.toml"); string memory toml = vm.readFile(path); config.deployerAddress = msg.sender; @@ -91,169 +80,83 @@ contract RegisterHyperchainScript is Script { // Config file must be parsed key by key, otherwise values returned // are parsed alfabetically and not by key. // https://book.getfoundry.sh/cheatcodes/parse-toml - config.ownerAddress = toml.readAddress("$.owner_addr"); + config.ownerAddress = toml.readAddress("$.owner_address"); - config.addresses.bridgehub = toml.readAddress("$.deployed_addresses.bridgehub.bridgehub_proxy_addr"); - config.addresses.stateTransitionProxy = toml.readAddress( + config.bridgehub = toml.readAddress("$.deployed_addresses.bridgehub.bridgehub_proxy_addr"); + config.stateTransitionProxy = toml.readAddress( "$.deployed_addresses.state_transition.state_transition_proxy_addr" ); - config.addresses.adminFacet = toml.readAddress("$.deployed_addresses.state_transition.admin_facet_addr"); - config.addresses.gettersFacet = toml.readAddress("$.deployed_addresses.state_transition.getters_facet_addr"); - config.addresses.mailboxFacet = toml.readAddress("$.deployed_addresses.state_transition.mailbox_facet_addr"); - config.addresses.executorFacet = toml.readAddress("$.deployed_addresses.state_transition.executor_facet_addr"); - config.addresses.verifier = toml.readAddress("$.deployed_addresses.state_transition.verifier_addr"); - config.addresses.blobVersionedHashRetriever = toml.readAddress( - "$.deployed_addresses.blob_versioned_hash_retriever_addr" - ); - config.addresses.diamondInit = toml.readAddress("$.deployed_addresses.state_transition.diamond_init_addr"); - config.addresses.validatorTimelock = toml.readAddress("$.deployed_addresses.validator_timelock_addr"); - - config.contracts.diamondInitPubdataPricingMode = PubdataPricingMode( - toml.readUint("$.contracts_config.diamond_init_pubdata_pricing_mode") - ); - config.contracts.diamondInitBatchOverheadL1Gas = toml.readUint( - "$.contracts_config.diamond_init_batch_overhead_l1_gas" - ); - config.contracts.diamondInitMaxPubdataPerBatch = toml.readUint( - "$.contracts_config.diamond_init_max_pubdata_per_batch" - ); - config.contracts.diamondInitMaxL2GasPerBatch = toml.readUint( - "$.contracts_config.diamond_init_max_l2_gas_per_batch" - ); - config.contracts.diamondInitPriorityTxMaxPubdata = toml.readUint( - "$.contracts_config.diamond_init_priority_tx_max_pubdata" - ); - config.contracts.diamondInitMinimalL2GasPrice = toml.readUint( - "$.contracts_config.diamond_init_minimal_l2_gas_price" - ); - config.contracts.recursionNodeLevelVkHash = toml.readBytes32("$.contracts_config.recursion_node_level_vk_hash"); - config.contracts.recursionLeafLevelVkHash = toml.readBytes32("$.contracts_config.recursion_leaf_level_vk_hash"); - config.contracts.recursionCircuitsSetVksHash = toml.readBytes32( - "$.contracts_config.recursion_circuits_set_vks_hash" - ); - config.contracts.priorityTxMaxGasLimit = toml.readUint("$.contracts_config.priority_tx_max_gas_limit"); + config.validatorTimelock = toml.readAddress("$.deployed_addresses.validator_timelock_addr"); - // Grab config from l1 deployment config - root = vm.projectRoot(); - path = string.concat(root, "/script-config/config-deploy-l1.toml"); - toml = vm.readFile(path); + config.diamondCutData = toml.readBytes("$.contracts_config.diamond_cut_data"); config.hyperchainChainId = toml.readUint("$.hyperchain.hyperchain_chain_id"); - config.contracts.bridgehubCreateNewChainSalt = toml.readUint("$.hyperchain.bridgehub_create_new_chain_salt"); - config.addresses.baseToken = toml.readAddress("$.hyperchain.base_token_addr"); - config.contracts.validiumMode = toml.readBool("$.hyperchain.validium_mode"); - config.contracts.validatorSenderOperatorCommitEth = toml.readAddress( - "$.hyperchain.validator_sender_operator_commit_eth" - ); - config.contracts.validatorSenderOperatorBlobsEth = toml.readAddress( - "$.hyperchain.validator_sender_operator_blobs_eth" - ); - config.contracts.baseTokenGasPriceMultiplierNominator = uint128( + config.bridgehubCreateNewChainSalt = toml.readUint("$.hyperchain.bridgehub_create_new_chain_salt"); + config.baseToken = toml.readAddress("$.hyperchain.base_token_addr"); + config.validiumMode = toml.readBool("$.hyperchain.validium_mode"); + config.validatorSenderOperatorCommitEth = toml.readAddress("$.hyperchain.validator_sender_operator_commit_eth"); + config.validatorSenderOperatorBlobsEth = toml.readAddress("$.hyperchain.validator_sender_operator_blobs_eth"); + config.baseTokenGasPriceMultiplierNominator = uint128( toml.readUint("$.hyperchain.base_token_gas_price_multiplier_nominator") ); - config.contracts.baseTokenGasPriceMultiplierDenominator = uint128( + config.baseTokenGasPriceMultiplierDenominator = uint128( toml.readUint("$.hyperchain.base_token_gas_price_multiplier_denominator") ); + config.governanceMinDelay = uint256(toml.readUint("$.hyperchain.governance_min_delay")); + config.governanceSecurityCouncilAddress = toml.readAddress("$.hyperchain.governance_security_council_address"); } - function checkTokenAddress() internal { - if (config.addresses.baseToken == address(0)) { + function checkTokenAddress() internal view { + if (config.baseToken == address(0)) { revert("Token address is not set"); } // Check if it's ethereum address - if (config.addresses.baseToken == ADDRESS_ONE) { + if (config.baseToken == ADDRESS_ONE) { return; } - if (config.addresses.baseToken.code.length == 0) { + if (config.baseToken.code.length == 0) { revert("Token address is not a contract address"); } - console.log("Using base token address:", config.addresses.baseToken); + console.log("Using base token address:", config.baseToken); } function registerTokenOnBridgehub() internal { - IBridgehub bridgehub = IBridgehub(config.addresses.bridgehub); + IBridgehub bridgehub = IBridgehub(config.bridgehub); - if (bridgehub.tokenIsRegistered(config.addresses.baseToken)) { + if (bridgehub.tokenIsRegistered(config.baseToken)) { console.log("Token already registered on Bridgehub"); } else { vm.broadcast(); - bridgehub.addToken(config.addresses.baseToken); + bridgehub.addToken(config.baseToken); console.log("Token registered on Bridgehub"); } } - function registerHyperchain() internal { - Diamond.FacetCut[] memory facetCuts = new Diamond.FacetCut[](4); - facetCuts[0] = Diamond.FacetCut({ - facet: config.addresses.adminFacet, - action: Diamond.Action.Add, - isFreezable: false, - selectors: Utils.getAllSelectors(config.addresses.adminFacet.code) - }); - facetCuts[1] = Diamond.FacetCut({ - facet: config.addresses.gettersFacet, - action: Diamond.Action.Add, - isFreezable: false, - selectors: Utils.getAllSelectors(config.addresses.gettersFacet.code) - }); - facetCuts[2] = Diamond.FacetCut({ - facet: config.addresses.mailboxFacet, - action: Diamond.Action.Add, - isFreezable: true, - selectors: Utils.getAllSelectors(config.addresses.mailboxFacet.code) - }); - facetCuts[3] = Diamond.FacetCut({ - facet: config.addresses.executorFacet, - action: Diamond.Action.Add, - isFreezable: true, - selectors: Utils.getAllSelectors(config.addresses.executorFacet.code) - }); - - VerifierParams memory verifierParams = VerifierParams({ - recursionNodeLevelVkHash: config.contracts.recursionNodeLevelVkHash, - recursionLeafLevelVkHash: config.contracts.recursionLeafLevelVkHash, - recursionCircuitsSetVksHash: config.contracts.recursionCircuitsSetVksHash - }); - - FeeParams memory feeParams = FeeParams({ - pubdataPricingMode: config.contracts.diamondInitPubdataPricingMode, - batchOverheadL1Gas: uint32(config.contracts.diamondInitBatchOverheadL1Gas), - maxPubdataPerBatch: uint32(config.contracts.diamondInitMaxPubdataPerBatch), - maxL2GasPerBatch: uint32(config.contracts.diamondInitMaxL2GasPerBatch), - priorityTxMaxPubdata: uint32(config.contracts.diamondInitPriorityTxMaxPubdata), - minimalL2GasPrice: uint64(config.contracts.diamondInitMinimalL2GasPrice) - }); - - DiamondInitializeDataNewChain memory initializeData = DiamondInitializeDataNewChain({ - verifier: IVerifier(config.addresses.verifier), - verifierParams: verifierParams, - l2BootloaderBytecodeHash: bytes32(Utils.getBatchBootloaderBytecodeHash()), - l2DefaultAccountBytecodeHash: bytes32(Utils.readSystemContractsBytecode("DefaultAccount")), - priorityTxMaxGasLimit: config.contracts.priorityTxMaxGasLimit, - feeParams: feeParams, - blobVersionedHashRetriever: config.addresses.blobVersionedHashRetriever - }); - - Diamond.DiamondCutData memory initData = Diamond.DiamondCutData({ - facetCuts: facetCuts, - initAddress: config.addresses.diamondInit, - initCalldata: abi.encode(initializeData) - }); + function deployGovernance() internal { + Governance governance = new Governance( + config.ownerAddress, + config.governanceSecurityCouncilAddress, + config.governanceMinDelay + ); + console.log("Governance deployed at:", address(governance)); + config.governance = address(governance); + } - IBridgehub bridgehub = IBridgehub(config.addresses.bridgehub); + function registerHyperchain() internal { + IBridgehub bridgehub = IBridgehub(config.bridgehub); vm.broadcast(); vm.recordLogs(); bridgehub.createNewChain({ _chainId: config.hyperchainChainId, - _stateTransitionManager: config.addresses.stateTransitionProxy, - _baseToken: config.addresses.baseToken, - _salt: config.contracts.bridgehubCreateNewChainSalt, + _stateTransitionManager: config.stateTransitionProxy, + _baseToken: config.baseToken, + _salt: config.bridgehubCreateNewChainSalt, _admin: msg.sender, - _initData: abi.encode(initData) + _initData: config.diamondCutData }); console.log("Hyperchain registered"); @@ -269,28 +172,28 @@ contract RegisterHyperchainScript is Script { if (diamondProxyAddress == address(0)) { revert("Diamond proxy address not found"); } - config.addresses.newDiamondProxy = diamondProxyAddress; + config.newDiamondProxy = diamondProxyAddress; console.log("Hyperchain diamond proxy deployed at:", diamondProxyAddress); } function addValidators() internal { - ValidatorTimelock validatorTimelock = ValidatorTimelock(config.addresses.validatorTimelock); + ValidatorTimelock validatorTimelock = ValidatorTimelock(config.validatorTimelock); vm.startBroadcast(); - validatorTimelock.addValidator(config.hyperchainChainId, config.contracts.validatorSenderOperatorCommitEth); - validatorTimelock.addValidator(config.hyperchainChainId, config.contracts.validatorSenderOperatorBlobsEth); + validatorTimelock.addValidator(config.hyperchainChainId, config.validatorSenderOperatorCommitEth); + validatorTimelock.addValidator(config.hyperchainChainId, config.validatorSenderOperatorBlobsEth); vm.stopBroadcast(); console.log("Validators added"); } function configureZkSyncStateTransition() internal { - IZkSyncHyperchain zkSyncStateTransition = IZkSyncHyperchain(config.addresses.newDiamondProxy); + IZkSyncHyperchain hyperchain = IZkSyncHyperchain(config.newDiamondProxy); vm.startBroadcast(); - zkSyncStateTransition.setTokenMultiplier( - config.contracts.baseTokenGasPriceMultiplierNominator, - config.contracts.baseTokenGasPriceMultiplierDenominator + hyperchain.setTokenMultiplier( + config.baseTokenGasPriceMultiplierNominator, + config.baseTokenGasPriceMultiplierDenominator ); // TODO: support validium mode when available @@ -302,8 +205,16 @@ contract RegisterHyperchainScript is Script { console.log("ZkSync State Transition configured"); } + function setPendingAdmin() internal { + IZkSyncHyperchain hyperchain = IZkSyncHyperchain(config.newDiamondProxy); + + vm.broadcast(); + hyperchain.setPendingAdmin(config.governance); + console.log("Owner set"); + } + function saveOutput() internal { - string memory toml = vm.serializeAddress("root", "diamond_proxy_addr", config.addresses.newDiamondProxy); + string memory toml = vm.serializeAddress("root", "diamond_proxy_addr", config.newDiamondProxy); string memory root = vm.projectRoot(); string memory path = string.concat(root, "/script-out/output-register-hyperchain.toml"); vm.writeToml(toml, path); From 3e59239048049b366cfe55ce236170f6cc119b91 Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Thu, 2 May 2024 20:41:58 +0100 Subject: [PATCH 27/60] fix: correct local bridge testing (#440) Co-authored-by: Stanislav Breadless Co-authored-by: kelemeno <34402761+kelemeno@users.noreply.github.com> --- .../dev-contracts/DevL2SharedBridge.sol | 33 ++++++++++++ .../deploy-shared-bridge-on-l2-through-l1.ts | 51 ++++++++++++------- 2 files changed, 67 insertions(+), 17 deletions(-) create mode 100644 l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol diff --git a/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol new file mode 100644 index 000000000..12a6a187f --- /dev/null +++ b/l2-contracts/contracts/dev-contracts/DevL2SharedBridge.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {L2SharedBridge} from "../bridge/L2SharedBridge.sol"; +import {L2StandardERC20} from "../bridge/L2StandardERC20.sol"; +import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol"; + +/// @author Matter Labs +/// @notice The implementation of the shared bridge that allows setting legacy bridge. Must only be used in local testing environments. +contract DevL2SharedBridge is L2SharedBridge { + constructor(uint256 _eraChainId) L2SharedBridge(_eraChainId) {} + + function initializeDevBridge( + address _l1SharedBridge, + address _l1Bridge, + bytes32 _l2TokenProxyBytecodeHash, + address _aliasedOwner + ) external reinitializer(2) { + l1SharedBridge = _l1SharedBridge; + + address l2StandardToken = address(new L2StandardERC20{salt: bytes32(0)}()); + l2TokenBeacon = new UpgradeableBeacon{salt: bytes32(0)}(l2StandardToken); + l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; + l2TokenBeacon.transferOwnership(_aliasedOwner); + + // Unfortunately the `l1Bridge` is not an internal variable in the parent contract. + // To keep the changes to the production code minimal, we'll just manually set the variable here. + assembly { + sstore(4, _l1Bridge) + } + } +} diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index d24fe38f4..6fa655ceb 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -19,7 +19,6 @@ import { GAS_MULTIPLIER } from "../../l1-contracts/scripts/utils"; import * as hre from "hardhat"; export const L2_SHARED_BRIDGE_ABI = hre.artifacts.readArtifactSync("L2SharedBridge").abi; -export const L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE = hre.artifacts.readArtifactSync("L2SharedBridge").bytecode; export const L2_STANDARD_TOKEN_PROXY_BYTECODE = hre.artifacts.readArtifactSync("BeaconProxy").bytecode; export async function publishL2SharedBridgeDependencyBytecodesOnL2( @@ -60,18 +59,23 @@ export async function deploySharedBridgeImplOnL2ThroughL1( console.log("Deploying L2SharedBridge Implementation"); } const eraChainId = process.env.CONTRACTS_ERA_CHAIN_ID; - if (!L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE) { - throw new Error("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE not found"); + + const l2SharedBridgeImplementationBytecode = localLegacyBridgeTesting + ? hre.artifacts.readArtifactSync("DevL2SharedBridge").bytecode + : hre.artifacts.readArtifactSync("L2SharedBridge").bytecode; + + if (!l2SharedBridgeImplementationBytecode) { + throw new Error("l2SharedBridgeImplementationBytecode not found"); } if (deployer.verbose) { - console.log("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE loaded"); + console.log("l2SharedBridgeImplementationBytecode loaded"); console.log("Computing L2SharedBridge Implementation Address"); } const l2SharedBridgeImplAddress = computeL2Create2Address( deployer.deployWallet, - L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [localLegacyBridgeTesting ? 0 : eraChainId]), + l2SharedBridgeImplementationBytecode, + defaultAbiCoder.encode(["uint256"], [eraChainId]), ethers.constants.HashZero ); deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress; @@ -88,8 +92,8 @@ export async function deploySharedBridgeImplOnL2ThroughL1( const tx2 = await create2DeployFromL1( chainId, deployer.deployWallet, - L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [localLegacyBridgeTesting ? 0 : eraChainId]), + l2SharedBridgeImplementationBytecode, + defaultAbiCoder.encode(["uint256"], [eraChainId]), ethers.constants.HashZero, priorityTxMaxGasLimit, gasPrice, @@ -106,7 +110,8 @@ export async function deploySharedBridgeImplOnL2ThroughL1( export async function deploySharedBridgeProxyOnL2ThroughL1( deployer: Deployer, chainId: string, - gasPrice: BigNumberish + gasPrice: BigNumberish, + localLegacyBridgeTesting: boolean = false ) { const l1SharedBridge = deployer.defaultSharedBridge(deployer.deployWallet); if (deployer.verbose) { @@ -114,13 +119,25 @@ export async function deploySharedBridgeProxyOnL2ThroughL1( } /// prepare proxyInitializationParams const l2GovernorAddress = applyL1ToL2Alias(deployer.addresses.Governance); - const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("L2SharedBridge").abi); - const proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initialize", [ - l1SharedBridge.address, - deployer.addresses.Bridges.ERC20BridgeProxy, - hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE), - l2GovernorAddress, - ]); + + let proxyInitializationParams; + if (localLegacyBridgeTesting) { + const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("DevL2SharedBridge").abi); + proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initializeDevBridge", [ + l1SharedBridge.address, + deployer.addresses.Bridges.ERC20BridgeProxy, + hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE), + l2GovernorAddress, + ]); + } else { + const l2SharedBridgeInterface = new Interface(hre.artifacts.readArtifactSync("L2SharedBridge").abi); + proxyInitializationParams = l2SharedBridgeInterface.encodeFunctionData("initialize", [ + l1SharedBridge.address, + deployer.addresses.Bridges.ERC20BridgeProxy, + hashL2Bytecode(L2_STANDARD_TOKEN_PROXY_BYTECODE), + l2GovernorAddress, + ]); + } /// prepare constructor data const l2SharedBridgeProxyConstructorData = ethers.utils.arrayify( @@ -187,7 +204,7 @@ export async function deploySharedBridgeOnL2ThroughL1( ) { await publishL2SharedBridgeDependencyBytecodesOnL2(deployer, chainId, gasPrice); await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting); - await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice); + await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting); await initializeChainGovernance(deployer, chainId); } From 13445ad8de76690971ea2fd40eaf86c114fa9fc6 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Mon, 6 May 2024 17:28:48 +0200 Subject: [PATCH 28/60] Move gas bound caller to a separate folder (#425) Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> --- gas-bound-caller/README.md | 51 +++ .../canonical-bytecodes/GasBoundCaller | 1 + .../contracts/GasBoundCaller.sol | 35 +- gas-bound-caller/contracts/ISystemContext.sol | 61 +++ .../test-contracts/GasBoundCallerTester.sol | 41 +- .../test-contracts/SystemContractHelper.sol | 355 ++++++++++++++++++ .../test-contracts/SystemContractsCaller.sol | 268 +++++++++++++ gas-bound-caller/hardhat.config.ts | 62 +++ gas-bound-caller/package.json | 60 +++ .../scripts/check-canonical-bytecode.ts | 42 +++ .../scripts/deploy-on-hyperchain.ts | 104 +++++ gas-bound-caller/scripts/utils.ts | 11 + .../test/GasBoundCaller.spec.ts | 36 +- package.json | 6 +- system-contracts/SystemContractsHashes.json | 7 - yarn.lock | 7 +- 16 files changed, 1109 insertions(+), 38 deletions(-) create mode 100644 gas-bound-caller/README.md create mode 100644 gas-bound-caller/canonical-bytecodes/GasBoundCaller rename {system-contracts => gas-bound-caller}/contracts/GasBoundCaller.sol (71%) create mode 100644 gas-bound-caller/contracts/ISystemContext.sol rename {system-contracts => gas-bound-caller}/contracts/test-contracts/GasBoundCallerTester.sol (50%) create mode 100644 gas-bound-caller/contracts/test-contracts/SystemContractHelper.sol create mode 100644 gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol create mode 100644 gas-bound-caller/hardhat.config.ts create mode 100644 gas-bound-caller/package.json create mode 100644 gas-bound-caller/scripts/check-canonical-bytecode.ts create mode 100644 gas-bound-caller/scripts/deploy-on-hyperchain.ts create mode 100644 gas-bound-caller/scripts/utils.ts rename {system-contracts => gas-bound-caller}/test/GasBoundCaller.spec.ts (77%) diff --git a/gas-bound-caller/README.md b/gas-bound-caller/README.md new file mode 100644 index 000000000..71962937b --- /dev/null +++ b/gas-bound-caller/README.md @@ -0,0 +1,51 @@ +# GasBoundCaller + +Starting from v24 On Era, the gas for pubdata is charged at the end of the execution of the entire transaction. This means that if a subcall is not trusted, it can consume a significant amount of pubdata during the process. While this may not be an issue for most contracts, there are use cases, e.g., for relayers, where it is crucial to ensure that the subcall will not spend more money than intended. + +The `GasBoundCaller` is a contract with the following interface: + +```solidity +function gasBoundCall(address _to, uint256 _maxTotalGas, bytes calldata _data) external payable +``` + +> Note that the amount of gas passed into this function should be less than or equal to `_maxTotalGas`. If the computational gas provided is higher than `_maxTotalGas`, the higher value will be used. + +This contract will call the address `_to` with the entire execution gas passed to it, while ensuring that the total consumed gas does not exceed `_maxTotalGas` under any circumstances. + +If the call to the `_to` address fails, the gas used on pubdata is considered zero, and the total gas used is fully equivalent to the gas consumed within the execution. The `GasBoundCaller` will relay the revert message as-is. + +If the call to the `_to` address succeeds, the `GasBoundCaller` will ensure that the total consumed gas does not exceed `_maxTotalGas`. If it does, it will revert with a "Not enough gas for pubdata" error. If the total consumed gas is less than or equal to `_maxTotalGas`, the `GasBoundCaller` will return returndata equal to `abi.encode(bytes returndataFromSubcall, uint256 gasUsedForPubdata)`. + +## Usage + +Summing up the information from the previous chapter, the `GasBoundCaller` should be used in the following way: + +TODO(EVM-585): switch `addr` with address. + +```solidity +uint256 computeGasBefore = gasleft(); + +(bool success, bytes memory returnData) = address(this).call{gas: _gasToPass}(abi.encodeWithSelector(GasBoundCaller.gasBoundCall.selector, _to, _maxTotalGas, _data)); + +uint256 pubdataGasSpent; +if (success) { + (returnData, pubdataGasSpent) = abi.decode(returnData, (bytes, uint256)); +} else { + // `returnData` is fully equal to the returndata, while `pubdataGasSpent` is equal to 0 +} + +uint256 computeGasAfter = gasleft(); + +// This is the total gas that the subcall made the transaction to be charged for +uint256 totalGasConsumed = computeGasBefore - computeGasAfter + pubdataGasSpent; +``` + +### Preserving `msg.sender` + +Since `GasBoundCaller` would be the contract that calls the `_to` contract, the `msg.sender` will be equal to the `GasBoundCaller`'s address. To preserve the current `msg.sender`, this contract can be inherited from and used the same way, but instead of calling `GasBoundCaller.gasBoundCall`, `this.gasBoundCall` could be called. + +## Deployed Address + +It should be deployed via a built-in CREATE2 factory on each individual chain. + +TODO(EVM-585) diff --git a/gas-bound-caller/canonical-bytecodes/GasBoundCaller b/gas-bound-caller/canonical-bytecodes/GasBoundCaller new file mode 100644 index 000000000..17dcacc84 --- /dev/null +++ b/gas-bound-caller/canonical-bytecodes/GasBoundCaller @@ -0,0 +1 @@ +0x00120000000000020006000000000002000000000301001900000060043002700000009e03400197000100000031035500020000003103550003000000310355000400000031035500050000003103550006000000310355000700000031035500080000003103550009000000310355000a000000310355000b000000310355000c000000310355000d000000310355000e000000310355000f000000310355001000000031035500110000000103550000009e0040019d0000008004000039000000400040043f00000001022001900000004d0000c13d000000040230008c000000a50000413d000000000201043b000000a002200197000000a10220009c000000a50000c13d000000040230008a000000600220008c000000a50000413d0000000402100370000000000802043b000000a20280009c000000a50000213d0000004402100370000000000202043b000000a30420009c000000a50000213d0000002304200039000000a405000041000000000634004b00000000060000190000000006058019000000a404400197000000000704004b0000000005008019000000a40440009c000000000506c019000000000405004b000000a50000c13d0000000404200039000000000441034f000000000604043b000000a30460009c000000a50000213d00000024052000390000000004560019000000000234004b000000a50000213d0000002401100370000000000201043b0000000003000414000003200100008a000000000113004b000000550000413d000000b10100004100000000001004350000001101000039000000040010043f000000b20100004100000274000104300000000001000416000000000101004b000000a50000c13d0000002001000039000001000010044300000120000004430000009f01000041000002730001042e0000000001000414000000000121004b000000620000a13d000000af01000041000000800010043f0000002001000039000000840010043f0000001401000039000000a40010043f000000b401000041000000c40010043f000000b5010000410000027400010430000200000006001d000100000005001d000500000004001d000600000008001d000000a501000041000000800010043f0000009e01000041000400000002001d0000000002000414000300000003001d0000009e0320009c0000000002018019000000c001200210000000a6011001c70000800b02000039027202680000040f00000003030000290000000403300069000003200a30008a0000000403a0006c00000000030000190000000103002039000000000303004b000000000a00c019000000000301001900000060033002700000009e03300197000000200430008c000000000403001900000020040080390000001f0540018f00000005064002720000008c0000613d00000000070000190000000508700210000000000981034f000000000909043b000000800880003900000000009804350000000107700039000000000867004b000000840000413d000000000705004b000000060b0000290000009c0000613d0000000506600210000000000761034f00000003055002100000008006600039000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f00000000005604350000000102200190000000050c000029000000a70000613d0000001f01400039000000600210018f00000080012001bf000000400010043f000000200330008c000000ca0000813d00000000010000190000027400010430000000400200043d0000001f0430018f0000000505300272000000b40000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000000ac0000413d000000000604004b000000c30000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f00000000001504350000009e010000410000009e0420009c000000000201801900000040012002100000006002300210000000000121019f0000027400010430000000800900043d0000000004000414000000000600003100000011050003670000000003000416000000000703004b000000e80000c13d000000020300006b000000da0000613d00000001030000290000009e0330019700010000003503550000000007c6004b000000470000413d000000000535034f0000000006c600490000009e0360019700010000003503e50000009e0640009c000000f50000213d000400000009001d00050000000a001d00000000013503df000000c002400210000000a802200197000000aa022001c700010000002103b500000000012103af00000000020b00190000010f0000013d000000020700006b000000f10000613d00000001070000290000009e0770019700010000007503550000000008c6004b000000470000413d000000000575034f0000000006c600490000009e0660019700010000006503e5000000a70740009c000001030000413d000000af03000041000000000031043500000084032001bf00000020040000390000000000430435000000c403200039000000b3040000410000000000430435000000a402200039000000080300003900000000003204350000004001100210000000b0011001c70000027400010430000400000009001d00050000000a001d00000000016503df000000c002400210000000a802200197000000a9022001c700010000002103b500000000012103af000080090200003900000000040b0019000000000500001900000000060000190272026d0000040f000000000301001900000060033002700000009e033001970000000102200190000001d90000613d0000003f02300039000000ab02200197000000400600043d0000000002260019000000000462004b00000000040000190000000104004039000000a30520009c000001d50000213d0000000104400190000001d50000c13d000000400020043f000200000006001d00000000023604360000001f043000390000000504400272000001310000613d00000000050000310000001105500367000000000600001900000005076002100000000008720019000000000775034f000000000707043b00000000007804350000000106600039000000000746004b000001290000413d000000000400004b000001330000613d0000001f0430018f00000005033002720000013f0000613d000000000500001900000005065002100000000007620019000000000661034f000000000606043b00000000006704350000000105500039000000000635004b000001370000413d000000000504004b0000014e0000613d0000000503300210000000000131034f00000000023200190000000303400210000000000402043300000000043401cf000000000434022f000000000101043b0000010003300089000000000131022f00000000013101cf000000000141019f0000000000120435000000400400043d000600000004001d000000a50100004100000000001404350000009e0100004100000000020004140000009e0320009c00000000020180190000009e0340009c00000000010440190000004001100210000000c002200210000000000112019f000000ac011001c70000800b02000039027202680000040f000000060a000029000000000301001900000060033002700000009e03300197000000200430008c000000000403001900000020040080390000001f0540018f0000000506400272000001710000613d0000000007000019000000050870021000000000098a0019000000000881034f000000000808043b00000000008904350000000107700039000000000867004b000001690000413d00000000090a0019000000000705004b000001810000613d0000000506600210000000000761034f00000000066900190000000305500210000000000806043300000000085801cf000000000858022f000000000707043b0000010005500089000000000757022f00000000055701cf000000000585019f00000000005604350000000102200190000001f40000613d0000001f01400039000000600110018f0000000002910019000000000112004b00000000010000190000000101004039000300000002001d000000a30220009c000001d50000213d0000000101100190000001d50000c13d0000000301000029000000400010043f000000200130008c0000000501000029000000a50000413d000500000001001d0000000001090433000600000001001d000000ad01000041000000030400002900000000001404350000009e0100004100000000020004140000009e0320009c00000000020180190000009e0340009c00000000010440190000004001100210000000c002200210000000000112019f000000ac011001c70000800b02000039027202680000040f000000030b0000290000000605000029000000040450006a000000000354004b00000000030000190000000103002039000000000303004b000000000400c019000000000301001900000060033002700000009e03300197000000200530008c000000000503001900000020050080390000001f0650018f0000000507500272000001bf0000613d00000000080000190000000509800210000000000a9b0019000000000991034f000000000909043b00000000009a04350000000108800039000000000978004b000001b70000413d000000000806004b000001ce0000613d0000000507700210000000000871034f00000003077000290000000306600210000000000907043300000000096901cf000000000969022f000000000808043b0000010006600089000000000868022f00000000066801cf000000000696019f00000000006704350000000102200190000002110000613d0000001f01500039000000600110018f0000000301100029000000a30210009c0000022e0000a13d000000b101000041000000000010043500000041010000390000004a0000013d0000001f0430018f0000000502300272000001e40000613d00000000050000190000000506500210000000000761034f000000000707043b00000000007604350000000105500039000000000625004b000001dd0000413d000000000504004b000001f20000613d00000003044002100000000502200210000000000502043300000000054501cf000000000545022f000000000121034f000000000101043b0000010004400089000000000141022f00000000014101cf000000000151019f000000000012043500000060013002100000027400010430000000400200043d0000001f0430018f0000000505300272000002010000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000001f90000413d000000000604004b000002100000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000000c30000013d000000400200043d0000001f0430018f00000005053002720000021e0000613d000000000600001900000005076002100000000008720019000000000771034f000000000707043b00000000007804350000000106600039000000000756004b000002160000413d000000000604004b0000022d0000613d0000000505500210000000000151034f00000000055200190000000304400210000000000605043300000000064601cf000000000646022f000000000101043b0000010004400089000000000141022f00000000014101cf000000000161019f0000000000150435000000c30000013d000000400010043f000000200230008c000000a50000413d0000000302000029000000000302043300000000524300a9000000000503004b0000023b0000613d00000000533200d9000000000343004b000000470000c13d000000000302004b0000024c0000c13d0000000203000029000000200130008a0000000000210435000000400130008a00000040020000390000000000210435000000000203043300000060022000390000009e030000410000009e0420009c00000000020380190000009e0410009c000000000103801900000040011002100000006002200210000000000112019f000002730001042e00000000040004140000000503400029000000000443004b000000000400001900000001040040390000000104400190000000470000c13d000001910400008a000000000442004b000000470000213d0000019004200039000000000343004b0000023b0000813d0000004402100039000000ae03000041000000000032043500000024021000390000001a030000390000000000320435000000af0200004100000000002104350000000402100039000000200300003900000000003204350000009e020000410000009e0310009c0000000001028019000001000000013d0000026b002104230000000102000039000000000001042d0000000002000019000000000001042d00000270002104210000000102000039000000000001042d0000000002000019000000000001042d0000027200000432000002730001042e000002740001043000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffff0000000200000000000000000000000000000040000001000000000000000000ffffffff0000000000000000000000000000000000000000000000000000000041a8596c00000000000000000000000000000000000000000000000000000000000000000000000000000000ffffffffffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffffffffffffff8000000000000000000000000000000000000000000000000000000000000000c0d5b949000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000800000000000000000000000000000000000000000000000000000000000000000000000010000000000000000ffffffff0000000000000000000000000000000000000000000000000100000100000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001ffffffe000000000000000000000000000000000000000040000000000000000000000007cb9357e000000000000000000000000000000000000000000000000000000004e6f7420656e6f7567682067617320666f72207075626461746100000000000008c379a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000640000000000000000000000004e487b710000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000004f766572666c6f77000000000000000000000000000000000000000000000000476173206c696d697420697320746f6f206c6f7700000000000000000000000000000000000000000000000000000000000000640000008000000000000000006c300d3e2b009b9a5b1fe7d853a9ae64e30e1d513df698d5c9801da939df7831 \ No newline at end of file diff --git a/system-contracts/contracts/GasBoundCaller.sol b/gas-bound-caller/contracts/GasBoundCaller.sol similarity index 71% rename from system-contracts/contracts/GasBoundCaller.sol rename to gas-bound-caller/contracts/GasBoundCaller.sol index d45f64163..c0de7a23a 100644 --- a/system-contracts/contracts/GasBoundCaller.sol +++ b/gas-bound-caller/contracts/GasBoundCaller.sol @@ -2,8 +2,10 @@ pragma solidity 0.8.20; -import {EfficientCall} from "./libraries/EfficientCall.sol"; -import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; +import {EfficientCall} from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/EfficientCall.sol"; +import {ISystemContext} from "./ISystemContext.sol"; + +ISystemContext constant SYSTEM_CONTEXT_CONTRACT = ISystemContext(address(0x800b)); /** * @author Matter Labs @@ -18,7 +20,7 @@ contract GasBoundCaller { uint256 constant CALL_ENTRY_OVERHEAD = 800; /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` ergs are used for the O(1) operations at the end of the execution, /// as such relaying the return. - uint256 constant CALL_RETURN_OVERHEAD = 200; + uint256 constant CALL_RETURN_OVERHEAD = 400; /// @notice The function that implements limiting of the total gas expenditure of the call. /// @dev On Era, the gas for pubdata is charged at the end of the execution of the entire transaction, meaning @@ -48,7 +50,7 @@ contract GasBoundCaller { // This is the amount of gas that can be spent *exclusively* on pubdata in addition to the `gas` provided to this function. uint256 pubdataAllowance = _maxTotalGas > expectedForCompute ? _maxTotalGas - expectedForCompute : 0; - uint256 pubdataPublishedBefore = REAL_SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); + uint256 pubdataPublishedBefore = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); // We never permit system contract calls. // If the call fails, the `EfficientCall.call` will propagate the revert. @@ -62,7 +64,16 @@ contract GasBoundCaller { _isSystem: false }); - uint256 pubdataPublishedAfter = REAL_SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); + // We will calculate the length of the returndata to be used at the end of the function. + // We need additional `96` bytes to encode the offset `0x40` for the entire pubdata, + // the gas spent on pubdata as well as the length of the original returndata. + // Note, that it has to be padded to the 32 bytes to adhere to proper ABI encoding. + uint256 paddedReturndataLen = returnData.length + 96; + if (paddedReturndataLen % 32 != 0) { + paddedReturndataLen += 32 - (paddedReturndataLen % 32); + } + + uint256 pubdataPublishedAfter = SYSTEM_CONTEXT_CONTRACT.getCurrentPubdataSpent(); // It is possible that pubdataPublishedAfter < pubdataPublishedBefore if the call, e.g. removes // some of the previously created state diffs @@ -70,7 +81,7 @@ contract GasBoundCaller { ? pubdataPublishedAfter - pubdataPublishedBefore : 0; - uint256 pubdataGasRate = REAL_SYSTEM_CONTEXT_CONTRACT.gasPerPubdataByte(); + uint256 pubdataGasRate = SYSTEM_CONTEXT_CONTRACT.gasPerPubdataByte(); // In case there is an overflow here, the `_maxTotalGas` wouldn't be able to cover it anyway, so // we don't mind the contract panicking here in case of it. @@ -83,8 +94,16 @@ contract GasBoundCaller { } assembly { - // We just relay the return data from the call. - return(add(returnData, 0x20), mload(returnData)) + // This place does interfere with the memory layout, however, it is done right before + // the `return` statement, so it is safe to do. + // We need to transform `bytes memory returnData` into (bytes memory returndata, gasSpentOnPubdata) + // `bytes memory returnData` is encoded as `length` + `data`. + // We need to prepend it with 0x40 and `pubdataGas`. + // + // It is assumed that the position of returndata is >= 0x40, since 0x40 is the free memory pointer location. + mstore(sub(returnData, 0x40), 0x40) + mstore(sub(returnData, 0x20), pubdataGas) + return(sub(returnData, 0x40), paddedReturndataLen) } } } diff --git a/gas-bound-caller/contracts/ISystemContext.sol b/gas-bound-caller/contracts/ISystemContext.sol new file mode 100644 index 000000000..a122a04f5 --- /dev/null +++ b/gas-bound-caller/contracts/ISystemContext.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Contract that stores some of the context variables, that may be either + * block-scoped, tx-scoped or system-wide. + */ +interface ISystemContext { + struct BlockInfo { + uint128 timestamp; + uint128 number; + } + + /// @notice A structure representing the timeline for the upgrade from the batch numbers to the L2 block numbers. + /// @dev It will be used for the L1 batch -> L2 block migration in Q3 2023 only. + struct VirtualBlockUpgradeInfo { + /// @notice In order to maintain consistent results for `blockhash` requests, we'll + /// have to remember the number of the batch when the upgrade to the virtual blocks has been done. + /// The hashes for virtual blocks before the upgrade are identical to the hashes of the corresponding batches. + uint128 virtualBlockStartBatch; + /// @notice L2 block when the virtual blocks have caught up with the L2 blocks. Starting from this block, + /// all the information returned to users for block.timestamp/number, etc should be the information about the L2 blocks and + /// not virtual blocks. + uint128 virtualBlockFinishL2Block; + } + + function chainId() external view returns (uint256); + + function origin() external view returns (address); + + function gasPrice() external view returns (uint256); + + function blockGasLimit() external view returns (uint256); + + function coinbase() external view returns (address); + + function difficulty() external view returns (uint256); + + function baseFee() external view returns (uint256); + + function txNumberInBlock() external view returns (uint16); + + function getBlockHashEVM(uint256 _block) external view returns (bytes32); + + function getBatchHash(uint256 _batchNumber) external view returns (bytes32 hash); + + function getBlockNumber() external view returns (uint128); + + function getBlockTimestamp() external view returns (uint128); + + function getBatchNumberAndTimestamp() external view returns (uint128 blockNumber, uint128 blockTimestamp); + + function getL2BlockNumberAndTimestamp() external view returns (uint128 blockNumber, uint128 blockTimestamp); + + function gasPerPubdataByte() external view returns (uint256 gasPerPubdataByte); + + function getCurrentPubdataSpent() external view returns (uint256 currentPubdataSpent); +} diff --git a/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol b/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol similarity index 50% rename from system-contracts/contracts/test-contracts/GasBoundCallerTester.sol rename to gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol index 351a55f46..8c1b790d6 100644 --- a/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol +++ b/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.20; import {GasBoundCaller} from "../GasBoundCaller.sol"; -import {SystemContractHelper} from "../libraries/SystemContractHelper.sol"; +import {SystemContractHelper} from "./SystemContractHelper.sol"; /** * @author Matter Labs @@ -35,11 +35,24 @@ contract GasBoundCallerTester is GasBoundCaller { ); require(success, "Call failed"); + // It is not needed to query the exact value for the test. + uint256 pubdataGas = 100; + // `2/3` to ensure that the constant is good with sufficient overhead SystemContractHelper.burnGas(uint32(gasleft() - (2 * CALL_RETURN_OVERHEAD) / 3), 0); assembly { - // We just relay the return data from the call. - return(add(returnData, 0x20), mload(returnData)) + // This place does interfere with the memory layout, however, it is done right before + // the `return` statement, so it is safe to do. + // We need to transform `bytes memory returnData` into (bytes memory returndata, gasSpentOnPubdata) + // `bytes memory returnData` is encoded as `length` + `data`. + // We need to prepend it with 0x40 and `pubdataGas`. + // + // It is assumed that the position of returndata is >= 0x40, since 0x40 is the free memory pointer location. + mstore(sub(returnData, 0x40), 0x40) + mstore(sub(returnData, 0x20), pubdataGas) + let returndataLen := add(mload(returnData), 0x60) + + return(sub(returnData, 0x40), returndataLen) } } } @@ -50,16 +63,32 @@ contract GasBoundCallerTester is GasBoundCaller { lastRecordedGasLeft = gasbefore - gasleft(); } - function spender(uint32 _ergsToBurn, uint32 _pubdataToUse) external { + function spender(uint32 _ergsToBurn, uint32 _pubdataToUse, bytes memory expectedReturndata) external { SystemContractHelper.burnGas(_ergsToBurn, _pubdataToUse); + + assembly { + // Return the expected returndata + return(add(expectedReturndata, 0x20), mload(expectedReturndata)) + } } function gasBoundCallRelayer( uint256 _gasToPass, address _to, uint256 _maxTotalGas, - bytes calldata _data + bytes calldata _data, + bytes memory expectedReturndata, + uint256 expectedPubdataGas ) external payable { - this.gasBoundCall{gas: _gasToPass}(_to, _maxTotalGas, _data); + (bool success, bytes memory returnData) = address(this).call{gas: _gasToPass}( + abi.encodeWithSelector(GasBoundCaller.gasBoundCall.selector, _to, _maxTotalGas, _data) + ); + + require(success); + + (bytes memory realReturnData, uint256 pubdataGas) = abi.decode(returnData, (bytes, uint256)); + + require(keccak256(expectedReturndata) == keccak256(realReturnData), "Return data is incorrect"); + require(pubdataGas == expectedPubdataGas, "Pubdata gas is incorrect"); } } diff --git a/gas-bound-caller/contracts/test-contracts/SystemContractHelper.sol b/gas-bound-caller/contracts/test-contracts/SystemContractHelper.sol new file mode 100644 index 000000000..47f267005 --- /dev/null +++ b/gas-bound-caller/contracts/test-contracts/SystemContractHelper.sol @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {MAX_SYSTEM_CONTRACT_ADDRESS} from "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; + +import {CALLFLAGS_CALL_ADDRESS, CODE_ADDRESS_CALL_ADDRESS, EVENT_WRITE_ADDRESS, EVENT_INITIALIZE_ADDRESS, GET_EXTRA_ABI_DATA_ADDRESS, LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, META_CODE_SHARD_ID_OFFSET, META_CALLER_SHARD_ID_OFFSET, META_SHARD_ID_OFFSET, META_AUX_HEAP_SIZE_OFFSET, META_HEAP_SIZE_OFFSET, META_PUBDATA_PUBLISHED_OFFSET, META_CALL_ADDRESS, PTR_CALLDATA_CALL_ADDRESS, PTR_ADD_INTO_ACTIVE_CALL_ADDRESS, PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, PRECOMPILE_CALL_ADDRESS, SET_CONTEXT_VALUE_CALL_ADDRESS, TO_L1_CALL_ADDRESS} from "./SystemContractsCaller.sol"; + +uint256 constant UINT32_MASK = type(uint32).max; +uint256 constant UINT64_MASK = type(uint64).max; +uint256 constant UINT128_MASK = type(uint128).max; +uint256 constant ADDRESS_MASK = type(uint160).max; + +/// @notice NOTE: The `getZkSyncMeta` that is used to obtain this struct will experience a breaking change in 2024. +struct ZkSyncMeta { + uint32 pubdataPublished; + uint32 heapSize; + uint32 auxHeapSize; + uint8 shardId; + uint8 callerShardId; + uint8 codeShardId; +} + +enum Global { + CalldataPtr, + CallFlags, + ExtraABIData1, + ExtraABIData2, + ReturndataPtr +} + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice Library used for accessing zkEVM-specific opcodes, needed for the development + * of system contracts. + * @dev While this library will be eventually available to public, some of the provided + * methods won't work for non-system contracts and also breaking changes at short notice are possible. + * We do not recommend this library for external use. + */ +library SystemContractHelper { + /// @notice Send an L2Log to L1. + /// @param _isService The `isService` flag. + /// @param _key The `key` part of the L2Log. + /// @param _value The `value` part of the L2Log. + /// @dev The meaning of all these parameters is context-dependent, but they + /// have no intrinsic meaning per se. + function toL1(bool _isService, bytes32 _key, bytes32 _value) internal { + address callAddr = TO_L1_CALL_ADDRESS; + assembly { + // Ensuring that the type is bool + _isService := and(_isService, 1) + // This `success` is always 0, but the method always succeeds + // (except for the cases when there is not enough gas) + // solhint-disable-next-line no-unused-vars + let success := call(_isService, callAddr, _key, _value, 0xFFFF, 0, 0) + } + } + + /// @notice Get address of the currently executed code. + /// @dev This allows differentiating between `call` and `delegatecall`. + /// During the former `this` and `codeAddress` are the same, while + /// during the latter they are not. + function getCodeAddress() internal view returns (address addr) { + address callAddr = CODE_ADDRESS_CALL_ADDRESS; + assembly { + addr := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Provide a compiler hint, by placing calldata fat pointer into virtual `ACTIVE_PTR`, + /// that can be manipulated by `ptr.add`/`ptr.sub`/`ptr.pack`/`ptr.shrink` later. + /// @dev This allows making a call by forwarding calldata pointer to the child call. + /// It is a much more efficient way to forward calldata, than standard EVM bytes copying. + function loadCalldataIntoActivePtr() internal view { + address callAddr = LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS; + assembly { + pop(staticcall(0, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Compiler simulation of the `ptr.pack` opcode for the virtual `ACTIVE_PTR` pointer. + /// @dev Do the concatenation between lowest part of `ACTIVE_PTR` and highest part of `_farCallAbi` + /// forming packed fat pointer for a far call or ret ABI when necessary. + /// Note: Panics if the lowest 128 bits of `_farCallAbi` are not zeroes. + function ptrPackIntoActivePtr(uint256 _farCallAbi) internal view { + address callAddr = PTR_PACK_INTO_ACTIVE_CALL_ADDRESS; + assembly { + pop(staticcall(_farCallAbi, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Compiler simulation of the `ptr.add` opcode for the virtual `ACTIVE_PTR` pointer. + /// @dev Transforms `ACTIVE_PTR.offset` into `ACTIVE_PTR.offset + u32(_value)`. If overflow happens then it panics. + function ptrAddIntoActive(uint32 _value) internal view { + address callAddr = PTR_ADD_INTO_ACTIVE_CALL_ADDRESS; + uint256 cleanupMask = UINT32_MASK; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _value := and(_value, cleanupMask) + pop(staticcall(_value, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Compiler simulation of the `ptr.shrink` opcode for the virtual `ACTIVE_PTR` pointer. + /// @dev Transforms `ACTIVE_PTR.length` into `ACTIVE_PTR.length - u32(_shrink)`. If underflow happens then it panics. + function ptrShrinkIntoActive(uint32 _shrink) internal view { + address callAddr = PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS; + uint256 cleanupMask = UINT32_MASK; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _shrink := and(_shrink, cleanupMask) + pop(staticcall(_shrink, callAddr, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice packs precompile parameters into one word + /// @param _inputMemoryOffset The memory offset in 32-byte words for the input data for calling the precompile. + /// @param _inputMemoryLength The length of the input data in words. + /// @param _outputMemoryOffset The memory offset in 32-byte words for the output data. + /// @param _outputMemoryLength The length of the output data in words. + /// @param _perPrecompileInterpreted The constant, the meaning of which is defined separately for + /// each precompile. For information, please read the documentation of the precompilecall log in + /// the VM. + function packPrecompileParams( + uint32 _inputMemoryOffset, + uint32 _inputMemoryLength, + uint32 _outputMemoryOffset, + uint32 _outputMemoryLength, + uint64 _perPrecompileInterpreted + ) internal pure returns (uint256 rawParams) { + rawParams = _inputMemoryOffset; + rawParams |= uint256(_inputMemoryLength) << 32; + rawParams |= uint256(_outputMemoryOffset) << 64; + rawParams |= uint256(_outputMemoryLength) << 96; + rawParams |= uint256(_perPrecompileInterpreted) << 192; + } + + /// @notice Call precompile with given parameters. + /// @param _rawParams The packed precompile params. They can be retrieved by + /// the `packPrecompileParams` method. + /// @param _gasToBurn The number of gas to burn during this call. + /// @param _pubdataToSpend The number of pubdata bytes to burn during the call. + /// @return success Whether the call was successful. + /// @dev The list of currently available precompiles sha256, keccak256, ecrecover. + /// NOTE: The precompile type depends on `this` which calls precompile, which means that only + /// system contracts corresponding to the list of precompiles above can do `precompileCall`. + /// @dev If used not in the `sha256`, `keccak256` or `ecrecover` contracts, it will just burn the gas provided. + /// @dev This method is `unsafe` because it does not check whether there is enough gas to burn. + function unsafePrecompileCall( + uint256 _rawParams, + uint32 _gasToBurn, + uint32 _pubdataToSpend + ) internal view returns (bool success) { + address callAddr = PRECOMPILE_CALL_ADDRESS; + + uint256 params = uint256(_gasToBurn) + (uint256(_pubdataToSpend) << 32); + + uint256 cleanupMask = UINT64_MASK; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + params := and(params, cleanupMask) + success := staticcall(_rawParams, callAddr, params, 0xFFFF, 0, 0) + } + } + + /// @notice Set `msg.value` to next far call. + /// @param _value The msg.value that will be used for the *next* call. + /// @dev If called not in kernel mode, it will result in a revert (enforced by the VM) + function setValueForNextFarCall(uint128 _value) internal returns (bool success) { + uint256 cleanupMask = UINT128_MASK; + address callAddr = SET_CONTEXT_VALUE_CALL_ADDRESS; + assembly { + // Clearing input params as they are not cleaned by Solidity by default + _value := and(_value, cleanupMask) + success := call(0, callAddr, _value, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Initialize a new event. + /// @param initializer The event initializing value. + /// @param value1 The first topic or data chunk. + function eventInitialize(uint256 initializer, uint256 value1) internal { + address callAddr = EVENT_INITIALIZE_ADDRESS; + assembly { + pop(call(initializer, callAddr, value1, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Continue writing the previously initialized event. + /// @param value1 The first topic or data chunk. + /// @param value2 The second topic or data chunk. + function eventWrite(uint256 value1, uint256 value2) internal { + address callAddr = EVENT_WRITE_ADDRESS; + assembly { + pop(call(value1, callAddr, value2, 0, 0xFFFF, 0, 0)) + } + } + + /// @notice Get the packed representation of the `ZkSyncMeta` from the current context. + /// @notice NOTE: The behavior of this function will experience a breaking change in 2024. + /// @return meta The packed representation of the ZkSyncMeta. + /// @dev The fields in ZkSyncMeta are NOT tightly packed, i.e. there is a special rule on how + /// they are packed. For more information, please read the documentation on ZkSyncMeta. + function getZkSyncMetaBytes() internal view returns (uint256 meta) { + address callAddr = META_CALL_ADDRESS; + assembly { + meta := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns the bits [offset..offset+size-1] of the meta. + /// @param meta Packed representation of the ZkSyncMeta. + /// @param offset The offset of the bits. + /// @param size The size of the extracted number in bits. + /// @return result The extracted number. + function extractNumberFromMeta(uint256 meta, uint256 offset, uint256 size) internal pure returns (uint256 result) { + // Firstly, we delete all the bits after the field + uint256 shifted = (meta << (256 - size - offset)); + // Then we shift everything back + result = (shifted >> (256 - size)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of pubdata + /// bytes published in the batch so far. + /// @notice NOTE: The behavior of this function will experience a breaking change in 2024. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return pubdataPublished The amount of pubdata published in the system so far. + function getPubdataPublishedFromMeta(uint256 meta) internal pure returns (uint32 pubdataPublished) { + pubdataPublished = uint32(extractNumberFromMeta(meta, META_PUBDATA_PUBLISHED_OFFSET, 32)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of the current size + /// of the heap in bytes. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return heapSize The size of the memory in bytes byte. + /// @dev The following expression: getHeapSizeFromMeta(getZkSyncMetaBytes()) is + /// equivalent to the MSIZE in Solidity. + function getHeapSizeFromMeta(uint256 meta) internal pure returns (uint32 heapSize) { + heapSize = uint32(extractNumberFromMeta(meta, META_HEAP_SIZE_OFFSET, 32)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the number of the current size + /// of the auxiliary heap in bytes. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return auxHeapSize The size of the auxiliary memory in bytes byte. + /// @dev You can read more on auxiliary memory in the VM1.2 documentation. + function getAuxHeapSizeFromMeta(uint256 meta) internal pure returns (uint32 auxHeapSize) { + auxHeapSize = uint32(extractNumberFromMeta(meta, META_AUX_HEAP_SIZE_OFFSET, 32)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the shardId of `this`. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return shardId The shardId of `this`. + /// @dev Currently only shard 0 (zkRollup) is supported. + function getShardIdFromMeta(uint256 meta) internal pure returns (uint8 shardId) { + shardId = uint8(extractNumberFromMeta(meta, META_SHARD_ID_OFFSET, 8)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the shardId of + /// the msg.sender. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return callerShardId The shardId of the msg.sender. + /// @dev Currently only shard 0 (zkRollup) is supported. + function getCallerShardIdFromMeta(uint256 meta) internal pure returns (uint8 callerShardId) { + callerShardId = uint8(extractNumberFromMeta(meta, META_CALLER_SHARD_ID_OFFSET, 8)); + } + + /// @notice Given the packed representation of `ZkSyncMeta`, retrieves the shardId of + /// the currently executed code. + /// @param meta Packed representation of the ZkSyncMeta. + /// @return codeShardId The shardId of the currently executed code. + /// @dev Currently only shard 0 (zkRollup) is supported. + function getCodeShardIdFromMeta(uint256 meta) internal pure returns (uint8 codeShardId) { + codeShardId = uint8(extractNumberFromMeta(meta, META_CODE_SHARD_ID_OFFSET, 8)); + } + + /// @notice Retrieves the ZkSyncMeta structure. + /// @notice NOTE: The behavior of this function will experience a breaking change in 2024. + /// @return meta The ZkSyncMeta execution context parameters. + function getZkSyncMeta() internal view returns (ZkSyncMeta memory meta) { + uint256 metaPacked = getZkSyncMetaBytes(); + meta.pubdataPublished = getPubdataPublishedFromMeta(metaPacked); + meta.heapSize = getHeapSizeFromMeta(metaPacked); + meta.auxHeapSize = getAuxHeapSizeFromMeta(metaPacked); + meta.shardId = getShardIdFromMeta(metaPacked); + meta.callerShardId = getCallerShardIdFromMeta(metaPacked); + meta.codeShardId = getCodeShardIdFromMeta(metaPacked); + } + + /// @notice Returns the call flags for the current call. + /// @return callFlags The bitmask of the callflags. + /// @dev Call flags is the value of the first register + /// at the start of the call. + /// @dev The zero bit of the callFlags indicates whether the call is + /// a constructor call. The first bit of the callFlags indicates whether + /// the call is a system one. + function getCallFlags() internal view returns (uint256 callFlags) { + address callAddr = CALLFLAGS_CALL_ADDRESS; + assembly { + callFlags := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns the current calldata pointer. + /// @return ptr The current calldata pointer. + /// @dev NOTE: This file is just an integer and it cannot be used + /// to forward the calldata to the next calls in any way. + function getCalldataPtr() internal view returns (uint256 ptr) { + address callAddr = PTR_CALLDATA_CALL_ADDRESS; + assembly { + ptr := staticcall(0, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns the N-th extraAbiParam for the current call. + /// @return extraAbiData The value of the N-th extraAbiParam for this call. + /// @dev It is equal to the value of the (N+2)-th register + /// at the start of the call. + function getExtraAbiData(uint256 index) internal view returns (uint256 extraAbiData) { + require(index < 10, "There are only 10 accessible registers"); + + address callAddr = GET_EXTRA_ABI_DATA_ADDRESS; + assembly { + extraAbiData := staticcall(index, callAddr, 0, 0xFFFF, 0, 0) + } + } + + /// @notice Returns whether the current call is a system call. + /// @return `true` or `false` based on whether the current call is a system call. + function isSystemCall() internal view returns (bool) { + uint256 callFlags = getCallFlags(); + // When the system call is passed, the 2-bit is set to 1 + return (callFlags & 2) != 0; + } + + /// @notice Returns whether the address is a system contract. + /// @param _address The address to test + /// @return `true` or `false` based on whether the `_address` is a system contract. + function isSystemContract(address _address) internal pure returns (bool) { + return uint160(_address) <= uint160(MAX_SYSTEM_CONTRACT_ADDRESS); + } + + /// @notice Method used for burning a certain amount of gas. + /// @param _gasToPay The number of gas to burn. + /// @param _pubdataToSpend The number of pubdata bytes to burn during the call. + function burnGas(uint32 _gasToPay, uint32 _pubdataToSpend) internal view { + bool precompileCallSuccess = unsafePrecompileCall( + 0, // The precompile parameters are formal ones. We only need the precompile call to burn gas. + _gasToPay, + _pubdataToSpend + ); + require(precompileCallSuccess, "Failed to charge gas"); + } +} diff --git a/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol b/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol new file mode 100644 index 000000000..ca7c870c7 --- /dev/null +++ b/gas-bound-caller/contracts/test-contracts/SystemContractsCaller.sol @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.20; + +import {MSG_VALUE_SYSTEM_CONTRACT, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT} from "@matterlabs/zksync-contracts/l2/system-contracts/Constants.sol"; +import {Utils} from "@matterlabs/zksync-contracts/l2/system-contracts/libraries/Utils.sol"; + +// Addresses used for the compiler to be replaced with the +// zkSync-specific opcodes during the compilation. +// IMPORTANT: these are just compile-time constants and are used +// only if used in-place by Yul optimizer. +address constant TO_L1_CALL_ADDRESS = address((1 << 16) - 1); +address constant CODE_ADDRESS_CALL_ADDRESS = address((1 << 16) - 2); +address constant PRECOMPILE_CALL_ADDRESS = address((1 << 16) - 3); +address constant META_CALL_ADDRESS = address((1 << 16) - 4); +address constant MIMIC_CALL_CALL_ADDRESS = address((1 << 16) - 5); +address constant SYSTEM_MIMIC_CALL_CALL_ADDRESS = address((1 << 16) - 6); +address constant MIMIC_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 7); +address constant SYSTEM_MIMIC_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 8); +address constant RAW_FAR_CALL_CALL_ADDRESS = address((1 << 16) - 9); +address constant RAW_FAR_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 10); +address constant SYSTEM_CALL_CALL_ADDRESS = address((1 << 16) - 11); +address constant SYSTEM_CALL_BY_REF_CALL_ADDRESS = address((1 << 16) - 12); +address constant SET_CONTEXT_VALUE_CALL_ADDRESS = address((1 << 16) - 13); +address constant SET_PUBDATA_PRICE_CALL_ADDRESS = address((1 << 16) - 14); +address constant INCREMENT_TX_COUNTER_CALL_ADDRESS = address((1 << 16) - 15); +address constant PTR_CALLDATA_CALL_ADDRESS = address((1 << 16) - 16); +address constant CALLFLAGS_CALL_ADDRESS = address((1 << 16) - 17); +address constant PTR_RETURNDATA_CALL_ADDRESS = address((1 << 16) - 18); +address constant EVENT_INITIALIZE_ADDRESS = address((1 << 16) - 19); +address constant EVENT_WRITE_ADDRESS = address((1 << 16) - 20); +address constant LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS = address((1 << 16) - 21); +address constant LOAD_LATEST_RETURNDATA_INTO_ACTIVE_PTR_CALL_ADDRESS = address((1 << 16) - 22); +address constant PTR_ADD_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 23); +address constant PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 24); +address constant PTR_PACK_INTO_ACTIVE_CALL_ADDRESS = address((1 << 16) - 25); +address constant MULTIPLICATION_HIGH_ADDRESS = address((1 << 16) - 26); +address constant GET_EXTRA_ABI_DATA_ADDRESS = address((1 << 16) - 27); + +// All the offsets are in bits +uint256 constant META_PUBDATA_PUBLISHED_OFFSET = 0 * 8; +uint256 constant META_HEAP_SIZE_OFFSET = 8 * 8; +uint256 constant META_AUX_HEAP_SIZE_OFFSET = 12 * 8; +uint256 constant META_SHARD_ID_OFFSET = 28 * 8; +uint256 constant META_CALLER_SHARD_ID_OFFSET = 29 * 8; +uint256 constant META_CODE_SHARD_ID_OFFSET = 30 * 8; + +/// @notice The way to forward the calldata: +/// - Use the current heap (i.e. the same as on EVM). +/// - Use the auxiliary heap. +/// - Forward via a pointer +/// @dev Note, that currently, users do not have access to the auxiliary +/// heap and so the only type of forwarding that will be used by the users +/// are UseHeap and ForwardFatPointer for forwarding a slice of the current calldata +/// to the next call. +enum CalldataForwardingMode { + UseHeap, + ForwardFatPointer, + UseAuxHeap +} + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice A library that allows calling contracts with the `isSystem` flag. + * @dev It is needed to call ContractDeployer and NonceHolder. + */ +library SystemContractsCaller { + /// @notice Makes a call with the `isSystem` flag. + /// @param gasLimit The gas limit for the call. + /// @param to The address to call. + /// @param value The value to pass with the transaction. + /// @param data The calldata. + /// @return success Whether the transaction has been successful. + /// @dev Note, that the `isSystem` flag can only be set when calling system contracts. + function systemCall(uint32 gasLimit, address to, uint256 value, bytes memory data) internal returns (bool success) { + address callAddr = SYSTEM_CALL_CALL_ADDRESS; + + uint32 dataStart; + assembly { + dataStart := add(data, 0x20) + } + uint32 dataLength = uint32(Utils.safeCastToU32(data.length)); + + uint256 farCallAbi = SystemContractsCaller.getFarCallABI({ + dataOffset: 0, + memoryPage: 0, + dataStart: dataStart, + dataLength: dataLength, + gasPassed: gasLimit, + // Only rollup is supported for now + shardId: 0, + forwardingMode: CalldataForwardingMode.UseHeap, + isConstructorCall: false, + isSystemCall: true + }); + + if (value == 0) { + // Doing the system call directly + assembly { + success := call(to, callAddr, 0, 0, farCallAbi, 0, 0) + } + } else { + address msgValueSimulator = MSG_VALUE_SYSTEM_CONTRACT; + // We need to supply the mask to the MsgValueSimulator to denote + // that the call should be a system one. + uint256 forwardMask = MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT; + + assembly { + success := call(msgValueSimulator, callAddr, value, to, farCallAbi, forwardMask, 0) + } + } + } + + /// @notice Makes a call with the `isSystem` flag. + /// @param gasLimit The gas limit for the call. + /// @param to The address to call. + /// @param value The value to pass with the transaction. + /// @param data The calldata. + /// @return success Whether the transaction has been successful. + /// @return returnData The returndata of the transaction (revert reason in case the transaction has failed). + /// @dev Note, that the `isSystem` flag can only be set when calling system contracts. + function systemCallWithReturndata( + uint32 gasLimit, + address to, + uint128 value, + bytes memory data + ) internal returns (bool success, bytes memory returnData) { + success = systemCall(gasLimit, to, value, data); + + uint256 size; + assembly { + size := returndatasize() + } + + returnData = new bytes(size); + assembly { + returndatacopy(add(returnData, 0x20), 0, size) + } + } + + /// @notice Makes a call with the `isSystem` flag. + /// @param gasLimit The gas limit for the call. + /// @param to The address to call. + /// @param value The value to pass with the transaction. + /// @param data The calldata. + /// @return returnData The returndata of the transaction. In case the transaction reverts, the error + /// bubbles up to the parent frame. + /// @dev Note, that the `isSystem` flag can only be set when calling system contracts. + function systemCallWithPropagatedRevert( + uint32 gasLimit, + address to, + uint128 value, + bytes memory data + ) internal returns (bytes memory returnData) { + bool success; + (success, returnData) = systemCallWithReturndata(gasLimit, to, value, data); + + if (!success) { + assembly { + let size := mload(returnData) + revert(add(returnData, 0x20), size) + } + } + } + + /// @notice Calculates the packed representation of the FarCallABI. + /// @param dataOffset Calldata offset in memory. Provide 0 unless using custom pointer. + /// @param memoryPage Memory page to use. Provide 0 unless using custom pointer. + /// @param dataStart The start of the calldata slice. Provide the offset in memory + /// if not using custom pointer. + /// @param dataLength The calldata length. Provide the length of the calldata in bytes + /// unless using custom pointer. + /// @param gasPassed The gas to pass with the call. + /// @param shardId Of the account to call. Currently only 0 is supported. + /// @param forwardingMode The forwarding mode to use: + /// - provide CalldataForwardingMode.UseHeap when using your current memory + /// - provide CalldataForwardingMode.ForwardFatPointer when using custom pointer. + /// @param isConstructorCall Whether the call will be a call to the constructor + /// (ignored when the caller is not a system contract). + /// @param isSystemCall Whether the call will have the `isSystem` flag. + /// @return farCallAbi The far call ABI. + /// @dev The `FarCallABI` has the following structure: + /// pub struct FarCallABI { + /// pub memory_quasi_fat_pointer: FatPointer, + /// pub gas_passed: u32, + /// pub shard_id: u8, + /// pub forwarding_mode: FarCallForwardPageType, + /// pub constructor_call: bool, + /// pub to_system: bool, + /// } + /// + /// The FatPointer struct: + /// + /// pub struct FatPointer { + /// pub offset: u32, // offset relative to `start` + /// pub memory_page: u32, // memory page where slice is located + /// pub start: u32, // absolute start of the slice + /// pub length: u32, // length of the slice + /// } + /// + /// @dev Note, that the actual layout is the following: + /// + /// [0..32) bits -- the calldata offset + /// [32..64) bits -- the memory page to use. Can be left blank in most of the cases. + /// [64..96) bits -- the absolute start of the slice + /// [96..128) bits -- the length of the slice. + /// [128..192) bits -- empty bits. + /// [192..224) bits -- gasPassed. + /// [224..232) bits -- forwarding_mode + /// [232..240) bits -- shard id. + /// [240..248) bits -- constructor call flag + /// [248..256] bits -- system call flag + function getFarCallABI( + uint32 dataOffset, + uint32 memoryPage, + uint32 dataStart, + uint32 dataLength, + uint32 gasPassed, + uint8 shardId, + CalldataForwardingMode forwardingMode, + bool isConstructorCall, + bool isSystemCall + ) internal pure returns (uint256 farCallAbi) { + // Fill in the call parameter fields + farCallAbi = getFarCallABIWithEmptyFatPointer({ + gasPassed: gasPassed, + shardId: shardId, + forwardingMode: forwardingMode, + isConstructorCall: isConstructorCall, + isSystemCall: isSystemCall + }); + + // Fill in the fat pointer fields + farCallAbi |= dataOffset; + farCallAbi |= (uint256(memoryPage) << 32); + farCallAbi |= (uint256(dataStart) << 64); + farCallAbi |= (uint256(dataLength) << 96); + } + + /// @notice Calculates the packed representation of the FarCallABI with zero fat pointer fields. + /// @param gasPassed The gas to pass with the call. + /// @param shardId Of the account to call. Currently only 0 is supported. + /// @param forwardingMode The forwarding mode to use: + /// - provide CalldataForwardingMode.UseHeap when using your current memory + /// - provide CalldataForwardingMode.ForwardFatPointer when using custom pointer. + /// @param isConstructorCall Whether the call will be a call to the constructor + /// (ignored when the caller is not a system contract). + /// @param isSystemCall Whether the call will have the `isSystem` flag. + /// @return farCallAbiWithEmptyFatPtr The far call ABI with zero fat pointer fields. + function getFarCallABIWithEmptyFatPointer( + uint32 gasPassed, + uint8 shardId, + CalldataForwardingMode forwardingMode, + bool isConstructorCall, + bool isSystemCall + ) internal pure returns (uint256 farCallAbiWithEmptyFatPtr) { + farCallAbiWithEmptyFatPtr |= (uint256(gasPassed) << 192); + farCallAbiWithEmptyFatPtr |= (uint256(forwardingMode) << 224); + farCallAbiWithEmptyFatPtr |= (uint256(shardId) << 232); + if (isConstructorCall) { + farCallAbiWithEmptyFatPtr |= (1 << 240); + } + if (isSystemCall) { + farCallAbiWithEmptyFatPtr |= (1 << 248); + } + } +} diff --git a/gas-bound-caller/hardhat.config.ts b/gas-bound-caller/hardhat.config.ts new file mode 100644 index 000000000..2c50fa5fc --- /dev/null +++ b/gas-bound-caller/hardhat.config.ts @@ -0,0 +1,62 @@ +import "@matterlabs/hardhat-zksync-chai-matchers"; +import "@matterlabs/hardhat-zksync-node"; +import "@matterlabs/hardhat-zksync-solc"; +import "@nomiclabs/hardhat-ethers"; +import "hardhat-typechain"; + +// This version of system contracts requires a pre release of the compiler +const COMPILER_VERSION = "1.5.0"; +const PRE_RELEASE_VERSION = "prerelease-a167aa3-code4rena"; +function getZksolcUrl(): string { + // @ts-ignore + const platform = { darwin: "macosx", linux: "linux", win32: "windows" }[process.platform]; + // @ts-ignore + const toolchain = { linux: "-musl", win32: "-gnu", darwin: "" }[process.platform]; + const arch = process.arch === "x64" ? "amd64" : process.arch; + const ext = process.platform === "win32" ? ".exe" : ""; + + return `https://github.com/matter-labs/era-compiler-solidity/releases/download/${PRE_RELEASE_VERSION}/zksolc-${platform}-${arch}${toolchain}-v${COMPILER_VERSION}${ext}`; +} + +console.log(`Using zksolc from ${getZksolcUrl()}`); + +export default { + zksolc: { + compilerSource: "binary", + settings: { + compilerPath: getZksolcUrl(), + isSystem: true, + }, + }, + zkSyncDeploy: { + zkSyncNetwork: "http://localhost:3050", + ethNetwork: "http://localhost:8545", + }, + solidity: { + version: "0.8.20", + settings: { + optimizer: { + enabled: true, + runs: 9999999, + }, + outputSelection: { + "*": { + "*": ["storageLayout"], + }, + }, + }, + }, + networks: { + hardhat: { + zksync: true, + }, + zkSyncTestNode: { + url: "http://127.0.0.1:8011", + ethNetwork: "localhost", + zksync: true, + }, + }, + paths: { + sources: "./contracts", + }, +}; diff --git a/gas-bound-caller/package.json b/gas-bound-caller/package.json new file mode 100644 index 000000000..de6220930 --- /dev/null +++ b/gas-bound-caller/package.json @@ -0,0 +1,60 @@ +{ + "name": "gas-bound-caller", + "version": "0.1.0", + "repository": "git@github.com:matter-labs/era-contracts.git", + "license": "MIT", + "dependencies": { + "@matterlabs/hardhat-zksync-deploy": "^0.6.5", + "@matterlabs/hardhat-zksync-solc": "^1.1.4", + "@matterlabs/zksync-contracts": "^0.6.1", + "commander": "^9.4.1", + "eslint": "^8.51.0", + "eslint-plugin-import": "^2.29.0", + "eslint-plugin-prettier": "^5.0.1", + "ethers": "^5.7.0", + "fast-glob": "^3.3.2", + "hardhat": "^2.18.3", + "preprocess": "^3.2.0", + "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + }, + "devDependencies": { + "@matterlabs/hardhat-zksync-chai-matchers": "^0.1.4", + "@matterlabs/hardhat-zksync-node": "^0.0.1-beta.7", + "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", + "@nomiclabs/hardhat-ethers": "^2.0.0", + "@typechain/ethers-v5": "^2.0.0", + "@types/chai": "^4.2.21", + "@types/elliptic": "^6.4.18", + "@types/lodash": "^4.14.199", + "@types/mocha": "^8.2.3", + "@types/node": "^17.0.34", + "chai": "^4.3.10", + "elliptic": "^6.5.4", + "hardhat-typechain": "^0.3.3", + "lodash": "^4.17.21", + "mocha": "^9.0.2", + "template-file": "^6.0.1", + "ts-generator": "^0.1.1", + "ts-node": "^10.1.0", + "typechain": "^4.0.0", + "typescript": "^4.6.4", + "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + }, + "mocha": { + "timeout": 240000, + "exit": true, + "color": false, + "slow": 0, + "require": [ + "ts-node/register" + ] + }, + "scripts": { + "build": "hardhat compile", + "clean": "yarn clean:bootloader && yarn clean:system-contracts", + "test": "yarn build && hardhat test --network zkSyncTestNode", + "test-node": "hardhat node-zksync --tag v0.0.1-vm1.5.0", + "deploy-on-hyperchain": "ts-node ./scripts/deploy-on-hyperchain.ts", + "deploy-on-localhost": "hardhat deploy --network localhost" + } +} diff --git a/gas-bound-caller/scripts/check-canonical-bytecode.ts b/gas-bound-caller/scripts/check-canonical-bytecode.ts new file mode 100644 index 000000000..041e8e9d1 --- /dev/null +++ b/gas-bound-caller/scripts/check-canonical-bytecode.ts @@ -0,0 +1,42 @@ +// hardhat import should be the first import in the file +import * as hre from "hardhat"; +import { Command } from "commander"; +import { readCanonicalArtifact, writeCanonicalArtifact } from "./utils"; + +async function main() { + const program = new Command(); + + program + .version("0.1.0") + .name("check canonical bytecode") + .description("Checks that the locally built artifacts match the canonical bytecode"); + + program.command("check").action(async () => { + const compiledBytecode = (await hre.artifacts.readArtifact("GasBoundCaller")).bytecode; + const canonicalBytecode = readCanonicalArtifact(); + + if (compiledBytecode.toLocaleLowerCase() != canonicalBytecode.toLocaleLowerCase()) { + throw new Error("Compiled bytecode is not correct"); + } + }); + + program.command("fix").action(async () => { + const compiledBytecode = (await hre.artifacts.readArtifact("GasBoundCaller")).bytecode; + const canonicalBytecode = readCanonicalArtifact(); + + if (compiledBytecode.toLocaleLowerCase() != canonicalBytecode.toLocaleLowerCase()) { + writeCanonicalArtifact(compiledBytecode); + } else { + console.log("There is nothing to fix"); + } + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err.message || err); + process.exit(1); + }); diff --git a/gas-bound-caller/scripts/deploy-on-hyperchain.ts b/gas-bound-caller/scripts/deploy-on-hyperchain.ts new file mode 100644 index 000000000..35d013fd7 --- /dev/null +++ b/gas-bound-caller/scripts/deploy-on-hyperchain.ts @@ -0,0 +1,104 @@ +// hardhat import should be the first import in the file +import { ethers } from "ethers"; +import { Command } from "commander"; +import { readCanonicalArtifact } from "./utils"; +import { Wallet, Provider, Contract, utils } from "zksync-ethers"; + +// This factory should be predeployed on each post-v24 zksync network +const PREDEPLOYED_CREATE2_ADDRESS = "0x0000000000000000000000000000000000010000"; + +const singletonFactoryAbi = [ + { + inputs: [ + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + { + internalType: "bytes32", + name: "", + type: "bytes32", + }, + { + internalType: "bytes", + name: "", + type: "bytes", + }, + ], + name: "create2", + outputs: [ + { + internalType: "address", + name: "", + type: "address", + }, + ], + stateMutability: "payable", + type: "function", + }, +]; + +async function main() { + const program = new Command(); + + program + .version("0.1.0") + .name("Deploy on hyperchain") + .description("Deploys the GasBoundCaller on a predetermined Hyperchain network") + .option("--private-key ") + .option("--l2Rpc ") + .action(async (cmd) => { + console.log("Reading the canonical bytecode of the GasBoundCaller"); + const bytecode = readCanonicalArtifact(); + + const wallet = new Wallet(cmd.privateKey, new Provider(cmd.l2Rpc)); + + const singleTonFactory = new Contract(PREDEPLOYED_CREATE2_ADDRESS, singletonFactoryAbi, wallet); + + const bytecodeHash = ethers.utils.hexlify(utils.hashBytecode(bytecode)); + + const expectedAddress = utils.create2Address( + PREDEPLOYED_CREATE2_ADDRESS, + bytecodeHash, + ethers.constants.HashZero, + "0x" + ); + console.log("Expected address:", expectedAddress); + + const currentCode = await wallet.provider.getCode(expectedAddress); + if (currentCode !== "0x") { + if (currentCode === bytecode) { + console.log("The GasBoundCaller is already deployed on the expected address"); + return; + } + throw new Error("The expected address is already occupied by a contract with different bytecode"); + } + + console.log("Sending transaction to deploy the GasBoundCaller"); + const tx = await singleTonFactory.create2(ethers.constants.HashZero, bytecodeHash, "0x", { + customData: { + factoryDeps: [bytecode], + }, + }); + + console.log("Transaction hash:", tx.hash); + await tx.wait(); + + const codeAfterDeploy = await wallet.provider.getCode(expectedAddress); + if (codeAfterDeploy.toLowerCase() !== bytecode.toLowerCase()) { + throw new Error("Deployment failed. The bytecode on the expected address is not the same as the bytecode."); + } + + console.log("Transaction complete!"); + }); + + await program.parseAsync(process.argv); +} + +main() + .then(() => process.exit(0)) + .catch((err) => { + console.error("Error:", err.message || err); + process.exit(1); + }); diff --git a/gas-bound-caller/scripts/utils.ts b/gas-bound-caller/scripts/utils.ts new file mode 100644 index 000000000..81c84b4a7 --- /dev/null +++ b/gas-bound-caller/scripts/utils.ts @@ -0,0 +1,11 @@ +import * as fs from "fs"; + +const CANONICAL_BYTECODES_PATH = "./canonical-bytecodes/GasBoundCaller"; + +export function writeCanonicalArtifact(newBytecode: string) { + fs.writeFileSync(CANONICAL_BYTECODES_PATH, newBytecode); +} + +export function readCanonicalArtifact() { + return fs.readFileSync(CANONICAL_BYTECODES_PATH).toString(); +} diff --git a/system-contracts/test/GasBoundCaller.spec.ts b/gas-bound-caller/test/GasBoundCaller.spec.ts similarity index 77% rename from system-contracts/test/GasBoundCaller.spec.ts rename to gas-bound-caller/test/GasBoundCaller.spec.ts index ef6a300d6..1a970f0fc 100644 --- a/system-contracts/test/GasBoundCaller.spec.ts +++ b/gas-bound-caller/test/GasBoundCaller.spec.ts @@ -1,23 +1,22 @@ -import type { SystemContext, GasBoundCallerTester } from "../typechain"; -import { GasBoundCallerTesterFactory, SystemContextFactory } from "../typechain"; -import { REAL_SYSTEM_CONTEXT_ADDRESS } from "./shared/constants"; -import { deployContractOnAddress, getWallets } from "./shared/utils"; +import { REAL_SYSTEM_CONTEXT_ADDRESS } from "../../system-contracts/test/shared/constants"; +import { deployContractOnAddress, getWallets } from "../../system-contracts/test/shared/utils"; +import type { GasBoundCallerTester } from "../typechain"; +import { GasBoundCallerTesterFactory } from "../typechain"; +import type { ISystemContext } from "../typechain/ISystemContext"; +import { ISystemContextFactory } from "../typechain/ISystemContextFactory"; import { expect } from "chai"; -import { prepareEnvironment } from "./shared/mocks"; describe("GasBoundCaller tests", function () { let tester: GasBoundCallerTester; - let systemContext: SystemContext; + let systemContext: ISystemContext; before(async () => { - await prepareEnvironment(); - // Note, that while the gas bound caller itself does not need to be in kernel space, // it does help a lot for easier testing, so the tester is in kernel space. const GAS_BOUND_CALLER_TESTER_ADDRESS = "0x000000000000000000000000000000000000ffff"; await deployContractOnAddress(GAS_BOUND_CALLER_TESTER_ADDRESS, "GasBoundCallerTester"); tester = GasBoundCallerTesterFactory.connect(GAS_BOUND_CALLER_TESTER_ADDRESS, getWallets()[0]); - systemContext = SystemContextFactory.connect(REAL_SYSTEM_CONTEXT_ADDRESS, getWallets()[0]); + systemContext = ISystemContextFactory.connect(REAL_SYSTEM_CONTEXT_ADDRESS, getWallets()[0]); }); it("Test entry overhead", async () => { @@ -61,9 +60,14 @@ describe("GasBoundCaller tests", function () { it("Should work correctly if gas provided is enough to cover both gas and pubdata", async () => { // This tx should succeed, since enough gas was provided to it await ( - await tester.gasBoundCall(tester.address, 80_000_000, tester.interface.encodeFunctionData("spender", [0, 100]), { - gasLimit: 80_000_000, - }) + await tester.gasBoundCall( + tester.address, + 80_000_000, + tester.interface.encodeFunctionData("spender", [0, 100, "0x"]), + { + gasLimit: 80_000_000, + } + ) ).wait(); }); @@ -78,7 +82,9 @@ describe("GasBoundCaller tests", function () { gasSpentOnPubdata, tester.address, gasSpentOnPubdata, - tester.interface.encodeFunctionData("spender", [0, pubdataToSend]), + tester.interface.encodeFunctionData("spender", [0, pubdataToSend, "0x"]), + "0x", + gasSpentOnPubdata, { gasLimit: 80_000_000, } @@ -97,7 +103,9 @@ describe("GasBoundCaller tests", function () { gasSpentOnPubdata, tester.address, 80_000_000, - tester.interface.encodeFunctionData("spender", [0, pubdataToSend]), + tester.interface.encodeFunctionData("spender", [0, pubdataToSend, "0x12345678"]), + "0x12345678", + gasSpentOnPubdata, { // Since we'll also spend some funds on execution, this gasLimit: 80_000_000, diff --git a/package.json b/package.json index 9bb6bdd1e..466691d3a 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "packages": [ "l1-contracts", "l2-contracts", - "system-contracts" + "system-contracts", + "gas-bound-caller" ], "nohoist": [ "**/@openzeppelin/**" @@ -36,6 +37,7 @@ "prettier:fix": "prettier --write \"**/*.{js,json,md,sol,ts,yaml}\"", "l1": "yarn workspace l1-contracts", "l2": "yarn workspace l2-contracts", - "sc": "yarn workspace system-contracts" + "sc": "yarn workspace system-contracts", + "gas-bound-caller": "yarn workspace gas-bound-caller" } } diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 3944df256..7cb1c5b9c 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -55,13 +55,6 @@ "bytecodeHash": "0x0100000781e55a60f3f14fd7dd67e3c8caab896b7b0fca4a662583959299eede", "sourceCodeHash": "0xc88a4210dda96bc21fc852860fb74a4efeb0cc4101ffe6d928551cab46d15263" }, - { - "contractName": "GasBoundCaller", - "bytecodePath": "artifacts-zk/contracts-preprocessed/GasBoundCaller.sol/GasBoundCaller.json", - "sourceCodePath": "contracts-preprocessed/GasBoundCaller.sol", - "bytecodeHash": "0x010000b5e930829f22bd5df4fac3cb37b599cf9733554124bfb7e717fa4a726b", - "sourceCodeHash": "0x68db837d79ab575450f9123d97c7e566f311fb2e8d91c0d43dc9769ca895ccd3" - }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", diff --git a/yarn.lock b/yarn.lock index 2c64e92e6..a1b9caf1e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -773,6 +773,11 @@ resolved "https://registry.yarnpkg.com/@matterlabs/prettier-config/-/prettier-config-1.0.3.tgz#3e2eb559c0112bbe9671895f935700dad2a15d38" integrity sha512-JW7nHREPqEtjBWz3EfxLarkmJBD8vi7Kx/1AQ6eBZnz12eHc1VkOyrc6mpR5ogTf0dOUNXFAfZut+cDe2dn4kQ== +"@matterlabs/zksync-contracts@^0.6.1": + version "0.6.1" + resolved "https://registry.yarnpkg.com/@matterlabs/zksync-contracts/-/zksync-contracts-0.6.1.tgz#39f061959d5890fd0043a2f1ae710f764b172230" + integrity sha512-+hucLw4DhGmTmQlXOTEtpboYCaOm/X2VJcWmnW4abNcOgQXEHX+mTxQrxEfPjIZT0ZE6z5FTUrOK9+RgUZwBMQ== + "@metamask/eth-sig-util@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" @@ -6028,7 +6033,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.8.1: +resolve@^1.1.6, resolve@^1.22.4, resolve@^1.8.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== From f9e9d3c62ddf2cf117b6bda2985607ebfb5e0a8c Mon Sep 17 00:00:00 2001 From: vladbochok Date: Tue, 7 May 2024 12:03:44 +0100 Subject: [PATCH 29/60] Attempt to fix CI --- .github/workflows/slither.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/slither.yaml b/.github/workflows/slither.yaml index 652822dfd..ea278b2a3 100644 --- a/.github/workflows/slither.yaml +++ b/.github/workflows/slither.yaml @@ -43,4 +43,6 @@ jobs: rm -rf ./l1-contracts/contracts/dev-contracts/test/VerifierRecursiveTest.sol - name: Run Slither - run: slither --config ./l1-contracts/slither.config.json ./l1-contracts + run: | + cd l1-contracts + slither --config ./slither.config.json . From accecc4526c95fccbf190d7c2f97f174d1c5fce0 Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Wed, 8 May 2024 15:49:35 +0100 Subject: [PATCH 30/60] fix: hyperchain upgrade fix2 (don't merge) (#401) Co-authored-by: Stanislav Bezkorovainyi --- .github/workflows/slither.yaml | 4 +- .../scripts/governance-accept-ownership.ts | 23 +- l1-contracts/scripts/hyperchain-upgrade-1.ts | 6 +- l1-contracts/scripts/hyperchain-upgrade-2.ts | 3 +- l1-contracts/scripts/hyperchain-upgrade-3.ts | 5 +- l1-contracts/scripts/token-migration.ts | 4 +- .../scripts/upgrade-consistency-checker.ts | 122 ++--- l1-contracts/scripts/verify.ts | 146 +++++- l1-contracts/src.ts/deploy-utils.ts | 4 +- l1-contracts/src.ts/deploy.ts | 36 +- l1-contracts/src.ts/hyperchain-upgrade.ts | 457 +++++++----------- .../test/test_config/constant/hardhat.json | 32 +- l2-contracts/hardhat.config.ts | 2 +- .../src/upgrade-consistency-checker.ts | 4 +- l2-contracts/src/verify.ts | 3 +- system-contracts/hardhat.config.ts | 8 + system-contracts/scripts/deploy-preimages.ts | 2 +- 17 files changed, 438 insertions(+), 423 deletions(-) diff --git a/.github/workflows/slither.yaml b/.github/workflows/slither.yaml index ea278b2a3..fa253e159 100644 --- a/.github/workflows/slither.yaml +++ b/.github/workflows/slither.yaml @@ -44,5 +44,5 @@ jobs: - name: Run Slither run: | - cd l1-contracts - slither --config ./slither.config.json . + cd l1-contracts + slither --config ./slither.config.json . diff --git a/l1-contracts/scripts/governance-accept-ownership.ts b/l1-contracts/scripts/governance-accept-ownership.ts index e111f0ba3..1c366f684 100644 --- a/l1-contracts/scripts/governance-accept-ownership.ts +++ b/l1-contracts/scripts/governance-accept-ownership.ts @@ -63,11 +63,11 @@ async function main() { const proxyAdminAddr = ethers.utils.getAddress(cmd.proxyAdminAddr); console.log("Using Proxy Admin address: ", proxyAdminAddr); - await transferOwnership1StepTo(deployWallet, validatorTimelockAddr, ownerAddress); - await transferOwnership1StepTo(deployWallet, stmAddr, ownerAddress); - await transferOwnership1StepTo(deployWallet, l1SharedBridgeAddr, ownerAddress); - await transferOwnership1StepTo(deployWallet, bridgehubAddr, ownerAddress); - await transferOwnership1StepTo(deployWallet, proxyAdminAddr, ownerAddress); + await transferOwnership1StepTo(deployWallet, validatorTimelockAddr, ownerAddress, true); + await transferOwnership1StepTo(deployWallet, stmAddr, ownerAddress, true); + await transferOwnership1StepTo(deployWallet, l1SharedBridgeAddr, ownerAddress, true); + await transferOwnership1StepTo(deployWallet, bridgehubAddr, ownerAddress, true); + await transferOwnership1StepTo(deployWallet, proxyAdminAddr, ownerAddress, false); }); program @@ -114,14 +114,21 @@ main() process.exit(1); }); -async function transferOwnership1StepTo(wallet: ethers.Wallet, contractAddress: string, newOwner: string) { +async function transferOwnership1StepTo( + wallet: ethers.Wallet, + contractAddress: string, + newOwner: string, + printPendingOwner: boolean = true +) { const contract = new ethers.Contract(contractAddress, ownable2StepInterface, wallet); console.log("Transferring ownership of contract: ", contractAddress, " to: ", newOwner); const tx = await contract.transferOwnership(newOwner); console.log("Tx hash", tx.hash); await tx.wait(); - const newPendingOwner = await contract.pendingOwner(); - console.log("New pending owner: ", newPendingOwner); + if (printPendingOwner) { + const newPendingOwner = await contract.pendingOwner(); + console.log("New pending owner: ", newPendingOwner); + } } function acceptOwnershipCall(target: string) { diff --git a/l1-contracts/scripts/hyperchain-upgrade-1.ts b/l1-contracts/scripts/hyperchain-upgrade-1.ts index e99d84a8c..90a398ee3 100644 --- a/l1-contracts/scripts/hyperchain-upgrade-1.ts +++ b/l1-contracts/scripts/hyperchain-upgrade-1.ts @@ -2,7 +2,7 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import * as hardhat from "hardhat"; import { Command } from "commander"; -import { Wallet, ethers } from "ethers"; +import { Wallet } from "ethers"; import { Deployer } from "../src.ts/deploy"; import { formatUnits, parseUnits } from "ethers/lib/utils"; import { web3Provider, GAS_MULTIPLIER } from "./utils"; @@ -46,7 +46,9 @@ async function main() { const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); console.log(`Using nonce: ${nonce}`); - const create2Salt = cmd.create2Salt ? cmd.create2Salt : ethers.utils.hexlify(ethers.utils.randomBytes(32)); + const create2Salt = cmd.create2Salt + ? cmd.create2Salt + : "0x0000000000000000000000000000000000000000000000000000000000000000"; const deployer = new Deployer({ deployWallet, diff --git a/l1-contracts/scripts/hyperchain-upgrade-2.ts b/l1-contracts/scripts/hyperchain-upgrade-2.ts index edef79bf0..ae8fd93ad 100644 --- a/l1-contracts/scripts/hyperchain-upgrade-2.ts +++ b/l1-contracts/scripts/hyperchain-upgrade-2.ts @@ -24,6 +24,7 @@ async function main() { .option("--nonce ") .option("--owner-address ") .option("--create2-salt ") + .option("--print-file-path ") .option("--diamond-upgrade-init ") .option("--only-verifier") .action(async (cmd) => { @@ -53,7 +54,7 @@ async function main() { verbose: true, }); - await upgradeToHyperchains2(deployer, gasPrice); + await upgradeToHyperchains2(deployer, gasPrice, cmd.printFilePath); }); await program.parseAsync(process.argv); diff --git a/l1-contracts/scripts/hyperchain-upgrade-3.ts b/l1-contracts/scripts/hyperchain-upgrade-3.ts index d232a80d8..e66065d94 100644 --- a/l1-contracts/scripts/hyperchain-upgrade-3.ts +++ b/l1-contracts/scripts/hyperchain-upgrade-3.ts @@ -24,6 +24,7 @@ async function main() { .option("--nonce ") .option("--owner-address ") .option("--create2-salt ") + .option("--print-file-path ") .option("--diamond-upgrade-init ") .option("--only-verifier") .action(async (cmd) => { @@ -33,7 +34,7 @@ async function main() { process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, "m/44'/60'/0'/0/1" ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}, ${deployWallet.privateKey}`); + console.log(`Using deployer wallet: ${deployWallet.address}`); const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address; console.log(`Using owner address: ${ownerAddress}`); @@ -53,7 +54,7 @@ async function main() { verbose: true, }); - await upgradeToHyperchains3(deployer); + await upgradeToHyperchains3(deployer, cmd.printFilePath); }); await program.parseAsync(process.argv); diff --git a/l1-contracts/scripts/token-migration.ts b/l1-contracts/scripts/token-migration.ts index 09413b529..d9ec8757a 100644 --- a/l1-contracts/scripts/token-migration.ts +++ b/l1-contracts/scripts/token-migration.ts @@ -86,7 +86,7 @@ async function main() { .option("--tokens-per-signature ") .option("--shared-bridge-addr ") .option("--legacy-bridge-addr ") - .option("--era-chain-address ") + .option("--era-chain-addr ") .option("--era-chain-id ") .option("--delay ") @@ -106,7 +106,7 @@ async function main() { tokens, cmd.sharedBridgeAddr, cmd.legacyBridgeAddr, - cmd.eraChainAddress, + cmd.eraChainAddr, cmd.eraChainId, +cmd.gasPerToken, +cmd.delay diff --git a/l1-contracts/scripts/upgrade-consistency-checker.ts b/l1-contracts/scripts/upgrade-consistency-checker.ts index ae2d994d1..3972c8695 100644 --- a/l1-contracts/scripts/upgrade-consistency-checker.ts +++ b/l1-contracts/scripts/upgrade-consistency-checker.ts @@ -16,61 +16,60 @@ import { getCurrentFacetCutsForAdd } from "../src.ts/diamondCut"; // 2. Getter methods in STM. // List the contracts that should become the upgrade targets -const genesisUpgrade = "0xDdc72e56A3b90793271FF0EA9a762294f163F992"; -const validatorTimelockDeployTx = "0x1ada4121db6e83bfe38f1f92e31c0931e2f0f2b830429841a7d264c56cceb8b0"; -const validatorTimelock = "0xc47CBbc601dbB65439e7b02B0d19bbA9Dba57442"; -const upgradeHyperchains = "0xc029cE1EB5C61C4a3B2a6EE920bb3B7b026bc00b"; +const genesisUpgrade = "0xc6aB8b3b93f3E47fb4163eB9Dc7A61E1a5D86369"; +const validatorTimelockDeployTx = "0x420e0dddae4a1565fee430ecafa8f5ddbc3eebee2666d0c91f97a47bf054eeb4"; +const validatorTimelock = "0xc2d7a7Bd59a548249e64C1a587220c0E4F6F439E"; +const upgradeHyperchains = "0xb2963DDc6694a989B527AED0B1E19f9F0675AE4d"; -const verifier = "0x82856fED36d36e1d4db24398bC2056C440cB45FC"; -const proxyAdmin = "0xCb7F8e556Ef02771eA32F54e767D6F9742ED31c2"; +const verifier = "0x9D6c59D9A234F585B367b4ba3C62e5Ec7A6179FD"; +const proxyAdmin = "0xf2c1d17441074FFb18E9A918db81A17dB1752146"; -const bridgeHubImpl = "0x22c456Cb8E657bD48e14E9a54CE20169d78CB0F7"; -const bridgeHub = "0x236D1c3Ff32Bd0Ca26b72Af287E895627c0478cE"; +const bridgeHubImpl = "0xF9D2E98Ed518eC6Daac0579a9707d83da55D5f89"; +const bridgeHub = "0x5B5c82f4Da996e118B127880492a23391376F65c"; -const executorFacet = "0xd56f4696ecbE9ADc2e1539F5311ae6C92F4B2BAd"; -const adminFacet = "0x21924127192db478faDf6Ae07f57df928EBCA6AE"; -const mailboxFacetDeployTx = "0xad8028a8a1c7fe71e40fb6e32b80f5893b6b26af5475d9a014b9510faf460090"; -const mailboxFacet = "0x445aD49fC6d1845ec774783659aA5351381b0c49"; -const gettersFacet = "0xbF4C2dfBe9E722F0A87E104c3af5780d49872745"; +const executorFacet = "0x1a451d9bFBd176321966e9bc540596Ca9d39B4B1"; +const adminFacet = "0x342a09385E9BAD4AD32a6220765A6c333552e565"; +const mailboxFacetDeployTx = "0x2fa6af6e9317089be2734ffae73771c8099382d390d4edbb6c35e2db7f73b152"; +const mailboxFacet = "0x7814399116C17F2750Ca99cBFD2b75bA9a0793d7"; +const gettersFacet = "0x345c6ca2F3E08445614f4299001418F125AD330a"; -const diamondInit = "0x17384Fd6Cc64468b69df514A940caC89B602d01c"; +const diamondInit = "0x05D865AE297d236Bc5C7988328d02A00b3D38a4F"; -const stmImplDeployTx = "0x6dacf003368a922b9f916393f3c11c869c1f614c16345667cabd1d8b890ec0cb"; -const stmImpl = "0x91E088D2F36500c4826E5623c9C14Dd90912c23E"; -const stmDeployTx = "0x11ceebf3d0b95a4a49f798c937fd3e0085dc01a4e5d497b60b5072b13e58235a"; -const stm = "0x6F03861D12E6401623854E494beACd66BC46e6F0"; +const stmImplDeployTx = "0x7a077accd4ee39d14b6c23ef31ece4a84c87aff41cd64fd4d2ac23a3885dd4f8"; +const stmImpl = "0x3060D61538fC91B6580e34C5b5D09651CBB9c609"; +const stmDeployTx = "0x30138b826e8f8f855e7fe9e6153d49376b53bce71c34cb2a78e186b12156c966"; +const stm = "0x280372beAAf440C52a2ed893daa14CDACc0422b8"; -const sharedBridgeImplDeployTx = "0x6dacf003368a922b9f916393f3c11c869c1f614c16345667cabd1d8b890ec0cb"; -const sharedBridgeImpl = "0x91E088D2F36500c4826E5623c9C14Dd90912c23E"; -const sharedBridgeProxy = "0x6F03861D12E6401623854E494beACd66BC46e6F0"; +const sharedBridgeImplDeployTx = "0xd24d38cab0beb62f6de9a83cd0a5d7e339e985ba84ac6ef07a336efd79ae333a"; +const sharedBridgeImpl = "0x3819200C978d8A589a1e28A2e8fEb9a0CAD700F7"; +const sharedBridgeProxy = "0x241F19eA8CcD04515b309f1C9953A322F51891FC"; -const legacyBridgeImplDeployTx = "0xc0640213aa843f812c44d63723b5dc03064d8e5a32d85e94689e3273df6c3ef5"; -const legacyBridgeImpl = "0x8fE595B3f92AA34962d7A8aF106Fa50A3e4FC6fA"; +const legacyBridgeImplDeployTx = "0xd8cca5843318ca176afd1075ca6fbb941837a641324300d3719f9189e49fd62c"; +const legacyBridgeImpl = "0xbf3d4109D65A66c629D1999fb630bE2eE16d7038"; -const expectedL1WethAddress = "0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9"; -const initialOwner = "0x343Ee72DdD8CCD80cd43D6Adbc6c463a2DE433a7"; -const expectedOwner = "0x343Ee72DdD8CCD80cd43D6Adbc6c463a2DE433a7"; +const expectedL1WethAddress = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; +const initialOwner = "0x71d84c3404a6ae258E6471d4934B96a2033F9438"; +const expectedOwner = "0x71d84c3404a6ae258E6471d4934B96a2033F9438"; const expectedDelay = 0; -const eraChainId = 270; -const expectedSalt = "0x0000000000000000000000000000000000000000000000000000000000000005"; -const expectedHyperchainAddr = "0x6d6e010A2680E2E5a3b097ce411528b36d880EF6"; +const eraChainId = 324; +const expectedSalt = "0x0000000000000000000000000000000000000000000000000000000000000000"; +const expectedHyperchainAddr = "0x32400084c286cf3e17e7b677ea9583e60a000324"; const maxNumberOfHyperchains = 100; -const expectedStoredBatchHashZero = "0x53dc316f108d1b64412be840e0ab89193e94ba6c4af8b9ca57d39ad4d782e0f4"; -const expectedL2BridgeAddress = "0xCEB8d4888d2025aEaAD0272175281e0CaFC33152"; -const expectedL1LegacyBridge = "0x7303B5Ce64f1ADB0558572611a0b90620b6dd5F4"; -const expectedGenesisBatchCommitment = "0x49276362411c40c07ab01d3dfa9428abca95e361d8c980cd39f1ab6a9c561c0c"; +const expectedStoredBatchHashZero = "0x1574fa776dec8da2071e5f20d71840bfcbd82c2bca9ad68680edfedde1710bc4"; +const expectedL2BridgeAddress = "0x11f943b2c77b743AB90f4A0Ae7d5A4e7FCA3E102"; +const expectedL1LegacyBridge = "0x57891966931Eb4Bb6FB81430E6cE0A03AAbDe063"; +const expectedGenesisBatchCommitment = "0x2d00e5f8d77afcebf58a6b82ae56ba967566fe7dfbcb6760319fb0d215d18ffd"; const expectedIndexRepeatedStorageChanges = BigNumber.from(54); -const expectedProtocolVersion = 23; +const expectedProtocolVersion = 24; const expectedGenesisRoot = "0xabdb766b18a479a5c783a4b80e12686bc8ea3cc2d8a3050491b701d72370ebb5"; const expectedRecursionNodeLevelVkHash = "0xf520cd5b37e74e19fdb369c8d676a04dce8a19457497ac6686d2bb95d94109c8"; const expectedRecursionLeafLevelVkHash = "0x435202d277dd06ef3c64ddd99fda043fc27c2bd8b7c66882966840202c27f4f6"; const expectedRecursionCircuitsSetVksHash = "0x0000000000000000000000000000000000000000000000000000000000000000"; -const expectedBootloaderHash = "0x010008e7f0f15ed191392960117f88fe371348982b28a033c7207ed2c09bc0f4"; +const expectedBootloaderHash = "0x010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e"; const expectedDefaultAccountHash = "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32"; -const expectedGovernance = "0xEE73438083629026FAfA1f5F5bBE2bBD6Bad6331"; -const validatorOne = "0x0000000000000000000000000000000000000000"; // to do find -const validatorTwo = "0x0000000000000000000000000000000000000000"; // to do find +const validatorOne = "0x0D3250c3D5FAcb74Ac15834096397a3Ef790ec99"; +const validatorTwo = "0x3527439923a63F8C13CF72b8Fe80a77f6e572092"; const l1Provider = new ethers.providers.JsonRpcProvider(web3Url()); @@ -213,12 +212,10 @@ async function extractProxyInitializationData(contract: ethers.Contract, data: s const [ usedVerifier, - // We just unpack verifier params here recursionNodeLevelVkHash, recursionLeafLevelVkHash, recursionCircuitsSetVksHash, - l2BootloaderBytecodeHash, l2DefaultAccountBytecodeHash, // priorityTxMaxGasLimit, @@ -362,46 +359,6 @@ async function checkMailbox() { console.log("Mailbox is correct!"); } -async function checkUpgradeHyperchainParams() { - const artifact = await hardhat.artifacts.readArtifact("GettersFacet"); - const contract = new ethers.Contract(expectedHyperchainAddr, artifact.abi, l1Provider); - - // Note: there is no getters for chainId - const setBridgehub = await contract.getBridgehub(); - if (setBridgehub != bridgeHub) { - throw new Error("Bridgehub is not set in Era correctly"); - } - const setStateTransitionManager = await contract.getStateTransitionManager(); - if (setStateTransitionManager != stm) { - throw new Error("Bridgehub is not set in Era correctly"); - } - const setBaseTokenBridge = await contract.getBaseTokenBridge(); - if (setBaseTokenBridge != sharedBridgeProxy) { - throw new Error("Bridgehub is not set in Era correctly"); - } - const setBaseToken = await contract.getBaseToken(); - if (setBaseToken != utils.ETH_ADDRESS_IN_CONTRACTS) { - throw new Error("Bridgehub is not set in Era correctly"); - } - const baseTokenGasPriceMultiplierNominator = await contract.baseTokenGasPriceMultiplierNominator(); - if (baseTokenGasPriceMultiplierNominator != 1) { - throw new Error("baseTokenGasPriceMultiplierNominator is not set in Era correctly"); - } - const baseTokenGasPriceMultiplierDenominator = await contract.baseTokenGasPriceMultiplierDenominator(); - if (baseTokenGasPriceMultiplierDenominator != 1) { - throw new Error("baseTokenGasPriceMultiplierDenominator is not set in Era correctly"); - } - const admin = await contract.getAdmin(); - if (admin != expectedGovernance) { - throw new Error("admin is not set in Era correctly"); - } - const validatorTimelockIsRegistered = await contract.isValidator(validatorTimelock); - if (!validatorTimelockIsRegistered) { - throw new Error("Bridgehub is not set in Era correctly"); - } - console.log("Validator timelock and admin is set correctly in Era!"); -} - async function checkSTMImpl() { const artifact = await hardhat.artifacts.readArtifact("StateTransitionManager"); const contract = new ethers.Contract(stmImpl, artifact.abi, l1Provider); @@ -498,7 +455,7 @@ async function checkProxyAdmin() { const currentOwner = await contract.owner(); if (currentOwner.toLowerCase() != expectedOwner.toLowerCase()) { - throw new Error("ProxyAdmin owner is not correct"); + throw new Error(`ProxyAdmin owner is not correct ${currentOwner}, ${expectedOwner}`); } console.log("ProxyAdmin is correct!"); @@ -519,11 +476,10 @@ async function main() { await checkIdenticalBytecode(gettersFacet, "GettersFacet"); await checkIdenticalBytecode(adminFacet, "AdminFacet"); await checkIdenticalBytecode(bridgeHubImpl, "Bridgehub"); - await checkIdenticalBytecode(verifier, "TestnetVerifier"); + await checkIdenticalBytecode(verifier, eraChainId == 324 ? "Verifier" : "TestnetVerifier"); await checkIdenticalBytecode(diamondInit, "DiamondInit"); await checkMailbox(); - await checkUpgradeHyperchainParams(); await checkProxyAdmin(); diff --git a/l1-contracts/scripts/verify.ts b/l1-contracts/scripts/verify.ts index d70c34663..36c0980b5 100644 --- a/l1-contracts/scripts/verify.ts +++ b/l1-contracts/scripts/verify.ts @@ -1,17 +1,31 @@ // hardhat import should be the first import in the file import * as hardhat from "hardhat"; import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; +import { getNumberFromEnv, getHashFromEnv, getAddressFromEnv, ethTestConfig } from "../src.ts/utils"; + +import { Interface } from "ethers/lib/utils"; +import { Deployer } from "../src.ts/deploy"; +import { Wallet } from "ethers"; +import { web3Provider } from "./utils"; +import { getTokens } from "../src.ts/deploy-token"; + +const provider = web3Provider(); // eslint-disable-next-line @typescript-eslint/no-explicit-any function verifyPromise(address: string, constructorArguments?: Array, libraries?: object): Promise { return new Promise((resolve, reject) => { hardhat - .run("verify:verify", { address, constructorArguments, libraries }) + .run("verify:verify", { + address, + constructorArguments, + libraries, + }) .then(() => resolve(`Successfully verified ${address}`)) .catch((e) => reject(`Failed to verify ${address}\nError: ${e.message}`)); }); } +// Note: running all verifications in parallel might be too much for etherscan, comment out some of them if needed async function main() { if (process.env.CHAIN_ETH_NETWORK == "localhost") { console.log("Skip contract verification on localhost"); @@ -24,25 +38,21 @@ async function main() { const addresses = deployedAddressesFromEnv(); const promises = []; - // Contracts without constructor parameters - for (const address of [ - addresses.StateTransition.GettersFacet, - addresses.StateTransition.DiamondInit, - addresses.StateTransition.AdminFacet, - addresses.StateTransition.MailboxFacet, - addresses.StateTransition.ExecutorFacet, - addresses.StateTransition.Verifier, - ]) { - const promise = verifyPromise(address); - promises.push(promise); - } + const deployWalletAddress = "0x71d84c3404a6ae258E6471d4934B96a2033F9438"; + const deployWallet = Wallet.fromMnemonic(ethTestConfig.mnemonic, "m/44'/60'/0'/0/1").connect(provider); + const deployer = new Deployer({ + deployWallet, + addresses: deployedAddressesFromEnv(), + ownerAddress: deployWalletAddress, + verbose: true, + }); // TODO: Restore after switching to hardhat tasks (SMA-1711). // promises.push(verifyPromise(addresses.AllowList, [governor])); - // // Proxy + // Proxy // { - // // Create dummy deployer to get constructor parameters for diamond proxy + // Create dummy deployer to get constructor parameters for diamond proxy // const deployer = new Deployer({ // deployWallet: ethers.Wallet.createRandom(), // governorAddress: governor @@ -54,10 +64,112 @@ async function main() { // promises.push(promise); // } - // Bridges - const promise = verifyPromise(addresses.Bridges.ERC20BridgeImplementation, [addresses.StateTransition.DiamondProxy]); + const promise1 = verifyPromise(addresses.StateTransition.GenesisUpgrade); + promises.push(promise1); + + const executionDelay = getNumberFromEnv("CONTRACTS_VALIDATOR_TIMELOCK_EXECUTION_DELAY"); + const eraChainId = getNumberFromEnv("CONTRACTS_ERA_CHAIN_ID"); + const promise2 = verifyPromise(addresses.ValidatorTimeLock, [deployWalletAddress, executionDelay, eraChainId]); + promises.push(promise2); + + console.log("CONTRACTS_HYPERCHAIN_UPGRADE_ADDR", process.env.CONTRACTS_HYPERCHAIN_UPGRADE_ADDR); + const promise3 = verifyPromise(process.env.CONTRACTS_HYPERCHAIN_UPGRADE_ADDR); + promises.push(promise3); + + const promise5 = verifyPromise(addresses.TransparentProxyAdmin); + promises.push(promise5); + + // bridgehub + + const promise6 = verifyPromise(addresses.Bridgehub.BridgehubImplementation); + promises.push(promise6); + + const bridgehub = new Interface(hardhat.artifacts.readArtifactSync("Bridgehub").abi); + const initCalldata1 = bridgehub.encodeFunctionData("initialize", [deployWalletAddress]); + const promise7 = verifyPromise(addresses.Bridgehub.BridgehubProxy, [ + addresses.Bridgehub.BridgehubImplementation, + addresses.TransparentProxyAdmin, + initCalldata1, + ]); + promises.push(promise7); + + // stm + + // Contracts without constructor parameters + for (const address of [ + addresses.StateTransition.GettersFacet, + addresses.StateTransition.DiamondInit, + addresses.StateTransition.AdminFacet, + addresses.StateTransition.ExecutorFacet, + addresses.StateTransition.Verifier, + ]) { + const promise = verifyPromise(address); + promises.push(promise); + } + + const promise = verifyPromise(addresses.StateTransition.MailboxFacet, [eraChainId]); promises.push(promise); + const promise8 = verifyPromise(addresses.StateTransition.StateTransitionImplementation, [ + addresses.Bridgehub.BridgehubProxy, + getNumberFromEnv("CONTRACTS_MAX_NUMBER_OF_HYPERCHAINS"), + ]); + promises.push(promise8); + + const stateTransitionManager = new Interface(hardhat.artifacts.readArtifactSync("StateTransitionManager").abi); + const genesisBatchHash = getHashFromEnv("CONTRACTS_GENESIS_ROOT"); // TODO: confusing name + const genesisRollupLeafIndex = getNumberFromEnv("CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX"); + const genesisBatchCommitment = getHashFromEnv("CONTRACTS_GENESIS_BATCH_COMMITMENT"); + const diamondCut = await deployer.initialZkSyncHyperchainDiamondCut([]); + const protocolVersion = getNumberFromEnv("CONTRACTS_GENESIS_PROTOCOL_VERSION"); + + const initCalldata2 = stateTransitionManager.encodeFunctionData("initialize", [ + { + owner: addresses.Governance, + validatorTimelock: addresses.ValidatorTimeLock, + genesisUpgrade: addresses.StateTransition.GenesisUpgrade, + genesisBatchHash, + genesisIndexRepeatedStorageChanges: genesisRollupLeafIndex, + genesisBatchCommitment, + diamondCut, + protocolVersion, + }, + ]); + + const promise9 = verifyPromise(addresses.StateTransition.StateTransitionProxy, [ + addresses.StateTransition.StateTransitionImplementation, + addresses.TransparentProxyAdmin, + initCalldata2, + ]); + promises.push(promise9); + + // bridges + // Note: do this manually and pass in to verify:verify the following: contract:"contracts/bridge/L1ERC20Bridge.sol:L1ERC20Bridge" + const promise10 = verifyPromise(addresses.Bridges.ERC20BridgeImplementation, [addresses.Bridges.SharedBridgeProxy]); + promises.push(promise10); + + const eraDiamondProxy = getAddressFromEnv("CONTRACTS_ERA_DIAMOND_PROXY_ADDR"); + const tokens = getTokens(); + const l1WethToken = tokens.find((token: { symbol: string }) => token.symbol == "WETH")!.address; + + const promise12 = verifyPromise(addresses.Bridges.SharedBridgeImplementation, [ + l1WethToken, + addresses.Bridgehub.BridgehubProxy, + eraChainId, + eraDiamondProxy, + ]); + promises.push(promise12); + const initCalldata4 = new Interface(hardhat.artifacts.readArtifactSync("L1SharedBridge").abi).encodeFunctionData( + "initialize", + [deployWalletAddress] + ); + const promise13 = verifyPromise(addresses.Bridges.SharedBridgeProxy, [ + addresses.Bridges.SharedBridgeImplementation, + addresses.TransparentProxyAdmin, + initCalldata4, + ]); + promises.push(promise13); + const messages = await Promise.allSettled(promises); for (const message of messages) { console.log(message.status == "fulfilled" ? message.value : message.reason); diff --git a/l1-contracts/src.ts/deploy-utils.ts b/l1-contracts/src.ts/deploy-utils.ts index 8e810e652..80c41b195 100644 --- a/l1-contracts/src.ts/deploy-utils.ts +++ b/l1-contracts/src.ts/deploy-utils.ts @@ -71,7 +71,9 @@ export async function deployBytecodeViaCreate2( const receipt = await tx.wait(); const gasUsed = receipt.gasUsed; - log(`${contractName} deployed, gasUsed: ${gasUsed.toString()}`); + log( + `${contractName} deployed, gasUsed: ${gasUsed.toString()}, tx hash: ${tx.hash}, expected address: ${expectedAddress}` + ); const deployedBytecodeAfter = await deployWallet.provider.getCode(expectedAddress); if (ethers.utils.hexDataLength(deployedBytecodeAfter) == 0) { diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 7a1760762..a7009e868 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -45,6 +45,14 @@ export interface DeployerConfig { defaultAccountBytecodeHash?: string; } +export interface Operation { + calls: { target: string; value: BigNumberish; data: string }[]; + predecessor: string; + salt: string; +} + +export type OperationOrString = Operation | string; + export class Deployer { public addresses: DeployedAddresses; public deployWallet: Wallet; @@ -215,9 +223,9 @@ export class Deployer { public async deployTransparentProxyAdmin(create2Salt: string, ethTxOptions: ethers.providers.TransactionRequest) { ethTxOptions.gasLimit ??= 10_000_000; if (this.verbose) { - console.log("Deploying Proxy Admin factory"); + console.log("Deploying Proxy Admin"); } - + // Note: we cannot deploy using Create2, as the owner of the ProxyAdmin is msg.sender const contractFactory = await hardhat.ethers.getContractFactory("ProxyAdmin", { signer: this.deployWallet, }); @@ -443,13 +451,25 @@ export class Deployer { } /// this should be only use for local testing - public async executeUpgrade(targetAddress: string, value: BigNumberish, callData: string) { + public async executeUpgrade(targetAddress: string, value: BigNumberish, callData: string, printFileName?: string) { const governance = IGovernanceFactory.connect(this.addresses.Governance, this.deployWallet); const operation = { calls: [{ target: targetAddress, value: value, data: callData }], predecessor: ethers.constants.HashZero, salt: ethers.utils.hexlify(ethers.utils.randomBytes(32)), }; + if (printFileName) { + console.log("Operation:", operation); + console.log( + "Schedule operation: ", + governance.interface.encodeFunctionData("scheduleTransparent", [operation, 0]) + ); + console.log( + `Execute operation value: ${value}, calldata`, + governance.interface.encodeFunctionData("execute", [operation]) + ); + return; + } const scheduleTx = await governance.scheduleTransparent(operation, 0); await scheduleTx.wait(); if (this.verbose) { @@ -640,11 +660,13 @@ export class Deployer { public async registerStateTransitionManager() { const bridgehub = this.bridgehubContract(this.deployWallet); - const tx = await bridgehub.addStateTransitionManager(this.addresses.StateTransition.StateTransitionProxy); + if (!(await bridgehub.stateTransitionManagerIsRegistered(this.addresses.StateTransition.StateTransitionProxy))) { + const tx = await bridgehub.addStateTransitionManager(this.addresses.StateTransition.StateTransitionProxy); - const receipt = await tx.wait(); - if (this.verbose) { - console.log(`StateTransition System registered, gas used: ${receipt.gasUsed.toString()}`); + const receipt = await tx.wait(); + if (this.verbose) { + console.log(`StateTransition System registered, gas used: ${receipt.gasUsed.toString()}`); + } } } diff --git a/l1-contracts/src.ts/hyperchain-upgrade.ts b/l1-contracts/src.ts/hyperchain-upgrade.ts index 578ed92f0..56e8573a9 100644 --- a/l1-contracts/src.ts/hyperchain-upgrade.ts +++ b/l1-contracts/src.ts/hyperchain-upgrade.ts @@ -1,27 +1,21 @@ // hardhat import should be the first import in the file // eslint-disable-next-line @typescript-eslint/no-unused-vars import * as hardhat from "hardhat"; +import * as path from "path"; import "@nomiclabs/hardhat-ethers"; -// import * as path from "path"; import type { BigNumberish } from "ethers"; -import { BigNumber, ethers } from "ethers"; +import { ethers } from "ethers"; -import type { DiamondCut } from "./diamondCut"; -import { getFacetCutsForUpgrade } from "./diamondCut"; - -import { getTokens } from "./deploy-token"; import type { Deployer } from "./deploy"; import type { ITransparentUpgradeableProxy } from "../typechain/ITransparentUpgradeableProxy"; import { ITransparentUpgradeableProxyFactory } from "../typechain/ITransparentUpgradeableProxyFactory"; - -import { L1SharedBridgeFactory, StateTransitionManagerFactory } from "../typechain"; +import { StateTransitionManagerFactory, L1SharedBridgeFactory, ValidatorTimelockFactory } from "../typechain"; import { Interface } from "ethers/lib/utils"; -import { ADDRESS_ONE, getAddressFromEnv } from "./utils"; -import type { L2CanonicalTransaction, ProposedUpgrade, VerifierParams } from "./utils"; +import { ADDRESS_ONE, getAddressFromEnv, readBytecode } from "./utils"; import { REQUIRED_L2_GAS_PRICE_PER_PUBDATA, @@ -31,22 +25,22 @@ import { } from "../../l2-contracts/src/utils"; import { ETH_ADDRESS_IN_CONTRACTS } from "zksync-ethers/build/src/utils"; -const SYSTEM_UPGRADE_TX_TYPE = 254; -const FORCE_DEPLOYER_ADDRESS = "0x0000000000000000000000000000000000008007"; - -const BEACON_PROXY_BYTECODE = ethers.constants.HashZero; +const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/l2-contracts/artifacts-zk/"); +const openzeppelinBeaconProxyArtifactsPath = path.join(contractArtifactsPath, "@openzeppelin/contracts/proxy/beacon"); +export const BEACON_PROXY_BYTECODE = readBytecode(openzeppelinBeaconProxyArtifactsPath, "BeaconProxy"); /// In the hardhat tests we do the upgrade all at once. /// On localhost/stage/.. we will call the components and send the calldata to Governance manually export async function upgradeToHyperchains( deployer: Deployer, gasPrice: BigNumberish, + printFileName?: string, create2Salt?: string, nonce?: number ) { await upgradeToHyperchains1(deployer, gasPrice, create2Salt, nonce); - await upgradeToHyperchains2(deployer, gasPrice); - await upgradeToHyperchains3(deployer); + await upgradeToHyperchains2(deployer, gasPrice, printFileName); + await upgradeToHyperchains3(deployer, printFileName); } /// this just deploys the contract ( we do it here instead of using the protocol-upgrade tool, since we are deploying more than just facets, the Bridgehub, STM, etc.) @@ -56,67 +50,163 @@ export async function upgradeToHyperchains1( create2Salt?: string, nonce?: number ) { + /// we manually override the governance address so that we can set the variables + deployer.addresses.Governance = deployer.deployWallet.address; // does not interfere with existing system // note other contract were already deployed if (deployer.verbose) { console.log("Deploying new contracts"); } await deployNewContracts(deployer, gasPrice, create2Salt, nonce); + + // register Era in Bridgehub, STM + const stateTransitionManager = deployer.stateTransitionManagerContract(deployer.deployWallet); + + if (deployer.verbose) { + console.log("Registering Era in stateTransitionManager"); + } + const txRegister = await stateTransitionManager.registerAlreadyDeployedHyperchain( + deployer.chainId, + deployer.addresses.StateTransition.DiamondProxy + ); + + await txRegister.wait(); + + const bridgehub = deployer.bridgehubContract(deployer.deployWallet); + if (deployer.verbose) { + console.log("Registering Era in Bridgehub"); + } + + const tx = await bridgehub.createNewChain( + deployer.chainId, + deployer.addresses.StateTransition.StateTransitionProxy, + ETH_ADDRESS_IN_CONTRACTS, + ethers.constants.HashZero, + deployer.addresses.Governance, + ethers.constants.HashZero, + { gasPrice } + ); + await tx.wait(); + + if (deployer.verbose) { + console.log("Setting L1Erc20Bridge data in shared bridge"); + } + const sharedBridge = L1SharedBridgeFactory.connect( + deployer.addresses.Bridges.SharedBridgeProxy, + deployer.deployWallet + ); + const tx1 = await sharedBridge.setL1Erc20Bridge(deployer.addresses.Bridges.ERC20BridgeProxy); + await tx1.wait(); + + if (deployer.verbose) { + console.log("Initializing l2 bridge in shared bridge", deployer.addresses.Bridges.L2SharedBridgeProxy); + } + const tx2 = await sharedBridge.initializeChainGovernance( + deployer.chainId, + deployer.addresses.Bridges.L2SharedBridgeProxy + ); + await tx2.wait(); + + if (deployer.verbose) { + console.log("Setting Validator timelock in STM"); + } + const stm = StateTransitionManagerFactory.connect( + deployer.addresses.StateTransition.StateTransitionProxy, + deployer.deployWallet + ); + const tx3 = await stm.setValidatorTimelock(deployer.addresses.ValidatorTimeLock); + await tx3.wait(); + + if (deployer.verbose) { + console.log("Setting dummy STM in Validator timelock"); + } + + const ethTxOptions: ethers.providers.TransactionRequest = {}; + ethTxOptions.gasLimit ??= 10_000_000; + const migrationSTMAddress = await deployer.deployViaCreate2( + "MigrationSTM", + [deployer.deployWallet.address], + create2Salt, + ethTxOptions + ); + console.log("Migration STM address", migrationSTMAddress); + + const validatorTimelock = ValidatorTimelockFactory.connect( + deployer.addresses.ValidatorTimeLock, + deployer.deployWallet + ); + const tx4 = await validatorTimelock.setStateTransitionManager(migrationSTMAddress); + await tx4.wait(); + + const validatorOneAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR"); + const validatorTwoAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR"); + const tx5 = await validatorTimelock.addValidator(deployer.chainId, validatorOneAddress, { gasPrice }); + const receipt5 = await tx5.wait(); + const tx6 = await validatorTimelock.addValidator(deployer.chainId, validatorTwoAddress, { gasPrice }); + const receipt6 = await tx6.wait(); + + const tx7 = await validatorTimelock.setStateTransitionManager( + deployer.addresses.StateTransition.StateTransitionProxy + ); + const receipt7 = await tx7.wait(); + if (deployer.verbose) { + console.log( + "Validators added, stm transferred back", + receipt5.transactionHash, + receipt6.transactionHash, + receipt7.transactionHash + ); + } } -// this simulates the main part of the upgrade, the diamond cut, registration into the Bridgehub and STM, and the bridge upgrade -// before we call this we need to generate the facet cuts using the protocol upgrade tool, on hardhat we test the dummy diamondCut -export async function upgradeToHyperchains2(deployer: Deployer, gasPrice: BigNumberish) { +// this should be called after the diamond cut has been proposed and executed +// this simulates the main part of the upgrade, registration into the Bridgehub and STM, and the bridge upgrade +export async function upgradeToHyperchains2(deployer: Deployer, gasPrice: BigNumberish, printFileName?: string) { // upgrading system contracts on Era only adds setChainId in systemContext, does not interfere with anything // we first upgrade the DiamondProxy. the Mailbox is backwards compatible, so the L1ERC20 and other bridges should still work. // this requires the sharedBridge to be deployed. // In theory, the L1SharedBridge deposits should be disabled until the L2Bridge is upgraded. // However, without the Portal, UI being upgraded it does not matter (nobody will call it, they will call the legacy bridge) - if (deployer.verbose) { - console.log("Integrating Era into Bridgehub and upgrading L2 system contract"); - } - await integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer, gasPrice); // details for L2 system contract upgrade are part of the infrastructure/protocol_upgrade tool // the L2Bridge and L1ERC20Bridge should be updated relatively in sync, as new messages might not be parsed correctly by the old bridge. // however new bridges can parse old messages. L1->L2 messages are faster, so L2 side is upgraded first. if (deployer.verbose) { console.log("Upgrading L2 bridge"); } - await upgradeL2Bridge(deployer); + await upgradeL2Bridge(deployer, gasPrice, printFileName); + + if (deployer.verbose) { + console.log("Transferring L1 ERC20 bridge to proxy admin"); + } + await transferERC20BridgeToProxyAdmin(deployer, gasPrice, printFileName); - if (process.env.CHAIN_ETH_NETWORK === "localhost") { + if (process.env.CHAIN_ETH_NETWORK != "hardhat") { if (deployer.verbose) { console.log("Upgrading L1 ERC20 bridge"); } - await upgradeL1ERC20Bridge(deployer); + await upgradeL1ERC20Bridge(deployer, gasPrice, printFileName); } - - // note, withdrawals will not work until this step, but deposits will - if (deployer.verbose) { - console.log("Migrating assets from L1 ERC20 bridge and ChainBalance"); - } - await migrateAssets(deployer); } // This sets the Shared Bridge parameters. We need to do this separately, as these params will be known after the upgrade -export async function upgradeToHyperchains3(deployer: Deployer) { +export async function upgradeToHyperchains3(deployer: Deployer, printFileName?: string) { const sharedBridge = L1SharedBridgeFactory.connect( deployer.addresses.Bridges.SharedBridgeProxy, deployer.deployWallet ); const data2 = sharedBridge.interface.encodeFunctionData("setEraPostDiamondUpgradeFirstBatch", [ - process.env.CONTRACTS_ERA_POST_DIAMOND_UPGRADE_FIRST_BATCH ?? 1, + process.env.CONTRACTS_ERA_POST_DIAMOND_UPGRADE_FIRST_BATCH, ]); const data3 = sharedBridge.interface.encodeFunctionData("setEraPostLegacyBridgeUpgradeFirstBatch", [ - process.env.CONTRACTS_ERA_POST_LEGACY_BRIDGE_UPGRADE_FIRST_BATCH ?? 1, + process.env.CONTRACTS_ERA_POST_LEGACY_BRIDGE_UPGRADE_FIRST_BATCH, ]); const data4 = sharedBridge.interface.encodeFunctionData("setEraLegacyBridgeLastDepositTime", [ - process.env.CONTRACTS_ERA_LEGACY_UPGRADE_LAST_DEPOSIT_BATCH ?? 1, - process.env.CONTRACTS_ERA_LEGACY_UPGRADE_LAST_DEPOSIT_TX_NUMBER ?? 0, + process.env.CONTRACTS_ERA_LEGACY_UPGRADE_LAST_DEPOSIT_BATCH, + process.env.CONTRACTS_ERA_LEGACY_UPGRADE_LAST_DEPOSIT_TX_NUMBER, ]); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data2); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data3); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data4); + await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data2, printFileName); + await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data3, printFileName); + await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data4, printFileName); } async function deployNewContracts(deployer: Deployer, gasPrice: BigNumberish, create2Salt?: string, nonce?: number) { @@ -129,21 +219,19 @@ async function deployNewContracts(deployer: Deployer, gasPrice: BigNumberish, cr gasPrice, nonce, }); - nonce++; - await deployer.deployValidatorTimelock(create2Salt, { gasPrice, nonce }); - nonce++; + await deployer.deployValidatorTimelock(create2Salt, { gasPrice }); await deployer.deployHyperchainsUpgrade(create2Salt, { gasPrice, - nonce, }); - nonce++; - await deployer.deployVerifier(create2Salt, { gasPrice, nonce }); + await deployer.deployVerifier(create2Salt, { gasPrice }); if (process.env.CHAIN_ETH_NETWORK != "hardhat") { await deployer.deployTransparentProxyAdmin(create2Salt, { gasPrice }); } + // console.log("Proxy admin is already deployed (not via Create2)", deployer.addresses.TransparentProxyAdmin); + // console.log("CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR=0xf2c1d17441074FFb18E9A918db81A17dB1752146"); await deployer.deployBridgehubContract(create2Salt, gasPrice); await deployer.deployStateTransitionManagerContract(create2Salt, [], gasPrice); @@ -151,180 +239,16 @@ async function deployNewContracts(deployer: Deployer, gasPrice: BigNumberish, cr await deployer.deploySharedBridgeContracts(create2Salt, gasPrice); await deployer.deployERC20BridgeImplementation(create2Salt, { gasPrice }); - await deployer.deployERC20BridgeProxy(create2Salt, { gasPrice }); -} - -async function integrateEraIntoBridgehubAndUpgradeL2SystemContract(deployer: Deployer, gasPrice: BigNumberish) { - // publish L2 system contracts - if (process.env.CHAIN_ETH_NETWORK === "hardhat") { - // era facet cut - const newProtocolVersion = 24; - const toAddress: string = ethers.constants.AddressZero; - const calldata: string = ethers.constants.HashZero; - const l2ProtocolUpgradeTx: L2CanonicalTransaction = { - txType: SYSTEM_UPGRADE_TX_TYPE, - from: FORCE_DEPLOYER_ADDRESS, - to: toAddress, - gasLimit: 72_000_000, - gasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - maxFeePerGas: 0, - maxPriorityFeePerGas: 0, - paymaster: 0, - nonce: newProtocolVersion, - value: 0, - reserved: [0, 0, 0, 0], - data: calldata, - signature: "0x", - factoryDeps: [], - paymasterInput: "0x", - reservedDynamic: "0x", - }; - const upgradeTimestamp = BigNumber.from(100); - const verifierParams: VerifierParams = { - recursionNodeLevelVkHash: ethers.constants.HashZero, - recursionLeafLevelVkHash: ethers.constants.HashZero, - recursionCircuitsSetVksHash: ethers.constants.HashZero, - }; - const postUpgradeCalldata = new ethers.utils.AbiCoder().encode( - ["uint256", "address", "address", "address"], - [ - deployer.chainId, - deployer.addresses.Bridgehub.BridgehubProxy, - deployer.addresses.StateTransition.StateTransitionProxy, - deployer.addresses.Bridges.SharedBridgeProxy, - ] - ); - const proposedUpgrade: ProposedUpgrade = { - l2ProtocolUpgradeTx, - factoryDeps: [], - bootloaderHash: ethers.constants.HashZero, - defaultAccountHash: ethers.constants.HashZero, - verifier: ethers.constants.AddressZero, - verifierParams: verifierParams, - l1ContractsUpgradeCalldata: ethers.constants.HashZero, - postUpgradeCalldata: postUpgradeCalldata, - upgradeTimestamp: upgradeTimestamp, - newProtocolVersion: 24, - }; - const upgradeHyperchains = new Interface(hardhat.artifacts.readArtifactSync("UpgradeHyperchains").abi); - const defaultUpgradeData = upgradeHyperchains.encodeFunctionData("upgrade", [proposedUpgrade]); - - const facetCuts = await getFacetCutsForUpgrade( - deployer.deployWallet, - deployer.addresses.StateTransition.DiamondProxy, - deployer.addresses.StateTransition.AdminFacet, - deployer.addresses.StateTransition.GettersFacet, - deployer.addresses.StateTransition.MailboxFacet, - deployer.addresses.StateTransition.ExecutorFacet - ); - const diamondCut: DiamondCut = { - facetCuts, - initAddress: deployer.addresses.StateTransition.DefaultUpgrade, - initCalldata: defaultUpgradeData, - }; - const adminFacet = new Interface(hardhat.artifacts.readArtifactSync("DummyAdminFacetNoOverlap").abi); - - const data = adminFacet.encodeFunctionData("executeUpgradeNoOverlap", [diamondCut]); - await deployer.executeUpgrade(deployer.addresses.StateTransition.DiamondProxy, 0, data); - } - // register Era in Bridgehub, STM - const stateTransitionManager = deployer.stateTransitionManagerContract(deployer.deployWallet); - - if (deployer.verbose) { - console.log("Registering Era in stateTransitionManager"); - } - const registerData = stateTransitionManager.interface.encodeFunctionData("registerAlreadyDeployedHyperchain", [ - deployer.chainId, - deployer.addresses.StateTransition.DiamondProxy, - ]); - await deployer.executeUpgrade(deployer.addresses.StateTransition.StateTransitionProxy, 0, registerData); - const bridgehub = deployer.bridgehubContract(deployer.deployWallet); - if (deployer.verbose) { - console.log("Registering Era in Bridgehub"); - } - const tx = await bridgehub.createNewChain( - deployer.chainId, - deployer.addresses.StateTransition.StateTransitionProxy, - ETH_ADDRESS_IN_CONTRACTS, - ethers.constants.HashZero, - deployer.addresses.Governance, - ethers.constants.HashZero, - { gasPrice } - ); - - await tx.wait(); - if (deployer.verbose) { - console.log("Setting L1Erc20Bridge data in shared bridge"); - } - const sharedBridge = L1SharedBridgeFactory.connect( - deployer.addresses.Bridges.SharedBridgeProxy, - deployer.deployWallet - ); - const data1 = sharedBridge.interface.encodeFunctionData("setL1Erc20Bridge", [ - deployer.addresses.Bridges.ERC20BridgeProxy, - ]); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data1); - if (process.env.CHAIN_ETH_NETWORK != "hardhat") { - if (deployer.verbose) { - console.log("Initializing l2 bridge in shared bridge"); - } - const data2 = sharedBridge.interface.encodeFunctionData("initializeChainGovernance", [ - deployer.chainId, - deployer.addresses.Bridges.L2SharedBridgeProxy, - ]); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data2); - } - if (deployer.verbose) { - console.log("Setting validators in hyperchain"); - } - // we have to set it via the STM - const stm = StateTransitionManagerFactory.connect( - deployer.addresses.StateTransition.DiamondProxy, - deployer.deployWallet - ); - const data3 = stm.interface.encodeFunctionData("setValidator", [ - deployer.chainId, - deployer.addresses.ValidatorTimeLock, - true, - ]); - await deployer.executeUpgrade(deployer.addresses.StateTransition.StateTransitionProxy, 0, data3); - - if (deployer.verbose) { - console.log("Setting validators in validator timelock"); - } - - // adding to validator timelock - const validatorOneAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR"); - const validatorTwoAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR"); - const validatorTimelock = deployer.validatorTimelock(deployer.deployWallet); - const txRegisterValidator = await validatorTimelock.addValidator(deployer.chainId, validatorOneAddress, { - gasPrice, - }); - const receiptRegisterValidator = await txRegisterValidator.wait(); - if (deployer.verbose) { - console.log( - `Validator registered, gas used: ${receiptRegisterValidator.gasUsed.toString()}, tx hash: ${ - txRegisterValidator.hash - }` - ); - } - - const tx3 = await validatorTimelock.addValidator(deployer.chainId, validatorTwoAddress, { - gasPrice, - }); - const receipt3 = await tx3.wait(); - if (deployer.verbose) { - console.log(`Validator 2 registered, gas used: ${receipt3.gasUsed.toString()}`); - } } -async function upgradeL2Bridge(deployer: Deployer) { +async function upgradeL2Bridge(deployer: Deployer, gasPrice: BigNumberish, printFileName?: string) { const l2BridgeImplementationAddress = process.env.CONTRACTS_L2_SHARED_BRIDGE_IMPL_ADDR!; // upgrade from L1 governance. This has to come from governacne on L1. const l2BridgeAbi = ["function initialize(address, address, bytes32, address)"]; const l2BridgeContract = new ethers.Contract(ADDRESS_ONE, l2BridgeAbi, deployer.deployWallet); const l2Bridge = l2BridgeContract.interface; //L2_SHARED_BRIDGE_INTERFACE; + const l2BridgeCalldata = l2Bridge.encodeFunctionData("initialize", [ deployer.addresses.Bridges.SharedBridgeProxy, deployer.addresses.Bridges.ERC20BridgeProxy, @@ -341,48 +265,33 @@ async function upgradeL2Bridge(deployer: Deployer) { l2BridgeImplementationAddress, l2BridgeCalldata, ]); + // console.log("kl todo", l2BridgeImplementationAddress, l2BridgeCalldata) const factoryDeps = []; - const gasPrice = await deployer.deployWallet.getGasPrice(); const requiredValueForL2Tx = await deployer .bridgehubContract(deployer.deployWallet) .l2TransactionBaseCost(deployer.chainId, gasPrice, priorityTxMaxGasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); //"1000000000000000000"; - if (process.env.CHAIN_ETH_NETWORK === "localhost") { - // on the main branch the l2SharedBridge governor is incorrectly set to deploy wallet, so we can just make the call - const hyperchain = deployer.stateTransitionContract(deployer.deployWallet); - const tx = await hyperchain.requestL2Transaction( - process.env.CONTRACTS_L2_ERC20_BRIDGE_ADDR, - 0, - l2ProxyCalldata, - priorityTxMaxGasLimit, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - factoryDeps, - deployer.deployWallet.address, - { value: requiredValueForL2Tx.mul(10) } - ); - await tx.wait(); - } else { - const mailboxFacet = new Interface(hardhat.artifacts.readArtifactSync("MailboxFacet").abi); - const mailboxCalldata = mailboxFacet.encodeFunctionData("requestL2Transaction", [ - process.env.CONTRACTS_L2_ERC20_BRIDGE_ADDR, - 0, - l2ProxyCalldata, - priorityTxMaxGasLimit, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - factoryDeps, - deployer.deployWallet.address, - ]); + const mailboxFacet = new Interface(hardhat.artifacts.readArtifactSync("MailboxFacet").abi); + const mailboxCalldata = mailboxFacet.encodeFunctionData("requestL2Transaction", [ + process.env.CONTRACTS_L2_ERC20_BRIDGE_ADDR, + 0, + l2ProxyCalldata, + priorityTxMaxGasLimit, + REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + factoryDeps, + deployer.deployWallet.address, + ]); - await deployer.executeUpgrade( - deployer.addresses.StateTransition.DiamondProxy, - requiredValueForL2Tx.mul(10), - mailboxCalldata - ); - } + await deployer.executeUpgrade( + deployer.addresses.StateTransition.DiamondProxy, + requiredValueForL2Tx, + mailboxCalldata, + printFileName + ); } -async function upgradeL1ERC20Bridge(deployer: Deployer) { - if (process.env.CHAIN_ETH_NETWORK === "localhost") { +async function upgradeL1ERC20Bridge(deployer: Deployer, gasPrice: BigNumberish, printFileName?: string) { + if (process.env.CHAIN_ETH_NETWORK != "hardhat") { // we need to wait here for a new block await new Promise((resolve) => setTimeout(resolve, 5000)); // upgrade ERC20. @@ -397,7 +306,7 @@ async function upgradeL1ERC20Bridge(deployer: Deployer) { deployer.addresses.Bridges.ERC20BridgeImplementation, ]); - await deployer.executeUpgrade(deployer.addresses.TransparentProxyAdmin, 0, data1); + await deployer.executeUpgrade(deployer.addresses.TransparentProxyAdmin, 0, data1, printFileName); if (deployer.verbose) { console.log("L1ERC20Bridge upgrade sent"); @@ -405,41 +314,35 @@ async function upgradeL1ERC20Bridge(deployer: Deployer) { } } -async function migrateAssets(deployer: Deployer) { - // migrate assets from L1 ERC20 bridge - if (deployer.verbose) { - console.log("transferring Eth"); - } - const sharedBridge = deployer.defaultSharedBridge(deployer.deployWallet); - const ethTransferData = sharedBridge.interface.encodeFunctionData("safeTransferFundsFromLegacy", [ - ADDRESS_ONE, - deployer.addresses.StateTransition.DiamondProxy, - deployer.chainId, - 300_000, +export async function transferERC20BridgeToProxyAdmin( + deployer: Deployer, + gasPrice: BigNumberish, + printFileName?: string +) { + const bridgeProxy: ITransparentUpgradeableProxy = ITransparentUpgradeableProxyFactory.connect( + deployer.addresses.Bridges.ERC20BridgeProxy, + deployer.deployWallet + ); + const data1 = await bridgeProxy.interface.encodeFunctionData("changeAdmin", [ + deployer.addresses.TransparentProxyAdmin, ]); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, ethTransferData); - const tokens = getTokens(); - const altTokenAddress = tokens.find((token: { symbol: string }) => token.symbol == "DAI")!.address; + await deployer.executeUpgrade(deployer.addresses.Bridges.ERC20BridgeProxy, 0, data1, printFileName); + if (deployer.verbose) { - console.log("transferring Dai, ", altTokenAddress); + console.log("ERC20Bridge ownership transfer sent"); } +} - // Mint some tokens - const l1Erc20ABI = ["function mint(address to, uint256 amount)"]; - const l1Erc20Contract = new ethers.Contract(altTokenAddress, l1Erc20ABI, deployer.deployWallet); - const mintTx = await l1Erc20Contract.mint( +export async function transferTokens(deployer: Deployer, token: string) { + const sharedBridge = deployer.defaultSharedBridge(deployer.deployWallet); + const tx = await sharedBridge.safeTransferFundsFromLegacy( + token, deployer.addresses.Bridges.ERC20BridgeProxy, - ethers.utils.parseEther("10000.0") + "324", + "300000", + { gasLimit: 25_000_000 } ); - await mintTx.wait(); - - const daiTransferData = sharedBridge.interface.encodeFunctionData("safeTransferFundsFromLegacy", [ - altTokenAddress, - deployer.addresses.Bridges.ERC20BridgeProxy, - deployer.chainId, - 300_000, - ]); - // daiTransferData; - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, daiTransferData); + await tx.wait(); + console.log("Receipt", tx.hash); } diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index b9bd70c61..0e63431f0 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -3,96 +3,96 @@ "name": "DAI", "symbol": "DAI", "decimals": 18, - "address": "0xfCdA09988fC2433BFE27BBe9e95E0C007ee272Fd" + "address": "0xD6E49dd4fb0CA1549566869725d1820aDEb92Ae9" }, { "name": "wBTC", "symbol": "wBTC", "decimals": 8, - "address": "0x3b78cDD294f0b34755c8a9bA8f124Cb6c217b60a" + "address": "0xcee1f75F30B6908286Cd003C4228A5D9a2851FA4" }, { "name": "BAT", "symbol": "BAT", "decimals": 18, - "address": "0xd4a9D970EF600289dC96b67505027D17604FBfe1" + "address": "0x0Bc76A4EfE0748f1697F237fB100741ea6Ceda2d" }, { "name": "GNT", "symbol": "GNT", "decimals": 18, - "address": "0x4fE0EE70D78132fBb5C68C1d5e0020f3c05542f2" + "address": "0x51ae50BcCEE10ac5BEFFA1E4a64106a5f83bc3F8" }, { "name": "MLTT", "symbol": "MLTT", "decimals": 18, - "address": "0x3202935CA01eADd2F0B4e7aA23EFA52315121172" + "address": "0xa9c7fEEf8586E17D93A05f873BA65f28f48ED259" }, { "name": "DAIK", "symbol": "DAIK", "decimals": 18, - "address": "0xe73a1c05498e492f182f9B3E3cd65b2F9f52eE94" + "address": "0x99Efb27598804Aa408A1066550e9d01c45f21b05" }, { "name": "wBTCK", "symbol": "wBTCK", "decimals": 8, - "address": "0x7aAE2ee8317b384aDE246664933A147411b60045" + "address": "0x4B701928Da6B3e72775b462A15b8b76ba2d16BbD" }, { "name": "BATK", "symbol": "BATS", "decimals": 18, - "address": "0x02a344d1e31e92e39c2681937645F1d668C37d4e" + "address": "0xf7B03c921dfefB4286b13075BA0335099708368D" }, { "name": "GNTK", "symbol": "GNTS", "decimals": 18, - "address": "0x28033f8EdB2F43747E55401C4a3E3b4b2cF5146C" + "address": "0xc0581Ee28c519533B06cc0aAC1ace98cF63C817b" }, { "name": "MLTTK", "symbol": "MLTTS", "decimals": 18, - "address": "0x147dCc3a8E99794C2Ec79EaF1a142324D6778255" + "address": "0xeB6394F2E8DA607b94dBa2Cf345A965d6D9b3aCD" }, { "name": "DAIL", "symbol": "DAIL", "decimals": 18, - "address": "0x74cA8715E29196Bfbcd7444B09203d22dDaF7d1a" + "address": "0x4311643C5eD7cD0813B4E3Ff5428de71c7d7b8bB" }, { "name": "wBTCL", "symbol": "wBTCP", "decimals": 8, - "address": "0x2eAf3eac597d23db3A8427329482aE47935141d9" + "address": "0x6b3fbfC9Bb89Ab5F11BE782a1f67c1615c2A5fc3" }, { "name": "BATL", "symbol": "BATW", "decimals": 18, - "address": "0x2B1b32d23f2be391280bFbD2B51daB8Ad2a69B9e" + "address": "0xE003698b7831829843B69D3fB4f9a3133d97b257" }, { "name": "GNTL", "symbol": "GNTW", "decimals": 18, - "address": "0xc2Ca10940Ad80Cd98512B767457bd44713232B5a" + "address": "0x2417626170675Ccf6022d9db1eFC8f3c59836368" }, { "name": "MLTTL", "symbol": "MLTTW", "decimals": 18, - "address": "0xd6b4CDa9F0Ef6d9F6b35Ab5424df0dD95E6a6D1b" + "address": "0x28106C39BE5E51C31D9a289313361D86C9bb7C8E" }, { "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, - "address": "0x15CD4a1C10AE2D3727Dad680a1966947931588C9" + "address": "0x51E83b811930bb4a3aAb3494894ec237Cb6cEc49" } ] diff --git a/l2-contracts/hardhat.config.ts b/l2-contracts/hardhat.config.ts index 155611b6a..c0aaca03e 100644 --- a/l2-contracts/hardhat.config.ts +++ b/l2-contracts/hardhat.config.ts @@ -43,7 +43,7 @@ export default { // contract verification endpoint verifyURL: "https://explorer.sepolia.era.zksync.dev/contract_verification", }, - zksyncMainnet: { + zkSyncMainnet: { url: "https://mainnet.era.zksync.io", ethNetwork: "mainnet", zksync: true, diff --git a/l2-contracts/src/upgrade-consistency-checker.ts b/l2-contracts/src/upgrade-consistency-checker.ts index 74f286eae..8bebe197d 100644 --- a/l2-contracts/src/upgrade-consistency-checker.ts +++ b/l2-contracts/src/upgrade-consistency-checker.ts @@ -13,9 +13,9 @@ import { Provider } from "zksync-ethers"; // 2. Getter methods in STM. // List the contracts that should become the upgrade targets -const l2BridgeImplAddr = "0xce0a8c005a73e35d95cec41a9e8b75668470fb8f"; +const l2BridgeImplAddr = "0x470afaacce2acdaefcc662419b74c79d76c914ae"; -const eraChainId = 270; +const eraChainId = 324; const l2Provider = new Provider(process.env.API_WEB3_JSON_RPC_HTTP_URL); diff --git a/l2-contracts/src/verify.ts b/l2-contracts/src/verify.ts index 53fc28f33..a45c83795 100644 --- a/l2-contracts/src/verify.ts +++ b/l2-contracts/src/verify.ts @@ -22,13 +22,14 @@ async function main() { // Contracts without constructor parameters for (const address of [ process.env.CONTRACTS_L2_WETH_TOKEN_IMPL_ADDR, - process.env.CONTRACTS_L2_ERC20_BRIDGE_IMPL_ADDR, process.env.CONTRACTS_L2_ERC20_BRIDGE_TOKEN_IMPL_ADDR, ]) { const promise = verifyPromise(address); promises.push(promise); } + promises.push(verifyPromise(process.env.CONTRACTS_L2_SHARED_BRIDGE_IMPL_ADDR, [process.env.CONTRACTS_ERA_CHAIN_ID])); + const messages = await Promise.allSettled(promises); for (const message of messages) { console.log(message.status == "fulfilled" ? message.value : message.reason); diff --git a/system-contracts/hardhat.config.ts b/system-contracts/hardhat.config.ts index cc0a5e0b4..2adf0c440 100644 --- a/system-contracts/hardhat.config.ts +++ b/system-contracts/hardhat.config.ts @@ -55,6 +55,14 @@ export default { ethNetwork: "localhost", zksync: true, }, + stage: { + url: "https://z2-dev-api.zksync.dev/", + ethNetwork: "sepolia", + zksync: true, + }, + sepolia: { + url: "", // add your sepolia node url + }, }, paths: { sources: "./contracts-preprocessed", diff --git a/system-contracts/scripts/deploy-preimages.ts b/system-contracts/scripts/deploy-preimages.ts index 035b98e88..6803f9a53 100644 --- a/system-contracts/scripts/deploy-preimages.ts +++ b/system-contracts/scripts/deploy-preimages.ts @@ -19,7 +19,7 @@ const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_co const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); // Maximum length of the combined length of dependencies -const MAX_COMBINED_LENGTH = 90000; +const MAX_COMBINED_LENGTH = 125000; const DEFAULT_ACCOUNT_CONTRACT_NAME = "DefaultAccount"; const BOOTLOADER_CONTRACT_NAME = "Bootloader"; From fa85062fa68c8e3473355d079b4bf982b315a5a2 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Sat, 11 May 2024 07:24:54 -0400 Subject: [PATCH 31/60] remove log values when validium (#465) --- .../contracts/state-transition/chain-deps/facets/Executor.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index b5c977879..cb43a5880 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -52,6 +52,9 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { if (pricingMode == PubdataPricingMode.Validium) { // skipping data validation for validium, we just check that the data is empty require(_newBatch.pubdataCommitments.length == 1, "EF: v0l"); + for (uint8 i = uint8(SystemLogKey.BLOB_ONE_HASH_KEY); i <= uint8(SystemLogKey.BLOB_SIX_HASH_KEY); i++) { + logOutput.blobHashes[i - uint8(SystemLogKey.BLOB_ONE_HASH_KEY)] = bytes32(0); + } } else if (pubdataSource == uint8(PubdataSource.Blob)) { // In this scenario, pubdataCommitments is a list of: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) || proof (48 bytes)) = 144 bytes blobCommitments = _verifyBlobInformation(_newBatch.pubdataCommitments[1:], logOutput.blobHashes); From 46c9170db66b74e50cdcb14bbc74ee480747567c Mon Sep 17 00:00:00 2001 From: EmilLuta Date: Sat, 11 May 2024 15:52:28 +0200 Subject: [PATCH 32/60] Updates Verifier.sol for 1.5.0 patch --- l1-contracts/contracts/state-transition/Verifier.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 861f7e850..00b2c38bc 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -283,8 +283,8 @@ contract Verifier is IVerifier { function _loadVerificationKey() internal pure virtual { assembly { // gate setup commitments - mstore(VK_GATE_SETUP_0_X_SLOT, 0x2b344993e706c18427e96e2eefd8e89aaf4cd464814ed978b98793bf129a786c) - mstore(VK_GATE_SETUP_0_Y_SLOT, 0x123af72bf1c5e693516b037d16ba48711c3486823aec3772318b6737634575a4) + mstore(VK_GATE_SETUP_0_X_SLOT, 0x0e4e3895515c2c29cb6ba62733c4e337826da43b5ce3d953717ef58248174337) + mstore(VK_GATE_SETUP_0_Y_SLOT, 0x286f244ce4af2209863dfc81fd2d8d1b47552790fa8471446fe418a8b228e8ef) mstore(VK_GATE_SETUP_1_X_SLOT, 0x04659caf7b05471ba5ba85b1ab62267aa6c456836e625f169f7119d55b9462d2) mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0ea63403692148d2ad22189a1e5420076312f4d46e62036a043a6b0b84d5b410) mstore(VK_GATE_SETUP_2_X_SLOT, 0x0e6696d09d65fce1e42805be03fca1f14aea247281f688981f925e77d4ce2291) @@ -295,8 +295,8 @@ contract Verifier is IVerifier { mstore(VK_GATE_SETUP_4_Y_SLOT, 0x22e404bc91350f3bc7daad1d1025113742436983c85eac5ab7b42221a181b81e) mstore(VK_GATE_SETUP_5_X_SLOT, 0x0d9b29613037a5025655c82b143d2b7449c98f3aea358307c8529249cc54f3b9) mstore(VK_GATE_SETUP_5_Y_SLOT, 0x15b3c4c946ad1babfc4c03ff7c2423fd354af3a9305c499b7fb3aaebe2fee746) - mstore(VK_GATE_SETUP_6_X_SLOT, 0x18e466aac9b830ea5417e1ba2e920acf041e3976d36fe891be80beac1d1696c7) - mstore(VK_GATE_SETUP_6_Y_SLOT, 0x025f89444627d09c7b1bf665dc6f58055bf729c683a4b3e815215758a7075602) + mstore(VK_GATE_SETUP_6_X_SLOT, 0x2693ae0454ab607b949ef9951b18ca8f81b80f279054eb984dcccac4c83884ac) + mstore(VK_GATE_SETUP_6_Y_SLOT, 0x082f2ce318997eaebe1b03741ff39082ef878574ebb0286c41440c4a1c05d9bb) mstore(VK_GATE_SETUP_7_X_SLOT, 0x283344a1ab3e55ecfd904d0b8e9f4faea338df5a4ead2fa9a42f0e103da40abc) mstore(VK_GATE_SETUP_7_Y_SLOT, 0x223b37b83b9687512d322993edd70e508dd80adb10bcf7321a3cc8a44c269521) From 3a0dd43401fd06150160d4c5cd0d1e9cfa5b6bea Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Sat, 11 May 2024 10:25:43 -0400 Subject: [PATCH 33/60] update vk --- tools/data/scheduler_key.json | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tools/data/scheduler_key.json b/tools/data/scheduler_key.json index ab950921b..0adf6c743 100644 --- a/tools/data/scheduler_key.json +++ b/tools/data/scheduler_key.json @@ -6,16 +6,16 @@ "gate_setup_commitments": [ { "x": [ - 13368816467732756588, - 12631704582998645112, - 2875950984924293274, - 3113194142004855172 + 8178243913255437111, + 9398348572260555091, + 14657992099509887799, + 1030823578680699945 ], "y": [ - 3570060617207608740, - 2032397225743366002, - 5866786775367305329, - 1313634009443853971 + 8062596345722628335, + 5140058053345046852, + 9673165209890295067, + 2913587396604797449 ], "infinity": false }, @@ -96,16 +96,16 @@ }, { "x": [ - 13727181310656943815, - 296737807969282193, - 6059560013411781327, - 1793671435315065066 + 5606078582690972844, + 9347237689207090072, + 10709271382733671055, + 2779756728641347707 ], "y": [ - 1522594187298952706, - 6626811309287846888, - 8870954808386738181, - 171006237191164060 + 4702897423318899131, + 17259910834137606252, + 13698546488864641154, + 589739430090735278 ], "infinity": false }, From f3630fcb01ad8b6e2e423a6f313abefe8502c3a2 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Mon, 13 May 2024 22:04:37 +1000 Subject: [PATCH 34/60] chore: bump hardhat (#462) --- l1-contracts/package.json | 2 +- l2-contracts/package.json | 2 +- system-contracts/package.json | 2 +- yarn.lock | 464 +++++++++++----------------------- 4 files changed, 154 insertions(+), 316 deletions(-) diff --git a/l1-contracts/package.json b/l1-contracts/package.json index b722ef9d9..63b6a19a0 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -31,7 +31,7 @@ "ethjs": "^0.4.0", "fs": "^0.0.1-security", "handlebars": "^4.7.6", - "hardhat": "^2.18.3", + "hardhat": "=2.22.2", "hardhat-contract-sizer": "^2.0.2", "hardhat-gas-reporter": "^1.0.9", "hardhat-typechain": "^0.3.3", diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 46004d1eb..aa2280ca6 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -23,7 +23,7 @@ "chalk": "^4.1.0", "commander": "^6.0.0", "ethers": "^5.7.0", - "hardhat": "^2.18.3", + "hardhat": "=2.22.2", "hardhat-typechain": "^0.3.3", "mocha": "^9.0.2", "ts-node": "^10.1.0", diff --git a/system-contracts/package.json b/system-contracts/package.json index 6867cdbec..4b255f55d 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -9,7 +9,7 @@ "commander": "^9.4.1", "ethers": "^5.7.0", "fast-glob": "^3.3.2", - "hardhat": "^2.18.3", + "hardhat": "=2.22.2", "preprocess": "^3.2.0", "zksync-web3": "^0.14.3" }, diff --git a/yarn.lock b/yarn.lock index 4d3b46502..8accda709 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - "@babel/code-frame@^7.0.0": version "7.22.13" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" @@ -15,10 +10,10 @@ "@babel/highlight" "^7.22.13" chalk "^2.4.2" -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== +"@babel/helper-validator-identifier@^7.24.5": + version "7.24.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" + integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== "@babel/highlight@^7.22.13": version "7.22.20" @@ -47,42 +42,6 @@ "@blakek/curry" "^2.0.2" pathington "^1.1.7" -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" @@ -459,7 +418,7 @@ dependencies: "@ethersproject/logger" "^5.7.0" -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": +"@ethersproject/providers@5.7.2": version "5.7.2" resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== @@ -831,6 +790,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@noble/hashes@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" + integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== + "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": version "1.3.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" @@ -862,140 +826,84 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nomicfoundation/ethereumjs-block@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.2.tgz#13a7968f5964f1697da941281b7f7943b0465d04" - integrity sha512-hSe6CuHI4SsSiWWjHDIzWhSiAVpzMUcDRpWYzN0T9l8/Rz7xNn3elwVOJ/tAyS0LqL6vitUD78Uk7lQDXZun7Q== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.2.tgz#45323b673b3d2fab6b5008535340d1b8fea7d446" - integrity sha512-8UUsSXJs+MFfIIAKdh3cG16iNmWzWC/91P40sazNvrqhhdR/RtGDlFk2iFTGbBAZPs2+klZVzhRX8m2wvuvz3w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-ethash" "3.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.2": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.2.tgz#a15d1651ca36757588fdaf2a7d381a150662a3c3" - integrity sha512-I2WGP3HMGsOoycSdOTSqIaES0ughQTueOsddJ36aYVpI3SN8YSusgRFLwzDJwRFVIYDKx/iJz0sQ5kBHVgdDwg== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.2" - crc-32 "^1.2.0" - -"@nomicfoundation/ethereumjs-ethash@3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.2.tgz#da77147f806401ee996bfddfa6487500118addca" - integrity sha512-8PfoOQCcIcO9Pylq0Buijuq/O73tmMVURK0OqdjhwqcGHYC2PwhbajDh7GZ55ekB0Px197ajK3PQhpKoiI/UPg== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.2.tgz#4c2f4b84c056047102a4fa41c127454e3f0cfcf6" - integrity sha512-rBLcUaUfANJxyOx9HIdMX6uXGin6lANCulIm/pjMgRqfiCRMZie3WKYxTSd8ZE/d+qT+zTedBF4+VHTdTSePmQ== +"@nomicfoundation/edr-darwin-arm64@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.7.tgz#c204edc79643624dbd431b489b254778817d8244" + integrity sha512-6tK9Lv/lSfyBvpEQ4nsTfgxyDT1y1Uv/x8Wa+aB+E8qGo3ToexQ1BMVjxJk6PChXCDOWxB3B4KhqaZFjdhl3Ow== + +"@nomicfoundation/edr-darwin-x64@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.7.tgz#c3b394445084270cc5250d6c1869b0574e7ef810" + integrity sha512-1RrQ/1JPwxrYO69e0tglFv5H+ggour5Ii3bb727+yBpBShrxtOTQ7fZyfxA5h62LCN+0Z9wYOPeQ7XFcVurMaQ== + +"@nomicfoundation/edr-linux-arm64-gnu@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.7.tgz#6d65545a44d1323bb7ab08c3306947165d2071de" + integrity sha512-ds/CKlBoVXIihjhflhgPn13EdKWed6r5bgvMs/YwRqT5wldQAQJZWAfA2+nYm0Yi2gMGh1RUpBcfkyl4pq7G+g== + +"@nomicfoundation/edr-linux-arm64-musl@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.7.tgz#5368534bceac1a8c18b1be6b908caca5d39b0c03" + integrity sha512-e29udiRaPujhLkM3+R6ju7QISrcyOqpcaxb2FsDWBkuD7H8uU9JPZEyyUIpEp5uIY0Jh1eEJPKZKIXQmQAEAuw== + +"@nomicfoundation/edr-linux-x64-gnu@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.7.tgz#42349bf5941dbb54a5719942924c6e4e8cde348e" + integrity sha512-/xkjmTyv+bbJ4akBCW0qzFKxPOV4AqLOmqurov+s9umHb16oOv72osSa3SdzJED2gHDaKmpMITT4crxbar4Axg== + +"@nomicfoundation/edr-linux-x64-musl@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.7.tgz#e6babe11c9a8012f1284e6e48c3551861f2a7cd4" + integrity sha512-QwBP9xlmsbf/ldZDGLcE4QiAb8Zt46E/+WLpxHBATFhGa7MrpJh6Zse+h2VlrT/SYLPbh2cpHgSmoSlqVxWG9g== + +"@nomicfoundation/edr-win32-x64-msvc@0.3.7": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.7.tgz#1504b98f305f03be153b0220a546985660de9dc6" + integrity sha512-j/80DEnkxrF2ewdbk/gQ2EOPvgF0XSsg8D0o4+6cKhUVAW6XwtWKzIphNL6dyD2YaWEPgIrNvqiJK/aln0ww4Q== + +"@nomicfoundation/edr@^0.3.1": + version "0.3.7" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.3.7.tgz#9c75edf1fcf601617905b2c89acf103f4786d017" + integrity sha512-v2JFWnFKRsnOa6PDUrD+sr8amcdhxnG/YbL7LzmgRGU1odWEyOF4/EwNeUajQr4ZNKVWrYnJ6XjydXtUge5OBQ== + optionalDependencies: + "@nomicfoundation/edr-darwin-arm64" "0.3.7" + "@nomicfoundation/edr-darwin-x64" "0.3.7" + "@nomicfoundation/edr-linux-arm64-gnu" "0.3.7" + "@nomicfoundation/edr-linux-arm64-musl" "0.3.7" + "@nomicfoundation/edr-linux-x64-gnu" "0.3.7" + "@nomicfoundation/edr-linux-x64-musl" "0.3.7" + "@nomicfoundation/edr-win32-x64-msvc" "0.3.7" + +"@nomicfoundation/ethereumjs-common@4.0.4": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" + integrity sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg== dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" + "@nomicfoundation/ethereumjs-util" "9.0.4" -"@nomicfoundation/ethereumjs-rlp@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.2.tgz#4fee8dc58a53ac6ae87fb1fca7c15dc06c6b5dea" - integrity sha512-QwmemBc+MMsHJ1P1QvPl8R8p2aPvvVcKBbvHnQOKBpBztEo0omN0eaob6FeZS/e3y9NSe+mfu3nNFBHszqkjTA== +"@nomicfoundation/ethereumjs-rlp@5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30" + integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw== -"@nomicfoundation/ethereumjs-statemanager@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.2.tgz#3ba4253b29b1211cafe4f9265fee5a0d780976e0" - integrity sha512-dlKy5dIXLuDubx8Z74sipciZnJTRSV/uHG48RSijhgm1V7eXYFC567xgKtsKiVZB1ViTP9iFL4B6Je0xD6X2OA== +"@nomicfoundation/ethereumjs-tx@5.0.4": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da" + integrity sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw== dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - debug "^4.3.3" + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-rlp" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" -"@nomicfoundation/ethereumjs-trie@6.0.2": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.2.tgz#9a6dbd28482dca1bc162d12b3733acab8cd12835" - integrity sha512-yw8vg9hBeLYk4YNg5MrSJ5H55TLOv2FSWUTROtDtTMMmDGROsAu+0tBjiNGTnKRi400M6cEzoFfa89Fc5k8NTQ== +"@nomicfoundation/ethereumjs-util@9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38" + integrity sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q== dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.2": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.2.tgz#117813b69c0fdc14dd0446698a64be6df71d7e56" - integrity sha512-T+l4/MmTp7VhJeNloMkM+lPU3YMUaXdcXgTGCf8+ZFvV9NYZTRLFekRwlG6/JMmVfIfbrW+dRRJ9A6H5Q/Z64g== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" + "@nomicfoundation/ethereumjs-rlp" "5.0.4" ethereum-cryptography "0.1.3" -"@nomicfoundation/ethereumjs-util@9.0.2": - version "9.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.2.tgz#16bdc1bb36f333b8a3559bbb4b17dac805ce904d" - integrity sha512-4Wu9D3LykbSBWZo8nJCnzVIYGvGCuyiYLIJa9XXNVt1q1jUzHdB+sJvx95VGCpPkCT+IbLecW6yfzy3E1bQrwQ== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-vm@7.0.2": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.2.tgz#3b0852cb3584df0e18c182d0672a3596c9ca95e6" - integrity sha512-Bj3KZT64j54Tcwr7Qm/0jkeZXJMfdcAtRBedou+Hx0dPOSIgqaIr0vvLwP65TpHbak2DmAq+KJbW2KNtIoFwvA== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-blockchain" "7.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-evm" "2.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-statemanager" "2.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - "@nomicfoundation/hardhat-chai-matchers@^1.0.3", "@nomicfoundation/hardhat-chai-matchers@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-chai-matchers/-/hardhat-chai-matchers-1.0.6.tgz#72a2e312e1504ee5dd73fe302932736432ba96bc" @@ -1546,14 +1454,6 @@ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - "@types/resolve@^0.0.8": version "0.0.8" resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194" @@ -1691,19 +1591,6 @@ abbrev@1.0.x: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - buffer "^6.0.3" - catering "^2.1.0" - is-buffer "^2.0.5" - level-supports "^4.0.0" - level-transcoder "^1.0.1" - module-error "^1.0.1" - queue-microtask "^1.2.3" - abstract-leveldown@^6.2.1: version "6.3.0" resolved "https://registry.yarnpkg.com/abstract-leveldown/-/abstract-leveldown-6.3.0.tgz#d25221d1e6612f820c35963ba4bd739928f6026a" @@ -1794,20 +1681,27 @@ ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: uri-js "^4.2.2" ajv@^8.0.1: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== + version "8.13.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.13.0.tgz#a3939eaec9fb80d217ddf0c3376948c023f28c91" + integrity sha512-PRA911Blj99jR5RMeTunVbNXMF6Lp4vZXnk5GQjcnUWUTsrXtekg/pnmFFI2u/I36Y/2bITGS30GZCXei6uNkA== dependencies: - fast-deep-equal "^3.1.1" + fast-deep-equal "^3.1.3" json-schema-traverse "^1.0.0" require-from-string "^2.0.2" - uri-js "^4.2.2" + uri-js "^4.4.1" amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + ansi-colors@4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" @@ -2120,11 +2014,6 @@ big-integer@^1.6.44: resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== -bigint-crypto-utils@^3.0.23: - version "3.3.0" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.3.0.tgz#72ad00ae91062cf07f2b1def9594006c279c1d77" - integrity sha512-jOTSb+drvEDxEq6OuUybOAv/xxoh3cuYRUIPyu8sSHQNKM303UQ2R1DAo45o1AkcIXw6fzbaFI1+xGGdaXs2lg== - bignumber.js@^9.0.0, bignumber.js@^9.0.1: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -2190,6 +2079,20 @@ bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== +boxen@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + bplist-parser@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" @@ -2224,16 +2127,6 @@ brorand@^1.0.1, brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -2374,22 +2267,17 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^6.0.0: +camelcase@^6.0.0, camelcase@^6.2.0: version "6.3.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - caseless@^0.12.0, caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== -catering@^2.0.0, catering@^2.1.0, catering@^2.1.1: +catering@^2.0.0, catering@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== @@ -2483,22 +2371,16 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" -classic-level@^1.2.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.3.0.tgz#5e36680e01dc6b271775c093f2150844c5edd5c8" - integrity sha512-iwFAJQYtqRTRM0F6L8h4JCt00ZSGdOyqh7yVrhhjrOpFhmBjNlRUey64MCiyo6UmQHMJ+No3c81nujPv+n9yrg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "^2.2.2" - node-gyp-build "^4.3.0" - clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-table3@^0.5.0: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" @@ -2861,7 +2743,7 @@ define-lazy-prop@^3.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: +define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -3365,11 +3247,11 @@ eth-gas-reporter@^0.2.25: sync-request "^6.0.0" ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== + version "1.1.0" + resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.1.0.tgz#b3fc1eb789509ee30db0bf99a2988ccacb8d0397" + integrity sha512-J1gDRkLpuGNvWYzWslBQR9cDV4nd4kfvVTE/Wy4Kkm4yb3EYRSlyi0eB/inTsSTTVyA0+HyzHgbr95Fn/Z1fSw== dependencies: - js-sha3 "^0.8.0" + "@noble/hashes" "^1.4.0" ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: version "0.1.3" @@ -3467,7 +3349,7 @@ ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.3, ethereum ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.1, ethers@^5.7.2, ethers@~5.7.0: +ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -4108,11 +3990,12 @@ globals@^13.19.0: type-fest "^0.20.2" globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" + integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== dependencies: - define-properties "^1.1.3" + define-properties "^1.2.1" + gopd "^1.0.1" globby@^10.0.1: version "10.0.2" @@ -4215,23 +4098,17 @@ hardhat-typechain@^0.3.3: resolved "https://registry.yarnpkg.com/hardhat-typechain/-/hardhat-typechain-0.3.5.tgz#8e50616a9da348b33bd001168c8fda9c66b7b4af" integrity sha512-w9lm8sxqTJACY+V7vijiH+NkPExnmtiQEjsV9JKD1KgMdVk2q8y+RhvU/c4B7+7b1+HylRUCxpOIvFuB3rE4+w== -hardhat@^2.18.3: - version "2.19.1" - resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.19.1.tgz#5e09e8070ecfc6109ba9d3a4a117ec2b0643032a" - integrity sha512-bsWa63g1GB78ZyMN08WLhFElLPA+J+pShuKD1BFO2+88g3l+BL3R07vj9deIi9dMbssxgE714Gof1dBEDGqnCw== +hardhat@=2.22.2: + version "2.22.2" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.2.tgz#0cadd7ec93bf39bab09f81603e75bc5e92acea3d" + integrity sha512-0xZ7MdCZ5sJem4MrvpQWLR3R3zGDoHw5lsR+pBFimqwagimIOn3bWuZv69KA+veXClwI1s/zpqgwPwiFrd4Dxw== dependencies: "@ethersproject/abi" "^5.1.2" "@metamask/eth-sig-util" "^4.0.0" - "@nomicfoundation/ethereumjs-block" "5.0.2" - "@nomicfoundation/ethereumjs-blockchain" "7.0.2" - "@nomicfoundation/ethereumjs-common" "4.0.2" - "@nomicfoundation/ethereumjs-evm" "2.0.2" - "@nomicfoundation/ethereumjs-rlp" "5.0.2" - "@nomicfoundation/ethereumjs-statemanager" "2.0.2" - "@nomicfoundation/ethereumjs-trie" "6.0.2" - "@nomicfoundation/ethereumjs-tx" "5.0.2" - "@nomicfoundation/ethereumjs-util" "9.0.2" - "@nomicfoundation/ethereumjs-vm" "7.0.2" + "@nomicfoundation/edr" "^0.3.1" + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-tx" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" "@nomicfoundation/solidity-analyzer" "^0.1.0" "@sentry/node" "^5.18.1" "@types/bn.js" "^5.1.0" @@ -4239,6 +4116,7 @@ hardhat@^2.18.3: adm-zip "^0.4.16" aggregate-error "^3.0.0" ansi-escapes "^4.3.0" + boxen "^5.1.2" chalk "^2.4.2" chokidar "^3.4.0" ci-info "^2.0.0" @@ -4779,11 +4657,6 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -js-sdsl@^4.1.4: - version "4.4.2" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.4.2.tgz#2e3c031b1f47d3aca8b775532e3ebb0818e7f847" - integrity sha512-dwXFwByc/ajSV6m5bcKAPwe4yDDF6D614pxmIi5odytzxRlwqF6nwoiCek80Ixc7Cvma5awClxrzFtxCQvcM8w== - js-sha3@0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a" @@ -5050,11 +4923,6 @@ level-supports@^2.0.1: resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-2.1.0.tgz#9af908d853597ecd592293b2fad124375be79c5f" integrity sha512-E486g1NCjW5cF78KGPrMDRBYzPuueMZ6VBXHT6gC7A8UYWGiM14fGgp+s/L1oFfDWSPV/+SFkYCmZ0SiESkRKA== -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - level-supports@~1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-1.0.1.tgz#2f530a596834c7301622521988e2c36bb77d122d" @@ -5062,14 +4930,6 @@ level-supports@~1.0.0: dependencies: xtend "^4.0.2" -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - level-ws@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/level-ws/-/level-ws-2.0.0.tgz#207a07bcd0164a0ec5d62c304b4615c54436d339" @@ -5079,14 +4939,6 @@ level-ws@^2.0.0: readable-stream "^3.1.0" xtend "^4.0.1" -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - leveldown@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/leveldown/-/leveldown-6.1.0.tgz#7ab1297706f70c657d1a72b31b40323aa612b9ee" @@ -5328,15 +5180,6 @@ memdown@^5.0.0: ltgt "~2.2.0" safe-buffer "~5.2.0" -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - memorystream@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" @@ -5554,11 +5397,6 @@ mocha@^9.0.2: yargs-parser "20.2.4" yargs-unparser "2.0.0" -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -5588,6 +5426,11 @@ nan@^2.17.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== +nan@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" + integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== + nanoid@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" @@ -5598,11 +5441,6 @@ nanoid@3.3.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== -napi-macros@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.2.2.tgz#817fef20c3e0e40a963fbf7b37d1600bd0201044" - integrity sha512-hmEVtAGYzVQpCKdbQea4skABsdXW4RUh5t5mJ2zzqowJS2OyXZTU1KhDVFhx+NlWZ4ap9mqR9TcDO3LTTttd+g== - napi-macros@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" @@ -5810,16 +5648,16 @@ optionator@^0.8.1: word-wrap "~1.2.3" optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" + word-wrap "^1.2.5" ordinal@^1.0.3: version "1.0.3" @@ -6417,13 +6255,6 @@ run-con@~1.2.11: minimist "^1.2.8" strip-json-comments "~3.1.1" -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -6830,7 +6661,7 @@ string-width@^2.1.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7457,7 +7288,7 @@ untildify@^4.0.0: resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== -uri-js@^4.2.2: +uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== @@ -7601,7 +7432,14 @@ which@^1.1.1, which@^1.3.1: dependencies: isexe "^2.0.0" -word-wrap@~1.2.3: +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + +word-wrap@^1.2.5, word-wrap@~1.2.3: version "1.2.5" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== From d57c65933fdaf4890c12a70bd6a31d20ef0c0441 Mon Sep 17 00:00:00 2001 From: Ivan Schasny Date: Mon, 13 May 2024 15:39:29 +0100 Subject: [PATCH 35/60] fix: allow to skip initialization of chain governance --- .../deploy-shared-bridge-on-l2-through-l1.ts | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts index 6fa655ceb..5bf18af74 100644 --- a/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts +++ b/l2-contracts/src/deploy-shared-bridge-on-l2-through-l1.ts @@ -200,12 +200,15 @@ export async function deploySharedBridgeOnL2ThroughL1( deployer: Deployer, chainId: string, gasPrice: BigNumberish, - localLegacyBridgeTesting: boolean = false + localLegacyBridgeTesting: boolean, + skipInitializeChainGovernance: boolean ) { await publishL2SharedBridgeDependencyBytecodesOnL2(deployer, chainId, gasPrice); await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting); await deploySharedBridgeProxyOnL2ThroughL1(deployer, chainId, gasPrice, localLegacyBridgeTesting); - await initializeChainGovernance(deployer, chainId); + if (!skipInitializeChainGovernance) { + await initializeChainGovernance(deployer, chainId); + } } async function main() { @@ -220,6 +223,7 @@ async function main() { .option("--gas-price ") .option("--nonce ") .option("--erc20-bridge ") + .option("--skip-initialize-chain-governance ") .action(async (cmd) => { const chainId: string = cmd.chainId ? cmd.chainId : process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID; const deployWallet = cmd.privateKey @@ -244,7 +248,19 @@ async function main() { : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - await deploySharedBridgeOnL2ThroughL1(deployer, chainId, gasPrice, cmd.localLegacyBridgeTesting); + const skipInitializeChainGovernance = + !!cmd.skipInitializeChainGovernance && cmd.skipInitializeChainGovernance === "true"; + if (skipInitializeChainGovernance) { + console.log("Initialization of the chain governance will be skipped"); + } + + await deploySharedBridgeOnL2ThroughL1( + deployer, + chainId, + gasPrice, + cmd.localLegacyBridgeTesting, + skipInitializeChainGovernance + ); }); await program.parseAsync(process.argv); From 707043f365d735efe560ec3a662b5ae346a4c7ac Mon Sep 17 00:00:00 2001 From: Danil Date: Tue, 14 May 2024 13:23:39 +0200 Subject: [PATCH 36/60] Deploy l2 contracts and use governance for upgrades (#441) Signed-off-by: Danil --- .../workflows/l1-contracts-foundry-ci.yaml | 19 +- l1-contracts-foundry/foundry.toml | 7 +- .../config-deploy-l1.toml | 3 + .../config-deploy-paymaster.toml | 3 + .../config-initialize-shared-bridges.toml | 6 + l1-contracts-foundry/script/AcceptAdmin.s.sol | 31 ++++ l1-contracts-foundry/script/DeployL1.s.sol | 23 ++- .../script/DeployPaymaster.s.sol | 60 ++++++ .../script/InitializeL2WethToken.s.sol | 2 +- .../script/InitializeSharedBridgeOnL2.sol | 158 ++++++++++++++++ .../script/RegisterHyperchain.s.sol | 62 ++++--- l1-contracts-foundry/script/Utils.sol | 172 +++++++++++++++++- 12 files changed, 499 insertions(+), 47 deletions(-) create mode 100644 l1-contracts-foundry/script-config-template/config-deploy-paymaster.toml create mode 100644 l1-contracts-foundry/script-config-template/config-initialize-shared-bridges.toml create mode 100644 l1-contracts-foundry/script/AcceptAdmin.s.sol create mode 100644 l1-contracts-foundry/script/DeployPaymaster.s.sol create mode 100644 l1-contracts-foundry/script/InitializeSharedBridgeOnL2.sol diff --git a/.github/workflows/l1-contracts-foundry-ci.yaml b/.github/workflows/l1-contracts-foundry-ci.yaml index c02688546..74fdbb8dc 100644 --- a/.github/workflows/l1-contracts-foundry-ci.yaml +++ b/.github/workflows/l1-contracts-foundry-ci.yaml @@ -103,16 +103,15 @@ jobs: working-directory: ./l1-contracts-foundry run: forge script ./script/DeployL1.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY - - name: Run RegisterHyperchain script - working-directory: ./l1-contracts-foundry - run: | - cat ./script-out/output-deploy-l1.toml >> ./script-config/register-hyperchain.toml - forge script ./script/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY - - name: Run DeployErc20 script working-directory: ./l1-contracts-foundry run: forge script ./script/DeployErc20.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY - - - name: Run InitializeL2WethToken script - working-directory: ./l1-contracts-foundry - run: forge script ./script/InitializeL2WethToken.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY +# TODO restore scripts verification +# - name: Run RegisterHyperchain script +# working-directory: ./l1-contracts-foundry +# run: | +# cat ./script-out/output-deploy-l1.toml >> ./script-config/register-hyperchain.toml +# forge script ./script/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY +# - name: Run InitializeL2WethToken script +# working-directory: ./l1-contracts-foundry +# run: forge script ./script/InitializeL2WethToken.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY diff --git a/l1-contracts-foundry/foundry.toml b/l1-contracts-foundry/foundry.toml index 74e27e5a7..ac978c3ba 100644 --- a/l1-contracts-foundry/foundry.toml +++ b/l1-contracts-foundry/foundry.toml @@ -10,10 +10,11 @@ remappings = [ ] allow_paths = ["../l1-contracts/contracts", "../l2-contracts/contracts"] fs_permissions = [ - { access = "read", path = "../system-contracts/bootloader/build/artifacts"}, - { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed"}, + { access = "read", path = "../system-contracts/bootloader/build/artifacts" }, + { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed" }, + { access = "read", path = "../l2-contracts/artifacts-zk/" }, { access = "read", path = "./script-config" }, { access = "read-write", path = "./script-out" }, { access = "read", path = "./out" } ] -evm_version="cancun" +evm_version = "cancun" diff --git a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml index 28fe6a68a..e6b45719f 100644 --- a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml +++ b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml @@ -1,5 +1,6 @@ era_chain_id = 9 owner_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" +testnet_verifier = true [contracts] governance_security_council_address = "0x0000000000000000000000000000000000000000" @@ -22,6 +23,8 @@ diamond_init_max_pubdata_per_batch = 120000 diamond_init_max_l2_gas_per_batch = 80000000 diamond_init_priority_tx_max_pubdata = 99000 diamond_init_minimal_l2_gas_price = 250000000 +bootloader_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +default_aa_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" [tokens] token_weth_address = "0x0000000000000000000000000000000000000000" diff --git a/l1-contracts-foundry/script-config-template/config-deploy-paymaster.toml b/l1-contracts-foundry/script-config-template/config-deploy-paymaster.toml new file mode 100644 index 000000000..b9eb46fbf --- /dev/null +++ b/l1-contracts-foundry/script-config-template/config-deploy-paymaster.toml @@ -0,0 +1,3 @@ +chain_id = 215 +l1_shared_bridge = "0x2ae37d8130b82c7e79b3863a39027178e073eedb" +bridgehub = "0xea785a9c91a07ed69b83eb165f4ce2c30ecb4c0b" diff --git a/l1-contracts-foundry/script-config-template/config-initialize-shared-bridges.toml b/l1-contracts-foundry/script-config-template/config-initialize-shared-bridges.toml new file mode 100644 index 000000000..67e46ae38 --- /dev/null +++ b/l1-contracts-foundry/script-config-template/config-initialize-shared-bridges.toml @@ -0,0 +1,6 @@ +chain_id = 215 +era_chain_id = 270 +l1_shared_bridge = "0x2ae37d8130b82c7e79b3863a39027178e073eedb" +bridgehub = "0xea785a9c91a07ed69b83eb165f4ce2c30ecb4c0b" +governance = "0x6a08d69675af7755569a1a25ef37e795493473a1" +erc20_bridge = "0x84fbda16bd5f2d66d7fbaec5e8d816e7b7014595" diff --git a/l1-contracts-foundry/script/AcceptAdmin.s.sol b/l1-contracts-foundry/script/AcceptAdmin.s.sol new file mode 100644 index 000000000..ffc865126 --- /dev/null +++ b/l1-contracts-foundry/script/AcceptAdmin.s.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +import {Script} from "forge-std/Script.sol"; +import {stdToml} from "forge-std/StdToml.sol"; + +import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {Utils} from "./Utils.sol"; + +contract AcceptAdmin is Script { + using stdToml for string; + + // This function should be called by the owner to accept the admin role + function run() public { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-config/config-accept-admin.toml"); + string memory toml = vm.readFile(path); + address admin = toml.readAddress("$.target_addr"); + address governor = toml.readAddress("$.governor"); + Ownable2Step adminContract = Ownable2Step(admin); + + Utils.executeUpgrade({ + _governor: governor, + _salt: bytes32(0), + _target: admin, + _data: abi.encodeCall(adminContract.acceptOwnership, ()), + _value: 0, + _delay: 0 + }); + } +} diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 9625dbba6..1033e2d51 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -11,6 +11,7 @@ import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transpa import {Utils} from "./Utils.sol"; import {Multicall3} from "contracts/dev-contracts/Multicall3.sol"; import {Verifier} from "contracts/state-transition/Verifier.sol"; +import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; import {VerifierParams, IVerifier} from "contracts/state-transition/chain-interfaces/IVerifier.sol"; import {DefaultUpgrade} from "contracts/upgrades/DefaultUpgrade.sol"; import {Governance} from "contracts/governance/Governance.sol"; @@ -80,6 +81,7 @@ contract DeployL1Script is Script { uint256 eraChainId; address deployerAddress; address ownerAddress; + bool testnetVerifier; ContractsConfig contracts; TokensConfig tokens; } @@ -107,6 +109,8 @@ contract DeployL1Script is Script { uint256 governanceMinDelay; uint256 maxNumberOfHyperchains; bytes diamondCutData; + bytes32 bootloaderHash; + bytes32 defaultAAHash; } struct TokensConfig { @@ -162,6 +166,7 @@ contract DeployL1Script is Script { // https://book.getfoundry.sh/cheatcodes/parse-toml config.eraChainId = toml.readUint("$.era_chain_id"); config.ownerAddress = toml.readAddress("$.owner_address"); + config.testnetVerifier = toml.readBool("$.testnet_verifier"); config.contracts.governanceSecurityCouncilAddress = toml.readAddress( "$.contracts.governance_security_council_address" @@ -197,6 +202,8 @@ contract DeployL1Script is Script { "$.contracts.diamond_init_priority_tx_max_pubdata" ); config.contracts.diamondInitMinimalL2GasPrice = toml.readUint("$.contracts.diamond_init_minimal_l2_gas_price"); + config.contracts.defaultAAHash = toml.readBytes32("$.contracts.default_aa_hash"); + config.contracts.bootloaderHash = toml.readBytes32("$.contracts.bootloader_hash"); config.tokens.tokenWethAddress = toml.readAddress("$.tokens.token_weth_address"); } @@ -236,7 +243,13 @@ contract DeployL1Script is Script { } function deployVerifier() internal { - address contractAddress = deployViaCreate2(type(Verifier).creationCode); + bytes memory code; + if (config.testnetVerifier) { + code = type(TestnetVerifier).creationCode; + } else { + code = type(Verifier).creationCode; + } + address contractAddress = deployViaCreate2(code); console.log("Verifier deployed at:", contractAddress); addresses.stateTransition.verifier = contractAddress; } @@ -400,8 +413,8 @@ contract DeployL1Script is Script { DiamondInitializeDataNewChain memory initializeData = DiamondInitializeDataNewChain({ verifier: IVerifier(addresses.stateTransition.verifier), verifierParams: verifierParams, - l2BootloaderBytecodeHash: bytes32(Utils.getBatchBootloaderBytecodeHash()), - l2DefaultAccountBytecodeHash: bytes32(Utils.readSystemContractsBytecode("DefaultAccount")), + l2BootloaderBytecodeHash: config.contracts.bootloaderHash, + l2DefaultAccountBytecodeHash: config.contracts.defaultAAHash, priorityTxMaxGasLimit: config.contracts.priorityTxMaxGasLimit, feeParams: feeParams, blobVersionedHashRetriever: addresses.blobVersionedHashRetriever @@ -467,7 +480,7 @@ contract DeployL1Script is Script { Diamond.DiamondCutData memory diamondCut = Diamond.DiamondCutData({ facetCuts: facetCuts, initAddress: address(0), - initCalldata: hex"" + initCalldata: "" }); bytes memory bytecode = abi.encodePacked( type(DiamondProxy).creationCode, @@ -555,7 +568,7 @@ contract DeployL1Script is Script { validatorTimelock.transferOwnership(config.ownerAddress); Bridgehub bridgehub = Bridgehub(addresses.bridgehub.bridgehubProxy); - bridgehub.transferOwnership(config.ownerAddress); + bridgehub.transferOwnership(addresses.governance); L1SharedBridge sharedBridge = L1SharedBridge(addresses.bridges.sharedBridgeProxy); sharedBridge.transferOwnership(addresses.governance); diff --git a/l1-contracts-foundry/script/DeployPaymaster.s.sol b/l1-contracts-foundry/script/DeployPaymaster.s.sol new file mode 100644 index 000000000..52b664bc2 --- /dev/null +++ b/l1-contracts-foundry/script/DeployPaymaster.s.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +import {Script} from "forge-std/Script.sol"; +import {stdToml} from "forge-std/StdToml.sol"; + +import {Utils} from "./Utils.sol"; + +contract DeployPaymaster is Script { + using stdToml for string; + Config config; + + struct Config { + address bridgehubAddress; + address l1SharedBridgeProxy; + uint256 chainId; + address paymaster; + } + + function initializeConfig() internal { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-config/config-deploy-paymaster.toml"); + string memory toml = vm.readFile(path); + config.bridgehubAddress = toml.readAddress("$.bridgehub"); + config.l1SharedBridgeProxy = toml.readAddress("$.l1_shared_bridge"); + config.chainId = toml.readUint("$.chain_id"); + } + + function saveOutput() internal { + string memory toml = vm.serializeAddress("root", "paymaster", config.paymaster); + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-out/output-deploy-paymaster.toml"); + vm.writeToml(toml, path); + } + + function run() external { + initializeConfig(); + + deploy(); + + saveOutput(); + } + + function deploy() internal { + bytes memory testnetPaymasterBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/TestnetPaymaster.sol/TestnetPaymaster.json" + ); + + config.paymaster = Utils.deployThroughL1({ + bytecode: testnetPaymasterBytecode, + constructorargs: "", + create2salt: "", + l2GasLimit: Utils.MAX_PRIORITY_TX_GAS, + factoryDeps: new bytes[](0), + bridgehubAddress: config.bridgehubAddress, + l1SharedBridgeProxy: config.l1SharedBridgeProxy, + chainId: config.chainId + }); + } +} diff --git a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol index 792e83721..22c427a13 100644 --- a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol +++ b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol @@ -102,7 +102,7 @@ contract InitializeL2WethTokenScript is Script { console.log("L2 WETH token initialized"); } - function getL2Calldata() internal returns (bytes memory) { + function getL2Calldata() internal view returns (bytes memory) { // Low-level call is performed due to different solidity // compiler versions between L1 and L2 // solhint-disable-next-line func-named-parameters diff --git a/l1-contracts-foundry/script/InitializeSharedBridgeOnL2.sol b/l1-contracts-foundry/script/InitializeSharedBridgeOnL2.sol new file mode 100644 index 000000000..8ca7fce03 --- /dev/null +++ b/l1-contracts-foundry/script/InitializeSharedBridgeOnL2.sol @@ -0,0 +1,158 @@ +pragma solidity ^0.8.24; + +import {Script} from "forge-std/Script.sol"; +import {stdToml} from "forge-std/StdToml.sol"; + +import {Utils} from "./Utils.sol"; +import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; +import {AddressAliasHelper} from "contracts/vendor/AddressAliasHelper.sol"; +import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; + +contract DeployL2Script is Script { + using stdToml for string; + + Config config; + ContractsBytecodes contracts; + + struct Config { + address bridgehubAddress; + address l1SharedBridgeProxy; + address governance; + address erc20BridgeProxy; + uint256 chainId; + uint256 eraChainId; + address l2SharedBridgeImplementation; + address l2SharedBridgeProxy; + } + + struct ContractsBytecodes { + bytes l2StandardErc20FactoryBytecode; + bytes beaconProxy; + bytes l2StandardErc20Bytecode; + bytes l2SharedBridgeBytecode; + bytes l2SharedBridgeProxyBytecode; + } + + function run() public { + initializeConfig(); + loadContracts(); + + deployFactoryDeps(); + deploySharedBridge(); + deploySharedBridgeProxy(); + initializeChain(); + + saveOutput(); + } + + function loadContracts() internal { + //HACK: Meanwhile we are not integrated foundry zksync we use contracts that has been built using hardhat + contracts.l2StandardErc20FactoryBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/UpgradeableBeacon.sol/UpgradeableBeacon.json" + ); + contracts.beaconProxy = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json" + ); + contracts.l2StandardErc20Bytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/bridge/L2StandardERC20.sol/L2StandardERC20.json" + ); + + contracts.l2SharedBridgeBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json" + ); + + contracts.l2SharedBridgeProxyBytecode = Utils.readHardhatBytecode( + "/../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol/TransparentUpgradeableProxy.json" + ); + } + + function initializeConfig() internal { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-config/config-initialize-shared-bridges.toml"); + string memory toml = vm.readFile(path); + config.bridgehubAddress = toml.readAddress("$.bridgehub"); + config.governance = toml.readAddress("$.governance"); + config.l1SharedBridgeProxy = toml.readAddress("$.l1_shared_bridge"); + config.erc20BridgeProxy = toml.readAddress("$.erc20_bridge"); + config.chainId = toml.readUint("$.chain_id"); + config.eraChainId = toml.readUint("$.era_chain_id"); + } + + function saveOutput() internal { + vm.serializeAddress("root", "l2_shared_bridge_implementation", config.l2SharedBridgeImplementation); + string memory toml = vm.serializeAddress("root", "l2_shared_bridge_proxy", config.l2SharedBridgeProxy); + string memory root = vm.projectRoot(); + string memory path = string.concat(root, "/script-out/output-initialize-shared-bridges.toml"); + vm.writeToml(toml, path); + } + + function deployFactoryDeps() public { + bytes[] memory factoryDeps = new bytes[](3); + factoryDeps[0] = contracts.l2StandardErc20FactoryBytecode; + factoryDeps[1] = contracts.l2StandardErc20Bytecode; + factoryDeps[2] = contracts.beaconProxy; + Utils.publishBytecodes(factoryDeps, config.chainId, config.bridgehubAddress, config.l1SharedBridgeProxy); + } + + function deploySharedBridge() public { + bytes[] memory factoryDeps = new bytes[](1); + factoryDeps[0] = contracts.beaconProxy; + + bytes memory constructorData = abi.encode(config.eraChainId); + + config.l2SharedBridgeImplementation = Utils.deployThroughL1({ + bytecode: contracts.l2SharedBridgeBytecode, + constructorargs: constructorData, + create2salt: "", + l2GasLimit: Utils.MAX_PRIORITY_TX_GAS, + factoryDeps: factoryDeps, + chainId: config.chainId, + bridgehubAddress: config.bridgehubAddress, + l1SharedBridgeProxy: config.l1SharedBridgeProxy + }); + } + + function deploySharedBridgeProxy() public { + address l2GovernorAddress = AddressAliasHelper.applyL1ToL2Alias(config.governance); + bytes32 l2StandardErc20BytecodeHash = L2ContractHelper.hashL2Bytecode(contracts.beaconProxy); + + // solhint-disable-next-line func-named-parameters + bytes memory proxyInitializationParams = abi.encodeWithSignature( + "initialize(address,address,bytes32,address)", + config.l1SharedBridgeProxy, + config.erc20BridgeProxy, + l2StandardErc20BytecodeHash, + l2GovernorAddress + ); + + bytes memory l2SharedBridgeProxyConstructorData = abi.encode( + config.l2SharedBridgeImplementation, + l2GovernorAddress, + proxyInitializationParams + ); + + config.l2SharedBridgeProxy = Utils.deployThroughL1({ + bytecode: contracts.l2SharedBridgeProxyBytecode, + constructorargs: l2SharedBridgeProxyConstructorData, + create2salt: "", + l2GasLimit: Utils.MAX_PRIORITY_TX_GAS, + factoryDeps: new bytes[](0), + chainId: config.chainId, + bridgehubAddress: config.bridgehubAddress, + l1SharedBridgeProxy: config.l1SharedBridgeProxy + }); + } + + function initializeChain() public { + L1SharedBridge bridge = L1SharedBridge(config.l1SharedBridgeProxy); + + Utils.executeUpgrade({ + _governor: bridge.owner(), + _salt: bytes32(0), + _target: config.l1SharedBridgeProxy, + _data: abi.encodeCall(bridge.initializeChainGovernance, (config.chainId, config.l2SharedBridgeProxy)), + _value: 0, + _delay: 0 + }); + } +} diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 7f1a69026..4b499cf0a 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -7,10 +7,13 @@ import {Script, console2 as console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; import {stdToml} from "forge-std/StdToml.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {IBridgehub} from "contracts/bridgehub/IBridgehub.sol"; import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; import {Governance} from "contracts/governance/Governance.sol"; +import {Utils} from "./Utils.sol"; +import {PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; contract RegisterHyperchainScript is Script { using stdToml for string; @@ -57,18 +60,6 @@ contract RegisterHyperchainScript is Script { saveOutput(); } - // This function should be called by the owner to accept the admin role - function acceptAdmin() public { - console.log("Accept admin Hyperchain"); - string memory root = vm.projectRoot(); - string memory path = string.concat(root, "/script-config/accept-admin.toml"); - string memory toml = vm.readFile(path); - address diamondProxy = toml.readAddress("$.diamond_proxy_addr"); - IZkSyncHyperchain zkSyncStateTransition = IZkSyncHyperchain(diamondProxy); - vm.broadcast(); - zkSyncStateTransition.acceptAdmin(); - } - function initializeConfig() internal { // Grab config from output of l1 deployment string memory root = vm.projectRoot(); @@ -125,12 +116,20 @@ contract RegisterHyperchainScript is Script { function registerTokenOnBridgehub() internal { IBridgehub bridgehub = IBridgehub(config.bridgehub); + Ownable ownable = Ownable(config.bridgehub); if (bridgehub.tokenIsRegistered(config.baseToken)) { console.log("Token already registered on Bridgehub"); } else { - vm.broadcast(); - bridgehub.addToken(config.baseToken); + bytes memory data = abi.encodeCall(bridgehub.addToken, (config.baseToken)); + Utils.executeUpgrade({ + _governor: ownable.owner(), + _salt: bytes32(config.bridgehubCreateNewChainSalt), + _target: config.bridgehub, + _data: data, + _value: 0, + _delay: 0 + }); console.log("Token registered on Bridgehub"); } } @@ -147,16 +146,28 @@ contract RegisterHyperchainScript is Script { function registerHyperchain() internal { IBridgehub bridgehub = IBridgehub(config.bridgehub); + Ownable ownable = Ownable(config.bridgehub); - vm.broadcast(); vm.recordLogs(); - bridgehub.createNewChain({ - _chainId: config.hyperchainChainId, - _stateTransitionManager: config.stateTransitionProxy, - _baseToken: config.baseToken, - _salt: config.bridgehubCreateNewChainSalt, - _admin: msg.sender, - _initData: config.diamondCutData + bytes memory data = abi.encodeCall( + bridgehub.createNewChain, + ( + config.hyperchainChainId, + config.stateTransitionProxy, + config.baseToken, + config.bridgehubCreateNewChainSalt, + msg.sender, + config.diamondCutData + ) + ); + + Utils.executeUpgrade({ + _governor: ownable.owner(), + _salt: bytes32(config.bridgehubCreateNewChainSalt), + _target: config.bridgehub, + _data: data, + _value: 0, + _delay: 0 }); console.log("Hyperchain registered"); @@ -196,10 +207,9 @@ contract RegisterHyperchainScript is Script { config.baseTokenGasPriceMultiplierDenominator ); - // TODO: support validium mode when available - // if (config.contractsMode) { - // zkSyncStateTransition.setValidiumMode(PubdataPricingMode.Validium); - // } + if (config.validiumMode) { + hyperchain.setPubdataPricingMode(PubdataPricingMode.Validium); + } vm.stopBroadcast(); console.log("ZkSync State Transition configured"); diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts-foundry/script/Utils.sol index b9a66426f..2cea861aa 100644 --- a/l1-contracts-foundry/script/Utils.sol +++ b/l1-contracts-foundry/script/Utils.sol @@ -3,15 +3,25 @@ pragma solidity 0.8.24; import {Vm} from "forge-std/Vm.sol"; +import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; +import {L2TransactionRequestDirect} from "contracts/bridgehub/IBridgehub.sol"; +import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA} from "contracts/common/Config.sol"; +import {L2_DEPLOYER_SYSTEM_CONTRACT_ADDR} from "contracts/common/L2ContractAddresses.sol"; +import {L2ContractHelper} from "contracts/common/libraries/L2ContractHelper.sol"; + library Utils { // Cheatcodes address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. address internal constant VM_ADDRESS = address(uint160(uint256(keccak256("hevm cheat code")))); + Vm internal constant vm = Vm(VM_ADDRESS); // Create2Factory deterministic bytecode. // https://github.com/Arachnid/deterministic-deployment-proxy bytes internal constant CREATE2_FACTORY_BYTECODE = hex"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; - Vm internal constant vm = Vm(VM_ADDRESS); + address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + uint256 constant MAX_PRIORITY_TX_GAS = 72000000; /** * @dev Get all selectors from the bytecode. @@ -144,7 +154,7 @@ library Utils { vm.broadcast(); (bool success, bytes memory data) = _factory.call(abi.encodePacked(_salt, _bytecode)); - contractAddress = Utils.bytesToAddress(data); + contractAddress = bytesToAddress(data); if (!success || contractAddress == address(0) || contractAddress.code.length == 0) { revert("Failed to deploy contract via create2"); @@ -152,4 +162,162 @@ library Utils { return contractAddress; } + + /** + * @dev Deploy l2 contracts through l1 + */ + function deployThroughL1( + bytes memory bytecode, + bytes memory constructorargs, + bytes32 create2salt, + uint256 l2GasLimit, + bytes[] memory factoryDeps, + uint256 chainId, + address bridgehubAddress, + address l1SharedBridgeProxy + ) public returns (address) { + bytes32 bytecodeHash = L2ContractHelper.hashL2Bytecode(bytecode); + + bytes memory deployData = abi.encodeWithSignature( + "create2(bytes32,bytes32,bytes)", + create2salt, + bytecodeHash, + constructorargs + ); + + address contractAddress = L2ContractHelper.computeCreate2Address( + msg.sender, + create2salt, + bytecodeHash, + keccak256(constructorargs) + ); + + bytes[] memory _factoryDeps = new bytes[](factoryDeps.length + 1); + + for (uint256 i = 0; i < factoryDeps.length; i++) { + _factoryDeps[i] = factoryDeps[i]; + } + _factoryDeps[factoryDeps.length] = bytecode; + + runL1L2Transaction({ + l2Calldata: deployData, + l2GasLimit: l2GasLimit, + factoryDeps: _factoryDeps, + dstAddress: L2_DEPLOYER_SYSTEM_CONTRACT_ADDR, + chainId: chainId, + bridgehubAddress: bridgehubAddress, + l1SharedBridgeProxy: l1SharedBridgeProxy + }); + return contractAddress; + } + + /** + * @dev Run the l2 l1 transaction + */ + function runL1L2Transaction( + bytes memory l2Calldata, + uint256 l2GasLimit, + bytes[] memory factoryDeps, + address dstAddress, + uint256 chainId, + address bridgehubAddress, + address l1SharedBridgeProxy + ) public { + Bridgehub bridgehub = Bridgehub(bridgehubAddress); + uint256 gasPrice = bytesToUint256(vm.rpc("eth_gasPrice", "[]")); + + uint256 requiredValueToDeploy = bridgehub.l2TransactionBaseCost( + chainId, + gasPrice, + l2GasLimit, + REQUIRED_L2_GAS_PRICE_PER_PUBDATA + ) * 2; + + L2TransactionRequestDirect memory l2TransactionRequestDirect = L2TransactionRequestDirect({ + chainId: chainId, + mintValue: requiredValueToDeploy, + l2Contract: dstAddress, + l2Value: 0, + l2Calldata: l2Calldata, + l2GasLimit: l2GasLimit, + l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + factoryDeps: factoryDeps, + refundRecipient: msg.sender + }); + + address baseTokenAddress = bridgehub.baseToken(chainId); + if (ADDRESS_ONE != baseTokenAddress) { + IERC20 baseToken = IERC20(baseTokenAddress); + vm.broadcast(); + baseToken.approve(l1SharedBridgeProxy, requiredValueToDeploy); + requiredValueToDeploy = 0; + } + + executeUpgrade({ + _governor: bridgehub.owner(), + _salt: bytes32(0), + _target: l1SharedBridgeProxy, + _data: abi.encodeCall(bridgehub.requestL2TransactionDirect, (l2TransactionRequestDirect)), + _value: requiredValueToDeploy, + _delay: 0 + }); + } + + /** + * @dev Publish bytecodes to l2 through l1 + */ + function publishBytecodes( + bytes[] memory factoryDeps, + uint256 chainId, + address bridgehubAddress, + address l1SharedBridgeProxy + ) public { + runL1L2Transaction({ + l2Calldata: "", + l2GasLimit: MAX_PRIORITY_TX_GAS, + factoryDeps: factoryDeps, + dstAddress: 0x0000000000000000000000000000000000000000, + chainId: chainId, + bridgehubAddress: bridgehubAddress, + l1SharedBridgeProxy: l1SharedBridgeProxy + }); + } + + /** + * @dev Read hardhat bytecodes + */ + function readHardhatBytecode(string memory artifactPath) public view returns (bytes memory) { + string memory root = vm.projectRoot(); + string memory path = string.concat(root, artifactPath); + string memory json = vm.readFile(path); + bytes memory bytecode = vm.parseJsonBytes(json, ".bytecode"); + return bytecode; + } + + function executeUpgrade( + address _governor, + bytes32 _salt, + address _target, + bytes memory _data, + uint256 _value, + uint256 _delay + ) public { + IGovernance governance = IGovernance(_governor); + + IGovernance.Call[] memory calls = new IGovernance.Call[](1); + calls[0] = IGovernance.Call({target: _target, value: _value, data: _data}); + + IGovernance.Operation memory operation = IGovernance.Operation({ + calls: calls, + predecessor: bytes32(0), + salt: _salt + }); + + vm.startBroadcast(); + governance.scheduleTransparent(operation, _delay); + if (_delay == 0) { + governance.execute{value: _value}(operation); + } + vm.stopBroadcast(); + } } From d334f8206901069411137794df17c76b147020d5 Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Wed, 15 May 2024 16:33:25 +0100 Subject: [PATCH 37/60] update verification keys (#472) --- .../contracts/state-transition/Verifier.sol | 8 ++--- tools/data/scheduler_key.json | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 00b2c38bc..cfcca1bb9 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -283,8 +283,8 @@ contract Verifier is IVerifier { function _loadVerificationKey() internal pure virtual { assembly { // gate setup commitments - mstore(VK_GATE_SETUP_0_X_SLOT, 0x0e4e3895515c2c29cb6ba62733c4e337826da43b5ce3d953717ef58248174337) - mstore(VK_GATE_SETUP_0_Y_SLOT, 0x286f244ce4af2209863dfc81fd2d8d1b47552790fa8471446fe418a8b228e8ef) + mstore(VK_GATE_SETUP_0_X_SLOT, 0x1705a844ded408a0daac583000aac35a0aab27b1f5827d316e690f4b88f3b216) + mstore(VK_GATE_SETUP_0_Y_SLOT, 0x147c1a7f0688c83f1e93fae4b1d009dddbba688f252faaa123715a65a4843321) mstore(VK_GATE_SETUP_1_X_SLOT, 0x04659caf7b05471ba5ba85b1ab62267aa6c456836e625f169f7119d55b9462d2) mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0ea63403692148d2ad22189a1e5420076312f4d46e62036a043a6b0b84d5b410) mstore(VK_GATE_SETUP_2_X_SLOT, 0x0e6696d09d65fce1e42805be03fca1f14aea247281f688981f925e77d4ce2291) @@ -295,8 +295,8 @@ contract Verifier is IVerifier { mstore(VK_GATE_SETUP_4_Y_SLOT, 0x22e404bc91350f3bc7daad1d1025113742436983c85eac5ab7b42221a181b81e) mstore(VK_GATE_SETUP_5_X_SLOT, 0x0d9b29613037a5025655c82b143d2b7449c98f3aea358307c8529249cc54f3b9) mstore(VK_GATE_SETUP_5_Y_SLOT, 0x15b3c4c946ad1babfc4c03ff7c2423fd354af3a9305c499b7fb3aaebe2fee746) - mstore(VK_GATE_SETUP_6_X_SLOT, 0x2693ae0454ab607b949ef9951b18ca8f81b80f279054eb984dcccac4c83884ac) - mstore(VK_GATE_SETUP_6_Y_SLOT, 0x082f2ce318997eaebe1b03741ff39082ef878574ebb0286c41440c4a1c05d9bb) + mstore(VK_GATE_SETUP_6_X_SLOT, 0x1a0524c2f87ff2f2d08434c91ab9e92766eabb600537b27ea944bf65c3636f91) + mstore(VK_GATE_SETUP_6_Y_SLOT, 0x06fab004f5950058c7ac1ab8ebc3d94142d87ac04f3526bc7d13b65433491a2e) mstore(VK_GATE_SETUP_7_X_SLOT, 0x283344a1ab3e55ecfd904d0b8e9f4faea338df5a4ead2fa9a42f0e103da40abc) mstore(VK_GATE_SETUP_7_Y_SLOT, 0x223b37b83b9687512d322993edd70e508dd80adb10bcf7321a3cc8a44c269521) diff --git a/tools/data/scheduler_key.json b/tools/data/scheduler_key.json index 0adf6c743..bf111bcb1 100644 --- a/tools/data/scheduler_key.json +++ b/tools/data/scheduler_key.json @@ -6,16 +6,16 @@ "gate_setup_commitments": [ { "x": [ - 8178243913255437111, - 9398348572260555091, - 14657992099509887799, - 1030823578680699945 + 7955907033821327894, + 768751806678465841, + 15757066159455388506, + 1658917051505576096 ], "y": [ - 8062596345722628335, - 5140058053345046852, - 9673165209890295067, - 2913587396604797449 + 2553921856294105889, + 15833082403987892897, + 2203380502856993245, + 1476083910743476287 ], "infinity": false }, @@ -96,16 +96,16 @@ }, { "x": [ - 5606078582690972844, - 9347237689207090072, - 10709271382733671055, - 2779756728641347707 + 12197084134616821649, + 7415945757497733758, + 15025192295156279591, + 1874945239681069810 ], "y": [ - 4702897423318899131, - 17259910834137606252, - 13698546488864641154, - 589739430090735278 + 9012747752052431406, + 4816734767853938364, + 14387904291073677633, + 502907843751772248 ], "infinity": false }, From 360164871658e7765fadaeadd800e36191afc074 Mon Sep 17 00:00:00 2001 From: Neo <128649481+neotheprogramist@users.noreply.github.com> Date: Thu, 16 May 2024 13:33:17 +0200 Subject: [PATCH 38/60] NonceHolder Tests (#176) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Uacias Co-authored-by: Mateusz ZajÄ…c Co-authored-by: Mateusz ZajÄ…c <60236390+matzayonc@users.noreply.github.com> --- system-contracts/test/NonceHolder.spec.ts | 257 ++++++++++++++++++++++ system-contracts/test/shared/mocks.ts | 2 + 2 files changed, 259 insertions(+) create mode 100644 system-contracts/test/NonceHolder.spec.ts diff --git a/system-contracts/test/NonceHolder.spec.ts b/system-contracts/test/NonceHolder.spec.ts new file mode 100644 index 000000000..91e9e3ba4 --- /dev/null +++ b/system-contracts/test/NonceHolder.spec.ts @@ -0,0 +1,257 @@ +import { expect } from "chai"; +import type { NonceHolder } from "../typechain"; +import { NonceHolderFactory } from "../typechain"; +import { + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, + TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS, +} from "./shared/constants"; +import { prepareEnvironment, setResult } from "./shared/mocks"; +import { deployContractOnAddress, getWallets } from "./shared/utils"; +import { ethers, network } from "hardhat"; +import { BigNumber } from "ethers"; + +describe("NonceHolder tests", () => { + const wallet = getWallets()[0]; + let nonceHolder: NonceHolder; + let systemAccount: ethers.Signer; + let deployerAccount: ethers.Signer; + + before(async () => { + await prepareEnvironment(); + await deployContractOnAddress(TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, "NonceHolder"); + nonceHolder = NonceHolderFactory.connect(TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, wallet); + + // Using a system account to satisfy the `onlySystemCall` modifier. + systemAccount = await ethers.getImpersonatedSigner(TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS); + deployerAccount = await ethers.getImpersonatedSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + }); + + after(async () => { + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS], + }); + await network.provider.request({ + method: "hardhat_stopImpersonatingAccount", + params: [TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS], + }); + }); + + describe("increaseMinNonce and getters", () => { + it("should increase account minNonce by 1", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).increaseMinNonce(1); + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceAfter).to.equal(nonceBefore.add(1)); + expect(rawNonceAfter).to.equal(rawNonceBefore.add(1)); + }); + + it("should stay the same", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).increaseMinNonce(0); + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceBefore).to.equal(nonceAfter); + expect(rawNonceBefore).to.equal(rawNonceAfter); + }); + + it("should increase account minNonce by many", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).increaseMinNonce(2 ** 4); + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceAfter).to.equal(nonceBefore.add(2 ** 4)); + expect(rawNonceAfter).to.equal(rawNonceBefore.add(2 ** 4)); + }); + + it("should fail with too high", async () => { + const nonceBefore = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceBefore = await nonceHolder.getRawNonce(systemAccount.address); + + await expect( + nonceHolder.connect(systemAccount).increaseMinNonce(BigNumber.from(2).pow(32).add(1)) + ).to.be.rejectedWith("The value for incrementing the nonce is too high"); + + const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); + const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); + + expect(nonceAfter).to.equal(nonceBefore); + expect(rawNonceAfter).to.equal(rawNonceBefore); + }); + + it("should revert This method require system call flag", async () => { + await expect(nonceHolder.increaseMinNonce(123)).to.be.rejectedWith("This method require system call flag"); + }); + }); + + describe("incrementMinNonceIfEquals", async () => { + it("should revert This method require system call flag", async () => { + const expectedNonce = await nonceHolder.getMinNonce(systemAccount.address); + await expect(nonceHolder.incrementMinNonceIfEquals(expectedNonce)).to.be.rejectedWith( + "This method require system call flag" + ); + }); + + it("should revert Incorrect nonce", async () => { + await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.rejectedWith( + "Incorrect nonce" + ); + }); + + it("should increment minNonce if equals to expected", async () => { + const expectedNonce = await nonceHolder.getMinNonce(systemAccount.address); + await nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(expectedNonce); + const result = await nonceHolder.getMinNonce(systemAccount.address); + expect(result).to.equal(expectedNonce.add(1)); + }); + }); + + describe("incrementDeploymentNonce", async () => { + it("should revert Only the contract deployer can increment the deployment nonce", async () => { + await expect(nonceHolder.incrementDeploymentNonce(deployerAccount.address)).to.be.rejectedWith( + "Only the contract deployer can increment the deployment nonce" + ); + }); + + it("should increment deployment nonce", async () => { + const nonceBefore = await nonceHolder.getDeploymentNonce(wallet.address); + const rawNonceBefore = await nonceHolder.getRawNonce(wallet.address); + await nonceHolder.connect(deployerAccount).incrementDeploymentNonce(wallet.address); + const nonceAfter = await nonceHolder.getDeploymentNonce(wallet.address); + const rawNonceAfter = await nonceHolder.getRawNonce(wallet.address); + + expect(nonceAfter).to.equal(nonceBefore.add(BigNumber.from(1))); + expect(rawNonceAfter).to.equal(rawNonceBefore.add(BigNumber.from(2).pow(128))); + }); + }); + + describe("setValueUnderNonce and getValueUnderNonce", async () => { + it("should revert Nonce value cannot be set to 0", async () => { + const accountInfo = [1, 0]; + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [accountInfo]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(124, 0)).to.be.rejectedWith( + "Nonce value cannot be set to 0" + ); + }); + + it("should revert Previous nonce has not been used", async () => { + const accountInfo = [1, 0]; + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [accountInfo]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(443, 111)).to.be.rejectedWith( + "Previous nonce has not been used" + ); + }); + + it("should emit ValueSetUnderNonce event", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const valueBefore = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce); + const value = valueBefore.add(42); + + const accountInfo = [1, 0]; + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [accountInfo]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce, value)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce, value); + + const valueAfter = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce); + expect(valueAfter).to.equal(value); + }); + + it("should emit ValueSetUnderNonce event arbitrary ordering", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const encodedAccountInfo = ethers.utils.defaultAbiCoder.encode(["tuple(uint8, uint8)"], [[1, 1]]); + await setResult("ContractDeployer", "getAccountInfo", [systemAccount.address], { + failure: false, + returnData: encodedAccountInfo, + }); + + const firstValue = (await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce)).add(111); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce, firstValue)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce, firstValue); + + const secondValue = (await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(2))).add(333); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce.add(2), secondValue)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce.add(2), secondValue); + + const thirdValue = (await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(1))).add(222); + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(currentNonce.add(1), thirdValue)) + .to.emit(nonceHolder, "ValueSetUnderNonce") + .withArgs(systemAccount.address, currentNonce.add(1), thirdValue); + + const storedValue = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce); + expect(storedValue).to.equal(firstValue); + const storedValueNext = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(1)); + expect(storedValueNext).to.equal(thirdValue); + const storedAfterNext = await nonceHolder.connect(systemAccount).getValueUnderNonce(currentNonce.add(2)); + expect(storedAfterNext).to.equal(secondValue); + }); + }); + + describe("isNonceUsed", () => { + it("used nonce because it too small", async () => { + const isUsed = await nonceHolder.isNonceUsed(systemAccount.address, 1); + expect(isUsed).to.equal(true); + }); + + it("used nonce because set", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const checkedNonce = currentNonce.add(1); + await nonceHolder.connect(systemAccount).setValueUnderNonce(checkedNonce, 5); + + const isUsed = await nonceHolder.isNonceUsed(systemAccount.address, checkedNonce); + expect(isUsed).to.equal(true); + }); + + it("not used nonce", async () => { + const currentNonce = await nonceHolder.getMinNonce(systemAccount.address); + const checkedNonce = currentNonce.add(2137 * 2 ** 10); + + const isUsed = await nonceHolder.isNonceUsed(systemAccount.address, checkedNonce); + expect(isUsed).to.be.false; + }); + }); + + describe("validateNonceUsage", () => { + it("used nonce & should not be used", async () => { + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 1, false)).to.be.rejectedWith( + "Reusing the same nonce twice" + ); + }); + + it("used nonce & should be used", async () => { + await nonceHolder.validateNonceUsage(systemAccount.address, 1, true); + }); + + it("not used nonce & should be used", async () => { + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, true)).to.be.rejectedWith( + "The nonce was not set as used" + ); + }); + + it("not used nonce & should not be used", async () => { + await nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, false); + }); + }); +}); diff --git a/system-contracts/test/shared/mocks.ts b/system-contracts/test/shared/mocks.ts index 2b8c35654..4dd51671e 100644 --- a/system-contracts/test/shared/mocks.ts +++ b/system-contracts/test/shared/mocks.ts @@ -2,6 +2,7 @@ import { ethers } from "hardhat"; import type { MockContract } from "../../typechain"; import { MockContractFactory } from "../../typechain"; import { + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, TEST_ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT_ADDRESS, TEST_BOOTLOADER_FORMAL_ADDRESS, TEST_BASE_TOKEN_SYSTEM_CONTRACT_ADDRESS, @@ -26,6 +27,7 @@ type CallResult = { const TEST_SYSTEM_CONTRACTS_MOCKS = { Compressor: TEST_COMPRESSOR_CONTRACT_ADDRESS, SystemContext: TEST_SYSTEM_CONTEXT_CONTRACT_ADDRESS, + ContractDeployer: TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, NonceHolder: TEST_NONCE_HOLDER_SYSTEM_CONTRACT_ADDRESS, L1Messenger: TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, KnownCodesStorage: TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, From 2840540271838df29351ce7e5b7e033431b6c0a1 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 09:55:30 -0400 Subject: [PATCH 39/60] chore(scripts): remove unconditionally removed facets (#448) --- .github/workflows/slither.yaml | 4 +++- l1-contracts/src.ts/diamondCut.ts | 8 +------- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/.github/workflows/slither.yaml b/.github/workflows/slither.yaml index 652822dfd..fa253e159 100644 --- a/.github/workflows/slither.yaml +++ b/.github/workflows/slither.yaml @@ -43,4 +43,6 @@ jobs: rm -rf ./l1-contracts/contracts/dev-contracts/test/VerifierRecursiveTest.sol - name: Run Slither - run: slither --config ./l1-contracts/slither.config.json ./l1-contracts + run: | + cd l1-contracts + slither --config ./slither.config.json . diff --git a/l1-contracts/src.ts/diamondCut.ts b/l1-contracts/src.ts/diamondCut.ts index f9eaadf0e..c2a8e8728 100644 --- a/l1-contracts/src.ts/diamondCut.ts +++ b/l1-contracts/src.ts/diamondCut.ts @@ -6,9 +6,6 @@ import { ethers } from "ethers"; import { IZkSyncHyperchainFactory } from "../typechain/IZkSyncHyperchainFactory"; import { IZkSyncHyperchainBaseFactory } from "../typechain/IZkSyncHyperchainBaseFactory"; -// Some of the facets are to be removed with the upcoming upgrade. -const UNCONDITIONALLY_REMOVED_FACETS = ["DiamondCutFacet", "GovernanceFacet"]; - export enum Action { Add = 0, Replace = 1, @@ -131,10 +128,7 @@ export async function getFacetCutsForUpgrade( namesOfFacetsToBeRemoved?: string[] ) { const newFacetCuts = await getCurrentFacetCutsForAdd(adminAddress, gettersAddress, mailboxAddress, executorAddress); - namesOfFacetsToBeRemoved = namesOfFacetsToBeRemoved || [ - ...UNCONDITIONALLY_REMOVED_FACETS, - ...Object.keys(newFacetCuts), - ]; + namesOfFacetsToBeRemoved = namesOfFacetsToBeRemoved || [...Object.keys(newFacetCuts)]; const oldFacetCuts = await getDeployedFacetCutsForRemove(wallet, zkSyncAddress, namesOfFacetsToBeRemoved); return [...oldFacetCuts, ...Object.values(newFacetCuts)]; } From 622638a43ecee3211b01ab3e43952b7705f5955b Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 09:59:09 -0400 Subject: [PATCH 40/60] chore(contracts): remove usage of ergs (#454) --- l2-contracts/src/upgrade-bridge-impl.ts | 2 +- system-contracts/SystemContractsHashes.json | 54 +++++++++---------- system-contracts/contracts/Constants.sol | 2 +- system-contracts/contracts/GasBoundCaller.sol | 4 +- .../test-contracts/GasBoundCallerTester.sol | 4 +- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/l2-contracts/src/upgrade-bridge-impl.ts b/l2-contracts/src/upgrade-bridge-impl.ts index 99c7475c7..af21fbac0 100644 --- a/l2-contracts/src/upgrade-bridge-impl.ts +++ b/l2-contracts/src/upgrade-bridge-impl.ts @@ -352,7 +352,7 @@ async function main() { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT ); - console.log(`Base cost for priority tx with max ergs: ${ethers.utils.formatEther(neededValue)} ETH`); + console.log(`Base cost for priority tx with max gas: ${ethers.utils.formatEther(neededValue)} ETH`); }); await program.parseAsync(process.argv); diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index eeb4a80f3..79fba0a88 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,49 +3,49 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x0100007549287362e4263ea5b204f01fc3c7f2ac09d71e6eb21029698220f01a", + "bytecodeHash": "0x01000075076d9e9ca73d51f8ef0af1bb2e7f74fd8377876ab6bc470a2900a4bf", "sourceCodeHash": "0xfbf66e830201c4b7fda14f0ddf28a53beb7fbb48a8406392bcfd0ef7ea9265c8" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007d1e53f2dca05f7e27ae5b7062291ed3a1470ca511140b8e786aae7eb77", + "bytecodeHash": "0x010007d1e60e441b0b776e8f6b1c8a9e0fdd787a944a9d851cd093a3b65b3daa", "sourceCodeHash": "0x9ff5a2da00acfa145ee4575381ad386587d96b6a0309d05015974f4726881132" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x01000055c1f27b8316ba61bf07959b11cf3b2a418aa357ccc5531c0914a2da27", + "bytecodeHash": "0x0100005576cef4b90577db7ca2e5cc02340a0b56ee9473b34756502963551a97", "sourceCodeHash": "0x0aa5d7ed159e783acde47856b13801b7f2268ba39b2fa50807fe3d705c506e96" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x01000179842b5aa1c76036f5b90652fe614dacb28438a89649d6ca48131bd402", + "bytecodeHash": "0x0100017924bee877f2ab925cfb1c161ef3c19a8a3034da5d4fd76d0c377a3749", "sourceCodeHash": "0xd43ac120a50398e0d6bdcfcf807154bfeece0c231509a0eb2e00bcad744e60cd" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010005215fda00bfbf95847a13078bd16cdcb1b875534261c1dda9940c7754fe", + "bytecodeHash": "0x010005217819daf0124b7ccb96aca43053d0d13c0c8ad8ae7568d811eecbc3bf", "sourceCodeHash": "0x635301b824f927b4d17b3d9974cf6abbf979dda49e610805637db7c677d5f522" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x0100004bc85f45ebf0f0bf004752bcbff1bb99792d6cc6494227970ec77fe53b", + "bytecodeHash": "0x0100004b3ac74b1706466d4b2f2b401addad6f17fabb7c8b979cea2fe700cbaf", "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32", + "bytecodeHash": "0x01000563e438856e95e453dd4380fbcbb2d8657320ebe7b067f88d7e7898d6bb", "sourceCodeHash": "0xa42423712ddaa8f357d26e46825fda80a9a870d0ac7ff52c98884355f1173ec7" }, { @@ -59,63 +59,63 @@ "contractName": "GasBoundCaller", "bytecodePath": "artifacts-zk/contracts-preprocessed/GasBoundCaller.sol/GasBoundCaller.json", "sourceCodePath": "contracts-preprocessed/GasBoundCaller.sol", - "bytecodeHash": "0x010000b5e930829f22bd5df4fac3cb37b599cf9733554124bfb7e717fa4a726b", - "sourceCodeHash": "0x68db837d79ab575450f9123d97c7e566f311fb2e8d91c0d43dc9769ca895ccd3" + "bytecodeHash": "0x010000b51b2bae505be6deb2294505457c6e8df65d6b8d08f32d0d85f8610c60", + "sourceCodeHash": "0xd6877ecfd598bcf8abe26ec344949ae8f992d9a8ab1ac8d529a21da521f77923" }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003de00c5ceaa3fdf4566a9822ce94abe676f68b17a6ae11c453e14455fd", + "bytecodeHash": "0x0100003dc7171a0acf2c4290f0ed222e9d2496b02a47202862e2b2dc70436c4a", "sourceCodeHash": "0x30df621c72cb35b8820b902b91057f72d0214a0e4a6b7ad4c0847e674e8b9df8" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100007d82d4a2eb62e539e3c89cc641f507132b247022ba05ef1ddfed2b0073", + "bytecodeHash": "0x0100007d6f907a56f64d3c054ae5e4a8f73499e1d9fdfea09684fc9de9542941", "sourceCodeHash": "0x51d388adc58f67ef975a94a7978caa60ed8a0df9d3bd9ac723dfcfc540286c70" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002b97ebf3c481ead775617590ffca139bee428e443aa49eb38b6a5b83657", + "bytecodeHash": "0x010002b9ed3fe658cc5fbc4c2d8b4b5325f47a417f9df02e7dba4360f290141c", "sourceCodeHash": "0x35c189f3babf5c7a9ce2590bed9eb62b59766e358b7733fdb1bc33f4c232f765" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x010001039329e4bb55b24531c7e7d27ed40d2c82ad145033fdd5ed5b8ea86cf3", + "bytecodeHash": "0x010001035dc295d66d39f6f5ae560801400c6ac1141fd1556acabff84c79c22c", "sourceCodeHash": "0x76ac95c12820d9a02cd1f177eab59092d99463816f2616e1e0f44637bf791a43" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x010000695a1e821b6d5fcb25e25793b81de0bdca3ff8277e3ac93a38e729e0a1", + "bytecodeHash": "0x01000069227f9b9d7666a4fc7ac51a280f33fd92021f2e8f06a2d5a458930563", "sourceCodeHash": "0x3f9e0af527875bebcdc20ca4ecb6822305877fd6038e4c4c58854d000b9ac115" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000e563d4ad7b4822cc19d8f74f2c41ee3d3153379be4b02b27d4498d52b6", + "bytecodeHash": "0x010000e5e7614688d2be15699477b56c66e3596a16b60c206f3c3e8a4763e6b4", "sourceCodeHash": "0x91847512344ac5026e9fd396189c23ad9e253f22cb6e2fe65805c20c915797d4" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x01000049eb6d79244e74e5286ed4d3f6eef2b5eb746b67d98691dbc28fa16984", + "bytecodeHash": "0x01000049d12af64a260c7dbfa32b778e60fe6793b73d50388cfdb0d38df4a97c", "sourceCodeHash": "0xbc62d673c2cf9ba2d2148e5e2f99ea577cd357c6fd3ad7d248f670c750050faa" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001b3f2c3a6bdd5ad00ae29a7cbbb32dca3c31fb608b5cd52f8f3056a3847", + "bytecodeHash": "0x010001b38acd12ee43d880840d48bd0474c519a8076cf28c8930489117e9bc73", "sourceCodeHash": "0xb90284d78f48a958d082c4c877fc91ec292d05f0e388c6c78e6cce6d3b069a63" }, { @@ -185,35 +185,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb722f6b3ac4928fadcb3ad05bb76a7e2497a5635efffb7bbc40f23d29", - "sourceCodeHash": "0x818032f314539edf7b5569c70099f27e2336199ce24313a3f1968e27082c18ae" + "bytecodeHash": "0x010003cb38a53b3466209bf803fc2cacd06f9dc4ff9b123a38f6ba41928f735b", + "sourceCodeHash": "0xd5b248e75ad4a0a433c47de88b5a6eb30c3b7b540e0a716e953c07903233c2d1" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x01000951a10ba35cd1fd7ea05039e53a06037213a162e6a3cfddf81ff6e54ad5", - "sourceCodeHash": "0x2cadacf92b4db89ecd699426b769526e5482e565d6d86ed287c9cc36cfe2cc2f" + "bytecodeHash": "0x010009519002105dd21a44bde50b697ffbc607baf3196d2eac80ad06f99e0f4c", + "sourceCodeHash": "0xbecdcccce351008db583c0447c7e1c7e8c69b5806abee65f22119e699e908e9d" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d750d8f3fa01d99a747a5113d133594b72f26f0dce3243b225f5b91f9a", - "sourceCodeHash": "0x9a3aead2fe745861da43b8f43028821f7d592ffd16da70f38af19d3b24ae5ef7" + "bytecodeHash": "0x010008d7d5b5c05e49761c406b847fe3ad0db839525b3e4370e9a5b86f2062af", + "sourceCodeHash": "0x533349c05727f117c00727ddcc25814055571afe74827a1d7130b037e131362b" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x010009579942207c3a46a48ad0e66d9f73b6141bb5a2435a8fdce6ee8dfdd17d", - "sourceCodeHash": "0x2302636e39803befa5438f557bfc24b7e1587cfd8edead02dc41a0bb4002f15f" + "bytecodeHash": "0x01000957163c0f203bb8a7d3eda31cd9024e0572d212cdefc3046d740cd35afc", + "sourceCodeHash": "0xcf9c1d03c4d5c087b5c80b2ced7eff33067121a9ae78e1b0ff4b3eba4b5fbe1d" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e7f0f15ed191392960117f88fe371348982b28a033c7207ed2c09bc0f4", - "sourceCodeHash": "0x55ce91a28b1d143ecba38dfe1b64d4877ad8f510256f47e5155fd4fd138840ea" + "bytecodeHash": "0x010008e7d48764fc25121571a4139372fb3dbfd326416ed4bf5c5857cb7affc4", + "sourceCodeHash": "0x5acea8e48b7e840467552341bcf15670856fa5d671614b398e6bd7141052671d" } ] diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index 0f8e2307f..fde7a5de5 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -35,7 +35,7 @@ address constant ECMUL_SYSTEM_CONTRACT = address(0x07); address constant ECPAIRING_SYSTEM_CONTRACT = address(0x08); -/// @dev The number of ergs that need to be spent for a single byte of pubdata regardless of the pubdata price. +/// @dev The number of gas that need to be spent for a single byte of pubdata regardless of the pubdata price. /// This variable is used to ensure the following: /// - That the long-term storage of the operator is compensated properly. /// - That it is not possible that the pubdata counter grows too high without spending proportional amount of computation. diff --git a/system-contracts/contracts/GasBoundCaller.sol b/system-contracts/contracts/GasBoundCaller.sol index d45f64163..67a43883e 100644 --- a/system-contracts/contracts/GasBoundCaller.sol +++ b/system-contracts/contracts/GasBoundCaller.sol @@ -13,10 +13,10 @@ import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; * system contracts have and it can relay call to any contract, breaking potential trust in system contracts. */ contract GasBoundCaller { - /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` ergs are used for the O(1) operations at the start + /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` gas are used for the O(1) operations at the start /// of execution of the contract, such as abi decoding the parameters, jumping to the correct function, etc. uint256 constant CALL_ENTRY_OVERHEAD = 800; - /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` ergs are used for the O(1) operations at the end of the execution, + /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, /// as such relaying the return. uint256 constant CALL_RETURN_OVERHEAD = 200; diff --git a/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol b/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol index 351a55f46..8a86c2e39 100644 --- a/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol +++ b/system-contracts/contracts/test-contracts/GasBoundCallerTester.sol @@ -50,8 +50,8 @@ contract GasBoundCallerTester is GasBoundCaller { lastRecordedGasLeft = gasbefore - gasleft(); } - function spender(uint32 _ergsToBurn, uint32 _pubdataToUse) external { - SystemContractHelper.burnGas(_ergsToBurn, _pubdataToUse); + function spender(uint32 _gasToBurn, uint32 _pubdataToUse) external { + SystemContractHelper.burnGas(_gasToBurn, _pubdataToUse); } function gasBoundCallRelayer( From bd9bec52933fae9a8a84542994a84c88aaf32c56 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 10:26:31 -0400 Subject: [PATCH 41/60] chore(verifier): update generation to include vk hash (#453) --- .../contracts/state-transition/Verifier.sol | 1 + tools/Cargo.lock | 6832 ++++++++++++++++- tools/Cargo.toml | 5 + tools/data/verifier_contract_template.txt | 1 + tools/rust-toolchain | 1 - tools/rust-toolchain.toml | 2 + tools/src/main.rs | 18 +- 7 files changed, 6615 insertions(+), 245 deletions(-) delete mode 100644 tools/rust-toolchain create mode 100644 tools/rust-toolchain.toml diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 861f7e850..4f0b1d043 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -9,6 +9,7 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. /// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. +/// @dev Contract was generated from a verification key with a hash of 0x1d485be42d712856dfe85b3cf7823f020fa5f83cb41c83f9da307fdc2089beee /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: diff --git a/tools/Cargo.lock b/tools/Cargo.lock index 90d7c01b3..da25711f1 100644 --- a/tools/Cargo.lock +++ b/tools/Cargo.lock @@ -3,455 +3,6803 @@ version = 3 [[package]] -name = "ansi_term" -version = "0.12.1" +name = "Inflector" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" dependencies = [ - "winapi", + "lazy_static", + "regex", ] [[package]] -name = "atty" -version = "0.2.14" +name = "addchain" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" dependencies = [ - "hermit-abi", - "libc", - "winapi", + "num-bigint 0.3.3", + "num-integer", + "num-traits", ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "addr2line" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] [[package]] -name = "block-buffer" -version = "0.10.4" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] -name = "cfg-if" -version = "1.0.0" +name = "aes" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] [[package]] -name = "clap" -version = "2.34.0" +name = "aho-corasick" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", + "memchr", ] [[package]] -name = "cpufeatures" -version = "0.2.9" +name = "android-tzdata" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" dependencies = [ "libc", ] [[package]] -name = "crypto-common" -version = "0.1.6" +name = "ansi_term" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" dependencies = [ - "generic-array", - "typenum", + "winapi", ] [[package]] -name = "digest" -version = "0.10.7" +name = "anstream" +version = "0.6.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" dependencies = [ - "block-buffer", - "crypto-common", + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", ] [[package]] -name = "generic-array" -version = "0.14.7" +name = "anstyle" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" + +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" dependencies = [ - "typenum", - "version_check", + "utf8parse", ] [[package]] -name = "handlebars" -version = "4.4.0" +name = "anstyle-query" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" +checksum = "a64c907d4e79225ac72e2a354c9ce84d50ebb4586dee56c82b3ee73004f537f5" dependencies = [ - "log", - "pest", - "pest_derive", - "serde", - "serde_json", - "thiserror", + "windows-sys 0.52.0", ] [[package]] -name = "heck" -version = "0.3.3" +name = "anstyle-wincon" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" dependencies = [ - "unicode-segmentation", + "anstyle", + "windows-sys 0.52.0", ] [[package]] -name = "hermit-abi" -version = "0.1.19" +name = "anyhow" +version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +checksum = "25bdb32cbbdce2b519a9cd7df3a678443100e265d5e25ca763b7572a5104f5f3" + +[[package]] +name = "arr_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a105bfda48707cf19220129e78fca01e9639433ffaef4163546ed8fb04120a5" dependencies = [ - "libc", + "arr_macro_impl", + "proc-macro-hack", ] [[package]] -name = "itoa" -version = "1.0.9" +name = "arr_macro_impl" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +checksum = "0609c78bd572f4edc74310dfb63a01f5609d53fa8b4dd7c4d98aef3b3e8d72d1" +dependencies = [ + "proc-macro-hack", + "quote 1.0.33", + "syn 1.0.109", +] [[package]] -name = "lazy_static" -version = "1.4.0" +name = "arrayref" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" [[package]] -name = "libc" -version = "0.2.148" +name = "arrayvec" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] [[package]] -name = "log" -version = "0.4.20" +name = "arrayvec" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] -name = "memchr" -version = "2.6.3" +name = "arrayvec" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" [[package]] -name = "once_cell" -version = "1.18.0" +name = "ascii-canvas" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6" +dependencies = [ + "term", +] [[package]] -name = "pest" -version = "2.7.3" +name = "async-trait" +version = "0.1.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ - "memchr", - "thiserror", - "ucd-trie", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", ] [[package]] -name = "pest_derive" -version = "2.7.3" +name = "async_io_stream" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" dependencies = [ - "pest", - "pest_generator", + "futures", + "pharos", + "rustc_version", ] [[package]] -name = "pest_generator" -version = "2.7.3" +name = "atty" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.33", + "hermit-abi 0.1.19", + "libc", + "winapi", ] [[package]] -name = "pest_meta" -version = "2.7.3" +name = "auto_impl" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4" dependencies = [ - "once_cell", - "pest", - "sha2", + "proc-macro-error", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", ] [[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "auto_impl" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "autocfg" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ - "proc-macro2", - "quote", - "version_check", + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", ] [[package]] -name = "proc-macro2" -version = "1.0.67" +name = "axum-core" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" dependencies = [ - "unicode-ident", + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", ] [[package]] -name = "quote" -version = "1.0.33" +name = "backtrace" +version = "0.3.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" dependencies = [ - "proc-macro2", + "addr2line", + "cc", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", ] [[package]] -name = "ryu" -version = "1.0.15" +name = "base16ct" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" [[package]] -name = "serde" -version = "1.0.188" +name = "base16ct" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" -dependencies = [ - "serde_derive", -] +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" [[package]] -name = "serde_derive" -version = "1.0.188" +name = "base58" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.33", -] +checksum = "5024ee8015f02155eee35c711107ddd9a9bf3cb689cf2a9089c97e79b6e1ae83" [[package]] -name = "serde_json" -version = "1.0.107" +name = "base58check" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +checksum = "2ee2fe4c9a0c84515f136aaae2466744a721af6d63339c18689d9e995d74d99b" dependencies = [ - "itoa", - "ryu", - "serde", + "base58", + "sha2 0.8.2", ] [[package]] -name = "sha2" -version = "0.10.7" +name = "base64" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest", -] +checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" [[package]] -name = "strsim" -version = "0.8.0" +name = "base64" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] -name = "structopt" -version = "0.3.26" +name = "base64" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] -name = "structopt-derive" -version = "0.4.18" +name = "base64" +version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", -] +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] -name = "syn" -version = "1.0.109" +name = "base64ct" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" [[package]] -name = "syn" -version = "2.0.33" +name = "bech32" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +checksum = "2dabbe35f96fb9507f7330793dc490461b2962659ac5d427181e451a623751d1" + +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + +[[package]] +name = "bellman_ce" +version = "0.3.2" +source = "git+https://github.com/matter-labs/bellman?branch=snark-wrapper#e01e5fa08a97a113e76ec8a69d06fe6cc2c82d17" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "arrayvec 0.7.4", + "bit-vec", + "blake2s_const", + "blake2s_simd", + "byteorder", + "cfg-if 1.0.0", + "crossbeam 0.7.3", + "futures", + "hex", + "lazy_static", + "num_cpus", + "pairing_ce 0.28.5 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.4.6", + "serde", + "smallvec", + "tiny-keccak 1.5.0", ] [[package]] -name = "textwrap" -version = "0.11.0" +name = "bigdecimal" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" dependencies = [ - "unicode-width", + "num-bigint 0.4.5", + "num-integer", + "num-traits", ] [[package]] -name = "thiserror" -version = "1.0.48" +name = "bincode" +version = "1.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" dependencies = [ - "thiserror-impl", + "serde", ] [[package]] -name = "thiserror-impl" -version = "1.0.48" +name = "bit-set" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.33", + "bit-vec", ] [[package]] -name = "typenum" -version = "1.16.0" +name = "bit-vec" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" +dependencies = [ + "serde", +] [[package]] -name = "ucd-trie" -version = "0.1.6" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "unicode-ident" -version = "1.0.12" +name = "bitflags" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" [[package]] -name = "unicode-segmentation" -version = "1.10.1" +name = "bitvec" +version = "0.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "41262f11d771fd4a61aa3ce019fca363b4b6c282fca9da2a31186d3965a47a5c" +dependencies = [ + "either", + "radium 0.3.0", +] [[package]] -name = "unicode-width" -version = "0.1.10" +name = "bitvec" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium 0.7.0", + "tap", + "wyz", +] [[package]] -name = "vec_map" -version = "0.8.2" +name = "blake2" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +dependencies = [ + "crypto-mac", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e#1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake2-rfc_bellman_edition" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc60350286c7c3db13b98e91dbe5c8b6830a6821bc20af5b0c310ce94d74915" +dependencies = [ + "arrayvec 0.4.12", + "byteorder", + "constant_time_eq", +] + +[[package]] +name = "blake2s_const" +version = "0.6.0" +source = "git+https://github.com/matter-labs/bellman?branch=snark-wrapper#e01e5fa08a97a113e76ec8a69d06fe6cc2c82d17" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "blake2s_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e461a7034e85b211a4acb57ee2e6730b32912b06c08cc242243c39fc21ae6a2" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" +dependencies = [ + "block-padding 0.1.5", + "byte-tools", + "byteorder", + "generic-array 0.12.4", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-padding" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5" +dependencies = [ + "byte-tools", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "boojum" +version = "0.2.0" +source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" +dependencies = [ + "arrayvec 0.7.4", + "bincode", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "const_format", + "convert_case 0.6.0", + "crossbeam 0.8.4", + "crypto-bigint 0.5.5", + "cs_derive", + "derivative", + "ethereum-types", + "firestorm", + "itertools 0.10.5", + "lazy_static", + "num-modular", + "num_cpus", + "packed_simd", + "pairing_ce 0.28.5 (git+https://github.com/matter-labs/pairing.git)", + "rand 0.8.5", + "rayon", + "serde", + "sha2 0.10.8", + "sha3 0.10.6", + "smallvec", + "unroll", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +dependencies = [ + "serde", +] + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.5", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "circuit_definitions" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.0#39665dffd576cff5007c80dd0e1b5334e230bd3b" +dependencies = [ + "circuit_encodings 0.1.40", + "crossbeam 0.8.4", + "derivative", + "seq-macro", + "serde", + "snark_wrapper", + "zk_evm 1.4.0", + "zkevm_circuits 1.4.0", +] + +[[package]] +name = "circuit_definitions" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.5.0#394e1c7d1aec06d2f3abd63bdc2ddf0efef5ac49" +dependencies = [ + "circuit_encodings 0.1.50", + "crossbeam 0.8.4", + "derivative", + "seq-macro", + "serde", + "snark_wrapper", +] + +[[package]] +name = "circuit_encodings" +version = "0.1.40" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.0#39665dffd576cff5007c80dd0e1b5334e230bd3b" +dependencies = [ + "derivative", + "serde", + "zk_evm 1.4.0", + "zkevm_circuits 1.4.0", +] + +[[package]] +name = "circuit_encodings" +version = "0.1.50" +source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.5.0#394e1c7d1aec06d2f3abd63bdc2ddf0efef5ac49" +dependencies = [ + "derivative", + "serde", + "zk_evm 1.5.0", + "zkevm_circuits 1.5.0", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "ansi_term", + "atty", + "bitflags 1.3.2", + "strsim 0.8.0", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "codegen" +version = "0.1.0" +source = "git+https://github.com/matter-labs/solidity_plonk_verifier.git?branch=snark_wrapper#5fb698f5118990bf53648bfd7027363bc4b03ff2" +dependencies = [ + "ethereum-types", + "franklin-crypto", + "handlebars", + "hex", + "paste", + "rescue_poseidon", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "coins-bip32" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634c509653de24b439672164bbf56f5f582a2ab0e313d3b0f6af0b7345cf2560" +dependencies = [ + "bincode", + "bs58", + "coins-core", + "digest 0.10.7", + "getrandom", + "hmac", + "k256 0.11.6", + "lazy_static", + "serde", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-bip39" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a11892bcac83b4c6e95ab84b5b06c76d9d70ad73548dd07418269c5c7977171" +dependencies = [ + "bitvec 0.17.4", + "coins-bip32", + "getrandom", + "hex", + "hmac", + "pbkdf2", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "coins-core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c94090a6663f224feae66ab01e41a2555a8296ee07b5f20dab8888bdefc9f617" +dependencies = [ + "base58check", + "base64 0.12.3", + "bech32", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "digest 0.10.7", + "generic-array 0.14.7", + "hex", + "ripemd", + "serde", + "serde_derive", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", +] + +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "compile-fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bed69047ed42e52c7e38d6421eeb8ceefb4f2a2b52eed59137f7bad7908f6800" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "unicode-xid 0.2.4", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-channel 0.4.4", + "crossbeam-deque 0.7.4", + "crossbeam-epoch 0.8.2", + "crossbeam-queue 0.2.3", + "crossbeam-utils 0.7.2", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel 0.5.12", + "crossbeam-deque 0.8.5", + "crossbeam-epoch 0.9.18", + "crossbeam-queue 0.3.11", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-channel" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +dependencies = [ + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20ff29ded3204c5106278a81a38f4b482636ed4fa1e6cfbeef193291beb29ed" +dependencies = [ + "crossbeam-epoch 0.8.2", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch 0.9.18", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +dependencies = [ + "cfg-if 0.1.10", + "crossbeam-utils 0.7.2", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if 0.1.10", + "lazy_static", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-boojum-validator-cli?branch=main#1661eef7b235fc10e92208fb738c9e261f58c653" +dependencies = [ + "anyhow", + "bincode", + "circuit_definitions 0.1.0", + "clap 4.5.4", + "codegen", + "colored", + "ethers", + "hex", + "once_cell", + "primitive-types", + "reqwest", + "serde", + "serde_json", + "sha3 0.9.1", + "tokio", + "zksync_types", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array 0.14.7", + "subtle", +] + +[[package]] +name = "cs_derive" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "serde", + "uuid 1.8.0", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case 0.4.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "rustc_version", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7abbfc297053be59290e3152f8cbcd52c8642e0728b69ee187d991d4c1af08d" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0-beta.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bba3e9872d7c58ce7ef0fcf1844fcc3e23ef2a58377b50df35dd98e42a5726e" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", + "unicode-xid 0.2.4", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pem-rfc7468", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", + "subtle", + "zeroize", +] + +[[package]] +name = "elsa" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10" +dependencies = [ + "stable_deref_trait", +] + +[[package]] +name = "ena" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +dependencies = [ + "log", +] + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "envy" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f47e0157f2cb54f5ae1bd371b30a2ae4311e1c028f575cd4e81de7353215965" +dependencies = [ + "serde", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "eth-keystore" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fda3bf123be441da5260717e0661c25a2fd9cb2b2c1d20bf2e05580047158ab" +dependencies = [ + "aes", + "ctr", + "digest 0.10.7", + "hex", + "hmac", + "pbkdf2", + "rand 0.8.5", + "scrypt", + "serde", + "serde_json", + "sha2 0.10.8", + "sha3 0.10.8", + "thiserror", + "uuid 0.8.2", +] + +[[package]] +name = "ethabi" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7413c5f74cc903ea37386a8965a936cbeb334bd270862fdece542c1b2dcbc898" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c22d4b5885b6aa2fe5e8b9329fb8d232bf739e434e6b87347c63bdd00c120f60" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethereum-types" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02d215cbf040552efcbe99a38372fe80ab9d00268e20012b79fcd0f073edd8ee" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "primitive-types", + "scale-info", + "uint", +] + +[[package]] +name = "ethers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11f26f9d8d80da18ca72aca51804c65eb2153093af3bec74fd5ce32aa0c1f665" +dependencies = [ + "ethers-addressbook", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-middleware", + "ethers-providers", + "ethers-signers", + "ethers-solc", +] + +[[package]] +name = "ethers-addressbook" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4be54dd2260945d784e06ccdeb5ad573e8f1541838cee13a1ab885485eaa0b" +dependencies = [ + "ethers-core", + "once_cell", + "serde", + "serde_json", +] + +[[package]] +name = "ethers-contract" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9c3c3e119a89f0a9a1e539e7faecea815f74ddcf7c90d0b00d1f524db2fdc9c" +dependencies = [ + "ethers-contract-abigen", + "ethers-contract-derive", + "ethers-core", + "ethers-providers", + "futures-util", + "hex", + "once_cell", + "pin-project", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ethers-contract-abigen" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d4e5ad46aede34901f71afdb7bb555710ed9613d88d644245c657dc371aa228" +dependencies = [ + "Inflector", + "cfg-if 1.0.0", + "dunce", + "ethers-core", + "eyre", + "getrandom", + "hex", + "proc-macro2 1.0.82", + "quote 1.0.33", + "regex", + "reqwest", + "serde", + "serde_json", + "syn 1.0.109", + "toml", + "url", + "walkdir", +] + +[[package]] +name = "ethers-contract-derive" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f192e8e4cf2b038318aae01e94e7644e0659a76219e94bcd3203df744341d61f" +dependencies = [ + "ethers-contract-abigen", + "ethers-core", + "hex", + "proc-macro2 1.0.82", + "quote 1.0.33", + "serde_json", + "syn 1.0.109", +] + +[[package]] +name = "ethers-core" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade3e9c97727343984e1ceada4fdab11142d2ee3472d2c67027d56b1251d4f15" +dependencies = [ + "arrayvec 0.7.4", + "bytes", + "cargo_metadata", + "chrono", + "convert_case 0.6.0", + "elliptic-curve 0.12.3", + "ethabi", + "generic-array 0.14.7", + "hex", + "k256 0.11.6", + "once_cell", + "open-fastrlp", + "proc-macro2 1.0.82", + "rand 0.8.5", + "rlp", + "rlp-derive", + "serde", + "serde_json", + "strum", + "syn 1.0.109", + "thiserror", + "tiny-keccak 2.0.2", + "unicode-xid 0.2.4", +] + +[[package]] +name = "ethers-etherscan" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9713f525348e5dde025d09b0a4217429f8074e8ff22c886263cc191e87d8216" +dependencies = [ + "ethers-core", + "getrandom", + "reqwest", + "semver", + "serde", + "serde-aux", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "ethers-middleware" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e71df7391b0a9a51208ffb5c7f2d068900e99d6b3128d3a4849d138f194778b7" +dependencies = [ + "async-trait", + "auto_impl 0.5.0", + "ethers-contract", + "ethers-core", + "ethers-etherscan", + "ethers-providers", + "ethers-signers", + "futures-locks", + "futures-util", + "instant", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", +] + +[[package]] +name = "ethers-providers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1a9e0597aa6b2fdc810ff58bc95e4eeaa2c219b3e615ed025106ecb027407d8" +dependencies = [ + "async-trait", + "auto_impl 1.2.0", + "base64 0.13.1", + "ethers-core", + "futures-channel", + "futures-core", + "futures-timer", + "futures-util", + "getrandom", + "hashers", + "hex", + "http", + "once_cell", + "parking_lot 0.11.2", + "pin-project", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tracing", + "tracing-futures", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-timer", + "web-sys", + "ws_stream_wasm", +] + +[[package]] +name = "ethers-signers" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f41ced186867f64773db2e55ffdd92959e094072a1d09a5e5e831d443204f98" +dependencies = [ + "async-trait", + "coins-bip32", + "coins-bip39", + "elliptic-curve 0.12.3", + "eth-keystore", + "ethers-core", + "hex", + "rand 0.8.5", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "ethers-solc" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbe9c0a6d296c57191e5f8a613a3b5e816812c28f4a28d6178a17c21db903d77" +dependencies = [ + "cfg-if 1.0.0", + "dunce", + "ethers-core", + "getrandom", + "glob", + "hex", + "home", + "md-5", + "num_cpus", + "once_cell", + "path-slash", + "rayon", + "regex", + "semver", + "serde", + "serde_json", + "solang-parser", + "svm-rs", + "thiserror", + "tiny-keccak 2.0.2", + "tokio", + "tracing", + "walkdir", + "yansi", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fake-simd" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "ff_ce" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b538e4231443a5b9c507caee3356f016d832cf7393d2d90f03ea3180d4e3fbc" +dependencies = [ + "byteorder", + "ff_derive_ce", + "hex", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "ff_derive_ce" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b96fbccd88dbb1fac4ee4a07c2fcc4ca719a74ffbd9d2b9d41d8c8eb073d8b20" +dependencies = [ + "num-bigint 0.4.5", + "num-integer", + "num-traits", + "proc-macro2 1.0.82", + "quote 1.0.33", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "firestorm" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c5f6c2c942da57e2aaaa84b8a521489486f14e75e7fa91dab70aba913975f98" + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "franklin-crypto" +version = "0.0.5" +source = "git+https://github.com/matter-labs/franklin-crypto?branch=snark_wrapper#2546c63b91b59bdb0ad342d26f03fb57477550b2" +dependencies = [ + "arr_macro", + "bellman_ce", + "bit-vec", + "blake2 0.9.2", + "blake2-rfc_bellman_edition", + "blake2s_simd", + "boojum", + "byteorder", + "derivative", + "digest 0.9.0", + "hex", + "indexmap 1.9.3", + "itertools 0.10.5", + "lazy_static", + "num-bigint 0.4.5", + "num-derive", + "num-integer", + "num-traits", + "rand 0.4.6", + "serde", + "sha2 0.9.9", + "sha3 0.9.1", + "smallvec", + "splitmut", + "tiny-keccak 1.5.0", +] + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-locks" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45ec6fe3675af967e67c5536c0b9d44e34e6c52f86bedc4ea49c5317b8e94d06" +dependencies = [ + "futures-channel", + "futures-task", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c39b3bc2a8f715298032cf5087e58573809374b08160aa7d750582bdb82d2683" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashers" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2bca93b15ea5a746f220e56587f71e73c6165eab783df9e26590069953e3c30" +dependencies = [ + "fxhash", +] + +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.7", + "bytes", + "headers-core", + "http", + "httpdate", + "mime", + "sha1", +] + +[[package]] +name = "headers-core" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" +dependencies = [ + "http", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc88fc67028ae3db0c853baa36269d398d5f45b6982f95549ff5def78c935cd" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3 0.10.8", +] + +[[package]] +name = "k256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +dependencies = [ + "cfg-if 1.0.0", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lalrpop" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a1cbf952127589f2851ab2046af368fd20645491bb4b376f04b7f94d7a9837b" +dependencies = [ + "ascii-canvas", + "bit-set", + "diff", + "ena", + "is-terminal", + "itertools 0.10.5", + "lalrpop-util", + "petgraph", + "regex", + "regex-syntax 0.6.29", + "string_cache", + "term", + "tiny-keccak 2.0.2", + "unicode-xid 0.2.4", +] + +[[package]] +name = "lalrpop-util" +version = "0.19.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3c48237b9604c5a4702de6b824e02006c3214327564636aef27c1028a8fa0ed" +dependencies = [ + "regex", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.154" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.5.0", + "libc", +] + +[[package]] +name = "linkme" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3ae8aae8e1d516e0a3ceee1219eded7f73741607e4227bf11ef2c3e31580427" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad083d767be37e709a232ae2a244445ed032bb9c6bf7d9442dd416ba5a7b7264" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "logos" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c000ca4d908ff18ac99b93a062cb8958d331c3220719c52e77cb19cc6ac5d2c1" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" +dependencies = [ + "beef", + "fnv", + "proc-macro2 1.0.82", + "quote 1.0.33", + "regex-syntax 0.6.29", + "syn 2.0.33", +] + +[[package]] +name = "logos-derive" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbfc0d229f1f42d790440136d941afd806bc9e949e2bcb8faa813b0f00d1267e" +dependencies = [ + "logos-codegen", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if 1.0.0", + "digest 0.10.7", +] + +[[package]] +name = "memchr" +version = "2.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c" + +[[package]] +name = "memoffset" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" +dependencies = [ + "autocfg", +] + +[[package]] +name = "miette" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59bb584eaeeab6bd0226ccf3509a69d7936d148cf3d036ad350abe35e8c6856e" +dependencies = [ + "miette-derive", + "once_cell", + "thiserror", + "unicode-width", +] + +[[package]] +name = "miette-derive" +version = "5.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +dependencies = [ + "num-bigint 0.4.5", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c165a9ab64cf766f73521c0dd2cfdff64f488b8f0b3e621face3462d3db536d7" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-modular" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64a5fe11d4135c3bcdf3a95b18b194afa9608a5f6ff034f5d857bc9a27fb0119" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint 0.4.5", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a015b430d3c108a207fd776d2e2196aaf8b1cf8cf93253e3a097ff3085076a1" +dependencies = [ + "num_enum_derive 0.6.1", +] + +[[package]] +name = "num_enum" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +dependencies = [ + "num_enum_derive 0.7.2", +] + +[[package]] +name = "num_enum_derive" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +dependencies = [ + "proc-macro-crate 3.1.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "open-fastrlp" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "786393f80485445794f6043fd3138854dd109cc6c4bd1a6383db304c9ce9b9ce" +dependencies = [ + "arrayvec 0.7.4", + "auto_impl 1.2.0", + "bytes", + "ethereum-types", + "open-fastrlp-derive", +] + +[[package]] +name = "open-fastrlp-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" +dependencies = [ + "bytes", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "opentelemetry" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-http" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7594ec0e11d8e33faf03530a4c49af7064ebba81c1480e01be67d90b356508b" +dependencies = [ + "async-trait", + "bytes", + "http", + "opentelemetry_api", + "reqwest", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e5e5a5c4135864099f3faafbe939eb4d7f9b80ebf68a8448da961b32a7c1275" +dependencies = [ + "async-trait", + "futures-core", + "http", + "opentelemetry-http", + "opentelemetry-proto", + "opentelemetry-semantic-conventions", + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "reqwest", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e3f814aa9f8c905d0ee4bde026afd3b2577a97c10e1699912e3e44f0c4cbeb" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", + "prost 0.11.9", + "tonic", +] + +[[package]] +name = "opentelemetry-semantic-conventions" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73c9f9340ad135068800e7f1b24e9e09ed9e7143f5bf8518ded3d3ec69789269" +dependencies = [ + "opentelemetry", +] + +[[package]] +name = "opentelemetry_api" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a81f725323db1b1206ca3da8bb19874bbd3f57c3bcd59471bfb04525b265b9b" +dependencies = [ + "futures-channel", + "futures-util", + "indexmap 1.9.3", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", + "urlencoding", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +dependencies = [ + "async-trait", + "crossbeam-channel 0.5.12", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "ordered-float 3.9.2", + "percent-encoding", + "rand 0.8.5", + "regex", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", +] + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "os_info" +version = "3.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2 0.10.8", +] + +[[package]] +name = "packed_simd" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f9f08af0c877571712e2e3e686ad79efad9657dbf0f7c3c8ba943ff6c38932d" +dependencies = [ + "cfg-if 1.0.0", + "num-traits", +] + +[[package]] +name = "pairing_ce" +version = "0.28.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db007b21259660d025918e653508f03050bf23fb96a88601f9936329faadc597" +dependencies = [ + "byteorder", + "cfg-if 1.0.0", + "ff_ce", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "pairing_ce" +version = "0.28.5" +source = "git+https://github.com/matter-labs/pairing.git#d24f2c5871089c4cd4f54c0ca266bb9fef6115eb" +dependencies = [ + "byteorder", + "cfg-if 1.0.0", + "ff_ce", + "rand 0.4.6", + "serde", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +dependencies = [ + "arrayvec 0.7.4", + "bitvec 1.0.1", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +dependencies = [ + "proc-macro-crate 2.0.0", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.5.1", + "smallvec", + "windows-targets 0.52.5", +] + +[[package]] +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "path-slash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e91099d4268b0e11973f036e885d652fb0b21fedcf69738c627f94db6a44f42" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", + "hmac", + "password-hash", + "sha2 0.10.8", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a4d085fd991ac8d5b05a147b437791b4260b76326baf0fc60cf7c9c27ecd33" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bee7be22ce7918f641a33f08e3f43388c7656772244e2bbb2477f44cc9021a" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1511785c5e98d79a05e8a6bc34b4ac2168a0e3e92161862030ad84daa223141" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "pest_meta" +version = "2.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42f0394d3123e33353ca5e1e89092e533d2cc490389f2bd6131c43c634ebc5f" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros", + "phf_shared", + "proc-macro-hack", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro-hack", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "prettyplease" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +dependencies = [ + "proc-macro2 1.0.82", + "syn 2.0.33", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "scale-info", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +dependencies = [ + "dtoa", + "itoa", + "parking_lot 0.12.2", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +dependencies = [ + "bytes", + "prost-derive 0.12.4", +] + +[[package]] +name = "prost-build" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" +dependencies = [ + "bytes", + "heck 0.4.1", + "itertools 0.12.1", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost 0.12.4", + "prost-types", + "regex", + "syn 2.0.33", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "prost-reflect" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "057237efdb71cf4b3f9396302a3d6599a92fa94063ba537b66130980ea9909f3" +dependencies = [ + "base64 0.21.7", + "logos", + "miette", + "once_cell", + "prost 0.12.4", + "prost-types", + "serde", + "serde-value", +] + +[[package]] +name = "prost-types" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" +dependencies = [ + "prost 0.12.4", +] + +[[package]] +name = "protox" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00bb76c5f6221de491fe2c8f39b106330bbd9762c6511119c07940e10eb9ff11" +dependencies = [ + "bytes", + "miette", + "prost 0.12.4", + "prost-reflect", + "prost-types", + "protox-parse", + "thiserror", +] + +[[package]] +name = "protox-parse" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b4581f441c58863525a3e6bec7b8de98188cf75239a56c725a3e7288450a33f" +dependencies = [ + "logos", + "miette", + "prost-types", + "thiserror", +] + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2 1.0.82", +] + +[[package]] +name = "radium" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def50a86306165861203e7f84ecffbbdfdea79f0e51039b33de1e952358c47ac" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" +dependencies = [ + "fuchsia-cprng", + "libc", + "rand_core 0.3.1", + "rdrand", + "winapi", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque 0.8.5", + "crossbeam-utils 0.8.19", +] + +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "redox_users" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +dependencies = [ + "getrandom", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots 0.25.4", + "winreg", +] + +[[package]] +name = "rescue_poseidon" +version = "0.4.1" +source = "git+https://github.com/matter-labs/rescue-poseidon?branch=poseidon2#126937ef0e7a281f1ff9f512ac41a746a691a342" +dependencies = [ + "addchain", + "arrayvec 0.7.4", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "byteorder", + "derivative", + "franklin-crypto", + "lazy_static", + "log", + "num-bigint 0.3.3", + "num-integer", + "num-iter", + "num-traits", + "rand 0.4.6", + "serde", + "sha3 0.9.1", + "smallvec", + "typemap_rev", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rlp-derive" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092474d1a01ea8278f69e6a358998405fae5b8b963ddaeb2b0b04a128bf1dfb0" + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scale-info" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c453e59a955f81fb62ee5d596b450383d699f152d350e9d23a0db2adb78e4c0" +dependencies = [ + "cfg-if 1.0.0", + "derive_more 0.99.17", + "parity-scale-codec", + "scale-info-derive", +] + +[[package]] +name = "scale-info-derive" +version = "2.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18cf6c6447f813ef19eb450e985bcce6705f9ce7660db221b59093d15c79c4b7" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scrypt" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f9e24d2b632954ded8ab2ef9fea0a0c769ea56ea98bddbafbad22caeeadf45d" +dependencies = [ + "hmac", + "pbkdf2", + "salsa20", + "sha2 0.10.8", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.9", + "generic-array 0.14.7", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "secp256k1" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25996b82292a7a57ed3508f052cfff8640d38d32018784acd714758b43da9c8f" +dependencies = [ + "secp256k1-sys", +] + +[[package]] +name = "secp256k1-sys" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +dependencies = [ + "serde", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "sentry" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce4b57f1b521f674df7a1d200be8ff5d74e3712020ee25b553146657b5377d5" +dependencies = [ + "httpdate", + "native-tls", + "reqwest", + "sentry-backtrace", + "sentry-contexts", + "sentry-core", + "sentry-debug-images", + "sentry-panic", + "sentry-tracing", + "tokio", + "ureq", +] + +[[package]] +name = "sentry-backtrace" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cc8d4e04a73de8f718dc703943666d03f25d3e9e4d0fb271ca0b8c76dfa00e" +dependencies = [ + "backtrace", + "once_cell", + "regex", + "sentry-core", +] + +[[package]] +name = "sentry-contexts" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6436c1bad22cdeb02179ea8ef116ffc217797c028927def303bc593d9320c0d1" +dependencies = [ + "hostname", + "libc", + "os_info", + "rustc_version", + "sentry-core", + "uname", +] + +[[package]] +name = "sentry-core" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "901f761681f97db3db836ef9e094acdd8756c40215326c194201941947164ef1" +dependencies = [ + "once_cell", + "rand 0.8.5", + "sentry-types", + "serde", + "serde_json", +] + +[[package]] +name = "sentry-debug-images" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afdb263e73d22f39946f6022ed455b7561b22ff5553aca9be3c6a047fa39c328" +dependencies = [ + "findshlibs", + "once_cell", + "sentry-core", +] + +[[package]] +name = "sentry-panic" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74fbf1c163f8b6a9d05912e1b272afa27c652e8b47ea60cb9a57ad5e481eea99" +dependencies = [ + "sentry-backtrace", + "sentry-core", +] + +[[package]] +name = "sentry-tracing" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82eabcab0a047040befd44599a1da73d3adb228ff53b5ed9795ae04535577704" +dependencies = [ + "sentry-backtrace", + "sentry-core", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "sentry-types" +version = "0.31.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da956cca56e0101998c8688bc65ce1a96f00673a0e58e663664023d4c7911e82" +dependencies = [ + "debugid", + "hex", + "rand 0.8.5", + "serde", + "serde_json", + "thiserror", + "time", + "url", + "uuid 1.8.0", +] + +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-aux" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float 2.10.1", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "serde_json" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15e0ef66bf939a7c890a0bf6d5a733c70202225f9888a89ed5c62298b019129" +dependencies = [ + "indexmap 2.2.6", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer 0.7.3", + "digest 0.8.1", + "fake-simd", + "opaque-debug 0.2.3", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha2" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=1731ced4a116d61ba9dc6ee6d0f38fb8102e357a#1731ced4a116d61ba9dc6ee6d0f38fb8102e357a" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug 0.3.1", +] + +[[package]] +name = "sha3" +version = "0.10.6" +source = "git+https://github.com/RustCrypto/hashes.git?rev=7a187e934c1f6c68e4b4e5cf37541b7a0d64d303#7a187e934c1f6c68e4b4e5cf37541b7a0d64d303" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] + +[[package]] +name = "snark_wrapper" +version = "0.1.0" +source = "git+https://github.com/matter-labs/snark-wrapper.git?branch=main#76959cadabeec344b9fa1458728400d60340e496" +dependencies = [ + "derivative", + "rand 0.4.6", + "rescue_poseidon", +] + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes", + "futures", + "httparse", + "log", + "rand 0.8.5", + "sha-1 0.9.8", +] + +[[package]] +name = "solang-parser" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8ac4bfef383f368bd9bb045107a501cd9cd0b64ad1983e1b7e839d6a44ecad" +dependencies = [ + "itertools 0.10.5", + "lalrpop", + "lalrpop-util", + "phf", + "unicode-xid 0.2.4", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", +] + +[[package]] +name = "splitmut" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c85070f382340e8b23a75808e83573ddf65f9ad9143df9573ca37c1ed2ee956a" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "string_cache" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" +dependencies = [ + "new_debug_unreachable", + "once_cell", + "parking_lot 0.12.2", + "phf_shared", + "precomputed-hash", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap 2.34.0", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2 1.0.82", + "quote 1.0.33", + "rustversion", + "syn 1.0.109", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "svm-rs" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a04fc4f5cd35c700153b233f5575ccb3237e0f941fa5049d9e98254d10bf2fe" +dependencies = [ + "fs2", + "hex", + "home", + "once_cell", + "reqwest", + "semver", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "url", + "zip", +] + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9caece70c63bfba29ec2fed841a09851b14a235c60010fa4de58089b6c025668" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "term" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f" +dependencies = [ + "dirs-next", + "rustversion", + "winapi", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e3de26b0965292219b4287ff031fcba86837900fe9cd2b34ea8ad893c0953d2" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "268026685b2be38d7103e9e507c938a1fcb3d7e6eb15e87870b617bf37b6d581" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d8a021c69bb74a44ccedb824a046447e2c84a01df9e5c20779750acb38e11b2" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.2", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f714dd15bead90401d77e04243611caec13726c2408afd5b31901dfcdcb3b181" +dependencies = [ + "futures-util", + "log", + "rustls 0.20.9", + "tokio", + "tokio-rustls 0.23.4", + "tungstenite", + "webpki", + "webpki-roots 0.22.6", +] + +[[package]] +name = "tokio-util" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap 2.2.6", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand 0.8.5", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75327c6b667828ddc28f5e3f169036cb793c3f588d83bf0f262a7f062ffed3c8" +dependencies = [ + "once_cell", + "opentelemetry", + "opentelemetry_sdk", + "smallvec", + "tracing", + "tracing-core", + "tracing-log 0.1.4", + "tracing-subscriber", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "time", + "tracing", + "tracing-core", + "tracing-log 0.2.0", + "tracing-serde", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.17.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e27992fd6a8c29ee7eef28fc78349aa244134e10ad447ce3b9f0ac0ed0fa4ce0" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes", + "http", + "httparse", + "log", + "rand 0.8.5", + "rustls 0.20.9", + "sha-1 0.10.1", + "thiserror", + "url", + "utf-8", + "webpki", +] + +[[package]] +name = "typemap_rev" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74b08b0c1257381af16a5c3605254d529d3e7e109f3c62befc5d168968192998" + +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "uname" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8" +dependencies = [ + "libc", +] + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "unroll" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ad948c1cb799b1a70f836077721a92a35ac177d4daddf4c20a633786d4cf618" +dependencies = [ + "quote 1.0.33", + "syn 1.0.109", +] + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "ureq" +version = "2.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d11a831e3c0b56e438a28308e7c810799e3c118417f342d30ecec080105395cd" +dependencies = [ + "base64 0.22.1", + "log", + "native-tls", + "once_cell", + "url", +] + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom", + "serde", +] + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "serde", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" [[package]] name = "version_check" version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "vise" +version = "0.1.0" +source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" +dependencies = [ + "compile-fmt", + "elsa", + "linkme", + "once_cell", + "prometheus-client", + "vise-macros", +] + +[[package]] +name = "vise-macros" +version = "0.1.0" +source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "vlog" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "chrono", + "opentelemetry", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "sentry", + "serde_json", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote 1.0.33", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2 1.0.82", + "quote 1.0.33", + "syn 2.0.33", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-timer" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.11.2", + "pin-utils", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5388522c899d1e1c96a4c307e3797e0f697ba7c77dd8e0e625ecba9dd0342937" +dependencies = [ + "arrayvec 0.7.4", + "base64 0.21.7", + "bytes", + "derive_more 0.99.17", + "ethabi", + "ethereum-types", + "futures", + "futures-timer", + "headers", + "hex", + "idna 0.4.0", + "jsonrpc-core", + "log", + "once_cell", + "parking_lot 0.12.2", + "pin-project", + "reqwest", + "rlp", + "secp256k1", + "serde", + "serde_json", + "soketto", + "tiny-keccak 2.0.2", + "tokio", + "tokio-stream", + "tokio-util", + "url", + "web3-async-native-tls", +] + +[[package]] +name = "web3-async-native-tls" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6d8d1636b2627fe63518d5a9b38a569405d9c9bc665c43c9c341de57227ebb" +dependencies = [ + "native-tls", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] [[package]] -name = "winapi" -version = "0.3.9" +name = "windows-targets" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", ] [[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" +name = "windows_aarch64_gnullvm" +version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "aes", + "byteorder", + "bzip2", + "constant_time_eq", + "crc32fast", + "crossbeam-utils 0.8.19", + "flate2", + "hmac", + "pbkdf2", + "sha1", + "time", + "zstd", +] + +[[package]] +name = "zk_evm" +version = "1.3.3" +source = "git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2#fbee20f5bac7d6ca3e22ae69b2077c510a07de4e" +dependencies = [ + "anyhow", + "lazy_static", + "num", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions 0.1.0", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm" +version = "1.4.0" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.4.0#dd76fc5badf2c05278a21b38015a7798fe2fe358" +dependencies = [ + "anyhow", + "lazy_static", + "num", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions 0.1.0", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.5.0#6119ce908ab714f2f99804794e725b97298a6b11" +dependencies = [ + "anyhow", + "lazy_static", + "num", + "serde", + "serde_json", + "static_assertions", + "zk_evm_abstractions 1.5.0", +] + +[[package]] +name = "zk_evm_abstractions" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git#32dd320953841aa78579d9da08abbc70bcaed175" +dependencies = [ + "anyhow", + "num_enum 0.6.1", + "serde", + "static_assertions", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zk_evm_abstractions" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git?branch=v1.5.0#e464b2cf2b146d883be80e7d690c752bf670ff05" +dependencies = [ + "anyhow", + "num_enum 0.6.1", + "serde", + "static_assertions", + "zkevm_opcode_defs 1.5.0", +] + +[[package]] +name = "zkevm_circuits" +version = "1.4.0" +source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.4.0#fb3e2574b5c890342518fc930c145443f039a105" +dependencies = [ + "arrayvec 0.7.4", + "bincode", + "boojum", + "cs_derive", + "derivative", + "hex", + "itertools 0.10.5", + "rand 0.4.6", + "rand 0.8.5", + "seq-macro", + "serde", + "serde_json", + "smallvec", + "zkevm_opcode_defs 1.3.2", +] + +[[package]] +name = "zkevm_circuits" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.5.0#861f81029bf3a916dae55afa5bd7f82b2eaca98b" +dependencies = [ + "arrayvec 0.7.4", + "boojum", + "cs_derive", + "derivative", + "hex", + "itertools 0.10.5", + "rand 0.4.6", + "rand 0.8.5", + "seq-macro", + "serde", + "smallvec", + "zkevm_opcode_defs 1.5.0", +] + +[[package]] +name = "zkevm_opcode_defs" +version = "1.3.2" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.3.2#dffacadeccdfdbff4bc124d44c595c4a6eae5013" +dependencies = [ + "bitflags 2.5.0", + "blake2 0.10.6 (git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e)", + "ethereum-types", + "k256 0.11.6", + "lazy_static", + "sha2 0.10.6", + "sha3 0.10.6", +] + +[[package]] +name = "zkevm_opcode_defs" +version = "1.5.0" +source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.5.0#109d9f734804a8b9dc0531c0b576e2a0f55a40de" +dependencies = [ + "bitflags 2.5.0", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "ethereum-types", + "k256 0.13.2", + "lazy_static", + "p256", + "serde", + "sha2 0.10.8", + "sha3 0.10.8", +] + +[[package]] +name = "zksync_basic_types" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "chrono", + "num_enum 0.7.2", + "serde", + "serde_json", + "strum", + "url", + "web3", +] + +[[package]] +name = "zksync_concurrency" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "anyhow", + "once_cell", + "pin-project", + "rand 0.8.5", + "sha3 0.10.8", + "thiserror", + "time", + "tokio", + "tracing", + "tracing-subscriber", + "vise", +] + +[[package]] +name = "zksync_config" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "rand 0.8.5", + "serde", + "url", + "zksync_basic_types", + "zksync_consensus_utils", + "zksync_crypto_primitives", +] + +[[package]] +name = "zksync_consensus_utils" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "rand 0.8.5", + "thiserror", + "zksync_concurrency", +] + +[[package]] +name = "zksync_contracts" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "envy", + "ethabi", + "hex", + "once_cell", + "serde", + "serde_json", + "zksync_utils", +] + +[[package]] +name = "zksync_crypto" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "hex", + "once_cell", + "serde", + "sha2 0.10.8", + "thiserror", + "zksync_basic_types", +] + +[[package]] +name = "zksync_crypto_primitives" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "hex", + "rand 0.8.5", + "secp256k1", + "serde", + "serde_json", + "thiserror", + "web3", + "zksync_basic_types", + "zksync_utils", +] + +[[package]] +name = "zksync_mini_merkle_tree" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "once_cell", + "zksync_basic_types", + "zksync_crypto", +] + +[[package]] +name = "zksync_protobuf" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "anyhow", + "bit-vec", + "once_cell", + "prost 0.12.4", + "prost-reflect", + "quick-protobuf", + "rand 0.8.5", + "serde", + "serde_json", + "serde_yaml", + "zksync_concurrency", + "zksync_consensus_utils", + "zksync_protobuf_build", +] + +[[package]] +name = "zksync_protobuf_build" +version = "0.1.0" +source = "git+https://github.com/matter-labs/era-consensus.git?rev=92ecb2d5d65e3bc4a883dacd18d0640e86576c8c#92ecb2d5d65e3bc4a883dacd18d0640e86576c8c" +dependencies = [ + "anyhow", + "heck 0.5.0", + "prettyplease", + "proc-macro2 1.0.82", + "prost-build", + "prost-reflect", + "protox", + "quote 1.0.33", + "syn 2.0.33", +] + +[[package]] +name = "zksync_system_constants" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "once_cell", + "zksync_basic_types", + "zksync_utils", +] + +[[package]] +name = "zksync_types" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "chrono", + "derive_more 1.0.0-beta.6", + "hex", + "itertools 0.10.5", + "num", + "num_enum 0.7.2", + "once_cell", + "prost 0.12.4", + "rlp", + "secp256k1", + "serde", + "serde_json", + "strum", + "thiserror", + "zksync_basic_types", + "zksync_config", + "zksync_contracts", + "zksync_crypto_primitives", + "zksync_mini_merkle_tree", + "zksync_protobuf", + "zksync_protobuf_build", + "zksync_system_constants", + "zksync_utils", +] + +[[package]] +name = "zksync_utils" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?branch=main#29a4ffc6b9420590f32a9e1d1585ebffb95eeb6c" +dependencies = [ + "anyhow", + "bigdecimal", + "futures", + "hex", + "itertools 0.10.5", + "num", + "reqwest", + "serde", + "thiserror", + "tokio", + "tracing", + "vlog", + "zk_evm 1.3.3", + "zksync_basic_types", +] [[package]] name = "zksync_verifier_contract_generator" version = "0.1.0" dependencies = [ + "circuit_definitions 1.5.0", + "crypto", "handlebars", + "hex", "lazy_static", "serde_derive", "serde_json", + "sha3 0.10.8", "structopt", ] + +[[package]] +name = "zstd" +version = "0.11.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "5.0.2+zstd.1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/tools/Cargo.toml b/tools/Cargo.toml index 204440623..b32b52bdb 100644 --- a/tools/Cargo.toml +++ b/tools/Cargo.toml @@ -4,10 +4,15 @@ version = "0.1.0" edition = "2021" [dependencies] +zksync_crypto = { git = "https://github.com/matter-labs/era-boojum-validator-cli", branch = "main", package = "crypto" } +circuit_definitions = {git = "https://github.com/matter-labs/era-zkevm_test_harness.git", branch="v1.5.0"} + serde_derive = "1.0" serde_json = "1.0" lazy_static = "1.4" structopt = "0.3.26" handlebars = "4.4.0" +sha3 = "0.10.8" +hex = "0.4.3" [workspace] diff --git a/tools/data/verifier_contract_template.txt b/tools/data/verifier_contract_template.txt index bef14e662..972123961 100644 --- a/tools/data/verifier_contract_template.txt +++ b/tools/data/verifier_contract_template.txt @@ -9,6 +9,7 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. /// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. +/// @dev Contract was generated from a verification key with a hash of 0x{{vk_hash}} /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: diff --git a/tools/rust-toolchain b/tools/rust-toolchain deleted file mode 100644 index 0834888f5..000000000 --- a/tools/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -1.72.0 diff --git a/tools/rust-toolchain.toml b/tools/rust-toolchain.toml new file mode 100644 index 000000000..1388c20ff --- /dev/null +++ b/tools/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-02-04" diff --git a/tools/src/main.rs b/tools/src/main.rs index 3ac8c3ff1..746373fe4 100644 --- a/tools/src/main.rs +++ b/tools/src/main.rs @@ -1,5 +1,9 @@ +use circuit_definitions::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey; +use circuit_definitions::snark_wrapper::franklin_crypto::bellman::pairing::bn256::Bn256; +use circuit_definitions::circuit_definitions::aux_layer::ZkSyncSnarkWrapperCircuit; use handlebars::Handlebars; use serde_json::json; +use zksync_crypto::calculate_verification_key_hash; use std::collections::HashMap; use std::error::Error; use std::fs; @@ -122,8 +126,16 @@ fn main() -> Result<(), Box> { let verifier_contract_template = fs::read_to_string("data/verifier_contract_template.txt")?; + let verification_key = fs::read_to_string(&opt.input_path) + .expect(&format!("Unable to read from {}", &opt.input_path)); + + let verification_key: VerificationKey = + serde_json::from_str(&verification_key).unwrap(); + + let vk_hash = hex::encode(calculate_verification_key_hash(verification_key).to_fixed_bytes()); + let verifier_contract_template = - insert_residue_elements_and_commitments(&verifier_contract_template, &vk)?; + insert_residue_elements_and_commitments(&verifier_contract_template, &vk, &vk_hash)?; let mut file = File::create(opt.output_path)?; @@ -134,6 +146,7 @@ fn main() -> Result<(), Box> { fn insert_residue_elements_and_commitments( template: &str, vk: &HashMap, + vk_hash: &str, ) -> Result> { let reg = Handlebars::new(); let residue_g2_elements = generate_residue_g2_elements(vk); @@ -145,7 +158,8 @@ fn insert_residue_elements_and_commitments( Ok(reg.render_template( &verifier_contract_template, &json!({"residue_g2_elements": residue_g2_elements, - "commitments": commitments}), + "commitments": commitments, + "vk_hash": vk_hash}), )?) } From 900c5c9865c04bedefc1fb8db2548af0cb54d2ae Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 13:47:35 -0400 Subject: [PATCH 42/60] Update Verifier from new vk (#474) --- .../contracts/state-transition/Verifier.sol | 8 ++--- tools/data/scheduler_key.json | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index cfcca1bb9..5d3585545 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -283,8 +283,8 @@ contract Verifier is IVerifier { function _loadVerificationKey() internal pure virtual { assembly { // gate setup commitments - mstore(VK_GATE_SETUP_0_X_SLOT, 0x1705a844ded408a0daac583000aac35a0aab27b1f5827d316e690f4b88f3b216) - mstore(VK_GATE_SETUP_0_Y_SLOT, 0x147c1a7f0688c83f1e93fae4b1d009dddbba688f252faaa123715a65a4843321) + mstore(VK_GATE_SETUP_0_X_SLOT, 0x1f718b0d8640b18fcb605c0b362408e5b96391e1ea32b12332829e557aa50925) + mstore(VK_GATE_SETUP_0_Y_SLOT, 0x0b0186811e335624d3034ed7a7fe02b1a259d5d37fef68694f188924b8d5cea0) mstore(VK_GATE_SETUP_1_X_SLOT, 0x04659caf7b05471ba5ba85b1ab62267aa6c456836e625f169f7119d55b9462d2) mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0ea63403692148d2ad22189a1e5420076312f4d46e62036a043a6b0b84d5b410) mstore(VK_GATE_SETUP_2_X_SLOT, 0x0e6696d09d65fce1e42805be03fca1f14aea247281f688981f925e77d4ce2291) @@ -295,8 +295,8 @@ contract Verifier is IVerifier { mstore(VK_GATE_SETUP_4_Y_SLOT, 0x22e404bc91350f3bc7daad1d1025113742436983c85eac5ab7b42221a181b81e) mstore(VK_GATE_SETUP_5_X_SLOT, 0x0d9b29613037a5025655c82b143d2b7449c98f3aea358307c8529249cc54f3b9) mstore(VK_GATE_SETUP_5_Y_SLOT, 0x15b3c4c946ad1babfc4c03ff7c2423fd354af3a9305c499b7fb3aaebe2fee746) - mstore(VK_GATE_SETUP_6_X_SLOT, 0x1a0524c2f87ff2f2d08434c91ab9e92766eabb600537b27ea944bf65c3636f91) - mstore(VK_GATE_SETUP_6_Y_SLOT, 0x06fab004f5950058c7ac1ab8ebc3d94142d87ac04f3526bc7d13b65433491a2e) + mstore(VK_GATE_SETUP_6_X_SLOT, 0x0ab21cb590aca747d70d9be12b035c786f5a42e002e621627189d5ef13561ce1) + mstore(VK_GATE_SETUP_6_Y_SLOT, 0x0d3c93aafe7eeebad42b789a046b02bb2d92193f6af460e4104ad7ac759ef82a) mstore(VK_GATE_SETUP_7_X_SLOT, 0x283344a1ab3e55ecfd904d0b8e9f4faea338df5a4ead2fa9a42f0e103da40abc) mstore(VK_GATE_SETUP_7_Y_SLOT, 0x223b37b83b9687512d322993edd70e508dd80adb10bcf7321a3cc8a44c269521) diff --git a/tools/data/scheduler_key.json b/tools/data/scheduler_key.json index bf111bcb1..4313abe76 100644 --- a/tools/data/scheduler_key.json +++ b/tools/data/scheduler_key.json @@ -6,16 +6,16 @@ "gate_setup_commitments": [ { "x": [ - 7955907033821327894, - 768751806678465841, - 15757066159455388506, - 1658917051505576096 + 3639645538835826981, + 13358681319193882915, + 14654814390686320869, + 2265744977747292559 ], "y": [ - 2553921856294105889, - 15833082403987892897, - 2203380502856993245, - 1476083910743476287 + 5699456119250210464, + 11698616611432786025, + 15205083455076303537, + 793062898509501988 ], "infinity": false }, @@ -96,16 +96,16 @@ }, { "x": [ - 12197084134616821649, - 7415945757497733758, - 15025192295156279591, - 1874945239681069810 + 8181305420893527265, + 8023799216002703714, + 15496213284243332216, + 770710052375668551 ], "y": [ - 9012747752052431406, - 4816734767853938364, - 14387904291073677633, - 502907843751772248 + 1173987788591134762, + 3283714838474547428, + 15288445962933699259, + 953799583719157434 ], "infinity": false }, From 994897b14eb1d8e77c809da2db3379e7b58125b5 Mon Sep 17 00:00:00 2001 From: koloz193 Date: Thu, 16 May 2024 19:27:36 -0400 Subject: [PATCH 43/60] chore(contract): applied new solhint rules across l1, l2, and system contracts (#473) --- .solhint.json | 45 ++-- .solhintignore | 4 + l1-contracts-foundry/script/DeployErc20.s.sol | 16 +- l1-contracts-foundry/script/DeployL1.s.sol | 17 +- .../script/InitializeL2WethToken.s.sol | 3 +- .../script/RegisterHyperchain.s.sol | 17 +- l1-contracts-foundry/script/Utils.sol | 33 ++- .../script/ZkSyncScriptErrors.sol | 15 ++ .../contracts/bridge/L1ERC20Bridge.sol | 2 + .../contracts/bridge/L1SharedBridge.sol | 6 +- .../contracts/bridgehub/Bridgehub.sol | 4 +- l1-contracts/contracts/common/Messaging.sol | 1 + .../contracts/common/ReentrancyGuard.sol | 2 + .../common/libraries/L2ContractHelper.sol | 2 + .../contracts/dev-contracts/Multicall.sol | 3 +- .../dev-contracts/SingletonFactory.sol | 1 + .../contracts/governance/Governance.sol | 13 + .../IStateTransitionManager.sol | 1 + .../StateTransitionManager.sol | 5 +- .../state-transition/ValidatorTimelock.sol | 6 +- .../chain-deps/DiamondInit.sol | 2 + .../chain-deps/DiamondProxy.sol | 2 + .../chain-deps/ZkSyncHyperchainStorage.sol | 1 + .../chain-deps/facets/Admin.sol | 2 + .../chain-deps/facets/Executor.sol | 18 +- .../chain-deps/facets/Getters.sol | 2 + .../chain-deps/facets/Mailbox.sol | 11 +- .../facets/ZkSyncHyperchainBase.sol | 2 + .../chain-interfaces/IDiamondInit.sol | 1 + .../chain-interfaces/IExecutor.sol | 1 + .../state-transition/libraries/Diamond.sol | 3 + .../state-transition/libraries/Merkle.sol | 2 + .../libraries/PriorityQueue.sol | 2 + .../libraries/TransactionValidator.sol | 2 + .../contracts/upgrades/BaseZkSyncUpgrade.sol | 5 +- .../upgrades/BaseZkSyncUpgradeGenesis.sol | 30 ++- .../contracts/upgrades/UpgradeHyperchains.sol | 2 + .../contracts/upgrades/Upgrade_v1_4_1.sol | 12 +- .../upgrades/ZkSyncUpgradeErrors.sol | 8 + .../contracts/vendor/AddressAliasHelper.sol | 3 +- l1-contracts/foundry.toml | 8 + .../_StateTransitionManager_Shared.t.sol | 2 +- .../test/test_config/constant/hardhat.json | 32 +-- l2-contracts/contracts/L2ContractErrors.sol | 20 ++ .../contracts/SystemContractsCaller.sol | 9 +- l2-contracts/contracts/TestnetPaymaster.sol | 22 +- .../contracts/bridge/L2SharedBridge.sol | 56 ++-- .../contracts/bridge/L2StandardERC20.sol | 33 ++- .../contracts/bridge/L2WrappedBaseToken.sol | 29 +- .../contracts/vendor/AddressAliasHelper.sol | 2 +- package.json | 2 +- system-contracts/SystemContractsHashes.json | 82 +++--- .../contracts/AccountCodeStorage.sol | 19 +- .../contracts/BootloaderUtilities.sol | 15 +- .../contracts/ComplexUpgrader.sol | 9 +- system-contracts/contracts/Compressor.sol | 70 +++-- .../contracts/ContractDeployer.sol | 55 ++-- system-contracts/contracts/DefaultAccount.sol | 21 +- system-contracts/contracts/GasBoundCaller.sol | 13 +- .../contracts/ImmutableSimulator.sol | 5 +- .../contracts/KnownCodesStorage.sol | 13 +- system-contracts/contracts/L1Messenger.sol | 63 +++-- system-contracts/contracts/L2BaseToken.sol | 20 +- .../contracts/MsgValueSimulator.sol | 10 +- system-contracts/contracts/NonceHolder.sol | 28 +- .../contracts/PubdataChunkPublisher.sol | 9 +- system-contracts/contracts/SystemContext.sol | 5 +- .../contracts/SystemContractErrors.sol | 75 ++++++ .../contracts/interfaces/ISystemContract.sol | 27 +- .../contracts/libraries/EfficientCall.sol | 9 +- .../contracts/libraries/RLPEncoder.sol | 2 +- .../libraries/SystemContractHelper.sol | 10 +- .../contracts/libraries/TransactionHelper.sol | 21 +- .../contracts/libraries/Utils.sol | 31 ++- .../test/AccountCodeStorage.spec.ts | 15 +- .../test/BootloaderUtilities.spec.ts | 15 +- system-contracts/test/ComplexUpgrader.spec.ts | 5 +- system-contracts/test/Compressor.spec.ts | 46 ++-- .../test/ContractDeployer.spec.ts | 46 ++-- .../test/ImmutableSimulator.spec.ts | 5 +- .../test/KnownCodesStorage.spec.ts | 19 +- system-contracts/test/L1Messenger.spec.ts | 20 +- system-contracts/test/L2BaseToken.spec.ts | 10 +- system-contracts/test/NonceHolder.spec.ts | 42 +-- .../test/PubdataChunkPublisher.spec.ts | 7 +- system-contracts/test/SystemContext.spec.ts | 14 +- yarn.lock | 254 +++++++++++++++++- 87 files changed, 1188 insertions(+), 444 deletions(-) create mode 100644 l1-contracts-foundry/script/ZkSyncScriptErrors.sol create mode 100644 l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol create mode 100644 l2-contracts/contracts/L2ContractErrors.sol create mode 100644 system-contracts/contracts/SystemContractErrors.sol diff --git a/.solhint.json b/.solhint.json index 617a892bf..ef3522c45 100644 --- a/.solhint.json +++ b/.solhint.json @@ -1,31 +1,40 @@ { "extends": "solhint:recommended", "rules": { - "state-visibility": "off", - "func-visibility": ["warn", { "ignoreConstructors": true }], - "var-name-mixedcase": "off", - "avoid-call-value": "off", - "no-empty-blocks": "off", - "not-rely-on-time": "off", + "avoid-call-value": "error", "avoid-low-level-calls": "off", - "no-inline-assembly": "off", + "avoid-sha3": "error", + "check-send-result": "error", + "compiler-version": ["error", "^0.8.0"], "const-name-snakecase": "off", - "no-complex-fallback": "off", - "reason-string": "off", + "contract-name-camelcase": "off", + "gas-calldata-parameters": "error", + "gas-custom-errors": "error", + "gas-increment-by-one": "error", + "gas-length-in-loops": "error", + "gas-struct-packing": "error", + "explicit-types": "error", "func-name-mixedcase": "off", - "custom-errors": "off", - "no-unused-vars": "error", + "func-named-parameters": ["error", 4], + "func-visibility": ["error", { "ignoreConstructors": true }], + "imports-on-top": "error", "max-states-count": "off", + "modifier-name-mixedcase": "error", + "named-parameters-mapping": "off", + "no-complex-fallback": "off", + "no-console": "error", + "no-empty-blocks": "off", "no-global-import": "error", + "no-inline-assembly": "off", "no-unused-import": "error", - "explicit-types": "error", - "modifier-name-mixedcase": "error", - "imports-on-top": "error", + "no-unused-vars": "error", + "not-rely-on-time": "off", "quotes": "error", - "use-forbidden-name": "error", - "visibility-modifier-order": "error", + "reason-string": "error", "reentrancy": "error", - "func-named-parameters": ["error", 4], - "compiler-version": ["error", "^0.8.0"] + "state-visibility": "error", + "use-forbidden-name": "error", + "var-name-mixedcase": "off", + "visibility-modifier-order": "error" } } diff --git a/.solhintignore b/.solhintignore index ec8271f7e..d6471dfce 100644 --- a/.solhintignore +++ b/.solhintignore @@ -6,6 +6,8 @@ l1-contracts/cache l1-contracts/cache-forge l1-contracts/lib l1-contracts/node_modules +l1-contracts/contracts/dev-contracts +l1-contracts/test # l1-contracts-foundry l1-contracts-foundry/cache @@ -18,3 +20,5 @@ l2-contracts/node_modules # system-contracts system-contracts/contracts/openzeppelin system-contracts/contracts/Constants.sol +system-contracts/contracts/test-contracts +system-contracts/contracts-preprocessed diff --git a/l1-contracts-foundry/script/DeployErc20.s.sol b/l1-contracts-foundry/script/DeployErc20.s.sol index 4a2046ec7..49786b7ca 100644 --- a/l1-contracts-foundry/script/DeployErc20.s.sol +++ b/l1-contracts-foundry/script/DeployErc20.s.sol @@ -7,6 +7,7 @@ import {Script, console2 as console} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; import {Utils} from "./Utils.sol"; +import {MintFailed} from "./ZkSyncScriptErrors.sol"; contract DeployErc20Script is Script { using stdToml for string; @@ -27,7 +28,7 @@ contract DeployErc20Script is Script { uint256 mint; } - Config config; + Config internal config; function run() public { console.log("Deploying ERC20 Tokens"); @@ -52,7 +53,8 @@ contract DeployErc20Script is Script { config.create2FactorySalt = vm.parseTomlBytes32(toml, "$.create2_factory_salt"); string[] memory tokens = vm.parseTomlKeys(toml, "$.tokens"); - for (uint256 i = 0; i < tokens.length; i++) { + uint256 tokensLength = tokens.length; + for (uint256 i = 0; i < tokensLength; ++i) { TokenDescription memory token; string memory key = string.concat("$.tokens.", tokens[i]); token.name = toml.readString(string.concat(key, ".name")); @@ -66,7 +68,8 @@ contract DeployErc20Script is Script { } function deployTokens() internal { - for (uint256 i = 0; i < config.tokens.length; i++) { + uint256 tokensLength = config.tokens.length; + for (uint256 i = 0; i < tokensLength; ++i) { TokenDescription memory token = config.tokens[i]; console.log("Deploying token:", token.name); address tokenAddress = deployErc20({ @@ -103,7 +106,9 @@ contract DeployErc20Script is Script { (bool success, ) = tokenAddress.call( abi.encodeWithSignature("mint(address,uint256)", config.deployerAddress, mint) ); - require(success, "Mint failed"); + if (!success) { + revert MintFailed(); + } } return tokenAddress; @@ -114,7 +119,8 @@ contract DeployErc20Script is Script { vm.serializeBytes32("root", "create2_factory_salt", config.create2FactorySalt); string memory tokens = ""; - for (uint256 i = 0; i < config.tokens.length; i++) { + uint256 tokensLength = config.tokens.length; + for (uint256 i = 0; i < tokensLength; ++i) { TokenDescription memory token = config.tokens[i]; vm.serializeString(token.symbol, "name", token.name); vm.serializeString(token.symbol, "symbol", token.symbol); diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 3768787de..cf20e4f7a 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -31,13 +31,15 @@ import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-de import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {L1ERC20Bridge} from "contracts/bridge/L1ERC20Bridge.sol"; import {DiamondProxy} from "contracts/state-transition/chain-deps/DiamondProxy.sol"; +import {AddressHasNoCode} from "./ZkSyncScriptErrors.sol"; contract DeployL1Script is Script { using stdToml for string; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - address constant DETERMINISTIC_CREATE2_ADDRESS = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + address internal constant DETERMINISTIC_CREATE2_ADDRESS = 0x4e59b44847b379578588920cA78FbF26c0B4956C; + // solhint-disable-next-line gas-struct-packing struct DeployedAddresses { BridgehubDeployedAddresses bridgehub; StateTransitionDeployedAddresses stateTransition; @@ -49,11 +51,13 @@ contract DeployL1Script is Script { address create2Factory; } + // solhint-disable-next-line gas-struct-packing struct BridgehubDeployedAddresses { address bridgehubImplementation; address bridgehubProxy; } + // solhint-disable-next-line gas-struct-packing struct StateTransitionDeployedAddresses { address stateTransitionProxy; address stateTransitionImplementation; @@ -68,6 +72,7 @@ contract DeployL1Script is Script { address diamondProxy; } + // solhint-disable-next-line gas-struct-packing struct BridgesDeployedAddresses { address erc20BridgeImplementation; address erc20BridgeProxy; @@ -75,6 +80,7 @@ contract DeployL1Script is Script { address sharedBridgeProxy; } + // solhint-disable-next-line gas-struct-packing struct Config { uint256 l1ChainId; uint256 eraChainId; @@ -84,6 +90,7 @@ contract DeployL1Script is Script { TokensConfig tokens; } + // solhint-disable-next-line gas-struct-packing struct ContractsConfig { bytes32 create2FactorySalt; address create2FactoryAddr; @@ -112,8 +119,8 @@ contract DeployL1Script is Script { address tokenWethAddress; } - Config config; - DeployedAddresses addresses; + Config internal config; + DeployedAddresses internal addresses; function run() public { console.log("Deploying L1 contracts"); @@ -208,7 +215,7 @@ contract DeployL1Script is Script { if (isConfigured) { if (config.contracts.create2FactoryAddr.code.length == 0) { - revert("Create2Factory configured address is empty"); + revert AddressHasNoCode(config.contracts.create2FactoryAddr); } contractAddress = config.contracts.create2FactoryAddr; console.log("Using configured Create2Factory address:", contractAddress); diff --git a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol index 96828fbe6..a147e3d00 100644 --- a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol +++ b/l1-contracts-foundry/script/InitializeL2WethToken.s.sol @@ -14,6 +14,7 @@ import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; contract InitializeL2WethTokenScript is Script { using stdToml for string; + // solhint-disable-next-line gas-struct-packing struct Config { address deployerAddress; address create2FactoryAddr; @@ -31,7 +32,7 @@ contract InitializeL2WethTokenScript is Script { uint256 gasMultiplier; } - Config config; + Config internal config; function run() public { initializeConfig(); diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 9429a472c..c0d776813 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -15,12 +15,13 @@ import {VerifierParams, IVerifier} from "contracts/state-transition/chain-interf import {FeeParams, PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; import {InitializeDataNewChain as DiamondInitializeDataNewChain} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; import {ValidatorTimelock} from "contracts/state-transition/ValidatorTimelock.sol"; +import {ZksyncContract, MissingAddress, AddressHasNoCode} from "./ZkSyncScriptErrors.sol"; contract RegisterHyperchainScript is Script { using stdToml for string; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - bytes32 constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + bytes32 internal constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); struct Config { ContractsConfig contracts; @@ -49,6 +50,7 @@ contract RegisterHyperchainScript is Script { uint128 baseTokenGasPriceMultiplierDenominator; } + // solhint-disable-next-line gas-struct-packing struct AddressesConfig { address baseToken; address bridgehub; @@ -64,7 +66,7 @@ contract RegisterHyperchainScript is Script { address newDiamondProxy; } - Config config; + Config internal config; function run() public { console.log("Deploying Hyperchain"); @@ -146,7 +148,7 @@ contract RegisterHyperchainScript is Script { function checkTokenAddress() internal { if (config.addresses.baseToken == address(0)) { - revert("Token address is not set"); + revert MissingAddress(ZksyncContract.BaseToken); } // Check if it's ethereum address @@ -155,7 +157,7 @@ contract RegisterHyperchainScript is Script { } if (config.addresses.baseToken.code.length == 0) { - revert("Token address is not a contract address"); + revert AddressHasNoCode(config.addresses.baseToken); } console.log("Using base token address:", config.addresses.baseToken); @@ -248,14 +250,15 @@ contract RegisterHyperchainScript is Script { // Get new diamond proxy address from emitted events Vm.Log[] memory logs = vm.getRecordedLogs(); address diamondProxyAddress; - for (uint256 i = 0; i < logs.length; i++) { + uint256 logsLength = logs.length; + for (uint256 i = 0; i < logsLength; ++i) { if (logs[i].topics[0] == STATE_TRANSITION_NEW_CHAIN_HASH) { diamondProxyAddress = address(uint160(uint256(logs[i].topics[2]))); break; } } if (diamondProxyAddress == address(0)) { - revert("Diamond proxy address not found"); + revert MissingAddress(ZksyncContract.DiamondProxy); } config.addresses.newDiamondProxy = diamondProxyAddress; } diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts-foundry/script/Utils.sol index b9a66426f..c694db463 100644 --- a/l1-contracts-foundry/script/Utils.sol +++ b/l1-contracts-foundry/script/Utils.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.24; import {Vm} from "forge-std/Vm.sol"; +import {ZksyncContract, FailedToDeploy, BytecodeNotSet, FailedToDeployViaCreate2} from "./ZkSyncScriptErrors.sol"; library Utils { // Cheatcodes address, 0x7109709ECfa91a80626fF3989D68f67F5b1DD12D. @@ -30,12 +31,13 @@ library Utils { // Extract selectors from the result string[] memory parts = vm.split(stringResult, "\n"); - bytes4[] memory selectors = new bytes4[](parts.length); - for (uint256 i = 0; i < parts.length; i++) { + uint256 partsLength = parts.length; + bytes4[] memory selectors = new bytes4[](partsLength); + for (uint256 i = 0; i < partsLength; ++i) { bytes memory part = bytes(parts[i]); bytes memory extractedSelector = new bytes(10); // Selector length 10 is 0x + 4 bytes - for (uint256 j = 0; j < 10; j++) { + for (uint256 j = 0; j < 10; ++j) { extractedSelector[j] = part[j]; } bytes4 selector = bytes4(vm.parseBytes(string(extractedSelector))); @@ -44,16 +46,17 @@ library Utils { // Remove `getName()` selector if existing bool hasGetName = false; - for (uint256 i = 0; i < selectors.length; i++) { + uint256 selectorsLength = selectors.length; + for (uint256 i = 0; i < selectorsLength; ++i) { if (selectors[i] == bytes4(keccak256("getName()"))) { - selectors[i] = selectors[selectors.length - 1]; + selectors[i] = selectors[selectorsLength - 1]; hasGetName = true; break; } } if (hasGetName) { - bytes4[] memory newSelectors = new bytes4[](selectors.length - 1); - for (uint256 i = 0; i < selectors.length - 1; i++) { + bytes4[] memory newSelectors = new bytes4[](selectorsLength - 1); + for (uint256 i = 0; i < selectorsLength - 1; ++i) { newSelectors[i] = selectors[i]; } return newSelectors; @@ -76,10 +79,11 @@ library Utils { */ function bytesToUint256(bytes memory bys) internal pure returns (uint256 value) { // Add left padding to 32 bytes if needed - if (bys.length < 32) { + uint256 bytesLength = bys.length; + if (bytesLength < 32) { bytes memory padded = new bytes(32); - for (uint256 i = 0; i < bys.length; i++) { - padded[i + 32 - bys.length] = bys[i]; + for (uint256 i = 0; i < bytesLength; ++i) { + padded[i + 32 - bytesLength] = bys[i]; } bys = padded; } @@ -125,8 +129,9 @@ library Utils { child := create(0, add(bytecode, 0x20), mload(bytecode)) } vm.stopBroadcast(); - require(child != address(0), "Failed to deploy Create2Factory"); - require(child.code.length > 0, "Failed to deploy Create2Factory"); + if (child == address(0) || child.code.length == 0) { + revert FailedToDeploy(ZksyncContract.Create2Factory); + } return child; } @@ -135,7 +140,7 @@ library Utils { */ function deployViaCreate2(bytes memory _bytecode, bytes32 _salt, address _factory) internal returns (address) { if (_bytecode.length == 0) { - revert("Bytecode is not set"); + revert BytecodeNotSet(); } address contractAddress = vm.computeCreate2Address(_salt, keccak256(_bytecode), _factory); if (contractAddress.code.length != 0) { @@ -147,7 +152,7 @@ library Utils { contractAddress = Utils.bytesToAddress(data); if (!success || contractAddress == address(0) || contractAddress.code.length == 0) { - revert("Failed to deploy contract via create2"); + revert FailedToDeployViaCreate2(); } return contractAddress; diff --git a/l1-contracts-foundry/script/ZkSyncScriptErrors.sol b/l1-contracts-foundry/script/ZkSyncScriptErrors.sol new file mode 100644 index 000000000..76295d633 --- /dev/null +++ b/l1-contracts-foundry/script/ZkSyncScriptErrors.sol @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +error FailedToDeploy(ZksyncContract); +error BytecodeNotSet(); +error FailedToDeployViaCreate2(); +error MissingAddress(ZksyncContract); +error AddressHasNoCode(address); +error MintFailed(); + +enum ZksyncContract { + Create2Factory, + DiamondProxy, + BaseToken +} diff --git a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol index da3098969..a19c1b31c 100644 --- a/l1-contracts/contracts/bridge/L1ERC20Bridge.sol +++ b/l1-contracts/contracts/bridge/L1ERC20Bridge.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index d2a9f4b0d..65033089e 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; @@ -37,10 +39,10 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade IBridgehub public immutable override BRIDGE_HUB; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 internal immutable ERA_CHAIN_ID; /// @dev The address of zkSync Era diamond proxy contract. - address immutable ERA_DIAMOND_PROXY; + address internal immutable ERA_DIAMOND_PROXY; /// @dev Stores the first batch number on the zkSync Era Diamond Proxy that was settled after Diamond proxy upgrade. /// This variable is used to differentiate between pre-upgrade and post-upgrade Eth withdrawals. Withdrawals from batches older diff --git a/l1-contracts/contracts/bridgehub/Bridgehub.sol b/l1-contracts/contracts/bridgehub/Bridgehub.sol index 539af6a0c..8a1498fec 100644 --- a/l1-contracts/contracts/bridgehub/Bridgehub.sol +++ b/l1-contracts/contracts/bridgehub/Bridgehub.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Ownable2StepUpgradeable} from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import {PausableUpgradeable} from "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; @@ -169,7 +171,7 @@ contract Bridgehub is IBridgehub, ReentrancyGuard, Ownable2StepUpgradeable, Paus uint256 _chainId, uint256 _batchNumber, uint256 _index, - L2Log memory _log, + L2Log calldata _log, bytes32[] calldata _proof ) external view override returns (bool) { address hyperchain = getHyperchain(_chainId); diff --git a/l1-contracts/contracts/common/Messaging.sol b/l1-contracts/contracts/common/Messaging.sol index 3c934ae5f..496760438 100644 --- a/l1-contracts/contracts/common/Messaging.sol +++ b/l1-contracts/contracts/common/Messaging.sol @@ -122,6 +122,7 @@ struct L2CanonicalTransaction { /// @param factoryDeps The array of L2 bytecodes that the tx depends on. /// @param refundRecipient The recipient of the refund for the transaction on L2. If the transaction fails, then /// this address will receive the `l2Value`. +// solhint-disable-next-line gas-struct-packing struct BridgehubL2TransactionRequest { address sender; address contractL2; diff --git a/l1-contracts/contracts/common/ReentrancyGuard.sol b/l1-contracts/contracts/common/ReentrancyGuard.sol index a19020b77..894f94f5e 100644 --- a/l1-contracts/contracts/common/ReentrancyGuard.sol +++ b/l1-contracts/contracts/common/ReentrancyGuard.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + /** * @custom:security-contact security@matterlabs.dev * @dev Contract module that helps prevent reentrant calls to a function. diff --git a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol index ae1a64250..808068d59 100644 --- a/l1-contracts/contracts/common/libraries/L2ContractHelper.sol +++ b/l1-contracts/contracts/common/libraries/L2ContractHelper.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + /** * @author Matter Labs * @custom:security-contact security@matterlabs.dev diff --git a/l1-contracts/contracts/dev-contracts/Multicall.sol b/l1-contracts/contracts/dev-contracts/Multicall.sol index e2b1391dd..242c01e24 100644 --- a/l1-contracts/contracts/dev-contracts/Multicall.sol +++ b/l1-contracts/contracts/dev-contracts/Multicall.sol @@ -33,7 +33,8 @@ contract Multicall { function aggregate(Call[] memory calls) public returns (uint256 blockNumber, bytes[] memory returnData) { blockNumber = block.number; returnData = new bytes[](calls.length); - for (uint256 i = 0; i < calls.length; ++i) { + uint256 callsLength = calls.length; + for (uint256 i = 0; i < callsLength; ++i) { (bool success, bytes memory ret) = calls[i].target.call(calls[i].callData); require(success, "multicall 1"); returnData[i] = ret; diff --git a/l1-contracts/contracts/dev-contracts/SingletonFactory.sol b/l1-contracts/contracts/dev-contracts/SingletonFactory.sol index b1bd999cf..3e8b9eec9 100644 --- a/l1-contracts/contracts/dev-contracts/SingletonFactory.sol +++ b/l1-contracts/contracts/dev-contracts/SingletonFactory.sol @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: MIT pragma solidity 0.8.24; /** diff --git a/l1-contracts/contracts/governance/Governance.sol b/l1-contracts/contracts/governance/Governance.sol index 42ac46e02..3f40721e9 100644 --- a/l1-contracts/contracts/governance/Governance.sol +++ b/l1-contracts/contracts/governance/Governance.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {IGovernance} from "./IGovernance.sol"; @@ -56,18 +58,21 @@ contract Governance is IGovernance, Ownable2Step { /// @notice Checks that the message sender is contract itself. modifier onlySelf() { + // solhint-disable-next-line reason-string require(msg.sender == address(this), "Only governance contract itself is allowed to call this function"); _; } /// @notice Checks that the message sender is an active security council. modifier onlySecurityCouncil() { + // solhint-disable-next-line reason-string require(msg.sender == securityCouncil, "Only security council is allowed to call this function"); _; } /// @notice Checks that the message sender is an active owner or an active security council. modifier onlyOwnerOrSecurityCouncil() { + // solhint-disable-next-line reason-string require( msg.sender == owner() || msg.sender == securityCouncil, "Only the owner and security council are allowed to call this function" @@ -170,12 +175,14 @@ contract Governance is IGovernance, Ownable2Step { // Check if the predecessor operation is completed. _checkPredecessorDone(_operation.predecessor); // Ensure that the operation is ready to proceed. + // solhint-disable-next-line reason-string require(isOperationReady(id), "Operation must be ready before execution"); // Execute operation. // slither-disable-next-line reentrancy-eth _execute(_operation.calls); // Reconfirming that the operation is still ready after execution. // This is needed to avoid unexpected reentrancy attacks of re-executing the same operation. + // solhint-disable-next-line reason-string require(isOperationReady(id), "Operation must be ready after execution"); // Set operation to be done timestamps[id] = EXECUTED_PROPOSAL_TIMESTAMP; @@ -191,12 +198,14 @@ contract Governance is IGovernance, Ownable2Step { // Check if the predecessor operation is completed. _checkPredecessorDone(_operation.predecessor); // Ensure that the operation is in a pending state before proceeding. + // solhint-disable-next-line reason-string require(isOperationPending(id), "Operation must be pending before execution"); // Execute operation. // slither-disable-next-line reentrancy-eth _execute(_operation.calls); // Reconfirming that the operation is still pending before execution. // This is needed to avoid unexpected reentrancy attacks of re-executing the same operation. + // solhint-disable-next-line reason-string require(isOperationPending(id), "Operation must be pending after execution"); // Set operation to be done timestamps[id] = EXECUTED_PROPOSAL_TIMESTAMP; @@ -217,8 +226,10 @@ contract Governance is IGovernance, Ownable2Step { /// @param _id The operation hash (see `hashOperation` function) /// @param _delay The delay time (in seconds) after which the proposed upgrade can be executed by the owner. function _schedule(bytes32 _id, uint256 _delay) internal { + // solhint-disable reason-string require(!isOperation(_id), "Operation with this proposal id already exists"); require(_delay >= minDelay, "Proposed delay is less than minimum delay"); + // solhint-enable reason-string timestamps[_id] = block.timestamp + _delay; } @@ -226,6 +237,7 @@ contract Governance is IGovernance, Ownable2Step { /// @dev Execute an operation's calls. /// @param _calls The array of calls to be executed. function _execute(Call[] calldata _calls) internal { + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _calls.length; ++i) { // slither-disable-next-line arbitrary-send-eth (bool success, bytes memory returnData) = _calls[i].target.call{value: _calls[i].value}(_calls[i].data); @@ -242,6 +254,7 @@ contract Governance is IGovernance, Ownable2Step { /// @param _predecessorId The hash of the operation that should be completed. /// @dev Doesn't check the operation to be complete if the input is zero. function _checkPredecessorDone(bytes32 _predecessorId) internal view { + // solhint-disable-next-line reason-string require(_predecessorId == bytes32(0) || isOperationDone(_predecessorId), "Predecessor operation not completed"); } diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index d201c8333..d275075d6 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -16,6 +16,7 @@ import {FeeParams} from "./chain-deps/ZkSyncHyperchainStorage.sol"; /// @param genesisBatchCommitment The zk-proof commitment for the genesis batch /// @param diamondCut The diamond cut for the first upgrade transaction on the newly deployed chain /// @param protocolVersion The initial protocol version on the newly deployed chain +// solhint-disable-next-line gas-struct-packing struct StateTransitionManagerInitializeData { address owner; address validatorTimelock; diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index 7271b253d..a152da054 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import {Diamond} from "./libraries/Diamond.sol"; @@ -88,7 +90,8 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own function getAllHyperchains() public view override returns (address[] memory chainAddresses) { uint256[] memory keys = hyperchainMap.keys(); chainAddresses = new address[](keys.length); - for (uint256 i = 0; i < keys.length; i++) { + uint256 keysLength = keys.length; + for (uint256 i = 0; i < keysLength; ++i) { chainAddresses[i] = hyperchainMap.get(i); } } diff --git a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol index d793783d6..396276306 100644 --- a/l1-contracts/contracts/state-transition/ValidatorTimelock.sol +++ b/l1-contracts/contracts/state-transition/ValidatorTimelock.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; import {LibMap} from "./libraries/LibMap.sol"; import {IExecutor} from "./chain-interfaces/IExecutor.sol"; @@ -52,7 +54,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { uint32 public executionDelay; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 internal immutable ERA_CHAIN_ID; constructor(address _initialOwner, uint32 _executionDelay, uint256 _eraChainId) { _transferOwnership(_initialOwner); @@ -130,6 +132,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { // This contract is only a temporary solution, that hopefully will be disabled until 2106 year, so... // It is safe to cast. uint32 timestamp = uint32(block.timestamp); + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; ++i) { committedBatchTimestamp[_chainId].set(_newBatchesData[i].batchNumber, timestamp); } @@ -193,6 +196,7 @@ contract ValidatorTimelock is IExecutor, Ownable2Step { function _executeBatchesInner(uint256 _chainId, StoredBatchInfo[] calldata _newBatchesData) internal { uint256 delay = executionDelay; // uint32 unchecked { + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; ++i) { uint256 commitBatchTimestamp = committedBatchTimestamp[_chainId].get(_newBatchesData[i].batchNumber); diff --git a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol index 424223396..145056590 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Diamond} from "../libraries/Diamond.sol"; import {ZkSyncHyperchainBase} from "./facets/ZkSyncHyperchainBase.sol"; import {L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_GAS_PER_TRANSACTION} from "../../common/Config.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol b/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol index 5cf26ac82..db29da126 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/DiamondProxy.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Diamond} from "../libraries/Diamond.sol"; /// @title Diamond Proxy Contract (EIP-2535) diff --git a/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol b/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol index e76d86f24..a06921fdb 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol @@ -63,6 +63,7 @@ struct FeeParams { /// but NOT to modify already existing variables or change their order. /// NOTE: variables prefixed with '__DEPRECATED_' are deprecated and shouldn't be used. /// Their presence is maintained for compatibility and to prevent storage collision. +// solhint-disable-next-line gas-struct-packing struct ZkSyncHyperchainStorage { /// @dev Storage of variables needed for deprecated diamond cut facet uint256[7] __DEPRECATED_diamondCutStorage; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol index 7eb6e7904..fd1f4929a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors, reason-string + import {IAdmin} from "../../chain-interfaces/IAdmin.sol"; import {Diamond} from "../../libraries/Diamond.sol"; import {MAX_GAS_PER_TRANSACTION} from "../../../common/Config.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 506379eb4..169426871 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors, reason-string + import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {COMMIT_TIMESTAMP_NOT_OLDER, COMMIT_TIMESTAMP_APPROXIMATION_DELTA, EMPTY_STRING_KECCAK, L2_TO_L1_LOG_SERIALIZE_SIZE, MAX_L2_TO_L1_LOGS_COMMITMENT_BYTES, PACKED_L2_BLOCK_TIMESTAMP_MASK, PUBLIC_INPUT_SHIFT, POINT_EVALUATION_PRECOMPILE_ADDR} from "../../../common/Config.sol"; import {IExecutor, L2_LOG_ADDRESS_OFFSET, L2_LOG_KEY_OFFSET, L2_LOG_VALUE_OFFSET, SystemLogKey, LogProcessingOutput, PubdataSource, BLS_MODULUS, PUBDATA_COMMITMENT_SIZE, PUBDATA_COMMITMENT_CLAIMED_VALUE_OFFSET, PUBDATA_COMMITMENT_COMMITMENT_OFFSET, MAX_NUMBER_OF_BLOBS, TOTAL_BLOBS_IN_COMMITMENT, BLOB_SIZE_BYTES} from "../../chain-interfaces/IExecutor.sol"; @@ -146,7 +148,8 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { uint256 processedLogs; // linear traversal of the logs - for (uint256 i = 0; i < emittedL2Logs.length; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { + uint256 logsLength = emittedL2Logs.length; + for (uint256 i = 0; i < logsLength; i = i.uncheckedAdd(L2_TO_L1_LOG_SERIALIZE_SIZE)) { // Extract the values to be compared to/used such as the log sender, key, and value // slither-disable-next-line unused-return (address logSender, ) = UnsafeBytes.readAddress(emittedL2Logs, i + L2_LOG_ADDRESS_OFFSET); @@ -212,7 +215,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { /// @inheritdoc IExecutor function commitBatches( - StoredBatchInfo memory _lastCommittedBatchData, + StoredBatchInfo calldata _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) external nonReentrant onlyValidator { _commitBatches(_lastCommittedBatchData, _newBatchesData); @@ -221,7 +224,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { /// @inheritdoc IExecutor function commitBatchesSharedBridge( uint256, // _chainId - StoredBatchInfo memory _lastCommittedBatchData, + StoredBatchInfo calldata _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) external nonReentrant onlyValidator { _commitBatches(_lastCommittedBatchData, _newBatchesData); @@ -269,6 +272,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { StoredBatchInfo memory _lastCommittedBatchData, CommitBatchInfo[] calldata _newBatchesData ) internal { + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { _lastCommittedBatchData = _commitOneBatch(_lastCommittedBatchData, _newBatchesData[i], bytes32(0)); @@ -301,6 +305,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // Save the batch number where the upgrade transaction was executed. s.l2SystemContractsUpgradeBatchNumber = _newBatchesData[0].batchNumber; + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _newBatchesData.length; i = i.uncheckedInc()) { // The upgrade transaction must only be included in the first batch. bytes32 expectedUpgradeTxHash = i == 0 ? _systemContractUpgradeTxHash : bytes32(0); @@ -566,7 +571,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { blobAuxOutputWords = new bytes32[](2 * TOTAL_BLOBS_IN_COMMITMENT); - for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { blobAuxOutputWords[i * 2] = _blobHashes[i]; blobAuxOutputWords[i * 2 + 1] = _blobCommitments[i]; } @@ -622,6 +627,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { require(_pubdataCommitments.length % PUBDATA_COMMITMENT_SIZE == 0, "bs"); blobCommitments = new bytes32[](MAX_NUMBER_OF_BLOBS); + // solhint-disable-next-line gas-length-in-loops for (uint256 i = 0; i < _pubdataCommitments.length; i += PUBDATA_COMMITMENT_SIZE) { bytes32 blobVersionedHash = _getBlobVersionedHash(versionedHashIndex); @@ -643,7 +649,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { blobCommitments[versionedHashIndex] = keccak256( abi.encodePacked(blobVersionedHash, _pubdataCommitments[i:i + PUBDATA_COMMITMENT_COMMITMENT_OFFSET]) ); - versionedHashIndex += 1; + ++versionedHashIndex; } // This check is required because we want to ensure that there aren't any extra blobs trying to be published. @@ -653,7 +659,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { // We verify that for each set of blobHash/blobCommitment are either both empty // or there are values for both. - for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { require( (_blobHashes[i] == bytes32(0) && blobCommitments[i] == bytes32(0)) || (_blobHashes[i] != bytes32(0) && blobCommitments[i] != bytes32(0)), diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol index 1769dceca..3c72805eb 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; import {VerifierParams} from "../../../state-transition/chain-interfaces/IVerifier.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol index 752913b3f..a65a47b55 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {IMailbox} from "../../chain-interfaces/IMailbox.sol"; @@ -34,7 +36,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { string public constant override getName = "MailboxFacet"; /// @dev Era's chainID - uint256 immutable ERA_CHAIN_ID; + uint256 public immutable ERA_CHAIN_ID; constructor(uint256 _eraChainId) { ERA_CHAIN_ID = _eraChainId; @@ -60,7 +62,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { function proveL2MessageInclusion( uint256 _batchNumber, uint256 _index, - L2Message memory _message, + L2Message calldata _message, bytes32[] calldata _proof ) public view returns (bool) { return _proveL2LogInclusion(_batchNumber, _index, _L2MessageToLog(_message), _proof); @@ -70,7 +72,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { function proveL2LogInclusion( uint256 _batchNumber, uint256 _index, - L2Log memory _log, + L2Log calldata _log, bytes32[] calldata _proof ) external view returns (bool) { return _proveL2LogInclusion(_batchNumber, _index, _log, _proof); @@ -134,7 +136,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { } /// @dev Convert arbitrary-length message to the raw l2 log - function _L2MessageToLog(L2Message memory _message) internal pure returns (L2Log memory) { + function _L2MessageToLog(L2Message calldata _message) internal pure returns (L2Log memory) { return L2Log({ l2ShardId: 0, @@ -279,6 +281,7 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { request.refundRecipient = AddressAliasHelper.actualRefundRecipient(request.refundRecipient, request.sender); // Change the sender address if it is a smart contract to prevent address collision between L1 and L2. // Please note, currently zkSync address derivation is different from Ethereum one, but it may be changed in the future. + // solhint-disable avoid-tx-origin // slither-disable-next-line tx-origin if (request.sender != tx.origin) { request.sender = AddressAliasHelper.applyL1ToL2Alias(request.sender); diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol index 59662d409..3c855e87a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {ZkSyncHyperchainStorage} from "../ZkSyncHyperchainStorage.sol"; import {ReentrancyGuard} from "../../../common/ReentrancyGuard.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol index eaa61c3e5..a8209b546 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol @@ -21,6 +21,7 @@ import {FeeParams} from "../chain-deps/ZkSyncHyperchainStorage.sol"; /// @param priorityTxMaxGasLimit maximum number of the L2 gas that a user can request for L1 -> L2 transactions /// @param feeParams Fee parameters to be used for L1->L2 transactions /// @param blobVersionedHashRetriever Address of contract used to pull the blob versioned hash for a transaction. +// solhint-disable-next-line gas-struct-packing struct InitializeData { uint256 chainId; address bridgehub; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol index 43a7485c7..149b97027 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IExecutor.sol @@ -88,6 +88,7 @@ interface IExecutor is IZkSyncHyperchainBase { /// @param l2LogsTreeRoot Root hash of tree that contains L2 -> L1 messages from this batch /// @param timestamp Rollup batch timestamp, have the same format as Ethereum batch constant /// @param commitment Verified input for the zkSync circuit + // solhint-disable-next-line gas-struct-packing struct StoredBatchInfo { uint64 batchNumber; bytes32 batchHash; diff --git a/l1-contracts/contracts/state-transition/libraries/Diamond.sol b/l1-contracts/contracts/state-transition/libraries/Diamond.sol index 4e44375da..8699f750e 100644 --- a/l1-contracts/contracts/state-transition/libraries/Diamond.sol +++ b/l1-contracts/contracts/state-transition/libraries/Diamond.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; @@ -59,6 +61,7 @@ library Diamond { /// @param action The action that is made on the facet /// @param isFreezable Denotes whether the facet & all their selectors can be frozen /// @param selectors An array of unique selectors that belongs to the facet address + // solhint-disable-next-line gas-struct-packing struct FacetCut { address facet; Action action; diff --git a/l1-contracts/contracts/state-transition/libraries/Merkle.sol b/l1-contracts/contracts/state-transition/libraries/Merkle.sol index ec31073aa..8680f9ac6 100644 --- a/l1-contracts/contracts/state-transition/libraries/Merkle.sol +++ b/l1-contracts/contracts/state-transition/libraries/Merkle.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {UncheckedMath} from "../../common/libraries/UncheckedMath.sol"; /// @author Matter Labs diff --git a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol index cb43068df..186ecda09 100644 --- a/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol +++ b/l1-contracts/contracts/state-transition/libraries/PriorityQueue.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + /// @notice The structure that contains meta information of the L2 transaction that was requested from L1 /// @dev The weird size of fields was selected specifically to minimize the structure storage size /// @param canonicalTxHash Hashed L2 transaction data that is needed to process it diff --git a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol index 71ef18a86..86bdb4294 100644 --- a/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol +++ b/l1-contracts/contracts/state-transition/libraries/TransactionValidator.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {L2CanonicalTransaction} from "../../common/Messaging.sol"; diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol index 07185b095..597563b03 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {ZkSyncHyperchainBase} from "../state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol"; import {VerifierParams} from "../state-transition/chain-interfaces/IVerifier.sol"; import {IVerifier} from "../state-transition/chain-interfaces/IVerifier.sol"; @@ -221,8 +223,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { function _verifyFactoryDeps(bytes[] calldata _factoryDeps, uint256[] calldata _expectedHashes) private pure { require(_factoryDeps.length == _expectedHashes.length, "Wrong number of factory deps"); require(_factoryDeps.length <= MAX_NEW_FACTORY_DEPS, "Factory deps can be at most 32"); + uint256 length = _factoryDeps.length; - for (uint256 i = 0; i < _factoryDeps.length; ++i) { + for (uint256 i = 0; i < length; ++i) { require( L2ContractHelper.hashL2Bytecode(_factoryDeps[i]) == bytes32(_expectedHashes[i]), "Wrong factory dep hash" diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol index 4dccf4565..656ddda13 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {MAX_ALLOWED_PROTOCOL_VERSION_DELTA} from "../common/Config.sol"; import {BaseZkSyncUpgrade} from "./BaseZkSyncUpgrade.sol"; +import {ProtocolVersionShouldBeGreater, ProtocolVersionDeltaTooLarge, PreviousUpgradeNotFinalized, PreviousUpgradeBatchNotCleared} from "./ZkSyncUpgradeErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -13,22 +14,25 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { /// @param _newProtocolVersion The new protocol version function _setNewProtocolVersion(uint256 _newProtocolVersion) internal override { uint256 previousProtocolVersion = s.protocolVersion; - require( + if ( // IMPORTANT Genesis Upgrade difference: Note this is the only thing change > to >= - _newProtocolVersion >= previousProtocolVersion, - "New protocol version is not greater than the current one" - ); - require( - _newProtocolVersion - previousProtocolVersion <= MAX_ALLOWED_PROTOCOL_VERSION_DELTA, - "Too big protocol version difference" - ); + _newProtocolVersion < previousProtocolVersion + ) { + revert ProtocolVersionShouldBeGreater(previousProtocolVersion, _newProtocolVersion); + } + uint256 protocolDiff = _newProtocolVersion - previousProtocolVersion; + if (protocolDiff > MAX_ALLOWED_PROTOCOL_VERSION_DELTA) { + revert ProtocolVersionDeltaTooLarge(protocolDiff, MAX_ALLOWED_PROTOCOL_VERSION_DELTA); + } // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. - require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); - require( - s.l2SystemContractsUpgradeBatchNumber == 0, - "The batch number of the previous upgrade has not been cleaned" - ); + if (s.l2SystemContractsUpgradeTxHash != bytes32(0)) { + revert PreviousUpgradeNotFinalized(); + } + + if (s.l2SystemContractsUpgradeBatchNumber != 0) { + revert PreviousUpgradeBatchNotCleared(); + } s.protocolVersion = _newProtocolVersion; emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion); diff --git a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol index ded2df649..32d6e4380 100644 --- a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol +++ b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable reason-string, gas-custom-errors + import {Diamond} from "../state-transition/libraries/Diamond.sol"; import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; import {ETH_TOKEN_ADDRESS} from "../common/Config.sol"; diff --git a/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol b/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol index baca21ab6..7db229f95 100644 --- a/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol +++ b/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +// solhint-disable gas-custom-errors + import {Diamond} from "../state-transition/libraries/Diamond.sol"; import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; import {PubdataPricingMode, FeeParams} from "../state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; @@ -9,11 +11,11 @@ import {PubdataPricingMode, FeeParams} from "../state-transition/chain-deps/ZkSy /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev contract Upgrade_v1_4_1 is BaseZkSyncUpgrade { - uint32 constant PRIORITY_TX_BATCH_OVERHEAD_L1_GAS = 1_000_000; - uint32 constant PRIORITY_TX_PUBDATA_PER_BATCH = 120_000; - uint32 constant PRIORITY_TX_MAX_GAS_PER_BATCH = 80_000_000; - uint32 constant PRIORITY_TX_MAX_PUBDATA = 99_000; - uint64 constant PRIORITY_TX_MINIMAL_GAS_PRICE = 250_000_000; + uint32 private constant PRIORITY_TX_BATCH_OVERHEAD_L1_GAS = 1_000_000; + uint32 private constant PRIORITY_TX_PUBDATA_PER_BATCH = 120_000; + uint32 private constant PRIORITY_TX_MAX_GAS_PER_BATCH = 80_000_000; + uint32 private constant PRIORITY_TX_MAX_PUBDATA = 99_000; + uint64 private constant PRIORITY_TX_MINIMAL_GAS_PRICE = 250_000_000; /// This event is an exact copy of the "IAdmin.NewFeeParams" event. Since they have the same name and parameters, /// these will be tracked by indexers in the same manner. diff --git a/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol new file mode 100644 index 000000000..d2e78011b --- /dev/null +++ b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +error ProtocolVersionShouldBeGreater(uint256 _oldProtocolVersion, uint256 _newProtocolVersion); +error ProtocolVersionDeltaTooLarge(uint256 _proposedDelta, uint256 _maxDelta); +error PreviousUpgradeNotFinalized(); +error PreviousUpgradeBatchNotCleared(); diff --git a/l1-contracts/contracts/vendor/AddressAliasHelper.sol b/l1-contracts/contracts/vendor/AddressAliasHelper.sol index 19f3b2d79..fe705cfc3 100644 --- a/l1-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l1-contracts/contracts/vendor/AddressAliasHelper.sol @@ -19,7 +19,7 @@ pragma solidity 0.8.24; library AddressAliasHelper { - uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); + uint160 private constant offset = uint160(0x1111000000000000000000000000000000001111); /// @notice Utility function converts the address that submitted a tx /// to the inbox on L1 to the msg.sender viewed on L2 @@ -51,6 +51,7 @@ library AddressAliasHelper { ) internal view returns (address _recipient) { if (_refundRecipient == address(0)) { // If the `_refundRecipient` is not provided, we use the `_prevMsgSender` as the recipient. + // solhint-disable avoid-tx-origin // slither-disable-next-line tx-origin _recipient = _prevMsgSender == tx.origin ? _prevMsgSender diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index dad521718..97b165ced 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -6,5 +6,13 @@ cache_path = 'cache-forge' test = 'test/foundry' solc_version = "0.8.24" evm_version = "cancun" +ignored_error_codes = [ + "missing-receive-ether", + "code-size", +] +ignored_warnings_from = [ + "test", + "contracts/dev-contracts" +] # See more config options https://github.com/foundry-rs/foundry/tree/master/crates/config diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol index cb7251185..7f7b7dfad 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol @@ -118,7 +118,7 @@ contract StateTransitionManagerTest is Test { vm.startPrank(governor); } - function getDiamondCutData(address _diamondInit) internal returns (Diamond.DiamondCutData memory) { + function getDiamondCutData(address _diamondInit) internal view returns (Diamond.DiamondCutData memory) { InitializeDataNewChain memory initializeData = Utils.makeInitializeDataForNewChain(testnetVerifier); bytes memory initCalldata = abi.encode(initializeData); diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index b9bd70c61..0b550819d 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -3,96 +3,96 @@ "name": "DAI", "symbol": "DAI", "decimals": 18, - "address": "0xfCdA09988fC2433BFE27BBe9e95E0C007ee272Fd" + "address": "0x3202935CA01eADd2F0B4e7aA23EFA52315121172" }, { "name": "wBTC", "symbol": "wBTC", "decimals": 8, - "address": "0x3b78cDD294f0b34755c8a9bA8f124Cb6c217b60a" + "address": "0xe73a1c05498e492f182f9B3E3cd65b2F9f52eE94" }, { "name": "BAT", "symbol": "BAT", "decimals": 18, - "address": "0xd4a9D970EF600289dC96b67505027D17604FBfe1" + "address": "0x7aAE2ee8317b384aDE246664933A147411b60045" }, { "name": "GNT", "symbol": "GNT", "decimals": 18, - "address": "0x4fE0EE70D78132fBb5C68C1d5e0020f3c05542f2" + "address": "0x02a344d1e31e92e39c2681937645F1d668C37d4e" }, { "name": "MLTT", "symbol": "MLTT", "decimals": 18, - "address": "0x3202935CA01eADd2F0B4e7aA23EFA52315121172" + "address": "0x28033f8EdB2F43747E55401C4a3E3b4b2cF5146C" }, { "name": "DAIK", "symbol": "DAIK", "decimals": 18, - "address": "0xe73a1c05498e492f182f9B3E3cd65b2F9f52eE94" + "address": "0x147dCc3a8E99794C2Ec79EaF1a142324D6778255" }, { "name": "wBTCK", "symbol": "wBTCK", "decimals": 8, - "address": "0x7aAE2ee8317b384aDE246664933A147411b60045" + "address": "0x74cA8715E29196Bfbcd7444B09203d22dDaF7d1a" }, { "name": "BATK", "symbol": "BATS", "decimals": 18, - "address": "0x02a344d1e31e92e39c2681937645F1d668C37d4e" + "address": "0x2eAf3eac597d23db3A8427329482aE47935141d9" }, { "name": "GNTK", "symbol": "GNTS", "decimals": 18, - "address": "0x28033f8EdB2F43747E55401C4a3E3b4b2cF5146C" + "address": "0x2B1b32d23f2be391280bFbD2B51daB8Ad2a69B9e" }, { "name": "MLTTK", "symbol": "MLTTS", "decimals": 18, - "address": "0x147dCc3a8E99794C2Ec79EaF1a142324D6778255" + "address": "0xc2Ca10940Ad80Cd98512B767457bd44713232B5a" }, { "name": "DAIL", "symbol": "DAIL", "decimals": 18, - "address": "0x74cA8715E29196Bfbcd7444B09203d22dDaF7d1a" + "address": "0xd6b4CDa9F0Ef6d9F6b35Ab5424df0dD95E6a6D1b" }, { "name": "wBTCL", "symbol": "wBTCP", "decimals": 8, - "address": "0x2eAf3eac597d23db3A8427329482aE47935141d9" + "address": "0x15CD4a1C10AE2D3727Dad680a1966947931588C9" }, { "name": "BATL", "symbol": "BATW", "decimals": 18, - "address": "0x2B1b32d23f2be391280bFbD2B51daB8Ad2a69B9e" + "address": "0x45f430CFD5Bf38eCE39f1B9A2930B3fD494619e8" }, { "name": "GNTL", "symbol": "GNTW", "decimals": 18, - "address": "0xc2Ca10940Ad80Cd98512B767457bd44713232B5a" + "address": "0x801Ab08819573537C0B256d139473eF13482B3Dd" }, { "name": "MLTTL", "symbol": "MLTTW", "decimals": 18, - "address": "0xd6b4CDa9F0Ef6d9F6b35Ab5424df0dD95E6a6D1b" + "address": "0xf55F3af54B9a507Bd0260e5844C1648921214745" }, { "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, - "address": "0x15CD4a1C10AE2D3727Dad680a1966947931588C9" + "address": "0xed01DF970925Cc0BB427f9E8014449C8a529D303" } ] diff --git a/l2-contracts/contracts/L2ContractErrors.sol b/l2-contracts/contracts/L2ContractErrors.sol new file mode 100644 index 000000000..98b5048b3 --- /dev/null +++ b/l2-contracts/contracts/L2ContractErrors.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +error InvalidCaller(address); +error InvalidInput(); +error InsufficientAllowance(uint256 providedAllowance, uint256 requiredAmount); +error FailedToTransferTokens(address tokenContract, address to, uint256 amount); +error UnsupportedPaymasterFlow(); +error EmptyAddress(); +error EmptyBytes32(); +error AddressMismatch(address expected, address supplied); +error AmountMustBeGreaterThanZero(); +error DeployFailed(); +error Unauthorized(); +error NonSequentialVersion(); +error Unimplemented(); +error UnimplementedMessage(string); +error WithdrawFailed(); + +string constant BRIDGE_MINT_NOT_IMPLEMENTED = "bridgeMint is not implemented! Use deposit/depositTo methods instead."; diff --git a/l2-contracts/contracts/SystemContractsCaller.sol b/l2-contracts/contracts/SystemContractsCaller.sol index 36153eb6d..97753cbac 100644 --- a/l2-contracts/contracts/SystemContractsCaller.sol +++ b/l2-contracts/contracts/SystemContractsCaller.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT +// solhint-disable one-contract-per-file + pragma solidity 0.8.20; import {MSG_VALUE_SYSTEM_CONTRACT} from "./L2ContractHelper.sol"; @@ -23,9 +25,14 @@ enum CalldataForwardingMode { UseAuxHeap } +/// @notice Error thrown a cast from uint256 to u32 is not possible. +error U32CastOverflow(); + library Utils { function safeCastToU32(uint256 _x) internal pure returns (uint32) { - require(_x <= type(uint32).max, "Overflow"); + if (_x > type(uint32).max) { + revert U32CastOverflow(); + } return uint32(_x); } diff --git a/l2-contracts/contracts/TestnetPaymaster.sol b/l2-contracts/contracts/TestnetPaymaster.sol index 41ce678c1..6a85ff84c 100644 --- a/l2-contracts/contracts/TestnetPaymaster.sol +++ b/l2-contracts/contracts/TestnetPaymaster.sol @@ -7,6 +7,7 @@ import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import {IPaymaster, ExecutionResult, PAYMASTER_VALIDATION_SUCCESS_MAGIC} from "./interfaces/IPaymaster.sol"; import {IPaymasterFlow} from "./interfaces/IPaymasterFlow.sol"; import {Transaction, BOOTLOADER_ADDRESS} from "./L2ContractHelper.sol"; +import {InvalidCaller, InvalidInput, InsufficientAllowance, FailedToTransferTokens, UnsupportedPaymasterFlow} from "./L2ContractErrors.sol"; // This is a dummy paymaster. It expects the paymasterInput to contain its "signature" as well as the needed exchange rate. // It supports only approval-based paymaster flow. @@ -19,8 +20,13 @@ contract TestnetPaymaster is IPaymaster { // By default we consider the transaction as accepted. magic = PAYMASTER_VALIDATION_SUCCESS_MAGIC; - require(msg.sender == BOOTLOADER_ADDRESS, "Only bootloader can call this contract"); - require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long"); + if (msg.sender != BOOTLOADER_ADDRESS) { + revert InvalidCaller(msg.sender); + } + + if (_transaction.paymasterInput.length < 4) { + revert InvalidInput(); + } bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]); if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { @@ -33,7 +39,9 @@ contract TestnetPaymaster is IPaymaster { address thisAddress = address(this); uint256 providedAllowance = IERC20(token).allowance(userAddress, thisAddress); - require(providedAllowance >= amount, "The user did not provide enough allowance"); + if (providedAllowance < amount) { + revert InsufficientAllowance(providedAllowance, amount); + } // The testnet paymaster exchanges X wei of the token to the X wei of ETH. uint256 requiredETH = _transaction.gasLimit * _transaction.maxFeePerGas; @@ -51,7 +59,7 @@ contract TestnetPaymaster is IPaymaster { // If the revert reason is empty or represented by just a function selector, // we replace the error with a more user-friendly message if (revertReason.length <= 4) { - revert("Failed to transferFrom from users' account"); + revert FailedToTransferTokens(token, thisAddress, amount); } else { assembly { revert(add(0x20, revertReason), mload(revertReason)) @@ -61,9 +69,11 @@ contract TestnetPaymaster is IPaymaster { // The bootloader never returns any data, so it can safely be ignored here. (bool success, ) = payable(BOOTLOADER_ADDRESS).call{value: requiredETH}(""); - require(success, "Failed to transfer funds to the bootloader"); + if (!success) { + revert FailedToTransferTokens(address(0), BOOTLOADER_ADDRESS, requiredETH); + } } else { - revert("Unsupported paymaster flow"); + revert UnsupportedPaymasterFlow(); } } diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index 82c5bc615..e8102022b 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -15,6 +15,8 @@ import {AddressAliasHelper} from "../vendor/AddressAliasHelper.sol"; import {L2ContractHelper, DEPLOYER_SYSTEM_CONTRACT, IContractDeployer} from "../L2ContractHelper.sol"; import {SystemContractsCaller} from "../SystemContractsCaller.sol"; +import {EmptyAddress, EmptyBytes32, InvalidCaller, AddressMismatch, AmountMustBeGreaterThanZero, DeployFailed} from "../L2ContractErrors.sol"; + /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev /// @notice The "default" bridge implementation for the ERC20 tokens. Note, that it does not @@ -35,10 +37,10 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { address private l1LegacyBridge; + uint256 internal immutable ERA_CHAIN_ID; + /// @dev Contract is expected to be used as proxy implementation. /// @dev Disable the initialization to prevent Parity hack. - uint256 immutable ERA_CHAIN_ID; - constructor(uint256 _eraChainId) { ERA_CHAIN_ID = _eraChainId; _disableInitializers(); @@ -54,9 +56,17 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { bytes32 _l2TokenProxyBytecodeHash, address _aliasedOwner ) external reinitializer(2) { - require(_l1Bridge != address(0), "bf"); - require(_l2TokenProxyBytecodeHash != bytes32(0), "df"); - require(_aliasedOwner != address(0), "sf"); + if (_l1Bridge == address(0)) { + revert EmptyAddress(); + } + + if (_l2TokenProxyBytecodeHash == bytes32(0)) { + revert EmptyBytes32(); + } + + if (_aliasedOwner == address(0)) { + revert EmptyAddress(); + } l1Bridge = _l1Bridge; @@ -66,7 +76,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; l2TokenBeacon.transferOwnership(_aliasedOwner); } else { - require(_l1LegacyBridge != address(0), "bf2"); + if (_l1LegacyBridge == address(0)) { + revert EmptyAddress(); + } l1LegacyBridge = _l1LegacyBridge; // l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy } @@ -86,20 +98,26 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { bytes calldata _data ) external override { // Only the L1 bridge counterpart can initiate and finalize the deposit. - require( - AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1Bridge || - AddressAliasHelper.undoL1ToL2Alias(msg.sender) == l1LegacyBridge, - "mq" - ); + if ( + AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1Bridge && + AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1LegacyBridge + ) { + revert InvalidCaller(msg.sender); + } address expectedL2Token = l2TokenAddress(_l1Token); address currentL1Token = l1TokenAddress[expectedL2Token]; if (currentL1Token == address(0)) { address deployedToken = _deployL2Token(_l1Token, _data); - require(deployedToken == expectedL2Token, "mt"); + if (deployedToken != expectedL2Token) { + revert AddressMismatch(expectedL2Token, deployedToken); + } + l1TokenAddress[expectedL2Token] = _l1Token; } else { - require(currentL1Token == _l1Token, "gg"); // Double check that the expected value equal to real one + if (currentL1Token != _l1Token) { + revert AddressMismatch(_l1Token, currentL1Token); + } } IL2StandardToken(expectedL2Token).bridgeMint(_l2Receiver, _amount); @@ -122,12 +140,16 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { /// @param _l2Token The L2 token address which is withdrawn /// @param _amount The total amount of tokens to be withdrawn function withdraw(address _l1Receiver, address _l2Token, uint256 _amount) external override { - require(_amount > 0, "Amount cannot be zero"); + if (_amount == 0) { + revert AmountMustBeGreaterThanZero(); + } IL2StandardToken(_l2Token).bridgeBurn(msg.sender, _amount); address l1Token = l1TokenAddress[_l2Token]; - require(l1Token != address(0), "yh"); + if (l1Token == address(0)) { + revert EmptyAddress(); + } bytes memory message = _getL1WithdrawMessage(_l1Receiver, l1Token, _amount); L2ContractHelper.sendMessageToL1(message); @@ -174,7 +196,9 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { ); // The deployment should be successful and return the address of the proxy - require(success, "mk"); + if (!success) { + revert DeployFailed(); + } proxy = BeaconProxy(abi.decode(returndata, (address))); } } diff --git a/l2-contracts/contracts/bridge/L2StandardERC20.sol b/l2-contracts/contracts/bridge/L2StandardERC20.sol index d72608368..2104629f4 100644 --- a/l2-contracts/contracts/bridge/L2StandardERC20.sol +++ b/l2-contracts/contracts/bridge/L2StandardERC20.sol @@ -7,6 +7,7 @@ import {UpgradeableBeacon} from "@openzeppelin/contracts/proxy/beacon/Upgradeabl import {ERC1967Upgrade} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Upgrade.sol"; import {IL2StandardToken} from "./interfaces/IL2StandardToken.sol"; +import {EmptyAddress, Unauthorized, NonSequentialVersion, Unimplemented} from "../L2ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -47,8 +48,10 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg /// @param _l1Address Address of the L1 token that can be deposited to mint this L2 token /// @param _data The additional data that the L1 bridge provide for initialization. /// In this case, it is packed `name`/`symbol`/`decimals` of the L1 token. - function bridgeInitialize(address _l1Address, bytes memory _data) external initializer { - require(_l1Address != address(0), "in6"); // Should be non-zero address + function bridgeInitialize(address _l1Address, bytes calldata _data) external initializer { + if (_l1Address == address(0)) { + revert EmptyAddress(); + } l1Address = _l1Address; l2Bridge = msg.sender; @@ -110,14 +113,16 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg /// to ensure that the governor can not accidentally disable future reinitialization of the token. function reinitializeToken( ERC20Getters calldata _availableGetters, - string memory _newName, - string memory _newSymbol, + string calldata _newName, + string calldata _newSymbol, uint8 _version ) external onlyNextVersion(_version) reinitializer(_version) { // It is expected that this token is deployed as a beacon proxy, so we'll // allow the governor of the beacon to reinitialize the token. address beaconAddress = _getBeacon(); - require(msg.sender == UpgradeableBeacon(beaconAddress).owner(), "tt"); + if (msg.sender != UpgradeableBeacon(beaconAddress).owner()) { + revert Unauthorized(); + } __ERC20_init_unchained(_newName, _newSymbol); __ERC20Permit_init(_newName); @@ -127,14 +132,18 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg } modifier onlyBridge() { - require(msg.sender == l2Bridge, "xnt"); // Only L2 bridge can call this method + if (msg.sender != l2Bridge) { + revert Unauthorized(); + } _; } modifier onlyNextVersion(uint8 _version) { // The version should be incremented by 1. Otherwise, the governor risks disabling // future reinitialization of the token by providing too large a version. - require(_version == _getInitializedVersion() + 1, "v"); + if (_version != _getInitializedVersion() + 1) { + revert NonSequentialVersion(); + } _; } @@ -158,29 +167,29 @@ contract L2StandardERC20 is ERC20PermitUpgradeable, IL2StandardToken, ERC1967Upg function name() public view override returns (string memory) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreName) revert(); + if (availableGetters.ignoreName) revert Unimplemented(); return super.name(); } function symbol() public view override returns (string memory) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreSymbol) revert(); + if (availableGetters.ignoreSymbol) revert Unimplemented(); return super.symbol(); } function decimals() public view override returns (uint8) { // If method is not available, behave like a token that does not implement this method - revert on call. - if (availableGetters.ignoreDecimals) revert(); + if (availableGetters.ignoreDecimals) revert Unimplemented(); return decimals_; } /// @dev External function to decode a string from bytes. - function decodeString(bytes memory _input) external pure returns (string memory result) { + function decodeString(bytes calldata _input) external pure returns (string memory result) { (result) = abi.decode(_input, (string)); } /// @dev External function to decode a uint8 from bytes. - function decodeUint8(bytes memory _input) external pure returns (uint8 result) { + function decodeUint8(bytes calldata _input) external pure returns (uint8 result) { (result) = abi.decode(_input, (uint8)); } } diff --git a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol index 8cf4d7b5c..8fc3b05b9 100644 --- a/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol +++ b/l2-contracts/contracts/bridge/L2WrappedBaseToken.sol @@ -7,6 +7,8 @@ import {ERC20PermitUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ import {IL2WrappedBaseToken} from "./interfaces/IL2WrappedBaseToken.sol"; import {IL2StandardToken} from "./interfaces/IL2StandardToken.sol"; +import {EmptyAddress, Unauthorized, UnimplementedMessage, BRIDGE_MINT_NOT_IMPLEMENTED, WithdrawFailed} from "../L2ContractErrors.sol"; + /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev /// @notice The canonical implementation of the WETH token. @@ -42,13 +44,18 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S /// @param _l1Address Address of the L1 token that can be deposited to mint this L2 WETH. /// Note: The decimals are hardcoded to 18, the same as on Ether. function initializeV2( - string memory name_, - string memory symbol_, + string calldata name_, + string calldata symbol_, address _l2Bridge, address _l1Address ) external reinitializer(2) { - require(_l2Bridge != address(0), "L2 bridge address cannot be zero"); - require(_l1Address != address(0), "L1 WETH token address cannot be zero"); + if (_l2Bridge == address(0)) { + revert EmptyAddress(); + } + + if (_l1Address == address(0)) { + revert EmptyAddress(); + } l2Bridge = _l2Bridge; l1Address = _l1Address; @@ -62,7 +69,9 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S } modifier onlyBridge() { - require(msg.sender == l2Bridge, "permission denied"); // Only L2 bridge can call this method + if (msg.sender != l2Bridge) { + revert Unauthorized(); + } _; } @@ -71,7 +80,7 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S /// Note: Use `deposit`/`depositTo` methods instead. // solhint-disable-next-line no-unused-vars function bridgeMint(address _to, uint256 _amount) external override onlyBridge { - revert("bridgeMint is not implemented! Use deposit/depositTo methods instead."); + revert UnimplementedMessage(BRIDGE_MINT_NOT_IMPLEMENTED); } /// @dev Burn tokens from a given account and send the same amount of Ether to the bridge. @@ -82,7 +91,9 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S _burn(_from, _amount); // sends Ether to the bridge (bool success, ) = msg.sender.call{value: _amount}(""); - require(success, "Failed withdrawal"); + if (!success) { + revert WithdrawFailed(); + } emit BridgeBurn(_from, _amount); } @@ -107,7 +118,9 @@ contract L2WrappedBaseToken is ERC20PermitUpgradeable, IL2WrappedBaseToken, IL2S function withdrawTo(address _to, uint256 _amount) public override { _burn(msg.sender, _amount); (bool success, ) = _to.call{value: _amount}(""); - require(success, "Failed withdrawal"); + if (!success) { + revert WithdrawFailed(); + } } /// @dev Fallback function to allow receiving Ether. diff --git a/l2-contracts/contracts/vendor/AddressAliasHelper.sol b/l2-contracts/contracts/vendor/AddressAliasHelper.sol index da0282ed8..33b5e95e8 100644 --- a/l2-contracts/contracts/vendor/AddressAliasHelper.sol +++ b/l2-contracts/contracts/vendor/AddressAliasHelper.sol @@ -19,7 +19,7 @@ pragma solidity 0.8.20; library AddressAliasHelper { - uint160 constant offset = uint160(0x1111000000000000000000000000000000001111); + uint160 internal constant offset = uint160(0x1111000000000000000000000000000000001111); /// @notice Utility function converts the address that submitted a tx /// to the inbox on L1 to the msg.sender viewed on L2 diff --git a/package.json b/package.json index 9bb6bdd1e..edb9817b9 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "markdownlint-cli": "^0.33.0", "prettier-plugin-solidity": "^1.1.3", "prettier": "^3.0.3", - "solhint": "^3.6.2" + "solhint": "4.5.4" }, "scripts": { "lint:check": "yarn lint:md && yarn lint:sol && yarn lint:ts && yarn prettier:check", diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 79fba0a88..e56f2dcc0 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -3,50 +3,50 @@ "contractName": "AccountCodeStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x01000075076d9e9ca73d51f8ef0af1bb2e7f74fd8377876ab6bc470a2900a4bf", - "sourceCodeHash": "0xfbf66e830201c4b7fda14f0ddf28a53beb7fbb48a8406392bcfd0ef7ea9265c8" + "bytecodeHash": "0x0100005db7d0621192834d201f8bcd14c6ac987b95f422ca8bb28d500748f1fa", + "sourceCodeHash": "0x69d2533e5481ff13e65f4442e650f4b90c46a48ac643cac9798bbbf421194353" }, { "contractName": "BootloaderUtilities", "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007d1e60e441b0b776e8f6b1c8a9e0fdd787a944a9d851cd093a3b65b3daa", - "sourceCodeHash": "0x9ff5a2da00acfa145ee4575381ad386587d96b6a0309d05015974f4726881132" + "bytecodeHash": "0x010007c7e006453f3693c1f1c7500b74c594e7a627076be9d2dcb35c1c268dc3", + "sourceCodeHash": "0x26060f33c7c63bd1f8a1a2f3b368b97ef8dd939bc53e95090f2c556248b99dce" }, { "contractName": "ComplexUpgrader", "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x0100005576cef4b90577db7ca2e5cc02340a0b56ee9473b34756502963551a97", - "sourceCodeHash": "0x0aa5d7ed159e783acde47856b13801b7f2268ba39b2fa50807fe3d705c506e96" + "bytecodeHash": "0x0100004db8b96797e7d854f2c67c2f13d3920dcf82602f77a6ce0e2353304b37", + "sourceCodeHash": "0xdde7c49a94cc3cd34c3e7ced1b5ba45e4740df68d26243871edbe393e7298f7a" }, { "contractName": "Compressor", "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x0100017924bee877f2ab925cfb1c161ef3c19a8a3034da5d4fd76d0c377a3749", - "sourceCodeHash": "0xd43ac120a50398e0d6bdcfcf807154bfeece0c231509a0eb2e00bcad744e60cd" + "bytecodeHash": "0x0100014387fd8393671b5edd2cc5bb58f72d357c033a44c6274fe92abf19f96d", + "sourceCodeHash": "0x63f5f3a541ac5b59736f9117b15f293346d1842fbfe75219f7961e73185315c5" }, { "contractName": "ContractDeployer", "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010005217819daf0124b7ccb96aca43053d0d13c0c8ad8ae7568d811eecbc3bf", - "sourceCodeHash": "0x635301b824f927b4d17b3d9974cf6abbf979dda49e610805637db7c677d5f522" + "bytecodeHash": "0x010004e5219e70c32d67ed1df0c46983a83a382e482abb5c4310ad554f55f738", + "sourceCodeHash": "0x28208c532ed8851077a9bb0a87636215840ce964397ab0767692f956a0fd11b3" }, { "contractName": "Create2Factory", "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x0100004b3ac74b1706466d4b2f2b401addad6f17fabb7c8b979cea2fe700cbaf", + "bytecodeHash": "0x01000049cd4b556f8ebc05b0bd35d9996e0b65412343bcc8eb6ce14d958dd21f", "sourceCodeHash": "0x217e65f55c8add77982171da65e0db8cc10141ba75159af582973b332a4e098a" }, { "contractName": "DefaultAccount", "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x01000563e438856e95e453dd4380fbcbb2d8657320ebe7b067f88d7e7898d6bb", - "sourceCodeHash": "0xa42423712ddaa8f357d26e46825fda80a9a870d0ac7ff52c98884355f1173ec7" + "bytecodeHash": "0x0100055dbcf921fb36006fa42209bda58bc468eb33257b1782e854ed29273e64", + "sourceCodeHash": "0xeb5ac8fc83e1c8619db058a9b6973958bd6ed1b6f4938f8f4541d702f12e085d" }, { "contractName": "EmptyContract", @@ -59,64 +59,64 @@ "contractName": "GasBoundCaller", "bytecodePath": "artifacts-zk/contracts-preprocessed/GasBoundCaller.sol/GasBoundCaller.json", "sourceCodePath": "contracts-preprocessed/GasBoundCaller.sol", - "bytecodeHash": "0x010000b51b2bae505be6deb2294505457c6e8df65d6b8d08f32d0d85f8610c60", - "sourceCodeHash": "0xd6877ecfd598bcf8abe26ec344949ae8f992d9a8ab1ac8d529a21da521f77923" + "bytecodeHash": "0x010000abbab74213f27d4d7f132761f7315ad84dd2239195f336aa910c9c92fc", + "sourceCodeHash": "0x7774719fe82d1664af19f3f30e9ca2223784374367d32399638671722e9da850" }, { "contractName": "ImmutableSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x0100003dc7171a0acf2c4290f0ed222e9d2496b02a47202862e2b2dc70436c4a", - "sourceCodeHash": "0x30df621c72cb35b8820b902b91057f72d0214a0e4a6b7ad4c0847e674e8b9df8" + "bytecodeHash": "0x0100003b91f0ceda986543b6b45811b72cb492cdcb80c42d8600185e33f72251", + "sourceCodeHash": "0x4212e99cbc1722887cfb5b4cb967f278ac8642834786f0e3c6f3b324a9316815" }, { "contractName": "KnownCodesStorage", "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100007d6f907a56f64d3c054ae5e4a8f73499e1d9fdfea09684fc9de9542941", - "sourceCodeHash": "0x51d388adc58f67ef975a94a7978caa60ed8a0df9d3bd9ac723dfcfc540286c70" + "bytecodeHash": "0x0100006f8342acd40c21d8e535e8ceb65d370ad76a116f3a893fa67452bb616f", + "sourceCodeHash": "0x8da495a9fc5aa0d7d20a165a4fc8bc77012bec29c472015ea5ecc0a2bd706137" }, { "contractName": "L1Messenger", "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002b9ed3fe658cc5fbc4c2d8b4b5325f47a417f9df02e7dba4360f290141c", - "sourceCodeHash": "0x35c189f3babf5c7a9ce2590bed9eb62b59766e358b7733fdb1bc33f4c232f765" + "bytecodeHash": "0x0100029361cc1606b2e55c12bef0a9ccbb36f70f6a12b41593b34053ea93f433", + "sourceCodeHash": "0x3e4c749b52c9fd8e6040b836dac10df29305ee0fc4fc9418326d3197e1630c38" }, { "contractName": "L2BaseToken", "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x010001035dc295d66d39f6f5ae560801400c6ac1141fd1556acabff84c79c22c", - "sourceCodeHash": "0x76ac95c12820d9a02cd1f177eab59092d99463816f2616e1e0f44637bf791a43" + "bytecodeHash": "0x010001055346ab8d4eb1b48ef7e768a95930d4ef6300c57ca173f4a76d1a9258", + "sourceCodeHash": "0x4cdafafd4cfdf410b31641e14487ea657be3af25e5ec1754fcd7ad67ec23d8be" }, { "contractName": "MsgValueSimulator", "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x01000069227f9b9d7666a4fc7ac51a280f33fd92021f2e8f06a2d5a458930563", - "sourceCodeHash": "0x3f9e0af527875bebcdc20ca4ecb6822305877fd6038e4c4c58854d000b9ac115" + "bytecodeHash": "0x0100005d606dc17844411ee44a09b08e574347fd92fb4df7d1739fe02ebae2cc", + "sourceCodeHash": "0x4834adf62dbaefa1a1c15d36b5ad1bf2826e7d888a17be495f7ed4e4ea381aa8" }, { "contractName": "NonceHolder", "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000e5e7614688d2be15699477b56c66e3596a16b60c206f3c3e8a4763e6b4", - "sourceCodeHash": "0x91847512344ac5026e9fd396189c23ad9e253f22cb6e2fe65805c20c915797d4" + "bytecodeHash": "0x010000dbe03a15e6478090c69b0565c273a9cb034c8af48b70d8e71baf5ecf94", + "sourceCodeHash": "0xaa2ed3a26af30032c00a612ac327e0cdf5288b7c932ae903462355f863f950cb" }, { "contractName": "PubdataChunkPublisher", "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x01000049d12af64a260c7dbfa32b778e60fe6793b73d50388cfdb0d38df4a97c", - "sourceCodeHash": "0xbc62d673c2cf9ba2d2148e5e2f99ea577cd357c6fd3ad7d248f670c750050faa" + "bytecodeHash": "0x01000047abbd0db8bc506c1cb48e3aab878da3e5ea1bbacf1d4b5f46391f2493", + "sourceCodeHash": "0x0568a9a12bdac94c9e055ca303824a6bf4dc4aa503cfe9a2586c7d3dda8d45da" }, { "contractName": "SystemContext", "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001b38acd12ee43d880840d48bd0474c519a8076cf28c8930489117e9bc73", - "sourceCodeHash": "0xb90284d78f48a958d082c4c877fc91ec292d05f0e388c6c78e6cce6d3b069a63" + "bytecodeHash": "0x010001a55d8778874657090f2db3a8aeabd491a5f3352f04c89eadabdd92e6ba", + "sourceCodeHash": "0xf23d12ad2f17ad3b26e909fabfdcfaf4e1d158923e7cb8eeb9b5965a0b464406" }, { "contractName": "EventWriter", @@ -185,35 +185,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cb38a53b3466209bf803fc2cacd06f9dc4ff9b123a38f6ba41928f735b", - "sourceCodeHash": "0xd5b248e75ad4a0a433c47de88b5a6eb30c3b7b540e0a716e953c07903233c2d1" + "bytecodeHash": "0x010003cbda052f30cd056d0c758c7cc5be2c31f77461591d4be73dc3291b6ca5", + "sourceCodeHash": "0xa13475403f910dff1ea0cf7ebf80633d9dcc37b4f8dd9f0c678a935793580932" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x010009519002105dd21a44bde50b697ffbc607baf3196d2eac80ad06f99e0f4c", - "sourceCodeHash": "0xbecdcccce351008db583c0447c7e1c7e8c69b5806abee65f22119e699e908e9d" + "bytecodeHash": "0x010009519c960b6baa12091cd1f8538d00fa0d7505c81943ba6e379a5f1c9c9e", + "sourceCodeHash": "0xbcdce81799656df718b5dfff4ba6ce8aac82087a78c0c33edb0675e55bb8364c" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d7d5b5c05e49761c406b847fe3ad0db839525b3e4370e9a5b86f2062af", - "sourceCodeHash": "0x533349c05727f117c00727ddcc25814055571afe74827a1d7130b037e131362b" + "bytecodeHash": "0x010008d7f0ddbde3a633aa89aff433666ba28dcf3adb35deb26a207ea1824454", + "sourceCodeHash": "0xe08f6eaca1995981baf257dd86e5dec8b62c1b5ac53a1173142cebca510b7859" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000957163c0f203bb8a7d3eda31cd9024e0572d212cdefc3046d740cd35afc", - "sourceCodeHash": "0xcf9c1d03c4d5c087b5c80b2ced7eff33067121a9ae78e1b0ff4b3eba4b5fbe1d" + "bytecodeHash": "0x01000957fe599ea1dfc3fc958c63b11f46a726d9462078b77c3f28c4db21446c", + "sourceCodeHash": "0x97e33d4d96f9ee25e171add92ec7d725de58904dfc68466e4aae1807e9997dc2" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e7d48764fc25121571a4139372fb3dbfd326416ed4bf5c5857cb7affc4", - "sourceCodeHash": "0x5acea8e48b7e840467552341bcf15670856fa5d671614b398e6bd7141052671d" + "bytecodeHash": "0x010008e756cd4ef7a22e5bf21b357fda5c90223b7947f38cd3749826a6faff68", + "sourceCodeHash": "0x62556a75277d8c72961a1fb9e1d0e1f1cef41c0e8f8d26a6e85cda336a734834" } ] diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 399ea54f5..5df2fdd8b 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.20; import {IAccountCodeStorage} from "./interfaces/IAccountCodeStorage.sol"; import {Utils} from "./libraries/Utils.sol"; import {DEPLOYER_SYSTEM_CONTRACT, NONCE_HOLDER_SYSTEM_CONTRACT, CURRENT_MAX_PRECOMPILE_ADDRESS} from "./Constants.sol"; +import {Unauthorized, InvalidCodeHash, CodeHashReason} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -20,10 +21,12 @@ import {DEPLOYER_SYSTEM_CONTRACT, NONCE_HOLDER_SYSTEM_CONTRACT, CURRENT_MAX_PREC * system contracts to enforce the invariants mentioned above. */ contract AccountCodeStorage is IAccountCodeStorage { - bytes32 constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; + bytes32 internal constant EMPTY_STRING_KECCAK = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; modifier onlyDeployer() { - require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract"); + if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { + revert Unauthorized(msg.sender); + } _; } @@ -34,7 +37,9 @@ contract AccountCodeStorage is IAccountCodeStorage { /// but checks whether the bytecode hash corresponds to the constructing smart contract. function storeAccountConstructingCodeHash(address _address, bytes32 _hash) external override onlyDeployer { // Check that code hash corresponds to the deploying smart contract - require(Utils.isContractConstructing(_hash), "Code hash is not for a contract on constructor"); + if (!Utils.isContractConstructing(_hash)) { + revert InvalidCodeHash(CodeHashReason.NotContractOnConstructor); + } _storeCodeHash(_address, _hash); } @@ -45,7 +50,9 @@ contract AccountCodeStorage is IAccountCodeStorage { /// but checks whether the bytecode hash corresponds to the constructed smart contract. function storeAccountConstructedCodeHash(address _address, bytes32 _hash) external override onlyDeployer { // Check that code hash corresponds to the deploying smart contract - require(Utils.isContractConstructed(_hash), "Code hash is not for a constructed contract"); + if (!Utils.isContractConstructed(_hash)) { + revert InvalidCodeHash(CodeHashReason.NotConstructedContract); + } _storeCodeHash(_address, _hash); } @@ -54,7 +61,9 @@ contract AccountCodeStorage is IAccountCodeStorage { function markAccountCodeHashAsConstructed(address _address) external override onlyDeployer { bytes32 codeHash = getRawCodeHash(_address); - require(Utils.isContractConstructing(codeHash), "Code hash is not for a contract on constructor"); + if (!Utils.isContractConstructing(codeHash)) { + revert InvalidCodeHash(CodeHashReason.NotContractOnConstructor); + } // Get the bytecode hash with "isConstructor" flag equal to false bytes32 constructedBytecodeHash = Utils.constructedBytecodeHash(codeHash); diff --git a/system-contracts/contracts/BootloaderUtilities.sol b/system-contracts/contracts/BootloaderUtilities.sol index 5551764dd..0aafee7be 100644 --- a/system-contracts/contracts/BootloaderUtilities.sol +++ b/system-contracts/contracts/BootloaderUtilities.sol @@ -6,6 +6,7 @@ import {IBootloaderUtilities} from "./interfaces/IBootloaderUtilities.sol"; import {Transaction, TransactionHelper, EIP_712_TX_TYPE, LEGACY_TX_TYPE, EIP_2930_TX_TYPE, EIP_1559_TX_TYPE} from "./libraries/TransactionHelper.sol"; import {RLPEncoder} from "./libraries/RLPEncoder.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; +import {UnsupportedTxType, InvalidSig, SigField} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -34,7 +35,7 @@ contract BootloaderUtilities is IBootloaderUtilities { } else if (_transaction.txType == EIP_2930_TX_TYPE) { txHash = encodeEIP2930TransactionHash(_transaction); } else { - revert("Unsupported tx type"); + revert UnsupportedTxType(_transaction.txType); } } @@ -89,7 +90,9 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory vEncoded; { uint256 vInt = uint256(uint8(_transaction.signature[64])); - require(vInt == 27 || vInt == 28, "Invalid v value"); + if (vInt != 27 && vInt != 28) { + revert InvalidSig(SigField.V, vInt); + } // If the `chainId` is specified in the transaction, then the `v` value is encoded as // `35 + y + 2 * chainId == vInt + 8 + 2 * chainId`, where y - parity bit (see EIP-155). @@ -190,7 +193,9 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory vEncoded; { uint256 vInt = uint256(uint8(_transaction.signature[64])); - require(vInt == 27 || vInt == 28, "Invalid v value"); + if (vInt != 27 && vInt != 28) { + revert InvalidSig(SigField.V, vInt); + } vEncoded = RLPEncoder.encodeUint256(vInt - 27); } @@ -287,7 +292,9 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory vEncoded; { uint256 vInt = uint256(uint8(_transaction.signature[64])); - require(vInt == 27 || vInt == 28, "Invalid v value"); + if (vInt != 27 && vInt != 28) { + revert InvalidSig(SigField.V, vInt); + } vEncoded = RLPEncoder.encodeUint256(vInt - 27); } diff --git a/system-contracts/contracts/ComplexUpgrader.sol b/system-contracts/contracts/ComplexUpgrader.sol index 2f4d886cd..009e8994d 100644 --- a/system-contracts/contracts/ComplexUpgrader.sol +++ b/system-contracts/contracts/ComplexUpgrader.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {IComplexUpgrader} from "./interfaces/IComplexUpgrader.sol"; import {FORCE_DEPLOYER} from "./Constants.sol"; +import {Unauthorized, AddressHasNoCode} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -19,9 +20,13 @@ contract ComplexUpgrader is IComplexUpgrader { /// @param _delegateTo the address of the contract to which the calls will be delegated /// @param _calldata the calldata to be delegate called in the `_delegateTo` contract function upgrade(address _delegateTo, bytes calldata _calldata) external payable { - require(msg.sender == FORCE_DEPLOYER, "Can only be called by FORCE_DEPLOYER"); + if (msg.sender != FORCE_DEPLOYER) { + revert Unauthorized(msg.sender); + } - require(_delegateTo.code.length > 0, "Delegatee is an EOA"); + if (_delegateTo.code.length == 0) { + revert AddressHasNoCode(_delegateTo); + } (bool success, bytes memory returnData) = _delegateTo.delegatecall(_calldata); assembly { if iszero(success) { diff --git a/system-contracts/contracts/Compressor.sol b/system-contracts/contracts/Compressor.sol index f52c18ed4..73582f639 100644 --- a/system-contracts/contracts/Compressor.sol +++ b/system-contracts/contracts/Compressor.sol @@ -8,6 +8,7 @@ import {Utils} from "./libraries/Utils.sol"; import {UnsafeBytesCalldata} from "./libraries/UnsafeBytesCalldata.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {L1_MESSENGER_CONTRACT, STATE_DIFF_ENTRY_SIZE, KNOWN_CODE_STORAGE_CONTRACT} from "./Constants.sol"; +import {MalformedBytecode, BytecodeError, IndexOutOfBounds, IndexSizeError, ValuesNotEqual, UnsupportedOperation} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -48,24 +49,27 @@ contract Compressor is ICompressor, ISystemContract { unchecked { (bytes calldata dictionary, bytes calldata encodedData) = _decodeRawBytecode(_rawCompressedData); - require( - encodedData.length * 4 == _bytecode.length, - "Encoded data length should be 4 times shorter than the original bytecode" - ); + if (encodedData.length * 4 != _bytecode.length) { + revert MalformedBytecode(BytecodeError.Length); + } - require( - dictionary.length / 8 <= encodedData.length / 2, - "Dictionary should have at most the same number of entries as the encoded data" - ); + if (dictionary.length / 8 > encodedData.length / 2) { + revert MalformedBytecode(BytecodeError.DictionaryLength); + } + // solhint-disable-next-line gas-length-in-loops for (uint256 encodedDataPointer = 0; encodedDataPointer < encodedData.length; encodedDataPointer += 2) { uint256 indexOfEncodedChunk = uint256(encodedData.readUint16(encodedDataPointer)) * 8; - require(indexOfEncodedChunk < dictionary.length, "Encoded chunk index is out of bounds"); + if (indexOfEncodedChunk > dictionary.length - 1) { + revert IndexOutOfBounds(); + } uint64 encodedChunk = dictionary.readUint64(indexOfEncodedChunk); uint64 realChunk = _bytecode.readUint64(encodedDataPointer * 4); - require(encodedChunk == realChunk, "Encoded chunk does not match the original bytecode"); + if (encodedChunk != realChunk) { + revert ValuesNotEqual(realChunk, encodedChunk); + } } } @@ -116,7 +120,9 @@ contract Compressor is ICompressor, ISystemContract { // We do not enforce the operator to use the optimal, i.e. the minimally possible _enumerationIndexSize. // We do enforce however, that the _enumerationIndexSize is not larger than 8 bytes long, which is the // maximal ever possible size for enumeration index. - require(_enumerationIndexSize <= MAX_ENUMERATION_INDEX_SIZE, "enumeration index size is too large"); + if (_enumerationIndexSize > MAX_ENUMERATION_INDEX_SIZE) { + revert IndexSizeError(); + } uint256 numberOfInitialWrites = uint256(_compressedStateDiffs.readUint16(0)); @@ -132,16 +138,18 @@ contract Compressor is ICompressor, ISystemContract { continue; } - numInitialWritesProcessed++; + ++numInitialWritesProcessed; bytes32 derivedKey = stateDiff.readBytes32(52); uint256 initValue = stateDiff.readUint256(92); uint256 finalValue = stateDiff.readUint256(124); - require(derivedKey == _compressedStateDiffs.readBytes32(stateDiffPtr), "iw: initial key mismatch"); + if (derivedKey != _compressedStateDiffs.readBytes32(stateDiffPtr)) { + revert ValuesNotEqual(uint256(derivedKey), _compressedStateDiffs.readUint256(stateDiffPtr)); + } stateDiffPtr += 32; uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr])); - stateDiffPtr++; + ++stateDiffPtr; uint8 operation = metadata & OPERATION_BITMASK; uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; _verifyValueCompression( @@ -153,7 +161,9 @@ contract Compressor is ICompressor, ISystemContract { stateDiffPtr += len; } - require(numInitialWritesProcessed == numberOfInitialWrites, "Incorrect number of initial storage diffs"); + if (numInitialWritesProcessed != numberOfInitialWrites) { + revert ValuesNotEqual(numberOfInitialWrites, numInitialWritesProcessed); + } // Process repeated writes for (uint256 i = 0; i < _numberOfStateDiffs * STATE_DIFF_ENTRY_SIZE; i += STATE_DIFF_ENTRY_SIZE) { @@ -168,11 +178,13 @@ contract Compressor is ICompressor, ISystemContract { uint256 compressedEnumIndex = _sliceToUint256( _compressedStateDiffs[stateDiffPtr:stateDiffPtr + _enumerationIndexSize] ); - require(enumIndex == compressedEnumIndex, "rw: enum key mismatch"); + if (enumIndex != compressedEnumIndex) { + revert ValuesNotEqual(enumIndex, compressedEnumIndex); + } stateDiffPtr += _enumerationIndexSize; uint8 metadata = uint8(bytes1(_compressedStateDiffs[stateDiffPtr])); - stateDiffPtr += 1; + ++stateDiffPtr; uint8 operation = metadata & OPERATION_BITMASK; uint8 len = operation == 0 ? 32 : metadata >> LENGTH_BITS_OFFSET; _verifyValueCompression( @@ -184,7 +196,9 @@ contract Compressor is ICompressor, ISystemContract { stateDiffPtr += len; } - require(stateDiffPtr == _compressedStateDiffs.length, "Extra data in _compressedStateDiffs"); + if (stateDiffPtr != _compressedStateDiffs.length) { + revert ValuesNotEqual(stateDiffPtr, _compressedStateDiffs.length); + } stateDiffHash = EfficientCall.keccak(_stateDiffs); } @@ -227,19 +241,19 @@ contract Compressor is ICompressor, ISystemContract { unchecked { if (_operation == 0 || _operation == 3) { - require(convertedValue == _finalValue, "transform or no compression: compressed and final mismatch"); + if (convertedValue != _finalValue) { + revert ValuesNotEqual(_finalValue, convertedValue); + } } else if (_operation == 1) { - require( - _initialValue + convertedValue == _finalValue, - "add: initial plus converted not equal to final" - ); + if (_initialValue + convertedValue != _finalValue) { + revert ValuesNotEqual(_finalValue, _initialValue + convertedValue); + } } else if (_operation == 2) { - require( - _initialValue - convertedValue == _finalValue, - "sub: initial minus converted not equal to final" - ); + if (_initialValue - convertedValue != _finalValue) { + revert ValuesNotEqual(_finalValue, _initialValue - convertedValue); + } } else { - revert("unsupported operation"); + revert UnsupportedOperation(); } } } diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index 01009da19..30d5e3930 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -10,6 +10,7 @@ import {Utils} from "./libraries/Utils.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; +import {Unauthorized, InvalidNonceOrderingChange, ValuesNotEqual, EmptyBytes32, NotAllowedToDeployInKernelSpace, HashIsNonZero, NonEmptyAccount, UnknownCodeHash, NonEmptyMsgValue} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -26,7 +27,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { mapping(address => AccountInfo) internal accountInfo; modifier onlySelf() { - require(msg.sender == address(this), "Callable only by self"); + if (msg.sender != address(this)) { + revert Unauthorized(msg.sender); + } _; } @@ -74,11 +77,12 @@ contract ContractDeployer is IContractDeployer, ISystemContract { function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external onlySystemCall { AccountInfo memory currentInfo = accountInfo[msg.sender]; - require( - _nonceOrdering == AccountNonceOrdering.Arbitrary && - currentInfo.nonceOrdering == AccountNonceOrdering.Sequential, - "It is only possible to change from sequential to arbitrary ordering" - ); + if ( + _nonceOrdering != AccountNonceOrdering.Arbitrary && + currentInfo.nonceOrdering != AccountNonceOrdering.Sequential + ) { + revert InvalidNonceOrderingChange(); + } currentInfo.nonceOrdering = _nonceOrdering; _storeAccountInfo(msg.sender, currentInfo); @@ -237,10 +241,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { /// @dev We do not require `onlySystemCall` here, since the method is accessible only /// by `FORCE_DEPLOYER`. function forceDeployOnAddresses(ForceDeployment[] calldata _deployments) external payable { - require( - msg.sender == FORCE_DEPLOYER || msg.sender == address(COMPLEX_UPGRADER_CONTRACT), - "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT" - ); + if (msg.sender != FORCE_DEPLOYER && msg.sender != address(COMPLEX_UPGRADER_CONTRACT)) { + revert Unauthorized(msg.sender); + } uint256 deploymentsLength = _deployments.length; // We need to ensure that the `value` provided by the call is enough to provide `value` @@ -249,7 +252,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { for (uint256 i = 0; i < deploymentsLength; ++i) { sumOfValues += _deployments[i].value; } - require(msg.value == sumOfValues, "`value` provided is not equal to the combined `value`s of deployments"); + if (msg.value != sumOfValues) { + revert ValuesNotEqual(sumOfValues, msg.value); + } for (uint256 i = 0; i < deploymentsLength; ++i) { this.forceDeployOnAddress{value: _deployments[i].value}(_deployments[i], msg.sender); @@ -262,16 +267,22 @@ contract ContractDeployer is IContractDeployer, ISystemContract { AccountAbstractionVersion _aaVersion, bytes calldata _input ) internal { - require(_bytecodeHash != bytes32(0x0), "BytecodeHash cannot be zero"); - require(uint160(_newAddress) > MAX_SYSTEM_CONTRACT_ADDRESS, "Can not deploy contracts in kernel space"); + if (_bytecodeHash == bytes32(0x0)) { + revert EmptyBytes32(); + } + if (uint160(_newAddress) <= MAX_SYSTEM_CONTRACT_ADDRESS) { + revert NotAllowedToDeployInKernelSpace(); + } // We do not allow deploying twice on the same address. - require( - ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0, - "Code hash is non-zero" - ); + bytes32 codeHash = ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))); + if (codeHash != 0x0) { + revert HashIsNonZero(codeHash); + } // Do not allow deploying contracts to default accounts that have already executed transactions. - require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x00, "Account is occupied"); + if (NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) != 0x00) { + revert NonEmptyAccount(); + } _performDeployOnAddress(_bytecodeHash, _newAddress, _aaVersion, _input); } @@ -308,7 +319,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { /// @notice Check that bytecode hash is marked as known on the `KnownCodeStorage` system contracts function _ensureBytecodeIsKnown(bytes32 _bytecodeHash) internal view { uint256 knownCodeMarker = KNOWN_CODE_STORAGE_CONTRACT.getMarker(_bytecodeHash); - require(knownCodeMarker > 0, "The code hash is not known"); + if (knownCodeMarker == 0) { + revert UnknownCodeHash(_bytecodeHash); + } } /// @notice Ensures that the _newAddress and assigns a new contract hash to it @@ -362,7 +375,9 @@ contract ContractDeployer is IContractDeployer, ISystemContract { ImmutableData[] memory immutables = abi.decode(returnData, (ImmutableData[])); IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT.setImmutables(_newAddress, immutables); } else { - require(value == 0, "The value must be zero if we do not call the constructor"); + if (value != 0) { + revert NonEmptyMsgValue(); + } // If we do not call the constructor, we need to set the constructed code hash. ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.storeAccountConstructedCodeHash(_newAddress, _bytecodeHash); } diff --git a/system-contracts/contracts/DefaultAccount.sol b/system-contracts/contracts/DefaultAccount.sol index 4c7356dd8..ff62e9a57 100644 --- a/system-contracts/contracts/DefaultAccount.sol +++ b/system-contracts/contracts/DefaultAccount.sol @@ -9,6 +9,7 @@ import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {BOOTLOADER_FORMAL_ADDRESS, NONCE_HOLDER_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, INonceHolder} from "./Constants.sol"; import {Utils} from "./libraries/Utils.sol"; +import {InsufficientFunds, InvalidSig, SigField, FailedToPayOperator} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -99,7 +100,9 @@ contract DefaultAccount is IAccount { // should be checked explicitly to prevent user paying for fee for a // transaction that wouldn't be included on Ethereum. uint256 totalRequiredBalance = _transaction.totalRequiredBalance(); - require(totalRequiredBalance <= address(this).balance, "Not enough balance for fee + value"); + if (totalRequiredBalance > address(this).balance) { + revert InsufficientFunds(totalRequiredBalance, address(this).balance); + } if (_isValidSignature(txHash, _transaction.signature)) { magic = ACCOUNT_VALIDATION_SUCCESS_MAGIC; @@ -165,7 +168,9 @@ contract DefaultAccount is IAccount { /// @param _signature The signature of the transaction. /// @return EIP1271_SUCCESS_RETURN_VALUE if the signature is correct. It reverts otherwise. function _isValidSignature(bytes32 _hash, bytes memory _signature) internal view returns (bool) { - require(_signature.length == 65, "Signature length is incorrect"); + if (_signature.length != 65) { + revert InvalidSig(SigField.Length, _signature.length); + } uint8 v; bytes32 r; bytes32 s; @@ -178,7 +183,9 @@ contract DefaultAccount is IAccount { s := mload(add(_signature, 0x40)) v := and(mload(add(_signature, 0x41)), 0xff) } - require(v == 27 || v == 28, "v is neither 27 nor 28"); + if (v != 27 && v != 28) { + revert InvalidSig(SigField.V, v); + } // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines @@ -189,7 +196,9 @@ contract DefaultAccount is IAccount { // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. - require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "Invalid s"); + if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { + revert InvalidSig(SigField.S, uint256(s)); + } address recoveredAddress = ecrecover(_hash, v, r, s); @@ -207,7 +216,9 @@ contract DefaultAccount is IAccount { Transaction calldata _transaction ) external payable ignoreNonBootloader ignoreInDelegateCall { bool success = _transaction.payToTheBootloader(); - require(success, "Failed to pay the fee to the operator"); + if (!success) { + revert FailedToPayOperator(); + } } /// @notice Method, where the user should prepare for the transaction to be diff --git a/system-contracts/contracts/GasBoundCaller.sol b/system-contracts/contracts/GasBoundCaller.sol index 67a43883e..47b12b6ff 100644 --- a/system-contracts/contracts/GasBoundCaller.sol +++ b/system-contracts/contracts/GasBoundCaller.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; +import {InsufficientGas} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -15,10 +16,10 @@ import {REAL_SYSTEM_CONTEXT_CONTRACT} from "./Constants.sol"; contract GasBoundCaller { /// @notice We assume that no more than `CALL_ENTRY_OVERHEAD` gas are used for the O(1) operations at the start /// of execution of the contract, such as abi decoding the parameters, jumping to the correct function, etc. - uint256 constant CALL_ENTRY_OVERHEAD = 800; + uint256 internal constant CALL_ENTRY_OVERHEAD = 800; /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, /// as such relaying the return. - uint256 constant CALL_RETURN_OVERHEAD = 200; + uint256 internal constant CALL_RETURN_OVERHEAD = 200; /// @notice The function that implements limiting of the total gas expenditure of the call. /// @dev On Era, the gas for pubdata is charged at the end of the execution of the entire transaction, meaning @@ -43,7 +44,9 @@ contract GasBoundCaller { // This require is more of a safety protection for the users that call this function with incorrect parameters. // // Ultimately, the entire `gas` sent to this call can be spent on compute regardless of the `_maxTotalGas` parameter. - require(_maxTotalGas >= gasleft(), "Gas limit is too low"); + if (_maxTotalGas < gasleft()) { + revert InsufficientGas(); + } // This is the amount of gas that can be spent *exclusively* on pubdata in addition to the `gas` provided to this function. uint256 pubdataAllowance = _maxTotalGas > expectedForCompute ? _maxTotalGas - expectedForCompute : 0; @@ -79,7 +82,9 @@ contract GasBoundCaller { if (pubdataGas != 0) { // Here we double check that the additional cost is not higher than the maximum allowed. // Note, that the `gasleft()` can be spent on pubdata too. - require(pubdataAllowance + gasleft() >= pubdataGas + CALL_RETURN_OVERHEAD, "Not enough gas for pubdata"); + if (pubdataAllowance + gasleft() < pubdataGas + CALL_RETURN_OVERHEAD) { + revert InsufficientGas(); + } } assembly { diff --git a/system-contracts/contracts/ImmutableSimulator.sol b/system-contracts/contracts/ImmutableSimulator.sol index 2d077316a..701ee5d90 100644 --- a/system-contracts/contracts/ImmutableSimulator.sol +++ b/system-contracts/contracts/ImmutableSimulator.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {IImmutableSimulator, ImmutableData} from "./interfaces/IImmutableSimulator.sol"; import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; +import {Unauthorized} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -32,7 +33,9 @@ contract ImmutableSimulator is IImmutableSimulator { /// @param _dest The address which to store the immutables for. /// @param _immutables The list of the immutables. function setImmutables(address _dest, ImmutableData[] calldata _immutables) external override { - require(msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), "Callable only by the deployer system contract"); + if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { + revert Unauthorized(msg.sender); + } unchecked { uint256 immutablesLength = _immutables.length; for (uint256 i = 0; i < immutablesLength; ++i) { diff --git a/system-contracts/contracts/KnownCodesStorage.sol b/system-contracts/contracts/KnownCodesStorage.sol index 3db07fe31..efddf5d9c 100644 --- a/system-contracts/contracts/KnownCodesStorage.sol +++ b/system-contracts/contracts/KnownCodesStorage.sol @@ -6,6 +6,7 @@ import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {Utils} from "./libraries/Utils.sol"; import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; +import {Unauthorized, MalformedBytecode, BytecodeError} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -17,7 +18,9 @@ import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; */ contract KnownCodesStorage is IKnownCodesStorage, ISystemContract { modifier onlyCompressor() { - require(msg.sender == address(COMPRESSOR_CONTRACT), "Callable only by the compressor"); + if (msg.sender != address(COMPRESSOR_CONTRACT)) { + revert Unauthorized(msg.sender); + } _; } @@ -73,8 +76,12 @@ contract KnownCodesStorage is IKnownCodesStorage, ISystemContract { /// That's why we need to validate it function _validateBytecode(bytes32 _bytecodeHash) internal pure { uint8 version = uint8(_bytecodeHash[0]); - require(version == 1 && _bytecodeHash[1] == bytes1(0), "Incorrectly formatted bytecodeHash"); + if (version != 1 || _bytecodeHash[1] != bytes1(0)) { + revert MalformedBytecode(BytecodeError.Version); + } - require(Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 1, "Code length in words must be odd"); + if (Utils.bytecodeLenInWords(_bytecodeHash) % 2 == 0) { + revert MalformedBytecode(BytecodeError.NumberOfWords); + } } } diff --git a/system-contracts/contracts/L1Messenger.sol b/system-contracts/contracts/L1Messenger.sol index 2b584d110..26d49672a 100644 --- a/system-contracts/contracts/L1Messenger.sol +++ b/system-contracts/contracts/L1Messenger.sol @@ -8,6 +8,7 @@ import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {Utils} from "./libraries/Utils.sol"; import {SystemLogKey, SYSTEM_CONTEXT_CONTRACT, KNOWN_CODE_STORAGE_CONTRACT, COMPRESSOR_CONTRACT, STATE_DIFF_ENTRY_SIZE, L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, PUBDATA_CHUNK_PUBLISHER, COMPUTATIONAL_PRICE_FOR_PUBDATA} from "./Constants.sol"; +import {ReconstructionMismatch, PubdataField} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -107,7 +108,7 @@ contract L1Messenger is IL1Messenger, ISystemContract { chainedLogsHash = keccak256(abi.encode(chainedLogsHash, hashedLog)); logIdInMerkleTree = numberOfLogsToProcess; - numberOfLogsToProcess++; + ++numberOfLogsToProcess; emit L2ToL1LogSent(_l2ToL1Log); } @@ -198,7 +199,13 @@ contract L1Messenger is IL1Messenger, ISystemContract { /// Check logs uint32 numberOfL2ToL1Logs = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); - require(numberOfL2ToL1Logs <= L2_TO_L1_LOGS_MERKLE_TREE_LEAVES, "Too many L2->L1 logs"); + if (numberOfL2ToL1Logs > L2_TO_L1_LOGS_MERKLE_TREE_LEAVES) { + revert ReconstructionMismatch( + PubdataField.NumberOfLogs, + bytes32(L2_TO_L1_LOGS_MERKLE_TREE_LEAVES), + bytes32(uint256(numberOfL2ToL1Logs)) + ); + } calldataPtr += 4; bytes32[] memory l2ToL1LogsTreeArray = new bytes32[](L2_TO_L1_LOGS_MERKLE_TREE_LEAVES); @@ -211,10 +218,9 @@ contract L1Messenger is IL1Messenger, ISystemContract { l2ToL1LogsTreeArray[i] = hashedLog; reconstructedChainedLogsHash = keccak256(abi.encode(reconstructedChainedLogsHash, hashedLog)); } - require( - reconstructedChainedLogsHash == chainedLogsHash, - "reconstructedChainedLogsHash is not equal to chainedLogsHash" - ); + if (reconstructedChainedLogsHash != chainedLogsHash) { + revert ReconstructionMismatch(PubdataField.LogsHash, chainedLogsHash, reconstructedChainedLogsHash); + } for (uint256 i = numberOfL2ToL1Logs; i < L2_TO_L1_LOGS_MERKLE_TREE_LEAVES; ++i) { l2ToL1LogsTreeArray[i] = L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH; } @@ -242,10 +248,9 @@ contract L1Messenger is IL1Messenger, ISystemContract { calldataPtr += currentMessageLength; reconstructedChainedMessagesHash = keccak256(abi.encode(reconstructedChainedMessagesHash, hashedMessage)); } - require( - reconstructedChainedMessagesHash == chainedMessagesHash, - "reconstructedChainedMessagesHash is not equal to chainedMessagesHash" - ); + if (reconstructedChainedMessagesHash != chainedMessagesHash) { + revert ReconstructionMismatch(PubdataField.MsgHash, chainedMessagesHash, reconstructedChainedMessagesHash); + } /// Check bytecodes uint32 numberOfBytecodes = uint32(bytes4(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 4])); @@ -266,28 +271,36 @@ contract L1Messenger is IL1Messenger, ISystemContract { ); calldataPtr += currentBytecodeLength; } - require( - reconstructedChainedL1BytecodesRevealDataHash == chainedL1BytecodesRevealDataHash, - "reconstructedChainedL1BytecodesRevealDataHash is not equal to chainedL1BytecodesRevealDataHash" - ); + if (reconstructedChainedL1BytecodesRevealDataHash != chainedL1BytecodesRevealDataHash) { + revert ReconstructionMismatch( + PubdataField.Bytecode, + chainedL1BytecodesRevealDataHash, + reconstructedChainedL1BytecodesRevealDataHash + ); + } /// Check State Diffs /// encoding is as follows: /// header (1 byte version, 3 bytes total len of compressed, 1 byte enumeration index size) /// body (`compressedStateDiffSize` bytes, 4 bytes number of state diffs, `numberOfStateDiffs` * `STATE_DIFF_ENTRY_SIZE` bytes for the uncompressed state diffs) /// encoded state diffs: [20bytes address][32bytes key][32bytes derived key][8bytes enum index][32bytes initial value][32bytes final value] - require( - uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) == - STATE_DIFF_COMPRESSION_VERSION_NUMBER, - "state diff compression version mismatch" - ); - calldataPtr++; + if ( + uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr]))) != + STATE_DIFF_COMPRESSION_VERSION_NUMBER + ) { + revert ReconstructionMismatch( + PubdataField.StateDiffCompressionVersion, + bytes32(STATE_DIFF_COMPRESSION_VERSION_NUMBER), + bytes32(uint256(uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr])))) + ); + } + ++calldataPtr; uint24 compressedStateDiffSize = uint24(bytes3(_totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + 3])); calldataPtr += 3; uint8 enumerationIndexSize = uint8(bytes1(_totalL2ToL1PubdataAndStateDiffs[calldataPtr])); - calldataPtr++; + ++calldataPtr; bytes calldata compressedStateDiffs = _totalL2ToL1PubdataAndStateDiffs[calldataPtr:calldataPtr + compressedStateDiffSize]; @@ -310,7 +323,13 @@ contract L1Messenger is IL1Messenger, ISystemContract { ); /// Check for calldata strict format - require(calldataPtr == _totalL2ToL1PubdataAndStateDiffs.length, "Extra data in the totalL2ToL1Pubdata array"); + if (calldataPtr != _totalL2ToL1PubdataAndStateDiffs.length) { + revert ReconstructionMismatch( + PubdataField.ExtraData, + bytes32(calldataPtr), + bytes32(_totalL2ToL1PubdataAndStateDiffs.length) + ); + } PUBDATA_CHUNK_PUBLISHER.chunkAndPublishPubdata(totalL2ToL1Pubdata); diff --git a/system-contracts/contracts/L2BaseToken.sol b/system-contracts/contracts/L2BaseToken.sol index 8101c638b..c5b934013 100644 --- a/system-contracts/contracts/L2BaseToken.sol +++ b/system-contracts/contracts/L2BaseToken.sol @@ -6,6 +6,7 @@ import {IBaseToken} from "./interfaces/IBaseToken.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {MSG_VALUE_SYSTEM_CONTRACT, DEPLOYER_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS, L1_MESSENGER_CONTRACT} from "./Constants.sol"; import {IMailbox} from "./interfaces/IMailbox.sol"; +import {Unauthorized, InsufficientFunds} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -30,15 +31,18 @@ contract L2BaseToken is IBaseToken, ISystemContract { /// @dev This function also emits "Transfer" event, which might be removed /// later on. function transferFromTo(address _from, address _to, uint256 _amount) external override { - require( - msg.sender == MSG_VALUE_SYSTEM_CONTRACT || - msg.sender == address(DEPLOYER_SYSTEM_CONTRACT) || - msg.sender == BOOTLOADER_FORMAL_ADDRESS, - "Only system contracts with special access can call this method" - ); + if ( + msg.sender != MSG_VALUE_SYSTEM_CONTRACT && + msg.sender != address(DEPLOYER_SYSTEM_CONTRACT) && + msg.sender != BOOTLOADER_FORMAL_ADDRESS + ) { + revert Unauthorized(msg.sender); + } uint256 fromBalance = balance[_from]; - require(fromBalance >= _amount, "Transfer amount exceeds balance"); + if (fromBalance < _amount) { + revert InsufficientFunds(_amount, fromBalance); + } unchecked { balance[_from] = fromBalance - _amount; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by @@ -82,7 +86,7 @@ contract L2BaseToken is IBaseToken, ISystemContract { /// @notice Initiate the withdrawal of the base token, with the sent message. The funds will be available to claim on L1 `finalizeEthWithdrawal` method. /// @param _l1Receiver The address on L1 to receive the funds. /// @param _additionalData Additional data to be sent to L1 with the withdrawal. - function withdrawWithMessage(address _l1Receiver, bytes memory _additionalData) external payable override { + function withdrawWithMessage(address _l1Receiver, bytes calldata _additionalData) external payable override { uint256 amount = _burnMsgValue(); // Send the L2 log, a user could use it as proof of the withdrawal diff --git a/system-contracts/contracts/MsgValueSimulator.sol b/system-contracts/contracts/MsgValueSimulator.sol index c1dcde694..61a221653 100644 --- a/system-contracts/contracts/MsgValueSimulator.sol +++ b/system-contracts/contracts/MsgValueSimulator.sol @@ -7,6 +7,7 @@ import {EfficientCall} from "./libraries/EfficientCall.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, REAL_BASE_TOKEN_SYSTEM_CONTRACT} from "./Constants.sol"; +import {InvalidCall} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -33,17 +34,18 @@ contract MsgValueSimulator is ISystemContract { } /// @notice The maximal number of gas out of the stipend that should be passed to the callee. - uint256 constant GAS_TO_PASS = 2300; + uint256 internal constant GAS_TO_PASS = 2300; /// @notice The amount of gas that is passed to the MsgValueSimulator as a stipend. /// This number servers to pay for the ETH transfer as well as to provide gas for the `GAS_TO_PASS` gas. /// It is equal to the following constant: https://github.com/matter-labs/era-zkevm_opcode_defs/blob/7bf8016f5bb13a73289f321ad6ea8f614540ece9/src/system_params.rs#L96. - uint256 constant MSG_VALUE_SIMULATOR_STIPEND_GAS = 27000; + uint256 internal constant MSG_VALUE_SIMULATOR_STIPEND_GAS = 27000; /// @notice The fallback function that is the main entry point for the MsgValueSimulator. /// @dev The contract accepts value, the callee and whether the call should be a system one via its ABI params. /// @param _data The calldata to be passed to the callee. /// @return The return data from the callee. + // solhint-disable-next-line payable-fallback fallback(bytes calldata _data) external onlySystemCall returns (bytes memory) { // Firstly we calculate how much gas has been actually provided by the user to the inner call. // For that, we need to get the total gas available in this context and subtract the stipend from it. @@ -57,7 +59,9 @@ contract MsgValueSimulator is ISystemContract { (uint256 value, bool isSystemCall, address to) = _getAbiParams(); // Prevent mimic call to the MsgValueSimulator to prevent an unexpected change of callee. - require(to != address(this), "MsgValueSimulator calls itself"); + if (to == address(this)) { + revert InvalidCall(); + } if (value != 0) { (bool success, ) = address(REAL_BASE_TOKEN_SYSTEM_CONTRACT).call( diff --git a/system-contracts/contracts/NonceHolder.sol b/system-contracts/contracts/NonceHolder.sol index 12abda8bd..b769d2d37 100644 --- a/system-contracts/contracts/NonceHolder.sol +++ b/system-contracts/contracts/NonceHolder.sol @@ -6,6 +6,7 @@ import {INonceHolder} from "./interfaces/INonceHolder.sol"; import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; +import {NonceIncreaseError, ZeroNonceError, NonceJumpError, ValuesNotEqual, NonceAlreadyUsed, NonceNotUsed, Unauthorized} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -63,7 +64,9 @@ contract NonceHolder is INonceHolder, ISystemContract { /// @param _value The number by which to increase the minimal nonce for msg.sender. /// @return oldMinNonce The value of the minimal nonce for msg.sender before the increase. function increaseMinNonce(uint256 _value) public onlySystemCall returns (uint256 oldMinNonce) { - require(_value <= MAXIMAL_MIN_NONCE_INCREMENT, "The value for incrementing the nonce is too high"); + if (_value > MAXIMAL_MIN_NONCE_INCREMENT) { + revert NonceIncreaseError(MAXIMAL_MIN_NONCE_INCREMENT, _value); + } uint256 addressAsKey = uint256(uint160(msg.sender)); uint256 oldRawNonce = rawNonces[addressAsKey]; @@ -82,11 +85,15 @@ contract NonceHolder is INonceHolder, ISystemContract { function setValueUnderNonce(uint256 _key, uint256 _value) public onlySystemCall { IContractDeployer.AccountInfo memory accountInfo = DEPLOYER_SYSTEM_CONTRACT.getAccountInfo(msg.sender); - require(_value != 0, "Nonce value cannot be set to 0"); + if (_value == 0) { + revert ZeroNonceError(); + } // If an account has sequential nonce ordering, we enforce that the previous // nonce has already been used. if (accountInfo.nonceOrdering == IContractDeployer.AccountNonceOrdering.Sequential && _key != 0) { - require(isNonceUsed(msg.sender, _key - 1), "Previous nonce has not been used"); + if (!isNonceUsed(msg.sender, _key - 1)) { + revert NonceJumpError(); + } } uint256 addressAsKey = uint256(uint160(msg.sender)); @@ -112,7 +119,9 @@ contract NonceHolder is INonceHolder, ISystemContract { uint256 oldRawNonce = rawNonces[addressAsKey]; (, uint256 oldMinNonce) = _splitRawNonce(oldRawNonce); - require(oldMinNonce == _expectedNonce, "Incorrect nonce"); + if (oldMinNonce != _expectedNonce) { + revert ValuesNotEqual(_expectedNonce, oldMinNonce); + } unchecked { rawNonces[addressAsKey] = oldRawNonce + 1; @@ -133,10 +142,9 @@ contract NonceHolder is INonceHolder, ISystemContract { /// @param _address The address of the account which to return the deploy nonce for. /// @return prevDeploymentNonce The deployment nonce at the time this function is called. function incrementDeploymentNonce(address _address) external returns (uint256 prevDeploymentNonce) { - require( - msg.sender == address(DEPLOYER_SYSTEM_CONTRACT), - "Only the contract deployer can increment the deployment nonce" - ); + if (msg.sender != address(DEPLOYER_SYSTEM_CONTRACT)) { + revert Unauthorized(msg.sender); + } uint256 addressAsKey = uint256(uint160(_address)); uint256 oldRawNonce = rawNonces[addressAsKey]; @@ -167,9 +175,9 @@ contract NonceHolder is INonceHolder, ISystemContract { bool isUsed = isNonceUsed(_address, _key); if (isUsed && !_shouldBeUsed) { - revert("Reusing the same nonce twice"); + revert NonceAlreadyUsed(_address, _key); } else if (!isUsed && _shouldBeUsed) { - revert("The nonce was not set as used"); + revert NonceNotUsed(_address, _key); } } diff --git a/system-contracts/contracts/PubdataChunkPublisher.sol b/system-contracts/contracts/PubdataChunkPublisher.sol index 53c265e9b..a096e6900 100644 --- a/system-contracts/contracts/PubdataChunkPublisher.sol +++ b/system-contracts/contracts/PubdataChunkPublisher.sol @@ -5,6 +5,7 @@ import {IPubdataChunkPublisher} from "./interfaces/IPubdataChunkPublisher.sol"; import {ISystemContract} from "./interfaces/ISystemContract.sol"; import {L1_MESSENGER_CONTRACT, BLOB_SIZE_BYTES, MAX_NUMBER_OF_BLOBS, SystemLogKey} from "./Constants.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {TooMuchPubdata} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -17,7 +18,9 @@ contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { /// @dev Note: This is an early implementation, in the future we plan to support up to 16 blobs per l1 batch. /// @dev We always publish 6 system logs even if our pubdata fits into a single blob. This makes processing logs on L1 easier. function chunkAndPublishPubdata(bytes calldata _pubdata) external onlyCallFrom(address(L1_MESSENGER_CONTRACT)) { - require(_pubdata.length <= BLOB_SIZE_BYTES * MAX_NUMBER_OF_BLOBS, "pubdata should fit in 6 blobs"); + if (_pubdata.length > BLOB_SIZE_BYTES * MAX_NUMBER_OF_BLOBS) { + revert TooMuchPubdata(BLOB_SIZE_BYTES * MAX_NUMBER_OF_BLOBS, _pubdata.length); + } bytes32[] memory blobHashes = new bytes32[](MAX_NUMBER_OF_BLOBS); @@ -31,7 +34,7 @@ contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { calldatacopy(ptr, _pubdata.offset, _pubdata.length) } - for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint256 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { uint256 start = BLOB_SIZE_BYTES * i; // We break if the pubdata isn't enough to cover all 6 blobs. On L1 it is expected that the hash @@ -50,7 +53,7 @@ contract PubdataChunkPublisher is IPubdataChunkPublisher, ISystemContract { blobHashes[i] = blobHash; } - for (uint8 i = 0; i < MAX_NUMBER_OF_BLOBS; i++) { + for (uint8 i = 0; i < MAX_NUMBER_OF_BLOBS; ++i) { SystemContractHelper.toL1( true, bytes32(uint256(SystemLogKey(i + uint256(SystemLogKey.BLOB_ONE_HASH_KEY)))), diff --git a/system-contracts/contracts/SystemContext.sol b/system-contracts/contracts/SystemContext.sol index 51b9633d9..a37cf0c19 100644 --- a/system-contracts/contracts/SystemContext.sol +++ b/system-contracts/contracts/SystemContext.sol @@ -1,5 +1,7 @@ // SPDX-License-Identifier: MIT +// solhint-disable reason-string, gas-custom-errors + pragma solidity 0.8.20; import {ISystemContext} from "./interfaces/ISystemContext.sol"; @@ -289,6 +291,7 @@ contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContr virtualBlockUpgradeInfo.virtualBlockStartBatch = currentBatchNumber; require(_maxVirtualBlocksToCreate > 0, "Can't initialize the first virtual block"); + // solhint-disable-next-line gas-increment-by-one _maxVirtualBlocksToCreate -= 1; } else if (_maxVirtualBlocksToCreate == 0) { // The virtual blocks have been already initialized, but the operator didn't ask to create @@ -484,7 +487,7 @@ contract SystemContext is ISystemContext, ISystemContextDeprecated, ISystemContr } function incrementTxNumberInBatch() external onlyCallFromBootloader { - txNumberInBlock += 1; + ++txNumberInBlock; } function resetTxNumberInBatch() external onlyCallFromBootloader { diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol new file mode 100644 index 000000000..5ab4ece43 --- /dev/null +++ b/system-contracts/contracts/SystemContractErrors.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.20; + +error Unauthorized(address); +error InvalidCodeHash(CodeHashReason); +error UnsupportedTxType(uint256); +error AddressHasNoCode(address); +error EncodingLengthMismatch(); +error IndexOutOfBounds(); +error ValuesNotEqual(uint256 expected, uint256 actual); +error HashMismatch(bytes32 expected, uint256 actual); +error IndexSizeError(); +error UnsupportedOperation(); +error InvalidNonceOrderingChange(); +error EmptyBytes32(); +error NotAllowedToDeployInKernelSpace(); +error HashIsNonZero(bytes32); +error NonEmptyAccount(); +error UnknownCodeHash(bytes32); +error NonEmptyMsgValue(); +error InsufficientFunds(uint256 required, uint256 actual); +error InvalidSig(SigField, uint256); +error FailedToPayOperator(); +error InsufficientGas(); +error MalformedBytecode(BytecodeError); +error ReconstructionMismatch(PubdataField, bytes32 expected, bytes32 actual); +error InvalidCall(); +error NonceIncreaseError(uint256 max, uint256 proposed); +error ZeroNonceError(); +error NonceJumpError(); +error NonceAlreadyUsed(address account, uint256 nonce); +error NonceNotUsed(address account, uint256 nonce); +error TooMuchPubdata(uint256 limit, uint256 supplied); +error UpgradeMustBeFirstTxn(); +error L2BlockMustBeGreaterThanZero(); +error FirstL2BlockInitializationError(); +error NonIncreasingTimestamp(); +error EmptyVirtualBlocks(); +error SystemCallFlagRequired(); +error CallerMustBeSystemContract(); +error CallerMustBeBootloader(); +error CallerMustBeForceDeployer(); +error InvalidData(); +error FailedToChargeGas(); +error Overflow(); +error InvalidInput(); +error UnsupportedPaymasterFlow(); + +enum CodeHashReason { + NotContractOnConstructor, + NotConstructedContract +} + +enum SigField { + Length, + V, + S +} + +enum PubdataField { + NumberOfLogs, + LogsHash, + MsgHash, + Bytecode, + StateDiffCompressionVersion, + ExtraData +} + +enum BytecodeError { + Version, + NumberOfWords, + Length, + WordsMustBeOdd, + DictionaryLength +} diff --git a/system-contracts/contracts/interfaces/ISystemContract.sol b/system-contracts/contracts/interfaces/ISystemContract.sol index 01ff9d95f..1f383a823 100644 --- a/system-contracts/contracts/interfaces/ISystemContract.sol +++ b/system-contracts/contracts/interfaces/ISystemContract.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.20; import {SystemContractHelper} from "../libraries/SystemContractHelper.sol"; import {BOOTLOADER_FORMAL_ADDRESS, FORCE_DEPLOYER} from "../Constants.sol"; +import {SystemCallFlagRequired, Unauthorized, CallerMustBeSystemContract, CallerMustBeBootloader, CallerMustBeForceDeployer} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -18,41 +19,45 @@ abstract contract ISystemContract { /// @notice Modifier that makes sure that the method /// can only be called via a system call. modifier onlySystemCall() { - require( - SystemContractHelper.isSystemCall() || SystemContractHelper.isSystemContract(msg.sender), - "This method require system call flag" - ); + if (!SystemContractHelper.isSystemCall() && !SystemContractHelper.isSystemContract(msg.sender)) { + revert SystemCallFlagRequired(); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from a system contract. modifier onlyCallFromSystemContract() { - require( - SystemContractHelper.isSystemContract(msg.sender), - "This method require the caller to be system contract" - ); + if (!SystemContractHelper.isSystemContract(msg.sender)) { + revert CallerMustBeSystemContract(); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from a special given address. modifier onlyCallFrom(address caller) { - require(msg.sender == caller, "Inappropriate caller"); + if (msg.sender != caller) { + revert Unauthorized(msg.sender); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from the bootloader. modifier onlyCallFromBootloader() { - require(msg.sender == BOOTLOADER_FORMAL_ADDRESS, "Callable only by the bootloader"); + if (msg.sender != BOOTLOADER_FORMAL_ADDRESS) { + revert CallerMustBeBootloader(); + } _; } /// @notice Modifier that makes sure that the method /// can only be called from the L1 force deployer. modifier onlyCallFromForceDeployer() { - require(msg.sender == FORCE_DEPLOYER); + if (msg.sender != FORCE_DEPLOYER) { + revert CallerMustBeForceDeployer(); + } _; } } diff --git a/system-contracts/contracts/libraries/EfficientCall.sol b/system-contracts/contracts/libraries/EfficientCall.sol index 8f9939f08..70f33ae5d 100644 --- a/system-contracts/contracts/libraries/EfficientCall.sol +++ b/system-contracts/contracts/libraries/EfficientCall.sol @@ -6,6 +6,7 @@ import {SystemContractHelper, ADDRESS_MASK} from "./SystemContractHelper.sol"; import {SystemContractsCaller, CalldataForwardingMode, RAW_FAR_CALL_BY_REF_CALL_ADDRESS, SYSTEM_CALL_BY_REF_CALL_ADDRESS, MSG_VALUE_SIMULATOR_IS_SYSTEM_BIT, MIMIC_CALL_BY_REF_CALL_ADDRESS} from "./SystemContractsCaller.sol"; import {Utils} from "./Utils.sol"; import {SHA256_SYSTEM_CONTRACT, KECCAK256_SYSTEM_CONTRACT, MSG_VALUE_SYSTEM_CONTRACT} from "../Constants.sol"; +import {InvalidData} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -36,7 +37,9 @@ library EfficientCall { /// @return The `keccak256` hash. function keccak(bytes calldata _data) internal view returns (bytes32) { bytes memory returnData = staticCall(gasleft(), KECCAK256_SYSTEM_CONTRACT, _data); - require(returnData.length == 32, "keccak256 returned invalid data"); + if (returnData.length != 32) { + revert InvalidData(); + } return bytes32(returnData); } @@ -45,7 +48,9 @@ library EfficientCall { /// @return The `sha256` hash. function sha(bytes calldata _data) internal view returns (bytes32) { bytes memory returnData = staticCall(gasleft(), SHA256_SYSTEM_CONTRACT, _data); - require(returnData.length == 32, "sha returned invalid data"); + if (returnData.length != 32) { + revert InvalidData(); + } return bytes32(returnData); } diff --git a/system-contracts/contracts/libraries/RLPEncoder.sol b/system-contracts/contracts/libraries/RLPEncoder.sol index 8e32ea9ba..7bfbd2a69 100644 --- a/system-contracts/contracts/libraries/RLPEncoder.sol +++ b/system-contracts/contracts/libraries/RLPEncoder.sol @@ -100,7 +100,7 @@ library RLPEncoder { hbs += 2; } if (_number > type(uint8).max) { - hbs += 1; + ++hbs; } } } diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol index 7ae75b520..14d29f100 100644 --- a/system-contracts/contracts/libraries/SystemContractHelper.sol +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -5,6 +5,7 @@ pragma solidity 0.8.20; import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; import {CALLFLAGS_CALL_ADDRESS, CODE_ADDRESS_CALL_ADDRESS, EVENT_WRITE_ADDRESS, EVENT_INITIALIZE_ADDRESS, GET_EXTRA_ABI_DATA_ADDRESS, LOAD_CALLDATA_INTO_ACTIVE_PTR_CALL_ADDRESS, META_CODE_SHARD_ID_OFFSET, META_CALLER_SHARD_ID_OFFSET, META_SHARD_ID_OFFSET, META_AUX_HEAP_SIZE_OFFSET, META_HEAP_SIZE_OFFSET, META_PUBDATA_PUBLISHED_OFFSET, META_CALL_ADDRESS, PTR_CALLDATA_CALL_ADDRESS, PTR_ADD_INTO_ACTIVE_CALL_ADDRESS, PTR_SHRINK_INTO_ACTIVE_CALL_ADDRESS, PTR_PACK_INTO_ACTIVE_CALL_ADDRESS, PRECOMPILE_CALL_ADDRESS, SET_CONTEXT_VALUE_CALL_ADDRESS, TO_L1_CALL_ADDRESS} from "./SystemContractsCaller.sol"; +import {IndexOutOfBounds, FailedToChargeGas} from "../SystemContractErrors.sol"; uint256 constant UINT32_MASK = type(uint32).max; uint256 constant UINT64_MASK = type(uint64).max; @@ -318,7 +319,10 @@ library SystemContractHelper { /// @dev It is equal to the value of the (N+2)-th register /// at the start of the call. function getExtraAbiData(uint256 index) internal view returns (uint256 extraAbiData) { - require(index < 10, "There are only 10 accessible registers"); + // Note that there are only 10 accessible registers (indices 0-9 inclusively) + if (index > 9) { + revert IndexOutOfBounds(); + } address callAddr = GET_EXTRA_ABI_DATA_ADDRESS; assembly { @@ -350,6 +354,8 @@ library SystemContractHelper { _gasToPay, _pubdataToSpend ); - require(precompileCallSuccess, "Failed to charge gas"); + if (!precompileCallSuccess) { + revert FailedToChargeGas(); + } } } diff --git a/system-contracts/contracts/libraries/TransactionHelper.sol b/system-contracts/contracts/libraries/TransactionHelper.sol index 9a2921010..fbdc57919 100644 --- a/system-contracts/contracts/libraries/TransactionHelper.sol +++ b/system-contracts/contracts/libraries/TransactionHelper.sol @@ -9,6 +9,7 @@ import {IPaymasterFlow} from "../interfaces/IPaymasterFlow.sol"; import {BASE_TOKEN_SYSTEM_CONTRACT, BOOTLOADER_FORMAL_ADDRESS} from "../Constants.sol"; import {RLPEncoder} from "./RLPEncoder.sol"; import {EfficientCall} from "./EfficientCall.sol"; +import {UnsupportedTxType, InvalidInput, UnsupportedPaymasterFlow} from "../SystemContractErrors.sol"; /// @dev The type id of zkSync's EIP-712-signed transaction. uint8 constant EIP_712_TX_TYPE = 0x71; @@ -78,9 +79,10 @@ library TransactionHelper { using SafeERC20 for IERC20; /// @notice The EIP-712 typehash for the contract's domain - bytes32 constant EIP712_DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId)"); + bytes32 internal constant EIP712_DOMAIN_TYPEHASH = + keccak256("EIP712Domain(string name,string version,uint256 chainId)"); - bytes32 constant EIP712_TRANSACTION_TYPE_HASH = + bytes32 internal constant EIP712_TRANSACTION_TYPE_HASH = keccak256( "Transaction(uint256 txType,uint256 from,uint256 to,uint256 gasLimit,uint256 gasPerPubdataByteLimit,uint256 maxFeePerGas,uint256 maxPriorityFeePerGas,uint256 paymaster,uint256 nonce,uint256 value,bytes data,bytes32[] factoryDeps,bytes paymasterInput)" ); @@ -108,7 +110,7 @@ library TransactionHelper { } else { // Currently no other transaction types are supported. // Any new transaction types will be processed in a similar manner. - revert("Encoding unsupported tx"); + revert UnsupportedTxType(_transaction.txType); } } @@ -365,14 +367,15 @@ library TransactionHelper { /// for tokens, etc. For more information on the expected behavior, check out /// the "Paymaster flows" section in the documentation. function processPaymasterInput(Transaction calldata _transaction) internal { - require(_transaction.paymasterInput.length >= 4, "The standard paymaster input must be at least 4 bytes long"); + if (_transaction.paymasterInput.length < 4) { + revert InvalidInput(); + } bytes4 paymasterInputSelector = bytes4(_transaction.paymasterInput[0:4]); if (paymasterInputSelector == IPaymasterFlow.approvalBased.selector) { - require( - _transaction.paymasterInput.length >= 68, - "The approvalBased paymaster input must be at least 68 bytes long" - ); + if (_transaction.paymasterInput.length < 68) { + revert InvalidInput(); + } // While the actual data consists of address, uint256 and bytes data, // the data is needed only for the paymaster, so we ignore it here for the sake of optimization @@ -390,7 +393,7 @@ library TransactionHelper { } else if (paymasterInputSelector == IPaymasterFlow.general.selector) { // Do nothing. general(bytes) paymaster flow means that the paymaster must interpret these bytes on his own. } else { - revert("Unsupported paymaster flow"); + revert UnsupportedPaymasterFlow(); } } diff --git a/system-contracts/contracts/libraries/Utils.sol b/system-contracts/contracts/libraries/Utils.sol index 5fa7eec6f..4f535e2c1 100644 --- a/system-contracts/contracts/libraries/Utils.sol +++ b/system-contracts/contracts/libraries/Utils.sol @@ -2,6 +2,7 @@ pragma solidity 0.8.20; import {EfficientCall} from "./EfficientCall.sol"; +import {MalformedBytecode, BytecodeError, Overflow} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -10,27 +11,33 @@ import {EfficientCall} from "./EfficientCall.sol"; */ library Utils { /// @dev Bit mask of bytecode hash "isConstructor" marker - bytes32 constant IS_CONSTRUCTOR_BYTECODE_HASH_BIT_MASK = + bytes32 internal constant IS_CONSTRUCTOR_BYTECODE_HASH_BIT_MASK = 0x00ff000000000000000000000000000000000000000000000000000000000000; /// @dev Bit mask to set the "isConstructor" marker in the bytecode hash - bytes32 constant SET_IS_CONSTRUCTOR_MARKER_BIT_MASK = + bytes32 internal constant SET_IS_CONSTRUCTOR_MARKER_BIT_MASK = 0x0001000000000000000000000000000000000000000000000000000000000000; function safeCastToU128(uint256 _x) internal pure returns (uint128) { - require(_x <= type(uint128).max, "Overflow"); + if (_x > type(uint128).max) { + revert Overflow(); + } return uint128(_x); } function safeCastToU32(uint256 _x) internal pure returns (uint32) { - require(_x <= type(uint32).max, "Overflow"); + if (_x > type(uint32).max) { + revert Overflow(); + } return uint32(_x); } function safeCastToU24(uint256 _x) internal pure returns (uint24) { - require(_x <= type(uint24).max, "Overflow"); + if (_x > type(uint24).max) { + revert Overflow(); + } return uint24(_x); } @@ -81,11 +88,19 @@ library Utils { /// - Bytecode words length is not odd function hashL2Bytecode(bytes calldata _bytecode) internal view returns (bytes32 hashedBytecode) { // Note that the length of the bytecode must be provided in 32-byte words. - require(_bytecode.length % 32 == 0, "po"); + if (_bytecode.length % 32 != 0) { + revert MalformedBytecode(BytecodeError.Length); + } uint256 lengthInWords = _bytecode.length / 32; - require(lengthInWords < 2 ** 16, "pp"); // bytecode length must be less than 2^16 words - require(lengthInWords % 2 == 1, "pr"); // bytecode length in words must be odd + // bytecode length must be less than 2^16 words + if (lengthInWords >= 2 ** 16) { + revert MalformedBytecode(BytecodeError.NumberOfWords); + } + // bytecode length in words must be odd + if (lengthInWords % 2 == 0) { + revert MalformedBytecode(BytecodeError.WordsMustBeOdd); + } hashedBytecode = EfficientCall.sha(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; diff --git a/system-contracts/test/AccountCodeStorage.spec.ts b/system-contracts/test/AccountCodeStorage.spec.ts index 994cfacc8..dca782e01 100644 --- a/system-contracts/test/AccountCodeStorage.spec.ts +++ b/system-contracts/test/AccountCodeStorage.spec.ts @@ -44,7 +44,7 @@ describe("AccountCodeStorage tests", function () { it("non-deployer failed to call", async () => { await expect( accountCodeStorage.storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) - ).to.be.revertedWith("Callable only by the deployer system contract"); + ).to.be.revertedWithCustomError(accountCodeStorage, "Unauthorized"); }); it("failed to set with constructed bytecode", async () => { @@ -52,7 +52,7 @@ describe("AccountCodeStorage tests", function () { accountCodeStorage .connect(deployerAccount) .storeAccountConstructingCodeHash(RANDOM_ADDRESS, CONSTRUCTED_BYTECODE_HASH) - ).to.be.revertedWith("Code hash is not for a contract on constructor"); + ).to.be.revertedWithCustomError(accountCodeStorage, "InvalidCodeHash"); }); it("successfully stored", async () => { @@ -72,7 +72,7 @@ describe("AccountCodeStorage tests", function () { it("non-deployer failed to call", async () => { await expect( accountCodeStorage.storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) - ).to.be.revertedWith("Callable only by the deployer system contract"); + ).to.be.revertedWithCustomError(accountCodeStorage, "Unauthorized"); }); it("failed to set with constructing bytecode", async () => { @@ -80,7 +80,7 @@ describe("AccountCodeStorage tests", function () { accountCodeStorage .connect(deployerAccount) .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTING_BYTECODE_HASH) - ).to.be.revertedWith("Code hash is not for a constructed contract"); + ).to.be.revertedWithCustomError(accountCodeStorage, "InvalidCodeHash"); }); it("successfully stored", async () => { @@ -96,8 +96,9 @@ describe("AccountCodeStorage tests", function () { describe("markAccountCodeHashAsConstructed", function () { it("non-deployer failed to call", async () => { - await expect(accountCodeStorage.markAccountCodeHashAsConstructed(RANDOM_ADDRESS)).to.be.revertedWith( - "Callable only by the deployer system contract" + await expect(accountCodeStorage.markAccountCodeHashAsConstructed(RANDOM_ADDRESS)).to.be.revertedWithCustomError( + accountCodeStorage, + "Unauthorized" ); }); @@ -108,7 +109,7 @@ describe("AccountCodeStorage tests", function () { await expect( accountCodeStorage.connect(deployerAccount).markAccountCodeHashAsConstructed(RANDOM_ADDRESS) - ).to.be.revertedWith("Code hash is not for a contract on constructor"); + ).to.be.revertedWithCustomError(accountCodeStorage, "InvalidCodeHash"); await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); }); diff --git a/system-contracts/test/BootloaderUtilities.spec.ts b/system-contracts/test/BootloaderUtilities.spec.ts index 2c4176a17..e47446e33 100644 --- a/system-contracts/test/BootloaderUtilities.spec.ts +++ b/system-contracts/test/BootloaderUtilities.spec.ts @@ -84,7 +84,10 @@ describe("BootloaderUtilities tests", function () { signature[64] = 29; txData.signature = signature; - await expect(bootloaderUtilities.getTransactionHashes(txData)).to.be.revertedWith("Invalid v value"); + await expect(bootloaderUtilities.getTransactionHashes(txData)).to.be.revertedWithCustomError( + bootloaderUtilities, + "InvalidSig" + ); }); }); @@ -130,7 +133,10 @@ describe("BootloaderUtilities tests", function () { signature[64] = 0; EIP1559TxData.signature = signature; - await expect(bootloaderUtilities.getTransactionHashes(EIP1559TxData)).to.be.revertedWith("Invalid v value"); + await expect(bootloaderUtilities.getTransactionHashes(EIP1559TxData)).to.be.revertedWithCustomError( + bootloaderUtilities, + "InvalidSig" + ); }); }); @@ -176,7 +182,10 @@ describe("BootloaderUtilities tests", function () { signature[64] = 100; EIP2930TxData.signature = signature; - await expect(bootloaderUtilities.getTransactionHashes(EIP2930TxData)).to.be.revertedWith("Invalid v value"); + await expect(bootloaderUtilities.getTransactionHashes(EIP2930TxData)).to.be.revertedWithCustomError( + bootloaderUtilities, + "InvalidSig" + ); }); }); }); diff --git a/system-contracts/test/ComplexUpgrader.spec.ts b/system-contracts/test/ComplexUpgrader.spec.ts index 63b4a61eb..e9104e010 100644 --- a/system-contracts/test/ComplexUpgrader.spec.ts +++ b/system-contracts/test/ComplexUpgrader.spec.ts @@ -18,8 +18,9 @@ describe("ComplexUpgrader tests", function () { describe("upgrade", function () { it("non force deployer failed to call", async () => { - await expect(complexUpgrader.upgrade(dummyUpgrade.address, "0xdeadbeef")).to.be.revertedWith( - "Can only be called by FORCE_DEPLOYER" + await expect(complexUpgrader.upgrade(dummyUpgrade.address, "0xdeadbeef")).to.be.revertedWithCustomError( + complexUpgrader, + "Unauthorized" ); }); diff --git a/system-contracts/test/Compressor.spec.ts b/system-contracts/test/Compressor.spec.ts index 094eddd99..363be1d13 100644 --- a/system-contracts/test/Compressor.spec.ts +++ b/system-contracts/test/Compressor.spec.ts @@ -46,8 +46,9 @@ describe("Compressor tests", function () { describe("publishCompressedBytecode", function () { it("should revert when it's a non-bootloader call", async () => { - await expect(compressor.publishCompressedBytecode("0x", "0x0000")).to.be.revertedWith( - "Callable only by the bootloader" + await expect(compressor.publishCompressedBytecode("0x", "0x0000")).to.be.revertedWithCustomError( + compressor, + "CallerMustBeBootloader" ); }); @@ -57,7 +58,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0002" + "deadbeefdeadbeef" + "0000" + "0000" + "0000" + "0000"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when there is no encoded data", async () => { @@ -66,7 +67,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0002" + "deadbeefdeadbeef" + "deadbeefdeadbeef"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the encoded data length is invalid", async () => { @@ -80,7 +81,7 @@ describe("Compressor tests", function () { // The length of the encodedData should be 32 / 4 = 8 bytes await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded data length should be 4 times shorter than the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the dictionary has too many entries", async () => { @@ -101,7 +102,7 @@ describe("Compressor tests", function () { // The dictionary should have at most encode data length entries await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Dictionary should have at most the same number of entries as the encoded data"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the encoded data has chunks where index is out of bounds", async () => { @@ -112,7 +113,7 @@ describe("Compressor tests", function () { // The dictionary has only 1 entry, so at the last entry of the encoded data the chunk index is out of bounds await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded chunk index is out of bounds"); + ).to.be.revertedWithCustomError(compressor, "IndexOutOfBounds"); }); it("should revert when the encoded data has chunks that does not match the original bytecode", async () => { @@ -122,7 +123,7 @@ describe("Compressor tests", function () { "0x0002" + "deadbeefdeadbeef" + "1111111111111111" + "0001" + "0000" + "0000" + "0001"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("Encoded chunk does not match the original bytecode"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("should revert when the bytecode length in bytes is invalid", async () => { @@ -131,7 +132,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0001" + "deadbeefdeadbeef" + "0000" + "0000" + "0000"; await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("po"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); it("should revert when the bytecode length in words is odd", async () => { @@ -140,7 +141,7 @@ describe("Compressor tests", function () { const COMPRESSED_BYTECODE = "0x0001" + "deadbeefdeadbeef" + "0000".repeat(4 * 2); await expect( compressor.connect(bootloaderAccount).publishCompressedBytecode(BYTECODE, COMPRESSED_BYTECODE) - ).to.be.revertedWith("pr"); + ).to.be.revertedWithCustomError(compressor, "MalformedBytecode"); }); // Test case with too big bytecode is unrealistic because API cannot accept so much data. @@ -183,8 +184,9 @@ describe("Compressor tests", function () { describe("verifyCompressedStateDiffs", function () { it("non l1 messenger failed to call", async () => { - await expect(compressor.verifyCompressedStateDiffs(0, 8, "0x", "0x0000")).to.be.revertedWith( - "Inappropriate caller" + await expect(compressor.verifyCompressedStateDiffs(0, 8, "0x", "0x0000")).to.be.revertedWithCustomError( + compressor, + "Unauthorized" ); }); @@ -202,7 +204,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(9, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 9, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("enumeration index size is too large"); + ).to.be.revertedWithCustomError(compressor, "IndexSizeError"); }); it("initial write key mismatch", async () => { @@ -219,7 +221,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(4, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 4, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("iw: initial key mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("repeated write key mismatch", async () => { @@ -236,7 +238,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(8, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 8, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("rw: enum key mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("no compression value mismatch", async () => { @@ -259,7 +261,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(3, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 3, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("transform or no compression: compressed and final mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("transform value mismatch", async () => { @@ -282,7 +284,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("transform or no compression: compressed and final mismatch"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("add value mismatch", async () => { @@ -299,7 +301,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("add: initial plus converted not equal to final"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("sub value mismatch", async () => { @@ -316,7 +318,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("sub: initial minus converted not equal to final"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("invalid operation", async () => { @@ -335,7 +337,7 @@ describe("Compressor tests", function () { compressedStateDiffs = compressedStateDiffsCharArray.join(""); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(1, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("unsupported operation"); + ).to.be.revertedWithCustomError(compressor, "UnsupportedOperation"); }); it("Incorrect number of initial storage diffs", async () => { @@ -363,7 +365,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("Incorrect number of initial storage diffs"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("Extra data in compressed state diffs", async () => { @@ -391,7 +393,7 @@ describe("Compressor tests", function () { const compressedStateDiffs = compressStateDiffs(1, stateDiffs); await expect( compressor.connect(l1MessengerAccount).verifyCompressedStateDiffs(2, 1, encodedStateDiffs, compressedStateDiffs) - ).to.be.revertedWith("Extra data in _compressedStateDiffs"); + ).to.be.revertedWithCustomError(compressor, "ValuesNotEqual"); }); it("successfully verified", async () => { diff --git a/system-contracts/test/ContractDeployer.spec.ts b/system-contracts/test/ContractDeployer.spec.ts index 6f8984eae..bcae882c0 100644 --- a/system-contracts/test/ContractDeployer.spec.ts +++ b/system-contracts/test/ContractDeployer.spec.ts @@ -68,8 +68,9 @@ describe("ContractDeployer tests", function () { describe("updateAccountVersion", function () { it("non system call failed", async () => { - await expect(contractDeployer.updateAccountVersion(AA_VERSION_NONE)).to.be.revertedWith( - "This method require system call flag" + await expect(contractDeployer.updateAccountVersion(AA_VERSION_NONE)).to.be.revertedWithCustomError( + contractDeployer, + "SystemCallFlagRequired" ); }); @@ -96,8 +97,9 @@ describe("ContractDeployer tests", function () { describe("updateNonceOrdering", function () { it("non system call failed", async () => { - await expect(contractDeployer.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWith( - "This method require system call flag" + await expect(contractDeployer.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWithCustomError( + contractDeployer, + "SystemCallFlagRequired" ); }); @@ -115,9 +117,9 @@ describe("ContractDeployer tests", function () { expect((await contractDeployer.getAccountInfo(contractDeployerSystemCall.address)).nonceOrdering).to.be.eq( NONCE_ORDERING_ARBITRARY ); - await expect(contractDeployerSystemCall.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL)).to.be.revertedWith( - "It is only possible to change from sequential to arbitrary ordering" - ); + await expect( + contractDeployerSystemCall.updateNonceOrdering(NONCE_ORDERING_SEQUENTIAL) + ).to.be.revertedWithCustomError(contractDeployer, "InvalidNonceOrderingChange"); }); }); @@ -233,7 +235,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("zero bytecode hash failed", async () => { @@ -244,7 +246,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("BytecodeHash cannot be zero"); + ).to.be.revertedWithCustomError(contractDeployer, "EmptyBytes32"); }); it("not known bytecode hash failed", async () => { @@ -261,7 +263,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("The code hash is not known"); + ).to.be.revertedWithCustomError(contractDeployer, "UnknownCodeHash"); }); // TODO: other mock events can be checked as well @@ -344,7 +346,7 @@ describe("ContractDeployer tests", function () { "0xdeadbeef", AA_VERSION_NONE ) - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("zero bytecode hash failed", async () => { @@ -355,7 +357,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("BytecodeHash cannot be zero"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "EmptyBytes32"); }); it("not known bytecode hash failed", async () => { @@ -386,7 +388,7 @@ describe("ContractDeployer tests", function () { "0x", AA_VERSION_NONE ) - ).to.be.revertedWith("The code hash is not known"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "UnknownCodeHash"); }); it("successfully deployed", async () => { @@ -419,7 +421,7 @@ describe("ContractDeployer tests", function () { "0xdeadbeef", AA_VERSION_NONE ) - ).to.be.revertedWith("Code hash is non-zero"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "HashIsNonZero"); await setResult("AccountCodeStorage", "getCodeHash", [expectedAddress], { failure: false, returnData: ethers.constants.HashZero, @@ -477,7 +479,7 @@ describe("ContractDeployer tests", function () { it("non system call failed", async () => { await expect( contractDeployer.create(ethers.constants.HashZero, utils.hashBytecode(deployableArtifact.bytecode), "0x") - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("successfully deployed", async () => { @@ -534,7 +536,7 @@ describe("ContractDeployer tests", function () { it("non system call failed", async () => { await expect( contractDeployer.create2(ethers.constants.HashZero, utils.hashBytecode(deployableArtifact.bytecode), "0xabcd") - ).to.be.revertedWith("This method require system call flag"); + ).to.be.revertedWithCustomError(contractDeployer, "SystemCallFlagRequired"); }); it("successfully deployed", async () => { @@ -564,8 +566,9 @@ describe("ContractDeployer tests", function () { value: 0, input: "0x", }; - await expect(contractDeployer.forceDeployOnAddress(deploymentData, wallet.address)).to.be.revertedWith( - "Callable only by self" + await expect(contractDeployer.forceDeployOnAddress(deploymentData, wallet.address)).to.be.revertedWithCustomError( + contractDeployer, + "Unauthorized" ); }); @@ -585,7 +588,7 @@ describe("ContractDeployer tests", function () { }; await expect( contractDeployer.connect(deployerAccount).forceDeployOnAddress(deploymentData, wallet.address) - ).to.be.revertedWith("The code hash is not known"); + ).to.be.revertedWithCustomError(contractDeployerSystemCall, "UnknownCodeHash"); }); it("successfully deployed", async () => { @@ -628,8 +631,9 @@ describe("ContractDeployer tests", function () { input: "0xab", }, ]; - await expect(contractDeployer.forceDeployOnAddresses(deploymentData)).to.be.revertedWith( - "Can only be called by FORCE_DEPLOYER or COMPLEX_UPGRADER_CONTRACT" + await expect(contractDeployer.forceDeployOnAddresses(deploymentData)).to.be.revertedWithCustomError( + contractDeployer, + "Unauthorized" ); }); diff --git a/system-contracts/test/ImmutableSimulator.spec.ts b/system-contracts/test/ImmutableSimulator.spec.ts index 530fa370c..0adce4c2e 100644 --- a/system-contracts/test/ImmutableSimulator.spec.ts +++ b/system-contracts/test/ImmutableSimulator.spec.ts @@ -31,8 +31,9 @@ describe("ImmutableSimulator tests", function () { describe("setImmutables", function () { it("non-deployer failed to call", async () => { - await expect(immutableSimulator.setImmutables(RANDOM_ADDRESS, IMMUTABLES_DATA)).to.be.revertedWith( - "Callable only by the deployer system contract" + await expect(immutableSimulator.setImmutables(RANDOM_ADDRESS, IMMUTABLES_DATA)).to.be.revertedWithCustomError( + immutableSimulator, + "Unauthorized" ); }); diff --git a/system-contracts/test/KnownCodesStorage.spec.ts b/system-contracts/test/KnownCodesStorage.spec.ts index 9558f85dc..36a034cb7 100644 --- a/system-contracts/test/KnownCodesStorage.spec.ts +++ b/system-contracts/test/KnownCodesStorage.spec.ts @@ -50,21 +50,22 @@ describe("KnownCodesStorage tests", function () { describe("markBytecodeAsPublished", function () { it("non-compressor failed to call", async () => { - await expect(knownCodesStorage.markBytecodeAsPublished(BYTECODE_HASH_1)).to.be.revertedWith( - "Callable only by the compressor" + await expect(knownCodesStorage.markBytecodeAsPublished(BYTECODE_HASH_1)).to.be.revertedWithCustomError( + knownCodesStorage, + "Unauthorized" ); }); it("incorrectly formatted bytecode hash failed to call", async () => { await expect( knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(INCORRECTLY_FORMATTED_HASH) - ).to.be.revertedWith("Incorrectly formatted bytecodeHash"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("invalid length bytecode hash failed to call", async () => { await expect( knownCodesStorage.connect(compressorAccount).markBytecodeAsPublished(INVALID_LENGTH_HASH) - ).to.be.revertedWith("Code length in words must be odd"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("successfully marked", async () => { @@ -85,9 +86,9 @@ describe("KnownCodesStorage tests", function () { describe("markFactoryDeps", function () { it("non-bootloader failed to call", async () => { - await expect(knownCodesStorage.markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3])).to.be.revertedWith( - "Callable only by the bootloader" - ); + await expect( + knownCodesStorage.markFactoryDeps(false, [BYTECODE_HASH_2, BYTECODE_HASH_3]) + ).to.be.revertedWithCustomError(knownCodesStorage, "CallerMustBeBootloader"); }); it("incorrectly formatted bytecode hash failed to call", async () => { @@ -95,13 +96,13 @@ describe("KnownCodesStorage tests", function () { knownCodesStorage .connect(bootloaderAccount) .markFactoryDeps(true, [BYTECODE_HASH_2, INCORRECTLY_FORMATTED_HASH]) - ).to.be.revertedWith("Incorrectly formatted bytecodeHash"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("invalid length bytecode hash failed to call", async () => { await expect( knownCodesStorage.connect(bootloaderAccount).markFactoryDeps(false, [INVALID_LENGTH_HASH, BYTECODE_HASH_3]) - ).to.be.revertedWith("Code length in words must be odd"); + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); }); it("successfully marked", async () => { diff --git a/system-contracts/test/L1Messenger.spec.ts b/system-contracts/test/L1Messenger.spec.ts index 74f16fc10..6910bc9f5 100644 --- a/system-contracts/test/L1Messenger.spec.ts +++ b/system-contracts/test/L1Messenger.spec.ts @@ -99,7 +99,7 @@ describe("L1Messenger tests", () => { l1Messenger .connect(bootloaderAccount) .publishPubdataAndClearState(emulator.buildTotalL2ToL1PubdataAndStateDiffs({ numberOfLogs: 0x4002 })) - ).to.be.rejectedWith("Too many L2->L1 logs"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert logshashes mismatch", async () => { @@ -121,7 +121,7 @@ describe("L1Messenger tests", () => { l1Messenger .connect(bootloaderAccount) .publishPubdataAndClearState(emulator.buildTotalL2ToL1PubdataAndStateDiffs(overrideData)) - ).to.be.rejectedWith("reconstructedChainedLogsHash is not equal to chainedLogsHash"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert chainedMessageHash mismatch", async () => { @@ -133,7 +133,7 @@ describe("L1Messenger tests", () => { l1Messenger .connect(bootloaderAccount) .publishPubdataAndClearState(emulator.buildTotalL2ToL1PubdataAndStateDiffs(overrideData)) - ).to.be.rejectedWith("reconstructedChainedMessagesHash is not equal to chainedMessagesHash"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert state diff compression version mismatch", async () => { @@ -151,7 +151,7 @@ describe("L1Messenger tests", () => { version: ethers.utils.hexZeroPad(ethers.utils.hexlify(66), 1), }) ) - ).to.be.rejectedWith("state diff compression version mismatch"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); it("should revert extra data", async () => { @@ -162,14 +162,15 @@ describe("L1Messenger tests", () => { .publishPubdataAndClearState( ethers.utils.concat([emulator.buildTotalL2ToL1PubdataAndStateDiffs(), Buffer.alloc(1, 64)]) ) - ).to.be.rejectedWith("Extra data in the totalL2ToL1Pubdata array"); + ).to.be.revertedWithCustomError(l1Messenger, "ReconstructionMismatch"); }); }); describe("sendL2ToL1Log", async () => { it("should revert when not called by the system contract", async () => { - await expect(l1Messenger.sendL2ToL1Log(true, logData.key, logData.value)).to.be.rejectedWith( - "This method require the caller to be system contract" + await expect(l1Messenger.sendL2ToL1Log(true, logData.key, logData.value)).to.be.revertedWithCustomError( + l1Messenger, + "CallerMustBeSystemContract" ); }); @@ -244,7 +245,10 @@ describe("L1Messenger tests", () => { describe("requestBytecodeL1Publication", async () => { it("should revert when not called by known code storage contract", async () => { const byteCodeHash = ethers.utils.hexlify(randomBytes(32)); - await expect(l1Messenger.requestBytecodeL1Publication(byteCodeHash)).to.be.rejectedWith("Inappropriate caller"); + await expect(l1Messenger.requestBytecodeL1Publication(byteCodeHash)).to.be.revertedWithCustomError( + l1Messenger, + "Unauthorized" + ); }); it("should emit event, called by known code system contract", async () => { diff --git a/system-contracts/test/L2BaseToken.spec.ts b/system-contracts/test/L2BaseToken.spec.ts index 3ef04d590..c1b03fb7e 100644 --- a/system-contracts/test/L2BaseToken.spec.ts +++ b/system-contracts/test/L2BaseToken.spec.ts @@ -53,9 +53,9 @@ describe("L2BaseToken tests", () => { it("not called by bootloader", async () => { const amountToMint: BigNumber = ethers.utils.parseEther("10.0"); - await expect(L2BaseToken.connect(wallets[0]).mint(wallets[0].address, amountToMint)).to.be.rejectedWith( - "Callable only by the bootloader" - ); + await expect( + L2BaseToken.connect(wallets[0]).mint(wallets[0].address, amountToMint) + ).to.be.revertedWithCustomError(L2BaseToken, "CallerMustBeBootloader"); }); }); @@ -90,7 +90,7 @@ describe("L2BaseToken tests", () => { await expect( L2BaseToken.connect(bootloaderAccount).transferFromTo(wallets[0].address, wallets[1].address, amountToTransfer) - ).to.be.rejectedWith("Transfer amount exceeds balance"); + ).to.be.revertedWithCustomError(L2BaseToken, "InsufficientFunds"); }); it("no transfer - require special access", async () => { @@ -107,7 +107,7 @@ describe("L2BaseToken tests", () => { wallets[1].address, amountToTransfer ) - ).to.be.rejectedWith("Only system contracts with special access can call this method"); + ).to.be.revertedWithCustomError(L2BaseToken, "Unauthorized"); }); }); diff --git a/system-contracts/test/NonceHolder.spec.ts b/system-contracts/test/NonceHolder.spec.ts index 91e9e3ba4..4c2ea8738 100644 --- a/system-contracts/test/NonceHolder.spec.ts +++ b/system-contracts/test/NonceHolder.spec.ts @@ -78,7 +78,7 @@ describe("NonceHolder tests", () => { await expect( nonceHolder.connect(systemAccount).increaseMinNonce(BigNumber.from(2).pow(32).add(1)) - ).to.be.rejectedWith("The value for incrementing the nonce is too high"); + ).to.be.revertedWithCustomError(nonceHolder, "NonceIncreaseError"); const nonceAfter = await nonceHolder.getMinNonce(systemAccount.address); const rawNonceAfter = await nonceHolder.getRawNonce(systemAccount.address); @@ -88,21 +88,26 @@ describe("NonceHolder tests", () => { }); it("should revert This method require system call flag", async () => { - await expect(nonceHolder.increaseMinNonce(123)).to.be.rejectedWith("This method require system call flag"); + await expect(nonceHolder.increaseMinNonce(123)).to.be.revertedWithCustomError( + nonceHolder, + "SystemCallFlagRequired" + ); }); }); describe("incrementMinNonceIfEquals", async () => { it("should revert This method require system call flag", async () => { const expectedNonce = await nonceHolder.getMinNonce(systemAccount.address); - await expect(nonceHolder.incrementMinNonceIfEquals(expectedNonce)).to.be.rejectedWith( - "This method require system call flag" + await expect(nonceHolder.incrementMinNonceIfEquals(expectedNonce)).to.be.revertedWithCustomError( + nonceHolder, + "SystemCallFlagRequired" ); }); it("should revert Incorrect nonce", async () => { - await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.rejectedWith( - "Incorrect nonce" + await expect(nonceHolder.connect(systemAccount).incrementMinNonceIfEquals(2222222)).to.be.revertedWithCustomError( + nonceHolder, + "ValuesNotEqual" ); }); @@ -116,8 +121,9 @@ describe("NonceHolder tests", () => { describe("incrementDeploymentNonce", async () => { it("should revert Only the contract deployer can increment the deployment nonce", async () => { - await expect(nonceHolder.incrementDeploymentNonce(deployerAccount.address)).to.be.rejectedWith( - "Only the contract deployer can increment the deployment nonce" + await expect(nonceHolder.incrementDeploymentNonce(deployerAccount.address)).to.be.revertedWithCustomError( + nonceHolder, + "Unauthorized" ); }); @@ -141,8 +147,9 @@ describe("NonceHolder tests", () => { failure: false, returnData: encodedAccountInfo, }); - await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(124, 0)).to.be.rejectedWith( - "Nonce value cannot be set to 0" + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(124, 0)).to.be.revertedWithCustomError( + nonceHolder, + "ZeroNonceError" ); }); @@ -153,8 +160,9 @@ describe("NonceHolder tests", () => { failure: false, returnData: encodedAccountInfo, }); - await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(443, 111)).to.be.rejectedWith( - "Previous nonce has not been used" + await expect(nonceHolder.connect(systemAccount).setValueUnderNonce(443, 111)).to.be.revertedWithCustomError( + nonceHolder, + "NonceJumpError" ); }); @@ -235,8 +243,9 @@ describe("NonceHolder tests", () => { describe("validateNonceUsage", () => { it("used nonce & should not be used", async () => { - await expect(nonceHolder.validateNonceUsage(systemAccount.address, 1, false)).to.be.rejectedWith( - "Reusing the same nonce twice" + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 1, false)).to.be.revertedWithCustomError( + nonceHolder, + "NonceAlreadyUsed" ); }); @@ -245,8 +254,9 @@ describe("NonceHolder tests", () => { }); it("not used nonce & should be used", async () => { - await expect(nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, true)).to.be.rejectedWith( - "The nonce was not set as used" + await expect(nonceHolder.validateNonceUsage(systemAccount.address, 2 ** 16, true)).to.be.revertedWithCustomError( + nonceHolder, + "NonceNotUsed" ); }); diff --git a/system-contracts/test/PubdataChunkPublisher.spec.ts b/system-contracts/test/PubdataChunkPublisher.spec.ts index 49dd5b05f..f007f2018 100644 --- a/system-contracts/test/PubdataChunkPublisher.spec.ts +++ b/system-contracts/test/PubdataChunkPublisher.spec.ts @@ -37,14 +37,17 @@ describe("PubdataChunkPublisher tests", () => { describe("chunkAndPublishPubdata", () => { it("non-L1Messenger failed to call", async () => { - await expect(pubdataChunkPublisher.chunkAndPublishPubdata("0x1337")).to.be.revertedWith("Inappropriate caller"); + await expect(pubdataChunkPublisher.chunkAndPublishPubdata("0x1337")).to.be.revertedWithCustomError( + pubdataChunkPublisher, + "Unauthorized" + ); }); it("Too Much Pubdata", async () => { const pubdata = genRandHex(blobSizeInBytes * maxNumberBlobs + 1); await expect( pubdataChunkPublisher.connect(l1MessengerAccount).chunkAndPublishPubdata(pubdata) - ).to.be.revertedWith("pubdata should fit in 6 blobs"); + ).to.be.revertedWithCustomError(pubdataChunkPublisher, "TooMuchPubdata"); }); it("Publish 1 Blob", async () => { diff --git a/system-contracts/test/SystemContext.spec.ts b/system-contracts/test/SystemContext.spec.ts index dd23acaf2..2117c59da 100644 --- a/system-contracts/test/SystemContext.spec.ts +++ b/system-contracts/test/SystemContext.spec.ts @@ -28,7 +28,10 @@ describe("SystemContext tests", () => { describe("setTxOrigin", async () => { it("should revert not called by bootlader", async () => { const txOriginExpected = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; - await expect(systemContext.setTxOrigin(txOriginExpected)).to.be.rejectedWith("Callable only by the bootloader"); + await expect(systemContext.setTxOrigin(txOriginExpected)).to.be.revertedWithCustomError( + systemContext, + "CallerMustBeBootloader" + ); }); it("should set tx.origin", async () => { @@ -44,7 +47,10 @@ describe("SystemContext tests", () => { describe("setGasPrice", async () => { it("should revert not called by bootlader", async () => { const newGasPrice = 4294967295; - await expect(systemContext.setGasPrice(newGasPrice)).to.be.rejectedWith("Callable only by the bootloader"); + await expect(systemContext.setGasPrice(newGasPrice)).to.be.revertedWithCustomError( + systemContext, + "CallerMustBeBootloader" + ); }); it("should set tx.gasprice", async () => { @@ -92,7 +98,7 @@ describe("SystemContext tests", () => { const batchHash = await systemContext.getBatchHash(batchData.batchNumber); await expect( systemContext.setNewBatch(batchHash, batchData.batchTimestamp.add(1), batchData.batchNumber.add(1), 1) - ).to.be.rejectedWith("Callable only by the bootloader"); + ).to.be.revertedWithCustomError(systemContext, "CallerMustBeBootloader"); }); it("should revert timestamp should be incremental", async () => { @@ -159,7 +165,7 @@ describe("SystemContext tests", () => { true, 1 ) - ).to.be.rejectedWith("Callable only by the bootloader"); + ).to.be.revertedWithCustomError(systemContext, "CallerMustBeBootloader"); }); it("should revert The timestamp of the L2 block must be greater than or equal to the timestamp of the current batch", async () => { diff --git a/yarn.lock b/yarn.lock index 2c64e92e6..1b462d2be 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1067,6 +1067,27 @@ resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== +"@pnpm/config.env-replace@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz#ab29da53df41e8948a00f2433f085f54de8b3a4c" + integrity sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w== + +"@pnpm/network.ca-file@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz#2ab05e09c1af0cdf2fcf5035bea1484e222f7983" + integrity sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA== + dependencies: + graceful-fs "4.2.10" + +"@pnpm/npm-conf@^2.1.0": + version "2.2.2" + resolved "https://registry.yarnpkg.com/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz#0058baf1c26cbb63a828f0193795401684ac86f0" + integrity sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA== + dependencies: + "@pnpm/config.env-replace" "^1.1.0" + "@pnpm/network.ca-file" "^1.0.1" + config-chain "^1.1.11" + "@resolver-engine/core@^0.3.3": version "0.3.3" resolved "https://registry.yarnpkg.com/@resolver-engine/core/-/core-0.3.3.tgz#590f77d85d45bc7ecc4e06c654f41345db6ca967" @@ -1211,6 +1232,11 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sindresorhus/is@^5.2.0": + version "5.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-5.6.0.tgz#41dd6093d34652cddb5d5bdeee04eafc33826668" + integrity sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g== + "@sinonjs/commons@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" @@ -1270,6 +1296,13 @@ resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.18.0.tgz#8e77a02a09ecce957255a2f48c9a7178ec191908" integrity sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA== +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + "@trufflesuite/bigint-buffer@1.1.10": version "1.1.10" resolved "https://registry.yarnpkg.com/@trufflesuite/bigint-buffer/-/bigint-buffer-1.1.10.tgz#a1d9ca22d3cad1a138b78baaf15543637a3e1692" @@ -1394,6 +1427,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@^4.0.2": + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz#b979ebad3919799c979b17c72621c0bc0a31c6c4" + integrity sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA== + "@types/json-schema@^7.0.12": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" @@ -1787,6 +1825,11 @@ antlr4@^4.11.0: resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1.tgz#1e0a1830a08faeb86217cb2e6c34716004e4253d" integrity sha512-kiXTspaRYvnIArgE97z5YVVf/cDVQABr3abFRR6mE7yesLMkgu4ujuyV/sgxafQ8wgve0DJQUJ38Z8tkgA2izA== +antlr4@^4.13.1-patch-1: + version "4.13.1-patch-1" + resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.13.1-patch-1.tgz#946176f863f890964a050c4f18c47fd6f7e57602" + integrity sha512-OjFLWWLzDMV9rdFhpvroCWR4ooktNg9/nvVYSA5z28wuVpU36QUNuioR1XLnQtcjVlf8npjyz593PxnU/f/Cow== + antlr4ts@^0.5.0-alpha.4: version "0.5.0-alpha.4" resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" @@ -2252,6 +2295,24 @@ bytes@3.1.2: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacheable-lookup@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz#3476a8215d046e5a3202a9209dd13fec1f933a27" + integrity sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w== + +cacheable-request@^10.2.8: + version "10.2.14" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-10.2.14.tgz#eb915b665fda41b79652782df3f553449c406b9d" + integrity sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ== + dependencies: + "@types/http-cache-semantics" "^4.0.2" + get-stream "^6.0.1" + http-cache-semantics "^4.1.1" + keyv "^4.5.3" + mimic-response "^4.0.0" + normalize-url "^8.0.0" + responselike "^3.0.0" + call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" @@ -2552,6 +2613,14 @@ concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@~1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +config-chain@^1.1.11: + version "1.1.13" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4" + integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + cookie@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" @@ -2719,6 +2788,13 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-eql@^4.0.1, deep-eql@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" @@ -2736,6 +2812,11 @@ deep-is@^0.1.3, deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + deferred-leveldown@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz#27a997ad95408b61161aa69bd489b86c71b78058" @@ -3687,6 +3768,11 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== +form-data-encoder@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-2.1.4.tgz#261ea35d2a70d48d30ec7a9603130fa5515e9cd5" + integrity sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw== + form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -3860,6 +3946,11 @@ get-stdin@~9.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-9.0.0.tgz#3983ff82e03d56f1b2ea0d3e60325f39d703a575" integrity sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA== +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.2.tgz#533744d5aa20aca4e079c8e5daf7fd44202821f5" @@ -4037,6 +4128,28 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" +got@^12.1.0: + version "12.6.1" + resolved "https://registry.yarnpkg.com/got/-/got-12.6.1.tgz#8869560d1383353204b5a9435f782df9c091f549" + integrity sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ== + dependencies: + "@sindresorhus/is" "^5.2.0" + "@szmarczak/http-timer" "^5.0.1" + cacheable-lookup "^7.0.0" + cacheable-request "^10.2.8" + decompress-response "^6.0.0" + form-data-encoder "^2.1.2" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^3.0.0" + +graceful-fs@4.2.10: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -4251,6 +4364,11 @@ http-basic@^8.1.1: http-response-object "^3.0.1" parse-cache-control "^1.0.1" +http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -4278,6 +4396,14 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^2.1.10: + version "2.2.1" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.1.tgz#310968153dcdedb160d8b72114363ef5fce1f64a" + integrity sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -4359,7 +4485,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== -ini@^1.3.5: +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== @@ -4813,6 +4939,13 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +latest-version@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-7.0.0.tgz#843201591ea81a4d404932eeb61240fe04e9e5da" + integrity sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg== + dependencies: + package-json "^8.1.0" + level-codec@^9.0.0: version "9.0.2" resolved "https://registry.yarnpkg.com/level-codec/-/level-codec-9.0.2.tgz#fd60df8c64786a80d44e63423096ffead63d8cbc" @@ -5033,6 +5166,11 @@ loupe@^2.3.6: dependencies: get-func-name "^2.0.1" +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -5197,6 +5335,16 @@ mime-types@^2.1.12, mime-types@~2.1.19: dependencies: mime-db "1.52.0" +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +mimic-response@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-4.0.0.tgz#35468b19e7c75d10f5165ea25e75a5ceea7cf70f" + integrity sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg== + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -5441,6 +5589,11 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@^8.0.0: + version "8.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.1.tgz#9b7d96af9836577c58f5883e939365fa15623a4a" + integrity sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w== + number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" @@ -5553,6 +5706,11 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -5600,6 +5758,16 @@ p-try@^1.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== +package-json@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-8.1.1.tgz#3e9948e43df40d1e8e78a85485f1070bf8f03dc8" + integrity sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA== + dependencies: + got "^12.1.0" + registry-auth-token "^5.0.1" + registry-url "^6.0.0" + semver "^7.3.7" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -5798,6 +5966,11 @@ proper-lockfile@^4.1.2: retry "^0.12.0" signal-exit "^3.0.2" +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA== + proxy-from-env@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" @@ -5861,6 +6034,11 @@ queue-microtask@^1.2.2, queue-microtask@^1.2.3: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.0.1, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -5878,6 +6056,16 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +rc@1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.5: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" @@ -5951,6 +6139,20 @@ regexp.prototype.flags@^1.5.2: es-errors "^1.3.0" set-function-name "^2.0.1" +registry-auth-token@^5.0.1: + version "5.0.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-5.0.2.tgz#8b026cc507c8552ebbe06724136267e63302f756" + integrity sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ== + dependencies: + "@pnpm/npm-conf" "^2.1.0" + +registry-url@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-6.0.1.tgz#056d9343680f2f64400032b1e199faa692286c58" + integrity sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q== + dependencies: + rc "1.2.8" + req-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" @@ -6001,6 +6203,11 @@ require-from-string@^2.0.0, require-from-string@^2.0.2: resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -6028,7 +6235,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.8.1: +resolve@^1.1.6, resolve@^1.22.4, resolve@^1.8.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -6037,6 +6244,13 @@ resolve@^1.1.6, resolve@^1.10.0, resolve@^1.22.4, resolve@^1.8.1: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-3.0.0.tgz#20decb6c298aff0dbee1c355ca95461d42823626" + integrity sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg== + dependencies: + lowercase-keys "^3.0.0" + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -6200,6 +6414,11 @@ semver@^7.3.4, semver@^7.5.1, semver@^7.5.2, semver@^7.5.4: dependencies: lru-cache "^6.0.0" +semver@^7.3.7: + version "7.6.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" + integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6375,6 +6594,32 @@ solhint-plugin-prettier@^0.0.5: dependencies: prettier-linter-helpers "^1.0.0" +solhint@4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/solhint/-/solhint-4.5.4.tgz#171cf33f46c36b8499efe60c0e425f6883a54e50" + integrity sha512-Cu1XiJXub2q1eCr9kkJ9VPv1sGcmj3V7Zb76B0CoezDOB9bu3DxKIFFH7ggCl9fWpEPD6xBmRLfZrYijkVmujQ== + dependencies: + "@solidity-parser/parser" "^0.18.0" + ajv "^6.12.6" + antlr4 "^4.13.1-patch-1" + ast-parents "^0.0.1" + chalk "^4.1.2" + commander "^10.0.0" + cosmiconfig "^8.0.0" + fast-diff "^1.2.0" + glob "^8.0.3" + ignore "^5.2.4" + js-yaml "^4.1.0" + latest-version "^7.0.0" + lodash "^4.17.21" + pluralize "^8.0.0" + semver "^7.5.2" + strip-ansi "^6.0.1" + table "^6.8.1" + text-table "^0.2.0" + optionalDependencies: + prettier "^2.8.3" + solhint@^3.6.2: version "3.6.2" resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.6.2.tgz#2b2acbec8fdc37b2c68206a71ba89c7f519943fe" @@ -6598,6 +6843,11 @@ strip-json-comments@3.1.1, strip-json-comments@^3.1.1, strip-json-comments@~3.1. resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + supports-color@8.1.1: version "8.1.1" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" From c64d4489b2da5d5db095e54455afd371229122a3 Mon Sep 17 00:00:00 2001 From: Danil Date: Fri, 17 May 2024 14:01:03 +0200 Subject: [PATCH 44/60] fix init bridges (#469) Signed-off-by: Danil --- l1-contracts-foundry/script/AcceptAdmin.s.sol | 40 +++++++++++++++---- .../script/RegisterHyperchain.s.sol | 6 ++- l1-contracts-foundry/script/Utils.sol | 10 +---- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/l1-contracts-foundry/script/AcceptAdmin.s.sol b/l1-contracts-foundry/script/AcceptAdmin.s.sol index ffc865126..00ade426a 100644 --- a/l1-contracts-foundry/script/AcceptAdmin.s.sol +++ b/l1-contracts-foundry/script/AcceptAdmin.s.sol @@ -5,27 +5,53 @@ import {Script} from "forge-std/Script.sol"; import {stdToml} from "forge-std/StdToml.sol"; import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol"; +import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; import {Utils} from "./Utils.sol"; contract AcceptAdmin is Script { using stdToml for string; - // This function should be called by the owner to accept the admin role - function run() public { + struct Config { + address admin; + address governor; + } + + Config config; + + function initConfig() public { string memory root = vm.projectRoot(); string memory path = string.concat(root, "/script-config/config-accept-admin.toml"); string memory toml = vm.readFile(path); - address admin = toml.readAddress("$.target_addr"); - address governor = toml.readAddress("$.governor"); - Ownable2Step adminContract = Ownable2Step(admin); + config.admin = toml.readAddress("$.target_addr"); + config.governor = toml.readAddress("$.governor"); + } + + // This function should be called by the owner to accept the admin role + function acceptOwner() public { + initConfig(); + Ownable2Step adminContract = Ownable2Step(config.admin); Utils.executeUpgrade({ - _governor: governor, + _governor: config.governor, _salt: bytes32(0), - _target: admin, + _target: config.admin, _data: abi.encodeCall(adminContract.acceptOwnership, ()), _value: 0, _delay: 0 }); } + + // This function should be called by the owner to accept the admin role + function acceptAdmin() public { + initConfig(); + IZkSyncHyperchain adminContract = IZkSyncHyperchain(config.admin); + Utils.executeUpgrade({ + _governor: config.governor, + _salt: bytes32(0), + _target: config.admin, + _data: abi.encodeCall(adminContract.acceptAdmin, ()), + _value: 0, + _delay: 0 + }); + } } diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 4b499cf0a..884ca771f 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -135,6 +135,7 @@ contract RegisterHyperchainScript is Script { } function deployGovernance() internal { + vm.broadcast(); Governance governance = new Governance( config.ownerAddress, config.governanceSecurityCouncilAddress, @@ -220,11 +221,12 @@ contract RegisterHyperchainScript is Script { vm.broadcast(); hyperchain.setPendingAdmin(config.governance); - console.log("Owner set"); + console.log("Owner for ", config.newDiamondProxy, "set to", config.governance); } function saveOutput() internal { - string memory toml = vm.serializeAddress("root", "diamond_proxy_addr", config.newDiamondProxy); + vm.serializeAddress("root", "diamond_proxy_addr", config.newDiamondProxy); + string memory toml = vm.serializeAddress("root", "governance_addr", config.governance); string memory root = vm.projectRoot(); string memory path = string.concat(root, "/script-out/output-register-hyperchain.toml"); vm.writeToml(toml, path); diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts-foundry/script/Utils.sol index 2cea861aa..3480c491f 100644 --- a/l1-contracts-foundry/script/Utils.sol +++ b/l1-contracts-foundry/script/Utils.sol @@ -253,14 +253,8 @@ library Utils { requiredValueToDeploy = 0; } - executeUpgrade({ - _governor: bridgehub.owner(), - _salt: bytes32(0), - _target: l1SharedBridgeProxy, - _data: abi.encodeCall(bridgehub.requestL2TransactionDirect, (l2TransactionRequestDirect)), - _value: requiredValueToDeploy, - _delay: 0 - }); + vm.broadcast(); + bridgehub.requestL2TransactionDirect{value: requiredValueToDeploy}(l2TransactionRequestDirect); } /** From 12a7d3bc1777ae5663e7525b2628061502755cbd Mon Sep 17 00:00:00 2001 From: Ivan Schasny <31857042+ischasny@users.noreply.github.com> Date: Mon, 20 May 2024 23:44:00 +0100 Subject: [PATCH 45/60] feat: register hyperchain through governance EVM-597 (#443) Co-authored-by: kelemeno --- l1-contracts/scripts/register-hyperchain.ts | 7 ++- l1-contracts/src.ts/deploy-process.ts | 15 ++++- l1-contracts/src.ts/deploy.ts | 67 ++++++++++++++++----- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/l1-contracts/scripts/register-hyperchain.ts b/l1-contracts/scripts/register-hyperchain.ts index bb21aeca5..d516f03c1 100644 --- a/l1-contracts/scripts/register-hyperchain.ts +++ b/l1-contracts/scripts/register-hyperchain.ts @@ -69,6 +69,7 @@ async function main() { .option("--validium-mode") .option("--base-token-name ") .option("--base-token-address ") + .option("--use-governance ") .action(async (cmd) => { const deployWallet = cmd.privateKey ? new Wallet(cmd.privateKey, provider) @@ -99,11 +100,13 @@ async function main() { await checkTokenAddress(baseTokenAddress); console.log(`Using base token address: ${baseTokenAddress}`); + const useGovernance = !!cmd.useGovernance && cmd.useGovernance === "true"; + if (!(await deployer.bridgehubContract(deployWallet).tokenIsRegistered(baseTokenAddress))) { - await deployer.registerToken(baseTokenAddress); + await deployer.registerToken(baseTokenAddress, useGovernance); } - await deployer.registerHyperchain(baseTokenAddress, cmd.validiumMode, null, gasPrice); + await deployer.registerHyperchain(baseTokenAddress, cmd.validiumMode, null, gasPrice, useGovernance); }); await program.parseAsync(process.argv); diff --git a/l1-contracts/src.ts/deploy-process.ts b/l1-contracts/src.ts/deploy-process.ts index 90cb030ef..f495bb69a 100644 --- a/l1-contracts/src.ts/deploy-process.ts +++ b/l1-contracts/src.ts/deploy-process.ts @@ -76,7 +76,8 @@ export async function registerHyperchain( extraFacets: FacetCut[], gasPrice: BigNumberish, baseTokenName?: string, - chainId?: string + chainId?: string, + useGovernance: boolean = false ) { const testnetTokens = getTokens(); @@ -85,7 +86,15 @@ export async function registerHyperchain( : ADDRESS_ONE; if (!(await deployer.bridgehubContract(deployer.deployWallet).tokenIsRegistered(baseTokenAddress))) { - await deployer.registerToken(baseTokenAddress); + await deployer.registerToken(baseTokenAddress, useGovernance); } - await deployer.registerHyperchain(baseTokenAddress, validiumMode, extraFacets, gasPrice, null, chainId); + await deployer.registerHyperchain( + baseTokenAddress, + validiumMode, + extraFacets, + gasPrice, + null, + chainId, + useGovernance + ); } diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index a7009e868..5373fd352 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -32,6 +32,7 @@ import type { FacetCut } from "./diamondCut"; import { diamondCut, getCurrentFacetCutsForAdd } from "./diamondCut"; import { ERC20Factory } from "../typechain"; +import type { Contract, Overrides } from "@ethersproject/contracts"; let L2_BOOTLOADER_BYTECODE_HASH: string; let L2_DEFAULT_ACCOUNT_BYTECODE_HASH: string; @@ -450,15 +451,39 @@ export class Deployer { } } + public async executeDirectOrGovernance( + useGovernance: boolean, + contract: Contract, + fname: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + fargs: any[], + value: BigNumberish, + overrides?: Overrides, + printOperation: boolean = false + ): Promise { + if (useGovernance) { + const cdata = contract.interface.encodeFunctionData(fname, fargs); + return this.executeUpgrade(contract.address, value, cdata, printOperation); + } else { + const tx: ethers.ContractTransaction = await contract[fname](...fargs, ...(overrides ? [overrides] : [])); + return await tx.wait(); + } + } + /// this should be only use for local testing - public async executeUpgrade(targetAddress: string, value: BigNumberish, callData: string, printFileName?: string) { + public async executeUpgrade( + targetAddress: string, + value: BigNumberish, + callData: string, + printOperation: boolean = false + ) { const governance = IGovernanceFactory.connect(this.addresses.Governance, this.deployWallet); const operation = { calls: [{ target: targetAddress, value: value, data: callData }], predecessor: ethers.constants.HashZero, salt: ethers.utils.hexlify(ethers.utils.randomBytes(32)), }; - if (printFileName) { + if (printOperation) { console.log("Operation:", operation); console.log( "Schedule operation: ", @@ -476,7 +501,7 @@ export class Deployer { console.log("Upgrade scheduled"); } const executeTX = await governance.execute(operation, { value: value }); - await executeTX.wait(); + const receipt = await executeTX.wait(); if (this.verbose) { console.log( "Upgrade with target ", @@ -485,6 +510,7 @@ export class Deployer { await governance.isOperationDone(await governance.hashOperation(operation)) ); } + return receipt; } // used for testing, mimics original deployment process. @@ -676,7 +702,8 @@ export class Deployer { extraFacets?: FacetCut[], gasPrice?: BigNumberish, nonce?, - predefinedChainId?: string + predefinedChainId?: string, + useGovernance: boolean = false ) { const gasLimit = 10_000_000; @@ -690,24 +717,34 @@ export class Deployer { const diamondCutData = await this.initialZkSyncHyperchainDiamondCut(extraFacets); const initialDiamondCut = new ethers.utils.AbiCoder().encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCutData]); - const tx = await bridgehub.createNewChain( - inputChainId, - this.addresses.StateTransition.StateTransitionProxy, - baseTokenAddress, - Date.now(), - admin, - initialDiamondCut, + const receipt = await this.executeDirectOrGovernance( + useGovernance, + bridgehub, + "createNewChain", + [ + inputChainId, + this.addresses.StateTransition.StateTransitionProxy, + baseTokenAddress, + Date.now(), + admin, + initialDiamondCut, + ], + 0, { gasPrice, nonce, gasLimit, } ); - const receipt = await tx.wait(); + const chainId = receipt.logs.find((log) => log.topics[0] == bridgehub.interface.getEventTopic("NewChain")) .topics[1]; nonce++; + if (useGovernance) { + // deploying through governance requires two transactions + nonce++; + } this.addresses.BaseToken = baseTokenAddress; @@ -777,11 +814,11 @@ export class Deployer { } } - public async registerToken(tokenAddress: string) { + public async registerToken(tokenAddress: string, useGovernance: boolean = false) { const bridgehub = this.bridgehubContract(this.deployWallet); - const tx = await bridgehub.addToken(tokenAddress); - const receipt = await tx.wait(); + const receipt = await this.executeDirectOrGovernance(useGovernance, bridgehub, "addToken", [tokenAddress], 0); + if (this.verbose) { console.log(`Token ${tokenAddress} was registered, gas used: ${receipt.gasUsed.toString()}`); } From 41fb9d91819890dc756cb548000dd9ba98e7805c Mon Sep 17 00:00:00 2001 From: Agustin Aon <21188659+aon@users.noreply.github.com> Date: Tue, 21 May 2024 14:48:15 -0300 Subject: [PATCH 46/60] feat: update foundry scripts with new config (#485) --- .../config-deploy-l1.toml | 2 +- .../register-hyperchain.toml | 4 +-- l1-contracts-foundry/script/DeployL1.s.sol | 6 ++-- .../script/RegisterHyperchain.s.sol | 28 +++++++++---------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml index e6b45719f..7e3f06e21 100644 --- a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml +++ b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml @@ -5,7 +5,7 @@ testnet_verifier = true [contracts] governance_security_council_address = "0x0000000000000000000000000000000000000000" governance_min_delay = 0 -max_number_of_hyperchains = 100 +max_number_of_chains = 100 create2_factory_salt = "0x00000000000000000000000000000000000000000000000000000000000000ff" create2_factory_addr = "0x0000000000000000000000000000000000000000" validator_timelock_execution_delay = 0 diff --git a/l1-contracts-foundry/script-config-template/register-hyperchain.toml b/l1-contracts-foundry/script-config-template/register-hyperchain.toml index 3d45e5b50..dd93f34a4 100644 --- a/l1-contracts-foundry/script-config-template/register-hyperchain.toml +++ b/l1-contracts-foundry/script-config-template/register-hyperchain.toml @@ -1,6 +1,6 @@ owner_address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8" -[hyperchain] -hyperchain_chain_id = 9 +[chain] +chain_chain_id = 9 base_token_addr = "0x0000000000000000000000000000000000000001" bridgehub_create_new_chain_salt = 0 validium_mode = false diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index 1033e2d51..c89eb3abc 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -107,7 +107,7 @@ contract DeployL1Script is Script { uint256 diamondInitMinimalL2GasPrice; address governanceSecurityCouncilAddress; uint256 governanceMinDelay; - uint256 maxNumberOfHyperchains; + uint256 maxNumberOfChains; bytes diamondCutData; bytes32 bootloaderHash; bytes32 defaultAAHash; @@ -172,7 +172,7 @@ contract DeployL1Script is Script { "$.contracts.governance_security_council_address" ); config.contracts.governanceMinDelay = toml.readUint("$.contracts.governance_min_delay"); - config.contracts.maxNumberOfHyperchains = toml.readUint("$.contracts.max_number_of_hyperchains"); + config.contracts.maxNumberOfChains = toml.readUint("$.contracts.max_number_of_chains"); config.contracts.create2FactorySalt = toml.readBytes32("$.contracts.create2_factory_salt"); if (vm.keyExistsToml(toml, "$.contracts.create2_factory_addr")) { config.contracts.create2FactoryAddr = toml.readAddress("$.contracts.create2_factory_addr"); @@ -361,7 +361,7 @@ contract DeployL1Script is Script { bytes memory bytecode = abi.encodePacked( type(StateTransitionManager).creationCode, abi.encode(addresses.bridgehub.bridgehubProxy), - abi.encode(config.contracts.maxNumberOfHyperchains) + abi.encode(config.contracts.maxNumberOfChains) ); address contractAddress = deployViaCreate2(bytecode); console.log("StateTransitionManagerImplementation deployed at:", contractAddress); diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts-foundry/script/RegisterHyperchain.s.sol index 884ca771f..4dd8c0636 100644 --- a/l1-contracts-foundry/script/RegisterHyperchain.s.sol +++ b/l1-contracts-foundry/script/RegisterHyperchain.s.sol @@ -24,7 +24,7 @@ contract RegisterHyperchainScript is Script { struct Config { address deployerAddress; address ownerAddress; - uint256 hyperchainChainId; + uint256 chainChainId; bool validiumMode; uint256 bridgehubCreateNewChainSalt; address validatorSenderOperatorCommitEth; @@ -81,20 +81,20 @@ contract RegisterHyperchainScript is Script { config.diamondCutData = toml.readBytes("$.contracts_config.diamond_cut_data"); - config.hyperchainChainId = toml.readUint("$.hyperchain.hyperchain_chain_id"); - config.bridgehubCreateNewChainSalt = toml.readUint("$.hyperchain.bridgehub_create_new_chain_salt"); - config.baseToken = toml.readAddress("$.hyperchain.base_token_addr"); - config.validiumMode = toml.readBool("$.hyperchain.validium_mode"); - config.validatorSenderOperatorCommitEth = toml.readAddress("$.hyperchain.validator_sender_operator_commit_eth"); - config.validatorSenderOperatorBlobsEth = toml.readAddress("$.hyperchain.validator_sender_operator_blobs_eth"); + config.chainChainId = toml.readUint("$.chain.chain_chain_id"); + config.bridgehubCreateNewChainSalt = toml.readUint("$.chain.bridgehub_create_new_chain_salt"); + config.baseToken = toml.readAddress("$.chain.base_token_addr"); + config.validiumMode = toml.readBool("$.chain.validium_mode"); + config.validatorSenderOperatorCommitEth = toml.readAddress("$.chain.validator_sender_operator_commit_eth"); + config.validatorSenderOperatorBlobsEth = toml.readAddress("$.chain.validator_sender_operator_blobs_eth"); config.baseTokenGasPriceMultiplierNominator = uint128( - toml.readUint("$.hyperchain.base_token_gas_price_multiplier_nominator") + toml.readUint("$.chain.base_token_gas_price_multiplier_nominator") ); config.baseTokenGasPriceMultiplierDenominator = uint128( - toml.readUint("$.hyperchain.base_token_gas_price_multiplier_denominator") + toml.readUint("$.chain.base_token_gas_price_multiplier_denominator") ); - config.governanceMinDelay = uint256(toml.readUint("$.hyperchain.governance_min_delay")); - config.governanceSecurityCouncilAddress = toml.readAddress("$.hyperchain.governance_security_council_address"); + config.governanceMinDelay = uint256(toml.readUint("$.chain.governance_min_delay")); + config.governanceSecurityCouncilAddress = toml.readAddress("$.chain.governance_security_council_address"); } function checkTokenAddress() internal view { @@ -153,7 +153,7 @@ contract RegisterHyperchainScript is Script { bytes memory data = abi.encodeCall( bridgehub.createNewChain, ( - config.hyperchainChainId, + config.chainChainId, config.stateTransitionProxy, config.baseToken, config.bridgehubCreateNewChainSalt, @@ -192,8 +192,8 @@ contract RegisterHyperchainScript is Script { ValidatorTimelock validatorTimelock = ValidatorTimelock(config.validatorTimelock); vm.startBroadcast(); - validatorTimelock.addValidator(config.hyperchainChainId, config.validatorSenderOperatorCommitEth); - validatorTimelock.addValidator(config.hyperchainChainId, config.validatorSenderOperatorBlobsEth); + validatorTimelock.addValidator(config.chainChainId, config.validatorSenderOperatorCommitEth); + validatorTimelock.addValidator(config.chainChainId, config.validatorSenderOperatorBlobsEth); vm.stopBroadcast(); console.log("Validators added"); From 5312fd40c12c622e15db9b5515cff0e5d6c5324d Mon Sep 17 00:00:00 2001 From: Agustin Aon <21188659+aon@users.noreply.github.com> Date: Wed, 22 May 2024 10:08:20 -0300 Subject: [PATCH 47/60] fix: utils library getting deployed (#487) --- l1-contracts-foundry/script/Utils.sol | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts-foundry/script/Utils.sol index 3480c491f..23bcf0ff8 100644 --- a/l1-contracts-foundry/script/Utils.sol +++ b/l1-contracts-foundry/script/Utils.sol @@ -175,7 +175,7 @@ library Utils { uint256 chainId, address bridgehubAddress, address l1SharedBridgeProxy - ) public returns (address) { + ) internal returns (address) { bytes32 bytecodeHash = L2ContractHelper.hashL2Bytecode(bytecode); bytes memory deployData = abi.encodeWithSignature( @@ -222,7 +222,7 @@ library Utils { uint256 chainId, address bridgehubAddress, address l1SharedBridgeProxy - ) public { + ) internal { Bridgehub bridgehub = Bridgehub(bridgehubAddress); uint256 gasPrice = bytesToUint256(vm.rpc("eth_gasPrice", "[]")); @@ -265,7 +265,7 @@ library Utils { uint256 chainId, address bridgehubAddress, address l1SharedBridgeProxy - ) public { + ) internal { runL1L2Transaction({ l2Calldata: "", l2GasLimit: MAX_PRIORITY_TX_GAS, @@ -280,7 +280,7 @@ library Utils { /** * @dev Read hardhat bytecodes */ - function readHardhatBytecode(string memory artifactPath) public view returns (bytes memory) { + function readHardhatBytecode(string memory artifactPath) internal view returns (bytes memory) { string memory root = vm.projectRoot(); string memory path = string.concat(root, artifactPath); string memory json = vm.readFile(path); @@ -295,7 +295,7 @@ library Utils { bytes memory _data, uint256 _value, uint256 _delay - ) public { + ) internal { IGovernance governance = IGovernance(_governor); IGovernance.Call[] memory calls = new IGovernance.Call[](1); From 8cc766e6f94906907c331acab012bb24dbb06614 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Wed, 29 May 2024 11:07:02 +0200 Subject: [PATCH 48/60] Packed protocol version (#492) Co-authored-by: perekopskiy Co-authored-by: Vlad Bochok <41153528+vladbochok@users.noreply.github.com> Co-authored-by: perekopskiy <53865202+perekopskiy@users.noreply.github.com> --- l1-contracts/contracts/common/Config.sol | 5 +- .../contracts/common/libraries/SemVer.sol | 48 ++++ .../dev-contracts/test/CustomUpgradeTest.sol | 7 +- .../IStateTransitionManager.sol | 2 + .../StateTransitionManager.sol | 22 +- .../chain-deps/facets/Getters.sol | 9 + .../chain-interfaces/IGetters.sol | 5 +- .../contracts/upgrades/BaseZkSyncUpgrade.sol | 86 ++++++-- .../upgrades/BaseZkSyncUpgradeGenesis.sol | 51 ++++- l1-contracts/scripts/utils.ts | 29 +++ l1-contracts/scripts/verify.ts | 4 +- l1-contracts/src.ts/deploy-test-process.ts | 2 +- l1-contracts/src.ts/deploy.ts | 10 +- .../facets/Admin/ExecuteUpgrade.t.sol | 43 ++++ .../test/unit_tests/l2-upgrade.test.spec.ts | 208 +++++++++++++++--- l1-contracts/test/unit_tests/utils.ts | 3 +- 16 files changed, 455 insertions(+), 79 deletions(-) create mode 100644 l1-contracts/contracts/common/libraries/SemVer.sol diff --git a/l1-contracts/contracts/common/Config.sol b/l1-contracts/contracts/common/Config.sol index 1e23213d1..72ca11aa1 100644 --- a/l1-contracts/contracts/common/Config.sol +++ b/l1-contracts/contracts/common/Config.sol @@ -27,10 +27,11 @@ uint256 constant PRIORITY_OPERATION_L2_TX_TYPE = 255; /// @dev Denotes the type of the zkSync transaction that is used for system upgrades. uint256 constant SYSTEM_UPGRADE_L2_TX_TYPE = 254; -/// @dev The maximal allowed difference between protocol versions in an upgrade. The 100 gap is needed +/// @dev The maximal allowed difference between protocol minor versions in an upgrade. The 100 gap is needed /// in case a protocol version has been tested on testnet, but then not launched on mainnet, e.g. /// due to a bug found. -uint256 constant MAX_ALLOWED_PROTOCOL_VERSION_DELTA = 100; +/// We are allowed to jump at most 100 minor versions at a time. The major version is always expected to be 0. +uint256 constant MAX_ALLOWED_MINOR_VERSION_DELTA = 100; /// @dev The amount of time in seconds the validator has to process the priority transaction /// NOTE: The constant is set to zero for the Alpha release period diff --git a/l1-contracts/contracts/common/libraries/SemVer.sol b/l1-contracts/contracts/common/libraries/SemVer.sol new file mode 100644 index 000000000..d20f6a1d1 --- /dev/null +++ b/l1-contracts/contracts/common/libraries/SemVer.sol @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @dev The number of bits dedicated to the "patch" portion of the protocol version. +/// This also defines the bit starting from which the "minor" part is located. +uint256 constant SEMVER_MINOR_OFFSET = 32; + +/// @dev The number of bits dedicated to the "patch" and "minor" portions of the protocol version. +/// This also defines the bit starting from which the "major" part is located. +/// Note, that currently, only major version of "0" is supported. +uint256 constant SEMVER_MAJOR_OFFSET = 64; + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The library for managing SemVer for the protocol version. + */ +library SemVer { + /// @notice Unpacks the SemVer version from a single uint256 into major, minor and patch components. + /// @param _packedProtocolVersion The packed protocol version. + /// @return major The major version. + /// @return minor The minor version. + /// @return patch The patch version. + function unpackSemVer( + uint96 _packedProtocolVersion + ) internal pure returns (uint32 major, uint32 minor, uint32 patch) { + patch = uint32(_packedProtocolVersion); + minor = uint32(_packedProtocolVersion >> SEMVER_MINOR_OFFSET); + major = uint32(_packedProtocolVersion >> SEMVER_MAJOR_OFFSET); + } + + /// @notice Packs the SemVer version from the major, minor and patch components into a single uint96. + /// @param _major The major version. + /// @param _minor The minor version. + /// @param _patch The patch version. + /// @return packedProtocolVersion The packed protocol version. + function packSemVer( + uint32 _major, + uint32 _minor, + uint32 _patch + ) internal pure returns (uint96 packedProtocolVersion) { + packedProtocolVersion = + uint96(_patch) | + (uint96(_minor) << SEMVER_MINOR_OFFSET) | + (uint96(_major) << SEMVER_MAJOR_OFFSET); + } +} diff --git a/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol b/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol index e7c82d29c..7055ce557 100644 --- a/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol +++ b/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol @@ -28,16 +28,17 @@ contract CustomUpgradeTest is BaseZkSyncUpgrade { /// @notice The main function that will be called by the upgrade proxy. /// @param _proposedUpgrade The upgrade to be executed. function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) { - _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); + (uint32 newMinorVersion, bool isPatchOnly) = _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); _upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata); _upgradeVerifier(_proposedUpgrade.verifier, _proposedUpgrade.verifierParams); - _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash); + _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash, isPatchOnly); bytes32 txHash; txHash = _setL2SystemContractUpgrade( _proposedUpgrade.l2ProtocolUpgradeTx, _proposedUpgrade.factoryDeps, - _proposedUpgrade.newProtocolVersion + newMinorVersion, + isPatchOnly ); _postUpgrade(_proposedUpgrade.postUpgradeCalldata); diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index d201c8333..4151a1454 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -131,4 +131,6 @@ interface IStateTransitionManager { uint256 _oldProtocolVersion, Diamond.DiamondCutData calldata _diamondCut ) external; + + function getSemverProtocolVersion() external view returns (uint32, uint32, uint32); } diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index c5367dd9b..812e6fa11 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import {Diamond} from "./libraries/Diamond.sol"; import {DiamondProxy} from "./chain-deps/DiamondProxy.sol"; @@ -21,6 +22,7 @@ import {ProposedUpgrade} from "../upgrades/BaseZkSyncUpgrade.sol"; import {ReentrancyGuard} from "../common/ReentrancyGuard.sol"; import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, L2_TO_L1_LOG_SERIALIZE_SIZE, DEFAULT_L2_LOGS_TREE_ROOT_HASH, EMPTY_STRING_KECCAK, SYSTEM_UPGRADE_L2_TX_TYPE, PRIORITY_TX_MAX_GAS_LIMIT} from "../common/Config.sol"; import {VerifierParams} from "./chain-interfaces/IVerifier.sol"; +import {SemVer} from "../common/libraries/SemVer.sol"; /// @title State Transition Manager contract /// @author Matter Labs @@ -47,7 +49,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own /// @dev The genesisUpgrade contract address, used to setChainId address public genesisUpgrade; - /// @dev The current protocolVersion + /// @dev The current packed protocolVersion. To access human-readable version, use `getSemverProtocolVersion` function. uint256 public protocolVersion; /// @dev The timestamp when protocolVersion can be last used @@ -84,6 +86,12 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own _; } + /// @return The tuple of (major, minor, patch) protocol version. + function getSemverProtocolVersion() external view returns (uint32, uint32, uint32) { + // slither-disable-next-line unused-return + return SemVer.unpackSemVer(SafeCast.toUint96(protocolVersion)); + } + /// @notice Returns all the registered hyperchain addresses function getAllHyperchains() public view override returns (address[] memory chainAddresses) { uint256[] memory keys = hyperchainMap.keys(); @@ -280,6 +288,10 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own uint256[] memory uintEmptyArray; bytes[] memory bytesEmptyArray; + uint256 cachedProtocolVersion = protocolVersion; + // slither-disable-next-line unused-return + (, uint32 minorVersion, ) = SemVer.unpackSemVer(SafeCast.toUint96(cachedProtocolVersion)); + L2CanonicalTransaction memory l2ProtocolUpgradeTx = L2CanonicalTransaction({ txType: SYSTEM_UPGRADE_L2_TX_TYPE, from: uint256(uint160(L2_FORCE_DEPLOYER_ADDR)), @@ -289,8 +301,8 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own maxFeePerGas: uint256(0), maxPriorityFeePerGas: uint256(0), paymaster: uint256(0), - // Note, that the protocol version is used as "nonce" for system upgrade transactions - nonce: protocolVersion, + // Note, that the `minor` of the protocol version is used as "nonce" for system upgrade transactions + nonce: uint256(minorVersion), value: 0, reserved: [uint256(0), 0, 0, 0], data: systemContextCalldata, @@ -314,7 +326,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own l1ContractsUpgradeCalldata: new bytes(0), postUpgradeCalldata: new bytes(0), upgradeTimestamp: 0, - newProtocolVersion: protocolVersion + newProtocolVersion: cachedProtocolVersion }); Diamond.FacetCut[] memory emptyArray; @@ -325,7 +337,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own }); IAdmin(_chainContract).executeUpgrade(cutData); - emit SetChainIdUpgrade(_chainContract, l2ProtocolUpgradeTx, protocolVersion); + emit SetChainIdUpgrade(_chainContract, l2ProtocolUpgradeTx, cachedProtocolVersion); } /// @dev used to register already deployed hyperchain contracts diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol index 1769dceca..ab87d31f0 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol @@ -2,6 +2,8 @@ pragma solidity 0.8.24; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; + import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; import {VerifierParams} from "../../../state-transition/chain-interfaces/IVerifier.sol"; @@ -10,6 +12,7 @@ import {PriorityQueue, PriorityOperation} from "../../../state-transition/librar import {UncheckedMath} from "../../../common/libraries/UncheckedMath.sol"; import {IGetters} from "../../chain-interfaces/IGetters.sol"; import {ILegacyGetters} from "../../chain-interfaces/ILegacyGetters.sol"; +import {SemVer} from "../../../common/libraries/SemVer.sol"; // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; @@ -143,6 +146,12 @@ contract GettersFacet is ZkSyncHyperchainBase, IGetters, ILegacyGetters { return s.protocolVersion; } + /// @inheritdoc IGetters + function getSemverProtocolVersion() external view returns (uint32, uint32, uint32) { + // slither-disable-next-line unused-return + return SemVer.unpackSemVer(SafeCast.toUint96(s.protocolVersion)); + } + /// @inheritdoc IGetters function getL2SystemContractsUpgradeTxHash() external view returns (bytes32) { return s.l2SystemContractsUpgradeTxHash; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol index 4eec88868..9d77efdf3 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol @@ -85,9 +85,12 @@ interface IGetters is IZkSyncHyperchainBase { /// @return Whether the diamond is frozen or not function isDiamondStorageFrozen() external view returns (bool); - /// @return The current protocol version + /// @return The current packed protocol version. To access human-readable version, use `getSemverProtocolVersion` function. function getProtocolVersion() external view returns (uint256); + /// @return The tuple of (major, minor, patch) protocol version. + function getSemverProtocolVersion() external view returns (uint32, uint32, uint32); + /// @return The upgrade system contract transaction hash, 0 if the upgrade is not initialized function getL2SystemContractsUpgradeTxHash() external view returns (bytes32); diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol index 07185b095..72c02f277 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol @@ -2,13 +2,16 @@ pragma solidity 0.8.24; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; + import {ZkSyncHyperchainBase} from "../state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol"; import {VerifierParams} from "../state-transition/chain-interfaces/IVerifier.sol"; import {IVerifier} from "../state-transition/chain-interfaces/IVerifier.sol"; import {L2ContractHelper} from "../common/libraries/L2ContractHelper.sol"; import {TransactionValidator} from "../state-transition/libraries/TransactionValidator.sol"; -import {MAX_NEW_FACTORY_DEPS, SYSTEM_UPGRADE_L2_TX_TYPE, MAX_ALLOWED_PROTOCOL_VERSION_DELTA} from "../common/Config.sol"; +import {MAX_NEW_FACTORY_DEPS, SYSTEM_UPGRADE_L2_TX_TYPE, MAX_ALLOWED_MINOR_VERSION_DELTA} from "../common/Config.sol"; import {L2CanonicalTransaction} from "../common/Messaging.sol"; +import {SemVer} from "../common/libraries/SemVer.sol"; /// @notice The struct that represents the upgrade proposal. /// @param l2ProtocolUpgradeTx The system upgrade transaction. @@ -70,15 +73,16 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { // as the permitted delay window is reduced in the future. require(block.timestamp >= _proposedUpgrade.upgradeTimestamp, "Upgrade is not ready yet"); - _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); + (uint32 newMinorVersion, bool isPatchOnly) = _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); _upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata); _upgradeVerifier(_proposedUpgrade.verifier, _proposedUpgrade.verifierParams); - _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash); + _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash, isPatchOnly); txHash = _setL2SystemContractUpgrade( _proposedUpgrade.l2ProtocolUpgradeTx, _proposedUpgrade.factoryDeps, - _proposedUpgrade.newProtocolVersion + newMinorVersion, + isPatchOnly ); _postUpgrade(_proposedUpgrade.postUpgradeCalldata); @@ -88,11 +92,14 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @notice Change default account bytecode hash, that is used on L2 /// @param _l2DefaultAccountBytecodeHash The hash of default account L2 bytecode - function _setL2DefaultAccountBytecodeHash(bytes32 _l2DefaultAccountBytecodeHash) private { + /// @param _patchOnly Whether only the patch part of the protocol version semver has changed + function _setL2DefaultAccountBytecodeHash(bytes32 _l2DefaultAccountBytecodeHash, bool _patchOnly) private { if (_l2DefaultAccountBytecodeHash == bytes32(0)) { return; } + require(!_patchOnly, "Patch only upgrade can not set new default account"); + L2ContractHelper.validateBytecodeHash(_l2DefaultAccountBytecodeHash); // Save previous value into the stack to put it into the event later @@ -105,11 +112,14 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @notice Change bootloader bytecode hash, that is used on L2 /// @param _l2BootloaderBytecodeHash The hash of bootloader L2 bytecode - function _setL2BootloaderBytecodeHash(bytes32 _l2BootloaderBytecodeHash) private { + /// @param _patchOnly Whether only the patch part of the protocol version semver has changed + function _setL2BootloaderBytecodeHash(bytes32 _l2BootloaderBytecodeHash, bool _patchOnly) private { if (_l2BootloaderBytecodeHash == bytes32(0)) { return; } + require(!_patchOnly, "Patch only upgrade can not set new bootloader"); + L2ContractHelper.validateBytecodeHash(_l2BootloaderBytecodeHash); // Save previous value into the stack to put it into the event later @@ -167,25 +177,33 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @notice Updates the bootloader hash and the hash of the default account /// @param _bootloaderHash The hash of the new bootloader bytecode. If zero, it will not be updated. /// @param _defaultAccountHash The hash of the new default account bytecode. If zero, it will not be updated. - function _setBaseSystemContracts(bytes32 _bootloaderHash, bytes32 _defaultAccountHash) internal { - _setL2BootloaderBytecodeHash(_bootloaderHash); - _setL2DefaultAccountBytecodeHash(_defaultAccountHash); + /// @param _patchOnly Whether only the patch part of the protocol version semver has changed. + function _setBaseSystemContracts(bytes32 _bootloaderHash, bytes32 _defaultAccountHash, bool _patchOnly) internal { + _setL2BootloaderBytecodeHash(_bootloaderHash, _patchOnly); + _setL2DefaultAccountBytecodeHash(_defaultAccountHash, _patchOnly); } /// @notice Sets the hash of the L2 system contract upgrade transaction for the next batch to be committed /// @dev If the transaction is noop (i.e. its type is 0) it does nothing and returns 0. /// @param _l2ProtocolUpgradeTx The L2 system contract upgrade transaction. + /// @param _factoryDeps The factory dependencies that are used by the transaction. + /// @param _newMinorProtocolVersion The new minor protocol version. It must be used as the `nonce` field + /// of the `_l2ProtocolUpgradeTx`. + /// @param _patchOnly Whether only the patch part of the protocol version semver has changed. /// @return System contracts upgrade transaction hash. Zero if no upgrade transaction is set. function _setL2SystemContractUpgrade( L2CanonicalTransaction calldata _l2ProtocolUpgradeTx, bytes[] calldata _factoryDeps, - uint256 _newProtocolVersion + uint32 _newMinorProtocolVersion, + bool _patchOnly ) internal returns (bytes32) { // If the type is 0, it is considered as noop and so will not be required to be executed. if (_l2ProtocolUpgradeTx.txType == 0) { return bytes32(0); } + require(!_patchOnly, "Patch only upgrade can not set upgrade transaction"); + require(_l2ProtocolUpgradeTx.txType == SYSTEM_UPGRADE_L2_TX_TYPE, "L2 system upgrade tx type is wrong"); bytes memory encodedTransaction = abi.encode(_l2ProtocolUpgradeTx); @@ -202,7 +220,7 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { // We want the hashes of l2 system upgrade transactions to be unique. // This is why we require that the `nonce` field is unique to each upgrade. require( - _l2ProtocolUpgradeTx.nonce == _newProtocolVersion, + _l2ProtocolUpgradeTx.nonce == _newMinorProtocolVersion, "The new protocol version should be included in the L2 system upgrade tx" ); @@ -232,24 +250,48 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @notice Changes the protocol version /// @param _newProtocolVersion The new protocol version - function _setNewProtocolVersion(uint256 _newProtocolVersion) internal virtual { + function _setNewProtocolVersion( + uint256 _newProtocolVersion + ) internal virtual returns (uint32 newMinorVersion, bool patchOnly) { uint256 previousProtocolVersion = s.protocolVersion; require( _newProtocolVersion > previousProtocolVersion, "New protocol version is not greater than the current one" ); - require( - _newProtocolVersion - previousProtocolVersion <= MAX_ALLOWED_PROTOCOL_VERSION_DELTA, - "Too big protocol version difference" + // slither-disable-next-line unused-return + (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( + SafeCast.toUint96(previousProtocolVersion) ); + require(previousMajorVersion == 0, "Implementation requires that the major version is 0 at all times"); - // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. - // Note it is important to keep this check, as otherwise hyperchains might skip upgrades by overwriting - require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); - require( - s.l2SystemContractsUpgradeBatchNumber == 0, - "The batch number of the previous upgrade has not been cleaned" - ); + uint32 newMajorVersion; + // slither-disable-next-line unused-return + (newMajorVersion, newMinorVersion, ) = SemVer.unpackSemVer(SafeCast.toUint96(_newProtocolVersion)); + require(newMajorVersion == 0, "Major must always be 0"); + + // Since `_newProtocolVersion > previousProtocolVersion`, and both old and new major version is 0, + // the difference between minor versions is >= 0. + uint256 minorDelta = newMinorVersion - previousMinorVersion; + + if (minorDelta == 0) { + patchOnly = true; + } + + // While this is implicitly enforced by other checks above, we still double check just in case + require(minorDelta <= MAX_ALLOWED_MINOR_VERSION_DELTA, "Too big protocol version difference"); + + // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. + // In case the minor version does not change, we permit to keep the old upgrade transaction in the system, but it + // must be ensured in the other parts of the upgrade that the is not overridden. + if (!patchOnly) { + // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. + // Note it is important to keep this check, as otherwise hyperchains might skip upgrades by overwriting + require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); + require( + s.l2SystemContractsUpgradeBatchNumber == 0, + "The batch number of the previous upgrade has not been cleaned" + ); + } s.protocolVersion = _newProtocolVersion; emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion); diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol index 4dccf4565..7cf9b5ceb 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol @@ -2,8 +2,11 @@ pragma solidity 0.8.24; -import {MAX_ALLOWED_PROTOCOL_VERSION_DELTA} from "../common/Config.sol"; +import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; + import {BaseZkSyncUpgrade} from "./BaseZkSyncUpgrade.sol"; +import {MAX_ALLOWED_MINOR_VERSION_DELTA} from "../common/Config.sol"; +import {SemVer} from "../common/libraries/SemVer.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -11,24 +14,48 @@ import {BaseZkSyncUpgrade} from "./BaseZkSyncUpgrade.sol"; abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { /// @notice Changes the protocol version /// @param _newProtocolVersion The new protocol version - function _setNewProtocolVersion(uint256 _newProtocolVersion) internal override { + function _setNewProtocolVersion( + uint256 _newProtocolVersion + ) internal override returns (uint32 newMinorVersion, bool patchOnly) { uint256 previousProtocolVersion = s.protocolVersion; + // IMPORTANT Genesis Upgrade difference: Note this is the only thing change > to >= require( - // IMPORTANT Genesis Upgrade difference: Note this is the only thing change > to >= _newProtocolVersion >= previousProtocolVersion, "New protocol version is not greater than the current one" ); - require( - _newProtocolVersion - previousProtocolVersion <= MAX_ALLOWED_PROTOCOL_VERSION_DELTA, - "Too big protocol version difference" + // slither-disable-next-line unused-return + (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( + SafeCast.toUint96(previousProtocolVersion) ); + require(previousMajorVersion == 0, "Implementation requires that the major version is 0 at all times"); - // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. - require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); - require( - s.l2SystemContractsUpgradeBatchNumber == 0, - "The batch number of the previous upgrade has not been cleaned" - ); + uint32 newMajorVersion; + // slither-disable-next-line unused-return + (newMajorVersion, newMinorVersion, ) = SemVer.unpackSemVer(SafeCast.toUint96(_newProtocolVersion)); + require(newMajorVersion == 0, "Major must always be 0"); + + // Since `_newProtocolVersion > previousProtocolVersion`, and both old and new major version is 0, + // the difference between minor versions is >= 0. + uint256 minorDelta = newMinorVersion - previousMinorVersion; + + // IMPORTANT Genesis Upgrade difference: We never set patchOnly to `true` to allow to put a system upgrade transaction there. + patchOnly = false; + + // While this is implicitly enforced by other checks above, we still double check just in case + require(minorDelta <= MAX_ALLOWED_MINOR_VERSION_DELTA, "Too big protocol version difference"); + + // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. + // In case the minor version does not change, we permit to keep the old upgrade transaction in the system, but it + // must be ensured in the other parts of the upgrade that the is not overridden. + if (!patchOnly) { + // If the previous upgrade had an L2 system upgrade transaction, we require that it is finalized. + // Note it is important to keep this check, as otherwise hyperchains might skip upgrades by overwriting + require(s.l2SystemContractsUpgradeTxHash == bytes32(0), "Previous upgrade has not been finalized"); + require( + s.l2SystemContractsUpgradeBatchNumber == 0, + "The batch number of the previous upgrade has not been cleaned" + ); + } s.protocolVersion = _newProtocolVersion; emit NewProtocolVersion(previousProtocolVersion, _newProtocolVersion); diff --git a/l1-contracts/scripts/utils.ts b/l1-contracts/scripts/utils.ts index 3a972b64c..5ae1bceac 100644 --- a/l1-contracts/scripts/utils.ts +++ b/l1-contracts/scripts/utils.ts @@ -10,6 +10,9 @@ const warning = chalk.bold.yellow; export const L1_TO_L2_ALIAS_OFFSET = "0x1111000000000000000000000000000000001111"; export const GAS_MULTIPLIER = 1; +// Bit shift by 32 does not work in JS, so we have to multiply by 2^32 +export const SEMVER_MINOR_VERSION_MULTIPLIER = 4294967296; + interface SystemConfig { requiredL2GasPricePerPubdata: number; priorityTxMinimalGasPrice: number; @@ -75,3 +78,29 @@ export function print(name: string, data: any) { export function getLowerCaseAddress(address: string) { return ethers.utils.getAddress(address).toLowerCase(); } + +export function unpackStringSemVer(semver: string): [number, number, number] { + const [major, minor, patch] = semver.split("."); + return [parseInt(major), parseInt(minor), parseInt(patch)]; +} + +function unpackNumberSemVer(semver: number): [number, number, number] { + const major = 0; + const minor = Math.floor(semver / SEMVER_MINOR_VERSION_MULTIPLIER); + const patch = semver % SEMVER_MINOR_VERSION_MULTIPLIER; + return [major, minor, patch]; +} + +// The major version is always 0 for now +export function packSemver(major: number, minor: number, patch: number) { + if (major !== 0) { + throw new Error("Major version must be 0"); + } + + return minor * SEMVER_MINOR_VERSION_MULTIPLIER + patch; +} + +export function addToProtocolVersion(packedProtocolVersion: number, minor: number, patch: number) { + const [major, minorVersion, patchVersion] = unpackNumberSemVer(packedProtocolVersion); + return packSemver(major, minorVersion + minor, patchVersion + patch); +} diff --git a/l1-contracts/scripts/verify.ts b/l1-contracts/scripts/verify.ts index 36c0980b5..82e17283b 100644 --- a/l1-contracts/scripts/verify.ts +++ b/l1-contracts/scripts/verify.ts @@ -6,7 +6,7 @@ import { getNumberFromEnv, getHashFromEnv, getAddressFromEnv, ethTestConfig } fr import { Interface } from "ethers/lib/utils"; import { Deployer } from "../src.ts/deploy"; import { Wallet } from "ethers"; -import { web3Provider } from "./utils"; +import { packSemver, unpackStringSemVer, web3Provider } from "./utils"; import { getTokens } from "../src.ts/deploy-token"; const provider = web3Provider(); @@ -121,7 +121,7 @@ async function main() { const genesisRollupLeafIndex = getNumberFromEnv("CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX"); const genesisBatchCommitment = getHashFromEnv("CONTRACTS_GENESIS_BATCH_COMMITMENT"); const diamondCut = await deployer.initialZkSyncHyperchainDiamondCut([]); - const protocolVersion = getNumberFromEnv("CONTRACTS_GENESIS_PROTOCOL_VERSION"); + const protocolVersion = packSemver(...unpackStringSemVer(process.env.CONTRACTS_GENESIS_PROTOCOL_SEMANTIC_VERSION)); const initCalldata2 = stateTransitionManager.encodeFunctionData("initialize", [ { diff --git a/l1-contracts/src.ts/deploy-test-process.ts b/l1-contracts/src.ts/deploy-test-process.ts index ac5665a3b..269d8a7a8 100644 --- a/l1-contracts/src.ts/deploy-test-process.ts +++ b/l1-contracts/src.ts/deploy-test-process.ts @@ -38,7 +38,7 @@ const addressConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/addresses.js const testnetTokenPath = `${testConfigPath}/hardhat.json`; export async function loadDefaultEnvVarsForTests(deployWallet: Wallet) { - process.env.CONTRACTS_GENESIS_PROTOCOL_VERSION = (21).toString(); + process.env.CONTRACTS_GENESIS_PROTOCOL_SEMANTIC_VERSION = "0.21.0"; process.env.CONTRACTS_GENESIS_ROOT = ethers.constants.HashZero; process.env.CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX = "0"; process.env.CONTRACTS_GENESIS_BATCH_COMMITMENT = ethers.constants.HashZero; diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 5373fd352..cad6d572d 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -6,7 +6,13 @@ import { ethers } from "ethers"; import { hexlify, Interface } from "ethers/lib/utils"; import type { DeployedAddresses } from "./deploy-utils"; import { deployedAddressesFromEnv, deployBytecodeViaCreate2, deployViaCreate2 } from "./deploy-utils"; -import { readBatchBootloaderBytecode, readSystemContractsBytecode, SYSTEM_CONFIG } from "../scripts/utils"; +import { + packSemver, + readBatchBootloaderBytecode, + readSystemContractsBytecode, + SYSTEM_CONFIG, + unpackStringSemVer, +} from "../scripts/utils"; import { getTokens } from "./deploy-token"; import { ADDRESS_ONE, @@ -307,7 +313,7 @@ export class Deployer { const genesisRollupLeafIndex = getNumberFromEnv("CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX"); const genesisBatchCommitment = getHashFromEnv("CONTRACTS_GENESIS_BATCH_COMMITMENT"); const diamondCut = await this.initialZkSyncHyperchainDiamondCut(extraFacets); - const protocolVersion = getNumberFromEnv("CONTRACTS_GENESIS_PROTOCOL_VERSION"); + const protocolVersion = packSemver(...unpackStringSemVer(process.env.CONTRACTS_GENESIS_PROTOCOL_SEMANTIC_VERSION)); const stateTransitionManager = new Interface(hardhat.artifacts.readArtifactSync("StateTransitionManager").abi); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol index d90d00df5..95c6f54af 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Admin/ExecuteUpgrade.t.sol @@ -4,8 +4,13 @@ pragma solidity 0.8.24; import {AdminTest} from "./_Admin_Shared.t.sol"; import {ERROR_ONLY_STATE_TRANSITION_MANAGER} from "../Base/_Base_Shared.t.sol"; +import {Utils} from "../../../../Utils/Utils.sol"; +import {VerifierParams} from "contracts/state-transition/chain-interfaces/IVerifier.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; +import {DefaultUpgrade} from "contracts/upgrades/DefaultUpgrade.sol"; +import {SemVer} from "contracts/common/libraries/SemVer.sol"; +import {ProposedUpgrade} from "contracts/upgrades/BaseZkSyncUpgrade.sol"; contract ExecuteUpgradeTest is AdminTest { event ExecuteUpgrade(Diamond.DiamondCutData diamondCut); @@ -23,6 +28,44 @@ contract ExecuteUpgradeTest is AdminTest { vm.startPrank(nonStateTransitionManager); adminFacet.executeUpgrade(diamondCutData); } + + /// TODO: This test should be removed after the migration to the semver is complete everywhere. + function test_migrateToSemVerApproach() public { + // Setting minor protocol version manually + utilsFacet.util_setProtocolVersion(22); + + VerifierParams memory verifierParams = VerifierParams({ + recursionNodeLevelVkHash: bytes32(0), + recursionLeafLevelVkHash: bytes32(0), + recursionCircuitsSetVksHash: bytes32(0) + }); + + ProposedUpgrade memory proposedUpgrade = ProposedUpgrade({ + l2ProtocolUpgradeTx: Utils.makeEmptyL2CanonicalTransaction(), + factoryDeps: new bytes[](0), + bootloaderHash: bytes32(0), + defaultAccountHash: bytes32(0), + verifier: address(0), + verifierParams: verifierParams, + l1ContractsUpgradeCalldata: hex"", + postUpgradeCalldata: hex"", + upgradeTimestamp: 0, + newProtocolVersion: SemVer.packSemVer(0, 22, 0) + }); + + DefaultUpgrade upgrade = new DefaultUpgrade(); + + Diamond.DiamondCutData memory diamondCutData = Diamond.DiamondCutData({ + facetCuts: new Diamond.FacetCut[](0), + initAddress: address(upgrade), + initCalldata: abi.encodeCall(upgrade.upgrade, (proposedUpgrade)) + }); + + address stm = utilsFacet.util_getStateTransitionManager(); + vm.startPrank(stm); + + adminFacet.executeUpgrade(diamondCutData); + } } interface IDiamondLibrary { diff --git a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts index cda99ac34..7352ce8cc 100644 --- a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts +++ b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts @@ -40,8 +40,9 @@ import { makeExecutedEqualCommitted, getBatchStoredInfo, } from "./utils"; +import { packSemver, unpackStringSemVer, addToProtocolVersion } from "../../scripts/utils"; -describe("L2 upgrade test", function () { +describe.only("L2 upgrade test", function () { let proxyExecutor: ExecutorFacet; let proxyAdmin: AdminFacet; let proxyGetters: GettersFacet; @@ -59,8 +60,8 @@ describe("L2 upgrade test", function () { let verifier: string; const noopUpgradeTransaction = buildL2CanonicalTransaction({ txType: 0 }); let chainId = process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID || 270; - // let priorityOperationsHash: string; let initialProtocolVersion = 0; + let initialMinorProtocolVersion = 0; before(async () => { [owner] = await hardhat.ethers.getSigners(); @@ -92,7 +93,14 @@ describe("L2 upgrade test", function () { const transferOwnershipTx = await ownable.acceptOwnership(); await transferOwnershipTx.wait(); - initialProtocolVersion = parseInt(process.env.CONTRACTS_GENESIS_PROTOCOL_VERSION); + const [initialMajor, initialMinor, initialPatch] = unpackStringSemVer( + process.env.CONTRACTS_GENESIS_PROTOCOL_SEMANTIC_VERSION + ); + if (initialMajor !== 0 || initialPatch !== 0) { + throw new Error("Initial protocol version must be 0.x.0"); + } + initialProtocolVersion = packSemver(initialMajor, initialMinor, initialPatch); + initialMinorProtocolVersion = initialMinor; chainId = deployer.chainId; verifier = deployer.addresses.StateTransition.Verifier; @@ -149,18 +157,75 @@ describe("L2 upgrade test", function () { await ( await executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { - newProtocolVersion: 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 1, 0), l2ProtocolUpgradeTx: noopUpgradeTransaction, }) ).wait(); - expect(await proxyGetters.getProtocolVersion()).to.equal(1 + initialProtocolVersion); + expect(await proxyGetters.getProtocolVersion()).to.equal(addToProtocolVersion(initialProtocolVersion, 1, 0)); storedBatch2Info = getBatchStoredInfo(batch2Info, commitment); await makeExecutedEqualCommitted(proxyExecutor, storedBatch1InfoChainIdUpgrade, [storedBatch2Info], []); }); + it("Should not allow base system contract changes during patch upgrade", async () => { + const { 0: major, 1: minor, 2: patch } = await proxyGetters.getSemverProtocolVersion(); + + const bootloaderRevertReason = await getCallRevertReason( + executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { + newProtocolVersion: packSemver(major, minor, patch + 1), + bootloaderHash: ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))), + l2ProtocolUpgradeTx: noopUpgradeTransaction, + }) + ); + expect(bootloaderRevertReason).to.equal("Patch only upgrade can not set new bootloader"); + + const defaultAccountRevertReason = await getCallRevertReason( + executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { + newProtocolVersion: packSemver(major, minor, patch + 1), + defaultAccountHash: ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))), + l2ProtocolUpgradeTx: noopUpgradeTransaction, + }) + ); + expect(defaultAccountRevertReason).to.equal("Patch only upgrade can not set new default account"); + }); + + it("Should not allow upgrade transaction during patch upgrade", async () => { + const { 0: major, 1: minor, 2: patch } = await proxyGetters.getSemverProtocolVersion(); + + const someTx = buildL2CanonicalTransaction({ + txType: 254, + nonce: 0, + }); + + const bootloaderRevertReason = await getCallRevertReason( + executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { + newProtocolVersion: packSemver(major, minor, patch + 1), + l2ProtocolUpgradeTx: someTx, + }) + ); + expect(bootloaderRevertReason).to.equal("Patch only upgrade can not set upgrade transaction"); + }); + + it("Should not allow major version change", async () => { + // 2**64 is the offset for a major version change + const newVersion = ethers.BigNumber.from(2).pow(64); + + const someTx = buildL2CanonicalTransaction({ + txType: 254, + nonce: 0, + }); + + const bootloaderRevertReason = await getCallRevertReason( + executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { + newProtocolVersion: newVersion, + l2ProtocolUpgradeTx: someTx, + }) + ); + expect(bootloaderRevertReason).to.equal("Major must always be 0"); + }); + it("Timestamp should behave correctly", async () => { // Upgrade was scheduled for now should work fine const timeNow = (await hardhat.ethers.provider.getBlock("latest")).timestamp; @@ -186,7 +251,7 @@ describe("L2 upgrade test", function () { const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, - newProtocolVersion: 3 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 3, 0), }) ); @@ -202,7 +267,7 @@ describe("L2 upgrade test", function () { const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -234,7 +299,7 @@ describe("L2 upgrade test", function () { const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, - newProtocolVersion: 100000, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 10000, 0), }) ); @@ -250,7 +315,7 @@ describe("L2 upgrade test", function () { const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -266,7 +331,7 @@ describe("L2 upgrade test", function () { const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -283,7 +348,7 @@ describe("L2 upgrade test", function () { const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -295,14 +360,14 @@ describe("L2 upgrade test", function () { const wrongFactoryDepHash = ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))); const wrongTx = buildL2CanonicalTransaction({ factoryDeps: [wrongFactoryDepHash], - nonce: 3 + 1 + initialProtocolVersion, + nonce: 4 + initialMinorProtocolVersion, }); const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, factoryDeps: [myFactoryDep], - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -313,14 +378,14 @@ describe("L2 upgrade test", function () { const myFactoryDep = ethers.utils.hexlify(ethers.utils.randomBytes(32)); const wrongTx = buildL2CanonicalTransaction({ factoryDeps: [], - nonce: 3 + 1 + initialProtocolVersion, + nonce: 4 + initialMinorProtocolVersion, }); const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, factoryDeps: [myFactoryDep], - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -333,14 +398,14 @@ describe("L2 upgrade test", function () { const wrongTx = buildL2CanonicalTransaction({ factoryDeps: Array(33).fill(randomDepHash), - nonce: 3 + 1 + initialProtocolVersion, + nonce: 4 + initialMinorProtocolVersion, }); const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { l2ProtocolUpgradeTx: wrongTx, factoryDeps: Array(33).fill(myFactoryDep), - newProtocolVersion: 3 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 4, 0), }) ); @@ -364,7 +429,7 @@ describe("L2 upgrade test", function () { const myFactoryDepHash = hashBytecode(myFactoryDep); const upgradeTx = buildL2CanonicalTransaction({ factoryDeps: [myFactoryDepHash], - nonce: 4 + 1 + initialProtocolVersion, + nonce: 5 + initialMinorProtocolVersion, }); const upgrade = { @@ -375,7 +440,7 @@ describe("L2 upgrade test", function () { executeUpgradeTx: true, l2ProtocolUpgradeTx: upgradeTx, factoryDeps: [myFactoryDep], - newProtocolVersion: 4 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 5, 0), }; const upgradeReceipt = await ( @@ -402,7 +467,7 @@ describe("L2 upgrade test", function () { expect(await proxyGetters.getL2BootloaderBytecodeHash()).to.equal(bootloaderHash); expect(await proxyGetters.getL2DefaultAccountBytecodeHash()).to.equal(defaultAccountHash); expect((await proxyGetters.getVerifier()).toLowerCase()).to.equal(newVerifier.toLowerCase()); - expect(await proxyGetters.getProtocolVersion()).to.equal(4 + 1 + initialProtocolVersion); + expect(await proxyGetters.getProtocolVersion()).to.equal(addToProtocolVersion(initialProtocolVersion, 5, 0)); const newVerifierParams = await proxyGetters.getVerifierParams(); expect(newVerifierParams.recursionNodeLevelVkHash).to.equal(newerVerifierParams.recursionNodeLevelVkHash); @@ -410,8 +475,12 @@ describe("L2 upgrade test", function () { expect(newVerifierParams.recursionCircuitsSetVksHash).to.equal(newerVerifierParams.recursionCircuitsSetVksHash); expect(upgradeEvents[0].name).to.eq("NewProtocolVersion"); - expect(upgradeEvents[0].args.previousProtocolVersion.toString()).to.eq((2 + initialProtocolVersion).toString()); - expect(upgradeEvents[0].args.newProtocolVersion.toString()).to.eq((4 + 1 + initialProtocolVersion).toString()); + expect(upgradeEvents[0].args.previousProtocolVersion.toString()).to.eq( + addToProtocolVersion(initialProtocolVersion, 2, 0).toString() + ); + expect(upgradeEvents[0].args.newProtocolVersion.toString()).to.eq( + addToProtocolVersion(initialProtocolVersion, 5, 0).toString() + ); expect(upgradeEvents[1].name).to.eq("NewVerifier"); expect(upgradeEvents[1].args.oldVerifier.toLowerCase()).to.eq(verifier.toLowerCase()); @@ -434,6 +503,84 @@ describe("L2 upgrade test", function () { expect(upgradeEvents[4].args.newBytecodeHash).to.eq(defaultAccountHash); }); + it("Should successfully perform a patch upgrade even if there is a pending minor upgrade", async () => { + const currentVerifier = await proxyGetters.getVerifier(); + const currentVerifierParams = await proxyGetters.getVerifierParams(); + const currentBootloaderHash = await proxyGetters.getL2BootloaderBytecodeHash(); + const currentL2DefaultAccountBytecodeHash = await proxyGetters.getL2DefaultAccountBytecodeHash(); + + const testnetVerifierFactory = await hardhat.ethers.getContractFactory("TestnetVerifier"); + const testnetVerifierContract = await testnetVerifierFactory.deploy(); + const newVerifier = testnetVerifierContract.address; + const newerVerifierParams = buildVerifierParams({ + recursionNodeLevelVkHash: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + recursionLeafLevelVkHash: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + recursionCircuitsSetVksHash: ethers.utils.hexlify(ethers.utils.randomBytes(32)), + }); + + const emptyTx = buildL2CanonicalTransaction({ + txType: 0, + nonce: 0, + }); + + const upgrade = { + verifier: newVerifier, + verifierParams: newerVerifierParams, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 5, 1), + l2ProtocolUpgradeTx: emptyTx, + }; + + const upgradeReceipt = await ( + await executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, upgrade) + ).wait(); + + const defaultUpgradeFactory = await hardhat.ethers.getContractFactory("DefaultUpgrade"); + const upgradeEvents = upgradeReceipt.logs.map((log) => { + // Not all events can be parsed there, but we don't care about them + try { + const event = defaultUpgradeFactory.interface.parseLog(log); + const parsedArgs = event.args; + return { + name: event.name, + args: parsedArgs, + }; + } catch (_) { + // lint no-empty + } + }); + + // Now, we check that all the data was set as expected + expect(await proxyGetters.getL2BootloaderBytecodeHash()).to.equal(currentBootloaderHash); + expect(await proxyGetters.getL2DefaultAccountBytecodeHash()).to.equal(currentL2DefaultAccountBytecodeHash); + expect((await proxyGetters.getVerifier()).toLowerCase()).to.equal(newVerifier.toLowerCase()); + expect(await proxyGetters.getProtocolVersion()).to.equal(addToProtocolVersion(initialProtocolVersion, 5, 1)); + + const newVerifierParams = await proxyGetters.getVerifierParams(); + expect(newVerifierParams.recursionNodeLevelVkHash).to.equal(newerVerifierParams.recursionNodeLevelVkHash); + expect(newVerifierParams.recursionLeafLevelVkHash).to.equal(newerVerifierParams.recursionLeafLevelVkHash); + expect(newVerifierParams.recursionCircuitsSetVksHash).to.equal(newerVerifierParams.recursionCircuitsSetVksHash); + + expect(upgradeEvents[0].name).to.eq("NewProtocolVersion"); + expect(upgradeEvents[0].args.previousProtocolVersion.toString()).to.eq( + addToProtocolVersion(initialProtocolVersion, 5, 0).toString() + ); + expect(upgradeEvents[0].args.newProtocolVersion.toString()).to.eq( + addToProtocolVersion(initialProtocolVersion, 5, 1).toString() + ); + + expect(upgradeEvents[1].name).to.eq("NewVerifier"); + expect(upgradeEvents[1].args.oldVerifier.toLowerCase()).to.eq(currentVerifier.toLowerCase()); + expect(upgradeEvents[1].args.newVerifier.toLowerCase()).to.eq(newVerifier.toLowerCase()); + + expect(upgradeEvents[2].name).to.eq("NewVerifierParams"); + expect(upgradeEvents[2].args.oldVerifierParams[0]).to.eq(currentVerifierParams.recursionNodeLevelVkHash); + expect(upgradeEvents[2].args.oldVerifierParams[1]).to.eq(currentVerifierParams.recursionLeafLevelVkHash); + expect(upgradeEvents[2].args.oldVerifierParams[2]).to.eq(currentVerifierParams.recursionCircuitsSetVksHash); + expect(upgradeEvents[2].args.newVerifierParams[0]).to.eq(newerVerifierParams.recursionNodeLevelVkHash); + expect(upgradeEvents[2].args.newVerifierParams[1]).to.eq(newerVerifierParams.recursionLeafLevelVkHash); + expect(upgradeEvents[2].args.newVerifierParams[2]).to.eq(newerVerifierParams.recursionCircuitsSetVksHash); + }); + it("Should fail to upgrade when there is already a pending upgrade", async () => { const bootloaderHash = ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))); const defaultAccountHash = ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))); @@ -448,7 +595,7 @@ describe("L2 upgrade test", function () { const myFactoryDepHash = hashBytecode(myFactoryDep); const upgradeTx = buildL2CanonicalTransaction({ factoryDeps: [myFactoryDepHash], - nonce: 5 + 1 + initialProtocolVersion, + nonce: 5 + 1 + initialMinorProtocolVersion, }); const upgrade = { @@ -459,12 +606,16 @@ describe("L2 upgrade test", function () { executeUpgradeTx: true, l2ProtocolUpgradeTx: upgradeTx, factoryDeps: [myFactoryDep], - newProtocolVersion: 5 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 5 + 1, 0), }; const revertReason = await getCallRevertReason( executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, upgrade) ); - await rollBackToVersion((4 + 1 + initialProtocolVersion).toString(), stateTransitionManager, upgrade); + await rollBackToVersion( + addToProtocolVersion(initialProtocolVersion, 5, 1).toString(), + stateTransitionManager, + upgrade + ); expect(revertReason).to.equal("Previous upgrade has not been finalized"); }); @@ -631,7 +782,7 @@ describe("L2 upgrade test", function () { expect(await proxyGetters.getL2SystemContractsUpgradeBatchNumber()).to.equal(0); await ( await executeUpgrade(chainId, proxyGetters, stateTransitionManager, proxyAdmin, { - newProtocolVersion: 5 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 5 + 1, 0), l2ProtocolUpgradeTx: noopUpgradeTransaction, }) ).wait(); @@ -670,7 +821,7 @@ describe("L2 upgrade test", function () { it("Should successfully commit custom upgrade", async () => { const upgradeReceipt = await ( await executeCustomUpgrade(chainId, proxyGetters, proxyAdmin, stateTransitionManager, { - newProtocolVersion: 6 + 1 + initialProtocolVersion, + newProtocolVersion: addToProtocolVersion(initialProtocolVersion, 6 + 1, 0), l2ProtocolUpgradeTx: noopUpgradeTransaction, }) ).wait(); @@ -811,7 +962,8 @@ async function executeUpgrade( contractFactory?: ethers.ethers.ContractFactory ) { if (partialUpgrade.newProtocolVersion == null) { - const newVersion = (await proxyGetters.getProtocolVersion()).add(1); + const { 0: major, 1: minor, 2: patch } = await proxyGetters.getSemverProtocolVersion(); + const newVersion = packSemver(major, minor + 1, patch); partialUpgrade.newProtocolVersion = newVersion; } const upgrade = buildProposeUpgrade(partialUpgrade); diff --git a/l1-contracts/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts index fd34a0e7f..f1a2b49f2 100644 --- a/l1-contracts/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -12,8 +12,9 @@ import type { ExecutorFacet } from "../../typechain"; import type { FeeParams, L2CanonicalTransaction } from "../../src.ts/utils"; import { ADDRESS_ONE, PubdataPricingMode, EMPTY_STRING_KECCAK } from "../../src.ts/utils"; +import { packSemver } from "../../scripts/utils"; -export const CONTRACTS_GENESIS_PROTOCOL_VERSION = (21).toString(); +export const CONTRACTS_GENESIS_PROTOCOL_VERSION = packSemver(0, 21, 0).toString(); // eslint-disable-next-line @typescript-eslint/no-var-requires export const IERC20_INTERFACE = require("@openzeppelin/contracts/build/contracts/IERC20"); export const DEFAULT_REVERT_REASON = "VM did not revert"; From 32ca4e665da89f5b4f2f705eee40d91024ad5b48 Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Thu, 30 May 2024 16:18:07 +0200 Subject: [PATCH 49/60] Use governance as hyperchain governor upon init (#501) --- l1-contracts/scripts/register-hyperchain.ts | 1 + l1-contracts/src.ts/deploy.ts | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/l1-contracts/scripts/register-hyperchain.ts b/l1-contracts/scripts/register-hyperchain.ts index d516f03c1..755352f9b 100644 --- a/l1-contracts/scripts/register-hyperchain.ts +++ b/l1-contracts/scripts/register-hyperchain.ts @@ -107,6 +107,7 @@ async function main() { } await deployer.registerHyperchain(baseTokenAddress, cmd.validiumMode, null, gasPrice, useGovernance); + await deployer.transferAdminFromDeployerToGovernance(); }); await program.parseAsync(process.argv); diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index cad6d572d..77dfba303 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -820,6 +820,23 @@ export class Deployer { } } + public async transferAdminFromDeployerToGovernance() { + const stm = this.stateTransitionManagerContract(this.deployWallet); + const diamondProxyAddress = await stm.getHyperchain(this.chainId); + const hyperchain = IZkSyncHyperchainFactory.connect(diamondProxyAddress, this.deployWallet); + + const receipt = await (await hyperchain.setPendingAdmin(this.addresses.Governance)).wait(); + if (this.verbose) { + console.log(`Governance set as pending admin, gas used: ${receipt.gasUsed.toString()}`); + } + + await this.executeUpgrade(hyperchain.address, 0, hyperchain.interface.encodeFunctionData("acceptAdmin"), false); + + if (this.verbose) { + console.log("Pending admin successfully accepted"); + } + } + public async registerToken(tokenAddress: string, useGovernance: boolean = false) { const bridgehub = this.bridgehubContract(this.deployWallet); From 16ae765897d38e9a60f611be7741bad53904fa2d Mon Sep 17 00:00:00 2001 From: Artem Fomiuk <88630083+Artemka374@users.noreply.github.com> Date: Fri, 31 May 2024 15:06:25 +0300 Subject: [PATCH 50/60] feat: update verifier (#503) --- .../contracts/state-transition/Verifier.sol | 8 ++--- tools/data/scheduler_key.json | 32 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 5d3585545..922f21ca3 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -283,8 +283,8 @@ contract Verifier is IVerifier { function _loadVerificationKey() internal pure virtual { assembly { // gate setup commitments - mstore(VK_GATE_SETUP_0_X_SLOT, 0x1f718b0d8640b18fcb605c0b362408e5b96391e1ea32b12332829e557aa50925) - mstore(VK_GATE_SETUP_0_Y_SLOT, 0x0b0186811e335624d3034ed7a7fe02b1a259d5d37fef68694f188924b8d5cea0) + mstore(VK_GATE_SETUP_0_X_SLOT, 0x110deb1e0863737f9a3d7b4de641a03aa00a77bc9f1a05acc9d55b76ab9fdd4d) + mstore(VK_GATE_SETUP_0_Y_SLOT, 0x2c9dc252441e9298b7f6df6335a252517b7bccb924adf537b87c5cd3383fd7a9) mstore(VK_GATE_SETUP_1_X_SLOT, 0x04659caf7b05471ba5ba85b1ab62267aa6c456836e625f169f7119d55b9462d2) mstore(VK_GATE_SETUP_1_Y_SLOT, 0x0ea63403692148d2ad22189a1e5420076312f4d46e62036a043a6b0b84d5b410) mstore(VK_GATE_SETUP_2_X_SLOT, 0x0e6696d09d65fce1e42805be03fca1f14aea247281f688981f925e77d4ce2291) @@ -295,8 +295,8 @@ contract Verifier is IVerifier { mstore(VK_GATE_SETUP_4_Y_SLOT, 0x22e404bc91350f3bc7daad1d1025113742436983c85eac5ab7b42221a181b81e) mstore(VK_GATE_SETUP_5_X_SLOT, 0x0d9b29613037a5025655c82b143d2b7449c98f3aea358307c8529249cc54f3b9) mstore(VK_GATE_SETUP_5_Y_SLOT, 0x15b3c4c946ad1babfc4c03ff7c2423fd354af3a9305c499b7fb3aaebe2fee746) - mstore(VK_GATE_SETUP_6_X_SLOT, 0x0ab21cb590aca747d70d9be12b035c786f5a42e002e621627189d5ef13561ce1) - mstore(VK_GATE_SETUP_6_Y_SLOT, 0x0d3c93aafe7eeebad42b789a046b02bb2d92193f6af460e4104ad7ac759ef82a) + mstore(VK_GATE_SETUP_6_X_SLOT, 0x2a4cb6c495dbc7201142cc773da895ae2046e790073988fb850aca6aead27b8a) + mstore(VK_GATE_SETUP_6_Y_SLOT, 0x28ef9200c3cb67da82030520d640292014f5f7c2e2909da608812e04671a3acf) mstore(VK_GATE_SETUP_7_X_SLOT, 0x283344a1ab3e55ecfd904d0b8e9f4faea338df5a4ead2fa9a42f0e103da40abc) mstore(VK_GATE_SETUP_7_Y_SLOT, 0x223b37b83b9687512d322993edd70e508dd80adb10bcf7321a3cc8a44c269521) diff --git a/tools/data/scheduler_key.json b/tools/data/scheduler_key.json index 4313abe76..acb7e3fe8 100644 --- a/tools/data/scheduler_key.json +++ b/tools/data/scheduler_key.json @@ -6,16 +6,16 @@ "gate_setup_commitments": [ { "x": [ - 3639645538835826981, - 13358681319193882915, - 14654814390686320869, - 2265744977747292559 + 14543631136906534221, + 11532161447842416044, + 11114175029926010938, + 1228896787564295039 ], "y": [ - 5699456119250210464, - 11698616611432786025, - 15205083455076303537, - 793062898509501988 + 13293602262342424489, + 8897930584356943159, + 13256028170406220369, + 3214939367598363288 ], "infinity": false }, @@ -96,16 +96,16 @@ }, { "x": [ - 8181305420893527265, - 8023799216002703714, - 15496213284243332216, - 770710052375668551 + 9586697317366528906, + 2325800863365957883, + 1243781259615311278, + 3048012003267036960 ], "y": [ - 1173987788591134762, - 3283714838474547428, - 15288445962933699259, - 953799583719157434 + 612821620743617231, + 1510385666449513894, + 9368337288452385056, + 2949736812933507034 ], "infinity": false }, From fe0b7f4d641fff75dd8c8fee4e05a3ec78dbdc9a Mon Sep 17 00:00:00 2001 From: Stanislav Bezkorovainyi Date: Fri, 31 May 2024 14:41:32 +0200 Subject: [PATCH 51/60] Change how we update chain creation params (#502) --- .../config-deploy-l1.toml | 6 +- l1-contracts-foundry/script/DeployL1.s.sol | 14 ++- .../IStateTransitionManager.sol | 31 +++-- .../StateTransitionManager.sol | 56 ++++++--- l1-contracts/src.ts/deploy-test-process.ts | 6 +- l1-contracts/src.ts/deploy.ts | 60 +++------- l1-contracts/src.ts/utils.ts | 113 ++++++++++++++++++ .../Bridgehub/experimental_bridge.t.sol | 12 +- .../RevertBatches.t.sol | 17 ++- .../SetChainCreationParams.t.sol | 57 +++++++++ .../SetInitialCutHash.t.sol | 21 ---- .../StateTransitionOwnerZero.t.sol | 16 ++- .../_StateTransitionManager_Shared.t.sol | 22 ++-- l1-contracts/test/unit_tests/utils.ts | 25 ++-- 14 files changed, 327 insertions(+), 129 deletions(-) create mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetChainCreationParams.t.sol delete mode 100644 l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetInitialCutHash.t.sol diff --git a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml index 7e3f06e21..ad8982ffc 100644 --- a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml +++ b/l1-contracts-foundry/script-config-template/config-deploy-l1.toml @@ -9,9 +9,9 @@ max_number_of_chains = 100 create2_factory_salt = "0x00000000000000000000000000000000000000000000000000000000000000ff" create2_factory_addr = "0x0000000000000000000000000000000000000000" validator_timelock_execution_delay = 0 -genesis_root = "0x0000000000000000000000000000000000000000000000000000000000000000" -genesis_rollup_leaf_index = 0 -genesis_batch_commitment = "0x0000000000000000000000000000000000000000000000000000000000000000" +genesis_root = "0x1000000000000000000000000000000000000000000000000000000000000000" +genesis_rollup_leaf_index = 1 +genesis_batch_commitment = "0x1000000000000000000000000000000000000000000000000000000000000000" latest_protocol_version = 0 recursion_node_level_vk_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" recursion_leaf_level_vk_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts-foundry/script/DeployL1.s.sol index c89eb3abc..6c2874e64 100644 --- a/l1-contracts-foundry/script/DeployL1.s.sol +++ b/l1-contracts-foundry/script/DeployL1.s.sol @@ -24,7 +24,7 @@ import {MailboxFacet} from "contracts/state-transition/chain-deps/facets/Mailbox import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; import {DiamondInit} from "contracts/state-transition/chain-deps/DiamondInit.sol"; import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol"; -import {StateTransitionManagerInitializeData} from "contracts/state-transition/IStateTransitionManager.sol"; +import {StateTransitionManagerInitializeData, ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {InitializeDataNewChain as DiamondInitializeDataNewChain} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; @@ -428,14 +428,18 @@ contract DeployL1Script is Script { config.contracts.diamondCutData = abi.encode(diamondCut); - StateTransitionManagerInitializeData memory diamondInitData = StateTransitionManagerInitializeData({ - owner: config.ownerAddress, - validatorTimelock: addresses.validatorTimelock, + ChainCreationParams memory chainCreationParams = ChainCreationParams({ genesisUpgrade: addresses.stateTransition.genesisUpgrade, genesisBatchHash: config.contracts.genesisRoot, genesisIndexRepeatedStorageChanges: uint64(config.contracts.genesisRollupLeafIndex), genesisBatchCommitment: config.contracts.genesisBatchCommitment, - diamondCut: diamondCut, + diamondCut: diamondCut + }); + + StateTransitionManagerInitializeData memory diamondInitData = StateTransitionManagerInitializeData({ + owner: config.ownerAddress, + validatorTimelock: addresses.validatorTimelock, + chainCreationParams: chainCreationParams, protocolVersion: config.contracts.latestProtocolVersion }); diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index 4151a1454..4d7f7fc6b 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -10,21 +10,28 @@ import {FeeParams} from "./chain-deps/ZkSyncHyperchainStorage.sol"; /// @dev We use struct instead of raw parameters in `initialize` function to prevent "Stack too deep" error /// @param owner The address who can manage non-critical updates in the contract /// @param validatorTimelock The address that serves as consensus, i.e. can submit blocks to be processed +/// @param chainCreationParams The struct that contains the fields that define how a new chain should be created +/// @param protocolVersion The initial protocol version on the newly deployed chain +struct StateTransitionManagerInitializeData { + address owner; + address validatorTimelock; + ChainCreationParams chainCreationParams; + uint256 protocolVersion; +} + +/// @notice The struct that contains the fields that define how a new chain should be created +/// within this STM. /// @param genesisUpgrade The address that is used in the diamond cut initialize address on chain creation /// @param genesisBatchHash Batch hash of the genesis (initial) batch /// @param genesisIndexRepeatedStorageChanges The serial number of the shortcut storage key for the genesis batch /// @param genesisBatchCommitment The zk-proof commitment for the genesis batch /// @param diamondCut The diamond cut for the first upgrade transaction on the newly deployed chain -/// @param protocolVersion The initial protocol version on the newly deployed chain -struct StateTransitionManagerInitializeData { - address owner; - address validatorTimelock; +struct ChainCreationParams { address genesisUpgrade; bytes32 genesisBatchHash; uint64 genesisIndexRepeatedStorageChanges; bytes32 genesisBatchCommitment; Diamond.DiamondCutData diamondCut; - uint256 protocolVersion; } interface IStateTransitionManager { @@ -48,8 +55,14 @@ interface IStateTransitionManager { /// @notice ValidatorTimelock changed event NewValidatorTimelock(address indexed oldValidatorTimelock, address indexed newValidatorTimelock); - /// @notice InitialCutHash changed - event NewInitialCutHash(bytes32 indexed oldInitialCutHash, bytes32 indexed newInitialCutHash); + /// @notice chain creation parameters changed + event NewChainCreationParams( + address genesisUpgrade, + bytes32 genesisBatchHash, + uint64 genesisIndexRepeatedStorageChanges, + bytes32 genesisBatchCommitment, + bytes32 newInitialCutHash + ); /// @notice new UpgradeCutHash event NewUpgradeCutHash(uint256 indexed protocolVersion, bytes32 indexed upgradeCutHash); @@ -85,10 +98,10 @@ interface IStateTransitionManager { function initialize(StateTransitionManagerInitializeData calldata _initializeData) external; - function setInitialCutHash(Diamond.DiamondCutData calldata _diamondCut) external; - function setValidatorTimelock(address _validatorTimelock) external; + function setChainCreationParams(ChainCreationParams calldata _chainCreationParams) external; + function getChainAdmin(uint256 _chainId) external view returns (address); function createNewChain( diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index 812e6fa11..dc4ac9446 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -11,7 +11,7 @@ import {IAdmin} from "./chain-interfaces/IAdmin.sol"; import {IDefaultUpgrade} from "../upgrades/IDefaultUpgrade.sol"; import {IDiamondInit} from "./chain-interfaces/IDiamondInit.sol"; import {IExecutor} from "./chain-interfaces/IExecutor.sol"; -import {IStateTransitionManager, StateTransitionManagerInitializeData} from "./IStateTransitionManager.sol"; +import {IStateTransitionManager, StateTransitionManagerInitializeData, ChainCreationParams} from "./IStateTransitionManager.sol"; import {ISystemContext} from "./l2-deps/ISystemContext.sol"; import {IZkSyncHyperchain} from "./chain-interfaces/IZkSyncHyperchain.sol"; import {FeeParams} from "./chain-deps/ZkSyncHyperchainStorage.sol"; @@ -72,6 +72,10 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own constructor(address _bridgehub, uint256 _maxNumberOfHyperchains) reentrancyGuardInitializer { BRIDGE_HUB = _bridgehub; MAX_NUMBER_OF_HYPERCHAINS = _maxNumberOfHyperchains; + + // While this does not provide a protection in the production, it is needed for local testing + // Length of the L2Log encoding should not be equal to the length of other L2Logs' tree nodes preimages + assert(L2_TO_L1_LOG_SERIALIZE_SIZE != 2 * 32); } /// @notice only the bridgehub can call @@ -124,28 +128,54 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own require(_initializeData.owner != address(0), "STM: owner zero"); _transferOwnership(_initializeData.owner); - genesisUpgrade = _initializeData.genesisUpgrade; protocolVersion = _initializeData.protocolVersion; protocolVersionDeadline[_initializeData.protocolVersion] = type(uint256).max; validatorTimelock = _initializeData.validatorTimelock; + _setChainCreationParams(_initializeData.chainCreationParams); + } + + /// @notice Updates the parameters with which a new chain is created + /// @param _chainCreationParams The new chain creation parameters + function _setChainCreationParams(ChainCreationParams calldata _chainCreationParams) internal { + require(_chainCreationParams.genesisUpgrade != address(0), "STM: genesisUpgrade zero"); + require(_chainCreationParams.genesisBatchHash != bytes32(0), "STM: genesisBatchHash zero"); + require( + _chainCreationParams.genesisIndexRepeatedStorageChanges != uint64(0), + "STM: genesisIndexRepeatedStorageChanges zero" + ); + require(_chainCreationParams.genesisBatchCommitment != bytes32(0), "STM: genesisBatchCommitment zero"); + + genesisUpgrade = _chainCreationParams.genesisUpgrade; + // We need to initialize the state hash because it is used in the commitment of the next batch IExecutor.StoredBatchInfo memory batchZero = IExecutor.StoredBatchInfo({ batchNumber: 0, - batchHash: _initializeData.genesisBatchHash, - indexRepeatedStorageChanges: _initializeData.genesisIndexRepeatedStorageChanges, + batchHash: _chainCreationParams.genesisBatchHash, + indexRepeatedStorageChanges: _chainCreationParams.genesisIndexRepeatedStorageChanges, numberOfLayer1Txs: 0, priorityOperationsHash: EMPTY_STRING_KECCAK, l2LogsTreeRoot: DEFAULT_L2_LOGS_TREE_ROOT_HASH, timestamp: 0, - commitment: _initializeData.genesisBatchCommitment + commitment: _chainCreationParams.genesisBatchCommitment }); storedBatchZero = keccak256(abi.encode(batchZero)); - initialCutHash = keccak256(abi.encode(_initializeData.diamondCut)); + bytes32 newInitialCutHash = keccak256(abi.encode(_chainCreationParams.diamondCut)); + initialCutHash = newInitialCutHash; + + emit NewChainCreationParams({ + genesisUpgrade: _chainCreationParams.genesisUpgrade, + genesisBatchHash: _chainCreationParams.genesisBatchHash, + genesisIndexRepeatedStorageChanges: _chainCreationParams.genesisIndexRepeatedStorageChanges, + genesisBatchCommitment: _chainCreationParams.genesisBatchCommitment, + newInitialCutHash: newInitialCutHash + }); + } - // While this does not provide a protection in the production, it is needed for local testing - // Length of the L2Log encoding should not be equal to the length of other L2Logs' tree nodes preimages - assert(L2_TO_L1_LOG_SERIALIZE_SIZE != 2 * 32); + /// @notice Updates the parameters with which a new chain is created + /// @param _chainCreationParams The new chain creation parameters + function setChainCreationParams(ChainCreationParams calldata _chainCreationParams) external onlyOwner { + _setChainCreationParams(_chainCreationParams); } /// @notice Starts the transfer of admin rights. Only the current admin can propose a new pending one. @@ -181,14 +211,6 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own emit NewValidatorTimelock(oldValidatorTimelock, _validatorTimelock); } - /// @dev set initial cutHash - function setInitialCutHash(Diamond.DiamondCutData calldata _diamondCut) external onlyOwner { - bytes32 oldInitialCutHash = initialCutHash; - bytes32 newCutHash = keccak256(abi.encode(_diamondCut)); - initialCutHash = newCutHash; - emit NewInitialCutHash(oldInitialCutHash, newCutHash); - } - /// @dev set New Version with upgrade from old version function setNewVersionUpgrade( Diamond.DiamondCutData calldata _cutData, diff --git a/l1-contracts/src.ts/deploy-test-process.ts b/l1-contracts/src.ts/deploy-test-process.ts index 269d8a7a8..fe383e755 100644 --- a/l1-contracts/src.ts/deploy-test-process.ts +++ b/l1-contracts/src.ts/deploy-test-process.ts @@ -39,9 +39,9 @@ const testnetTokenPath = `${testConfigPath}/hardhat.json`; export async function loadDefaultEnvVarsForTests(deployWallet: Wallet) { process.env.CONTRACTS_GENESIS_PROTOCOL_SEMANTIC_VERSION = "0.21.0"; - process.env.CONTRACTS_GENESIS_ROOT = ethers.constants.HashZero; - process.env.CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX = "0"; - process.env.CONTRACTS_GENESIS_BATCH_COMMITMENT = ethers.constants.HashZero; + process.env.CONTRACTS_GENESIS_ROOT = "0x0000000000000000000000000000000000000000000000000000000000000001"; + process.env.CONTRACTS_GENESIS_ROLLUP_LEAF_INDEX = "1"; + process.env.CONTRACTS_GENESIS_BATCH_COMMITMENT = "0x0000000000000000000000000000000000000000000000000000000000000001"; // process.env.CONTRACTS_GENESIS_UPGRADE_ADDR = ADDRESS_ONE; process.env.CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT = "72000000"; process.env.CONTRACTS_FRI_RECURSION_NODE_LEVEL_VK_HASH = ethers.constants.HashZero; diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 77dfba303..4ff958560 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -10,7 +10,6 @@ import { packSemver, readBatchBootloaderBytecode, readSystemContractsBytecode, - SYSTEM_CONFIG, unpackStringSemVer, } from "../scripts/utils"; import { getTokens } from "./deploy-token"; @@ -22,6 +21,7 @@ import { PubdataPricingMode, hashL2Bytecode, DIAMOND_CUT_DATA_ABI_STRING, + compileInitialCutHash, } from "./utils"; import { IBridgehubFactory } from "../typechain/IBridgehubFactory"; import { IGovernanceFactory } from "../typechain/IGovernanceFactory"; @@ -35,7 +35,7 @@ import { L1SharedBridgeFactory } from "../typechain/L1SharedBridgeFactory"; import { SingletonFactoryFactory } from "../typechain/SingletonFactoryFactory"; import { ValidatorTimelockFactory } from "../typechain/ValidatorTimelockFactory"; import type { FacetCut } from "./diamondCut"; -import { diamondCut, getCurrentFacetCutsForAdd } from "./diamondCut"; +import { getCurrentFacetCutsForAdd } from "./diamondCut"; import { ERC20Factory } from "../typechain"; import type { Contract, Overrides } from "@ethersproject/contracts"; @@ -98,43 +98,17 @@ export class Deployer { recursionCircuitsSetVksHash: "0x0000000000000000000000000000000000000000000000000000000000000000", }; const priorityTxMaxGasLimit = getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT"); - const DiamondInit = new Interface(hardhat.artifacts.readArtifactSync("DiamondInit").abi); - - const feeParams = { - pubdataPricingMode: PubdataPricingMode.Rollup, - batchOverheadL1Gas: SYSTEM_CONFIG.priorityTxBatchOverheadL1Gas, - maxPubdataPerBatch: SYSTEM_CONFIG.priorityTxPubdataPerBatch, - priorityTxMaxPubdata: SYSTEM_CONFIG.priorityTxMaxPubdata, - maxL2GasPerBatch: SYSTEM_CONFIG.priorityTxMaxGasPerBatch, - minimalL2GasPrice: SYSTEM_CONFIG.priorityTxMinimalGasPrice, - }; - const diamondInitCalldata = DiamondInit.encodeFunctionData("initialize", [ - // these first values are set in the contract - { - chainId: "0x0000000000000000000000000000000000000000000000000000000000000001", - bridgehub: "0x0000000000000000000000000000000000001234", - stateTransitionManager: "0x0000000000000000000000000000000000002234", - protocolVersion: "0x0000000000000000000000000000000000002234", - admin: "0x0000000000000000000000000000000000003234", - validatorTimelock: "0x0000000000000000000000000000000000004234", - baseToken: "0x0000000000000000000000000000000000004234", - baseTokenBridge: "0x0000000000000000000000000000000000004234", - storedBatchZero: "0x0000000000000000000000000000000000000000000000000000000000005432", - verifier: this.addresses.StateTransition.Verifier, - verifierParams, - l2BootloaderBytecodeHash: L2_BOOTLOADER_BYTECODE_HASH, - l2DefaultAccountBytecodeHash: L2_DEFAULT_ACCOUNT_BYTECODE_HASH, - priorityTxMaxGasLimit, - feeParams, - blobVersionedHashRetriever: this.addresses.BlobVersionedHashRetriever, - }, - ]); - - return diamondCut( + return compileInitialCutHash( facetCuts, + verifierParams, + L2_BOOTLOADER_BYTECODE_HASH, + L2_DEFAULT_ACCOUNT_BYTECODE_HASH, + this.addresses.StateTransition.Verifier, + this.addresses.BlobVersionedHashRetriever, + +priorityTxMaxGasLimit, this.addresses.StateTransition.DiamondInit, - "0x" + diamondInitCalldata.slice(2 + (4 + 9 * 32) * 2) + false ); } @@ -317,15 +291,19 @@ export class Deployer { const stateTransitionManager = new Interface(hardhat.artifacts.readArtifactSync("StateTransitionManager").abi); + const chainCreationParams = { + genesisUpgrade: this.addresses.StateTransition.GenesisUpgrade, + genesisBatchHash, + genesisIndexRepeatedStorageChanges: genesisRollupLeafIndex, + genesisBatchCommitment, + diamondCut, + }; + const initCalldata = stateTransitionManager.encodeFunctionData("initialize", [ { owner: this.addresses.Governance, validatorTimelock: this.addresses.ValidatorTimeLock, - genesisUpgrade: this.addresses.StateTransition.GenesisUpgrade, - genesisBatchHash, - genesisIndexRepeatedStorageChanges: genesisRollupLeafIndex, - genesisBatchCommitment, - diamondCut, + chainCreationParams, protocolVersion, }, ]); diff --git a/l1-contracts/src.ts/utils.ts b/l1-contracts/src.ts/utils.ts index e370e4499..ca18bc7e4 100644 --- a/l1-contracts/src.ts/utils.ts +++ b/l1-contracts/src.ts/utils.ts @@ -6,6 +6,10 @@ import type { BytesLike, BigNumberish } from "ethers"; import { ethers } from "ethers"; import * as fs from "fs"; import * as path from "path"; +import { DiamondInitFactory } from "../typechain"; +import type { DiamondCut, FacetCut } from "./diamondCut"; +import { diamondCut } from "./diamondCut"; +import { SYSTEM_CONFIG } from "../scripts/utils"; export const testConfigPath = process.env.ZKSYNC_ENV ? path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant") @@ -174,3 +178,112 @@ export interface L2CanonicalTransaction { // But it is still here, just in case we want to enable some additional functionality. reservedDynamic: BytesLike; } + +// Checks that the initial cut hash params are valid. +// Sometimes it makes sense to allow dummy values for testing purposes, but in production +// these values should be set correctly. +function checkValidInitialCutHashParams( + facetCuts: FacetCut[], + verifierParams: VerifierParams, + l2BootloaderBytecodeHash: string, + l2DefaultAccountBytecodeHash: string, + verifier: string, + blobVersionedHashRetriever: string, + priorityTxMaxGasLimit: number +) { + // We do not fetch the following numbers from the environment because they are very rarely changed + // and we want to avoid the risk of accidentally changing them. + const EXPECTED_FACET_CUTS = 4; + const EXPECTED_PRIORITY_TX_MAX_GAS_LIMIT = 72_000_000; + + if (facetCuts.length != EXPECTED_FACET_CUTS) { + throw new Error(`Expected ${EXPECTED_FACET_CUTS} facet cuts, got ${facetCuts.length}`); + } + + if (verifierParams.recursionNodeLevelVkHash === ethers.constants.HashZero) { + throw new Error("Recursion node level vk hash is zero"); + } + if (verifierParams.recursionLeafLevelVkHash === ethers.constants.HashZero) { + throw new Error("Recursion leaf level vk hash is zero"); + } + if (verifierParams.recursionCircuitsSetVksHash !== ethers.constants.HashZero) { + throw new Error("Recursion circuits set vks hash must be zero"); + } + if (l2BootloaderBytecodeHash === ethers.constants.HashZero) { + throw new Error("L2 bootloader bytecode hash is zero"); + } + if (l2DefaultAccountBytecodeHash === ethers.constants.HashZero) { + throw new Error("L2 default account bytecode hash is zero"); + } + if (verifier === ethers.constants.AddressZero) { + throw new Error("Verifier address is zero"); + } + if (blobVersionedHashRetriever === ethers.constants.AddressZero) { + throw new Error("Blob versioned hash retriever address is zero"); + } + if (priorityTxMaxGasLimit !== EXPECTED_PRIORITY_TX_MAX_GAS_LIMIT) { + throw new Error( + `Expected priority tx max gas limit to be ${EXPECTED_PRIORITY_TX_MAX_GAS_LIMIT}, got ${priorityTxMaxGasLimit}` + ); + } +} + +// We should either reuse code or add a test for this function. +export function compileInitialCutHash( + facetCuts: FacetCut[], + verifierParams: VerifierParams, + l2BootloaderBytecodeHash: string, + l2DefaultAccountBytecodeHash: string, + verifier: string, + blobVersionedHashRetriever: string, + priorityTxMaxGasLimit: number, + diamondInit: string, + strictMode: boolean = true +): DiamondCut { + if (strictMode) { + checkValidInitialCutHashParams( + facetCuts, + verifierParams, + l2BootloaderBytecodeHash, + l2DefaultAccountBytecodeHash, + verifier, + blobVersionedHashRetriever, + priorityTxMaxGasLimit + ); + } + + const factory = new DiamondInitFactory(); + + const feeParams = { + pubdataPricingMode: PubdataPricingMode.Rollup, + batchOverheadL1Gas: SYSTEM_CONFIG.priorityTxBatchOverheadL1Gas, + maxPubdataPerBatch: SYSTEM_CONFIG.priorityTxPubdataPerBatch, + priorityTxMaxPubdata: SYSTEM_CONFIG.priorityTxMaxPubdata, + maxL2GasPerBatch: SYSTEM_CONFIG.priorityTxMaxGasPerBatch, + minimalL2GasPrice: SYSTEM_CONFIG.priorityTxMinimalGasPrice, + }; + + const diamondInitCalldata = factory.interface.encodeFunctionData("initialize", [ + // these first values are set in the contract + { + chainId: "0x0000000000000000000000000000000000000000000000000000000000000001", + bridgehub: "0x0000000000000000000000000000000000001234", + stateTransitionManager: "0x0000000000000000000000000000000000002234", + protocolVersion: "0x0000000000000000000000000000000000002234", + admin: "0x0000000000000000000000000000000000003234", + validatorTimelock: "0x0000000000000000000000000000000000004234", + baseToken: "0x0000000000000000000000000000000000004234", + baseTokenBridge: "0x0000000000000000000000000000000000004234", + storedBatchZero: "0x0000000000000000000000000000000000000000000000000000000000005432", + verifier, + verifierParams, + l2BootloaderBytecodeHash, + l2DefaultAccountBytecodeHash, + priorityTxMaxGasLimit, + feeParams, + blobVersionedHashRetriever, + }, + ]); + + return diamondCut(facetCuts, diamondInit, "0x" + diamondInitCalldata.slice(2 + (4 + 9 * 32) * 2)); +} diff --git a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol index 3dcc863fc..9ef3ae0fb 100644 --- a/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Bridgehub/experimental_bridge.t.sol @@ -7,6 +7,7 @@ import {stdStorage, StdStorage, Test} from "forge-std/Test.sol"; import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {TestnetERC20Token} from "contracts/dev-contracts/TestnetERC20Token.sol"; import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; +import {ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; import {L2TransactionRequestDirect, L2TransactionRequestTwoBridgesOuter} from "contracts/bridgehub/IBridgehub.sol"; import {DummyStateTransitionManagerWBH} from "contracts/dev-contracts/test/DummyStateTransitionManagerWithBridgeHubAddress.sol"; import {DummyHyperchain} from "contracts/dev-contracts/test/DummyHyperchain.sol"; @@ -861,7 +862,16 @@ contract ExperimentalBridgeTest is Test { diamondCutData.initAddress = address(0); diamondCutData.initCalldata = ""; - mockSTM.setInitialCutHash(diamondCutData); + ChainCreationParams memory params = ChainCreationParams({ + diamondCut: diamondCutData, + // Just some dummy values: + genesisUpgrade: address(0x01), + genesisBatchHash: bytes32(uint256(0x01)), + genesisIndexRepeatedStorageChanges: uint64(0x01), + genesisBatchCommitment: bytes32(uint256(0x01)) + }); + + mockSTM.setChainCreationParams(params); return abi.encode(diamondCutData); } diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol index 7e277c1ec..2113f3467 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/RevertBatches.t.sol @@ -41,13 +41,13 @@ contract revertBatchesTest is StateTransitionManagerTest { genesisStoredBatchInfo = IExecutor.StoredBatchInfo({ batchNumber: 0, - batchHash: bytes32(""), - indexRepeatedStorageChanges: 0, + batchHash: bytes32(uint256(0x01)), + indexRepeatedStorageChanges: 1, numberOfLayer1Txs: 0, priorityOperationsHash: EMPTY_STRING_KECCAK, l2LogsTreeRoot: DEFAULT_L2_LOGS_TREE_ROOT_HASH, timestamp: 0, - commitment: bytes32("") + commitment: bytes32(uint256(0x01)) }); adminFacet.setTokenMultiplier(1, 1); @@ -65,7 +65,7 @@ contract revertBatchesTest is StateTransitionManagerTest { newCommitBatchInfo = IExecutor.CommitBatchInfo({ batchNumber: 1, timestamp: uint64(currentTimestamp), - indexRepeatedStorageChanges: 0, + indexRepeatedStorageChanges: 1, newStateRoot: Utils.randomBytes32("newStateRoot"), numberOfLayer1Txs: 0, priorityOperationsHash: keccak256(""), @@ -91,6 +91,13 @@ contract revertBatchesTest is StateTransitionManagerTest { Utils.packBatchTimestampAndBlockTimestamp(currentTimestamp, currentTimestamp) ); + correctL2Logs[uint256(uint256(SystemLogKey.PREV_BATCH_HASH_KEY))] = Utils.constructL2Log( + true, + L2_SYSTEM_CONTEXT_ADDRESS, + uint256(SystemLogKey.PREV_BATCH_HASH_KEY), + bytes32(uint256(0x01)) + ); + l2Logs = Utils.encodePacked(correctL2Logs); newCommitBatchInfo.timestamp = uint64(currentTimestamp); newCommitBatchInfo.systemLogs = l2Logs; @@ -107,7 +114,7 @@ contract revertBatchesTest is StateTransitionManagerTest { newStoredBatchInfo = IExecutor.StoredBatchInfo({ batchNumber: 1, batchHash: entries[0].topics[2], - indexRepeatedStorageChanges: 0, + indexRepeatedStorageChanges: 1, numberOfLayer1Txs: 0, priorityOperationsHash: keccak256(""), l2LogsTreeRoot: 0, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetChainCreationParams.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetChainCreationParams.t.sol new file mode 100644 index 000000000..85fa1a316 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetChainCreationParams.t.sol @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; +import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; +import {ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; +import {IExecutor} from "contracts/state-transition/chain-interfaces/IExecutor.sol"; +import {EMPTY_STRING_KECCAK, DEFAULT_L2_LOGS_TREE_ROOT_HASH} from "contracts/common/Config.sol"; + +contract SetChainCreationParamsTest is StateTransitionManagerTest { + function test_SettingInitialCutHash() public { + bytes32 initialCutHash = keccak256(abi.encode(getDiamondCutData(address(diamondInit)))); + address randomDiamondInit = address(0x303030303030303030303); + + assertEq(chainContractAddress.initialCutHash(), initialCutHash, "Initial cut hash is not correct"); + + Diamond.DiamondCutData memory newDiamondCutData = getDiamondCutData(address(randomDiamondInit)); + bytes32 newCutHash = keccak256(abi.encode(newDiamondCutData)); + + address newGenesisUpgrade = address(0x02); + bytes32 genesisBatchHash = bytes32(uint256(0x02)); + uint64 genesisIndexRepeatedStorageChanges = 2; + bytes32 genesisBatchCommitment = bytes32(uint256(0x02)); + + ChainCreationParams memory newChainCreationParams = ChainCreationParams({ + genesisUpgrade: newGenesisUpgrade, + genesisBatchHash: genesisBatchHash, + genesisIndexRepeatedStorageChanges: genesisIndexRepeatedStorageChanges, + genesisBatchCommitment: genesisBatchCommitment, + diamondCut: newDiamondCutData + }); + + chainContractAddress.setChainCreationParams(newChainCreationParams); + + assertEq(chainContractAddress.initialCutHash(), newCutHash, "Initial cut hash update was not successful"); + assertEq(chainContractAddress.genesisUpgrade(), newGenesisUpgrade, "Genesis upgrade was not set correctly"); + + // We need to initialize the state hash because it is used in the commitment of the next batch + IExecutor.StoredBatchInfo memory newBatchZero = IExecutor.StoredBatchInfo({ + batchNumber: 0, + batchHash: genesisBatchHash, + indexRepeatedStorageChanges: genesisIndexRepeatedStorageChanges, + numberOfLayer1Txs: 0, + priorityOperationsHash: EMPTY_STRING_KECCAK, + l2LogsTreeRoot: DEFAULT_L2_LOGS_TREE_ROOT_HASH, + timestamp: 0, + commitment: genesisBatchCommitment + }); + bytes32 expectedStoredBatchZero = keccak256(abi.encode(newBatchZero)); + + assertEq( + chainContractAddress.storedBatchZero(), + expectedStoredBatchZero, + "Stored batch zero was not set correctly" + ); + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetInitialCutHash.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetInitialCutHash.t.sol deleted file mode 100644 index f0fc37858..000000000 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetInitialCutHash.t.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity 0.8.24; - -import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; -import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; - -contract setInitialCutHashTest is StateTransitionManagerTest { - function test_SettingInitialCutHash() public { - bytes32 initialCutHash = keccak256(abi.encode(getDiamondCutData(address(diamondInit)))); - address randomDiamondInit = address(0x303030303030303030303); - - assertEq(chainContractAddress.initialCutHash(), initialCutHash, "Initial cut hash is not correct"); - - Diamond.DiamondCutData memory newDiamondCutData = getDiamondCutData(address(randomDiamondInit)); - bytes32 newCutHash = keccak256(abi.encode(newDiamondCutData)); - - chainContractAddress.setInitialCutHash(newDiamondCutData); - - assertEq(chainContractAddress.initialCutHash(), newCutHash, "Initial cut hash update was not successful"); - } -} diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol index 60c606a3d..8fae0aa1e 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/StateTransitionOwnerZero.t.sol @@ -4,18 +4,22 @@ pragma solidity 0.8.24; import {TransparentUpgradeableProxy} from "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol"; -import {StateTransitionManagerInitializeData} from "contracts/state-transition/IStateTransitionManager.sol"; +import {StateTransitionManagerInitializeData, ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; contract initializingSTMOwnerZeroTest is StateTransitionManagerTest { function test_InitializingSTMWithGovernorZeroShouldRevert() public { + ChainCreationParams memory chainCreationParams = ChainCreationParams({ + genesisUpgrade: address(genesisUpgradeContract), + genesisBatchHash: bytes32(uint256(0x01)), + genesisIndexRepeatedStorageChanges: 1, + genesisBatchCommitment: bytes32(uint256(0x01)), + diamondCut: getDiamondCutData(address(diamondInit)) + }); + StateTransitionManagerInitializeData memory stmInitializeDataNoOwner = StateTransitionManagerInitializeData({ owner: address(0), validatorTimelock: validator, - genesisUpgrade: address(genesisUpgradeContract), - genesisBatchHash: bytes32(""), - genesisIndexRepeatedStorageChanges: 0, - genesisBatchCommitment: bytes32(""), - diamondCut: getDiamondCutData(address(diamondInit)), + chainCreationParams: chainCreationParams, protocolVersion: 0 }); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol index cb7251185..2cdbd8e00 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/_StateTransitionManager_Shared.t.sol @@ -16,7 +16,7 @@ import {DiamondInit} from "contracts/state-transition/chain-deps/DiamondInit.sol import {GenesisUpgrade} from "contracts/upgrades/GenesisUpgrade.sol"; import {InitializeDataNewChain} from "contracts/state-transition/chain-interfaces/IDiamondInit.sol"; import {StateTransitionManager} from "contracts/state-transition/StateTransitionManager.sol"; -import {StateTransitionManagerInitializeData} from "contracts/state-transition/IStateTransitionManager.sol"; +import {StateTransitionManagerInitializeData, ChainCreationParams} from "contracts/state-transition/IStateTransitionManager.sol"; import {TestnetVerifier} from "contracts/state-transition/TestnetVerifier.sol"; contract StateTransitionManagerTest is Test { @@ -78,14 +78,18 @@ contract StateTransitionManagerTest is Test { }) ); + ChainCreationParams memory chainCreationParams = ChainCreationParams({ + genesisUpgrade: address(genesisUpgradeContract), + genesisBatchHash: bytes32(uint256(0x01)), + genesisIndexRepeatedStorageChanges: 0x01, + genesisBatchCommitment: bytes32(uint256(0x01)), + diamondCut: getDiamondCutData(address(diamondInit)) + }); + StateTransitionManagerInitializeData memory stmInitializeDataNoGovernor = StateTransitionManagerInitializeData({ owner: address(0), validatorTimelock: validator, - genesisUpgrade: address(genesisUpgradeContract), - genesisBatchHash: bytes32(""), - genesisIndexRepeatedStorageChanges: 0, - genesisBatchCommitment: bytes32(""), - diamondCut: getDiamondCutData(address(diamondInit)), + chainCreationParams: chainCreationParams, protocolVersion: 0 }); @@ -99,11 +103,7 @@ contract StateTransitionManagerTest is Test { StateTransitionManagerInitializeData memory stmInitializeData = StateTransitionManagerInitializeData({ owner: governor, validatorTimelock: validator, - genesisUpgrade: address(genesisUpgradeContract), - genesisBatchHash: bytes32(""), - genesisIndexRepeatedStorageChanges: 0, - genesisBatchCommitment: bytes32(""), - diamondCut: getDiamondCutData(address(diamondInit)), + chainCreationParams: chainCreationParams, protocolVersion: 0 }); diff --git a/l1-contracts/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts index f1a2b49f2..c42b55c19 100644 --- a/l1-contracts/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -253,7 +253,8 @@ export function createSystemLogs( export function createSystemLogsWithUpgrade( chainedPriorityTxHashKey?: BytesLike, numberOfLayer1Txs?: BigNumberish, - upgradeTxHash?: string + upgradeTxHash?: string, + previousBatchHash?: string ) { return [ constructL2Log(true, L2_TO_L1_MESSENGER, SYSTEM_LOG_KEYS.L2_TO_L1_LOGS_TREE_ROOT_KEY, ethers.constants.HashZero), @@ -265,7 +266,12 @@ export function createSystemLogsWithUpgrade( SYSTEM_LOG_KEYS.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY, ethers.constants.HashZero ), - constructL2Log(true, L2_SYSTEM_CONTEXT_ADDRESS, SYSTEM_LOG_KEYS.PREV_BATCH_HASH_KEY, ethers.constants.HashZero), + constructL2Log( + true, + L2_SYSTEM_CONTEXT_ADDRESS, + SYSTEM_LOG_KEYS.PREV_BATCH_HASH_KEY, + previousBatchHash ? previousBatchHash : ethers.constants.HashZero + ), constructL2Log( true, L2_BOOTLOADER_ADDRESS, @@ -311,13 +317,13 @@ export function createSystemLogsWithUpgrade( export function genesisStoredBatchInfo(): StoredBatchInfo { return { batchNumber: 0, - batchHash: ethers.constants.HashZero, - indexRepeatedStorageChanges: 0, + batchHash: "0x0000000000000000000000000000000000000000000000000000000000000001", + indexRepeatedStorageChanges: 1, numberOfLayer1Txs: 0, priorityOperationsHash: EMPTY_STRING_KECCAK, l2LogsTreeRoot: DEFAULT_L2_LOGS_TREE_ROOT_HASH, timestamp: 0, - commitment: ethers.constants.HashZero, + commitment: "0x0000000000000000000000000000000000000000000000000000000000000001", }; } @@ -427,7 +433,12 @@ export async function buildCommitBatchInfoWithUpgrade( upgradeTxHash: string ): Promise { const timestamp = info.timestamp || (await hardhat.ethers.provider.getBlock("latest")).timestamp; - const systemLogs = createSystemLogsWithUpgrade(info.priorityOperationsHash, info.numberOfLayer1Txs, upgradeTxHash); + const systemLogs = createSystemLogsWithUpgrade( + info.priorityOperationsHash, + info.numberOfLayer1Txs, + upgradeTxHash, + ethers.utils.hexlify(prevInfo.batchHash) + ); systemLogs[SYSTEM_LOG_KEYS.PACKED_BATCH_AND_L2_BLOCK_TIMESTAMP_KEY] = constructL2Log( true, L2_SYSTEM_CONTEXT_ADDRESS, @@ -437,7 +448,7 @@ export async function buildCommitBatchInfoWithUpgrade( return { timestamp, - indexRepeatedStorageChanges: 0, + indexRepeatedStorageChanges: 1, newStateRoot: ethers.utils.randomBytes(32), numberOfLayer1Txs: 0, priorityOperationsHash: EMPTY_STRING_KECCAK, From 8a70bbbc48125f5bde6189b4e3c6a3ee79631678 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Ignacio=20Gonz=C3=A1lez?= Date: Mon, 3 Jun 2024 11:35:31 +0200 Subject: [PATCH 52/60] chore: Move l1-contracts-foundry (#504) Co-authored-by: Danil Co-authored-by: Agustin Aon <21188659+aon@users.noreply.github.com> --- .../workflows/l1-contracts-foundry-ci.yaml | 28 +++++++++---------- .gitignore | 8 +++--- .gitmodules | 15 +++++----- l1-contracts-foundry/foundry.toml | 20 ------------- l1-contracts-foundry/lib/forge-std | 1 - .../lib/openzeppelin-contracts-upgradeable | 1 - .../config-deploy-erc20.toml | 0 .../config-deploy-l1.toml | 0 .../config-deploy-paymaster.toml | 0 .../config-initialize-l2-weth-token.toml | 0 .../config-initialize-shared-bridges.toml | 0 .../register-hyperchain.toml | 0 .../deploy-scripts}/AcceptAdmin.s.sol | 0 .../deploy-scripts}/DeployErc20.s.sol | 0 .../deploy-scripts}/DeployL1.s.sol | 0 .../deploy-scripts}/DeployPaymaster.s.sol | 0 .../InitializeL2WethToken.s.sol | 0 .../InitializeSharedBridgeOnL2.sol | 0 .../deploy-scripts}/RegisterHyperchain.s.sol | 0 .../deploy-scripts}/Utils.sol | 0 l1-contracts/foundry.toml | 14 ++++++++++ l1-contracts/lib/forge-std | 2 +- l1-contracts/lib/murky | 2 +- .../lib/openzeppelin-contracts | 0 .../lib/openzeppelin-contracts-upgradeable | 1 + l1-contracts/remappings.txt | 1 - .../script-out/.gitkeep | 0 27 files changed, 42 insertions(+), 51 deletions(-) delete mode 100644 l1-contracts-foundry/foundry.toml delete mode 160000 l1-contracts-foundry/lib/forge-std delete mode 160000 l1-contracts-foundry/lib/openzeppelin-contracts-upgradeable rename {l1-contracts-foundry/script-config-template => l1-contracts/deploy-script-config-template}/config-deploy-erc20.toml (100%) rename {l1-contracts-foundry/script-config-template => l1-contracts/deploy-script-config-template}/config-deploy-l1.toml (100%) rename {l1-contracts-foundry/script-config-template => l1-contracts/deploy-script-config-template}/config-deploy-paymaster.toml (100%) rename {l1-contracts-foundry/script-config-template => l1-contracts/deploy-script-config-template}/config-initialize-l2-weth-token.toml (100%) rename {l1-contracts-foundry/script-config-template => l1-contracts/deploy-script-config-template}/config-initialize-shared-bridges.toml (100%) rename {l1-contracts-foundry/script-config-template => l1-contracts/deploy-script-config-template}/register-hyperchain.toml (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/AcceptAdmin.s.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/DeployErc20.s.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/DeployL1.s.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/DeployPaymaster.s.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/InitializeL2WethToken.s.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/InitializeSharedBridgeOnL2.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/RegisterHyperchain.s.sol (100%) rename {l1-contracts-foundry/script => l1-contracts/deploy-scripts}/Utils.sol (100%) rename {l1-contracts-foundry => l1-contracts}/lib/openzeppelin-contracts (100%) create mode 160000 l1-contracts/lib/openzeppelin-contracts-upgradeable rename {l1-contracts-foundry => l1-contracts}/script-out/.gitkeep (100%) diff --git a/.github/workflows/l1-contracts-foundry-ci.yaml b/.github/workflows/l1-contracts-foundry-ci.yaml index 74fdbb8dc..02c551d63 100644 --- a/.github/workflows/l1-contracts-foundry-ci.yaml +++ b/.github/workflows/l1-contracts-foundry-ci.yaml @@ -29,7 +29,7 @@ jobs: run: yarn - name: Build artifacts - working-directory: ./l1-contracts-foundry + working-directory: ./l1-contracts run: forge build - name: Build system-contract artifacts @@ -40,8 +40,8 @@ jobs: with: key: artifacts-l1-contracts-foudry-${{ github.sha }} path: | - l1-contracts-foundry/cache - l1-contracts-foundry/out + l1-contracts/cache + l1-contracts/out system-contracts/artifacts-zk system-contracts/bootloader/build system-contracts/cache-zk @@ -63,8 +63,8 @@ jobs: fail-on-cache-miss: true key: artifacts-l1-contracts-foudry-${{ github.sha }} path: | - l1-contracts-foundry/cache - l1-contracts-foundry/out + l1-contracts/cache + l1-contracts/out system-contracts/artifacts-zk system-contracts/bootloader/build system-contracts/cache-zk @@ -75,8 +75,8 @@ jobs: uses: foundry-rs/foundry-toolchain@v1 - name: Copy configs from template - working-directory: ./l1-contracts-foundry - run: cp -r script-config-template script-config + working-directory: ./l1-contracts + run: cp -r deploy-script-config-template script-config - name: Run anvil run: | @@ -100,18 +100,18 @@ jobs: fi - name: Run DeployL1 script - working-directory: ./l1-contracts-foundry - run: forge script ./script/DeployL1.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY + working-directory: ./l1-contracts + run: forge script ./deploy-scripts/DeployL1.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY - name: Run DeployErc20 script - working-directory: ./l1-contracts-foundry - run: forge script ./script/DeployErc20.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY + working-directory: ./l1-contracts + run: forge script ./deploy-scripts/DeployErc20.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY # TODO restore scripts verification # - name: Run RegisterHyperchain script -# working-directory: ./l1-contracts-foundry +# working-directory: ./l1-contracts # run: | # cat ./script-out/output-deploy-l1.toml >> ./script-config/register-hyperchain.toml -# forge script ./script/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY +# forge script ./deploy-scripts/RegisterHyperchain.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY # - name: Run InitializeL2WethToken script # working-directory: ./l1-contracts-foundry -# run: forge script ./script/InitializeL2WethToken.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY +# run: forge script ./deploy-scripts/InitializeL2WethToken.s.sol --ffi --rpc-url $ANVIL_RPC_URL --broadcast --private-key $ANVIL_PRIVATE_KEY diff --git a/.gitignore b/.gitignore index ab8dbb92c..63f96063b 100644 --- a/.gitignore +++ b/.gitignore @@ -22,7 +22,7 @@ l1-contracts/lcov.info l1-contracts/report/* l1-contracts/coverage/* l1-contracts/out/* -l1-contracts-foundry/broadcast/* -l1-contracts-foundry/script-config/* -l1-contracts-foundry/script-out/* -!l1-contracts-foundry/script-out/.gitkeep +l1-contracts/broadcast/* +l1-contracts/script-config/* +l1-contracts/script-out/* +!l1-contracts/script-out/.gitkeep diff --git a/.gitmodules b/.gitmodules index 2a0ad281f..5cbc631ba 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,12 +4,11 @@ [submodule "l1-contracts/lib/murky"] path = l1-contracts/lib/murky url = https://github.com/dmfxyz/murky -[submodule "l1-contracts-foundry/lib/forge-std"] - path = l1-contracts-foundry/lib/forge-std - url = https://github.com/foundry-rs/forge-std -[submodule "l1-contracts-foundry/lib/openzeppelin-contracts"] - path = l1-contracts-foundry/lib/openzeppelin-contracts - url = https://github.com/Openzeppelin/openzeppelin-contracts -[submodule "l1-contracts-foundry/lib/openzeppelin-contracts-upgradeable"] - path = l1-contracts-foundry/lib/openzeppelin-contracts-upgradeable +[submodule "l1-contracts/lib/openzeppelin-contracts-upgradeable"] + path = l1-contracts/lib/openzeppelin-contracts-upgradeable url = https://github.com/Openzeppelin/openzeppelin-contracts-upgradeable + branch = release-v4.9 +[submodule "l1-contracts/lib/openzeppelin-contracts"] + path = l1-contracts/lib/openzeppelin-contracts + url = https://github.com/Openzeppelin/openzeppelin-contracts + branch = release-v4.9 diff --git a/l1-contracts-foundry/foundry.toml b/l1-contracts-foundry/foundry.toml deleted file mode 100644 index ac978c3ba..000000000 --- a/l1-contracts-foundry/foundry.toml +++ /dev/null @@ -1,20 +0,0 @@ -[profile.default] -src = "../l1-contracts/contracts" -out = "out" -libs = ["lib"] -remappings = [ - "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", - "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", - "contracts/=../l1-contracts/contracts/", - "l2-contracts/=../l2-contracts/contracts/" -] -allow_paths = ["../l1-contracts/contracts", "../l2-contracts/contracts"] -fs_permissions = [ - { access = "read", path = "../system-contracts/bootloader/build/artifacts" }, - { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed" }, - { access = "read", path = "../l2-contracts/artifacts-zk/" }, - { access = "read", path = "./script-config" }, - { access = "read-write", path = "./script-out" }, - { access = "read", path = "./out" } -] -evm_version = "cancun" diff --git a/l1-contracts-foundry/lib/forge-std b/l1-contracts-foundry/lib/forge-std deleted file mode 160000 index b6a506db2..000000000 --- a/l1-contracts-foundry/lib/forge-std +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b6a506db2262cad5ff982a87789ee6d1558ec861 diff --git a/l1-contracts-foundry/lib/openzeppelin-contracts-upgradeable b/l1-contracts-foundry/lib/openzeppelin-contracts-upgradeable deleted file mode 160000 index a40cb0bda..000000000 --- a/l1-contracts-foundry/lib/openzeppelin-contracts-upgradeable +++ /dev/null @@ -1 +0,0 @@ -Subproject commit a40cb0bda838c2ef3dfc252c179f5c37c32e80c4 diff --git a/l1-contracts-foundry/script-config-template/config-deploy-erc20.toml b/l1-contracts/deploy-script-config-template/config-deploy-erc20.toml similarity index 100% rename from l1-contracts-foundry/script-config-template/config-deploy-erc20.toml rename to l1-contracts/deploy-script-config-template/config-deploy-erc20.toml diff --git a/l1-contracts-foundry/script-config-template/config-deploy-l1.toml b/l1-contracts/deploy-script-config-template/config-deploy-l1.toml similarity index 100% rename from l1-contracts-foundry/script-config-template/config-deploy-l1.toml rename to l1-contracts/deploy-script-config-template/config-deploy-l1.toml diff --git a/l1-contracts-foundry/script-config-template/config-deploy-paymaster.toml b/l1-contracts/deploy-script-config-template/config-deploy-paymaster.toml similarity index 100% rename from l1-contracts-foundry/script-config-template/config-deploy-paymaster.toml rename to l1-contracts/deploy-script-config-template/config-deploy-paymaster.toml diff --git a/l1-contracts-foundry/script-config-template/config-initialize-l2-weth-token.toml b/l1-contracts/deploy-script-config-template/config-initialize-l2-weth-token.toml similarity index 100% rename from l1-contracts-foundry/script-config-template/config-initialize-l2-weth-token.toml rename to l1-contracts/deploy-script-config-template/config-initialize-l2-weth-token.toml diff --git a/l1-contracts-foundry/script-config-template/config-initialize-shared-bridges.toml b/l1-contracts/deploy-script-config-template/config-initialize-shared-bridges.toml similarity index 100% rename from l1-contracts-foundry/script-config-template/config-initialize-shared-bridges.toml rename to l1-contracts/deploy-script-config-template/config-initialize-shared-bridges.toml diff --git a/l1-contracts-foundry/script-config-template/register-hyperchain.toml b/l1-contracts/deploy-script-config-template/register-hyperchain.toml similarity index 100% rename from l1-contracts-foundry/script-config-template/register-hyperchain.toml rename to l1-contracts/deploy-script-config-template/register-hyperchain.toml diff --git a/l1-contracts-foundry/script/AcceptAdmin.s.sol b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol similarity index 100% rename from l1-contracts-foundry/script/AcceptAdmin.s.sol rename to l1-contracts/deploy-scripts/AcceptAdmin.s.sol diff --git a/l1-contracts-foundry/script/DeployErc20.s.sol b/l1-contracts/deploy-scripts/DeployErc20.s.sol similarity index 100% rename from l1-contracts-foundry/script/DeployErc20.s.sol rename to l1-contracts/deploy-scripts/DeployErc20.s.sol diff --git a/l1-contracts-foundry/script/DeployL1.s.sol b/l1-contracts/deploy-scripts/DeployL1.s.sol similarity index 100% rename from l1-contracts-foundry/script/DeployL1.s.sol rename to l1-contracts/deploy-scripts/DeployL1.s.sol diff --git a/l1-contracts-foundry/script/DeployPaymaster.s.sol b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol similarity index 100% rename from l1-contracts-foundry/script/DeployPaymaster.s.sol rename to l1-contracts/deploy-scripts/DeployPaymaster.s.sol diff --git a/l1-contracts-foundry/script/InitializeL2WethToken.s.sol b/l1-contracts/deploy-scripts/InitializeL2WethToken.s.sol similarity index 100% rename from l1-contracts-foundry/script/InitializeL2WethToken.s.sol rename to l1-contracts/deploy-scripts/InitializeL2WethToken.s.sol diff --git a/l1-contracts-foundry/script/InitializeSharedBridgeOnL2.sol b/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol similarity index 100% rename from l1-contracts-foundry/script/InitializeSharedBridgeOnL2.sol rename to l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol diff --git a/l1-contracts-foundry/script/RegisterHyperchain.s.sol b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol similarity index 100% rename from l1-contracts-foundry/script/RegisterHyperchain.s.sol rename to l1-contracts/deploy-scripts/RegisterHyperchain.s.sol diff --git a/l1-contracts-foundry/script/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol similarity index 100% rename from l1-contracts-foundry/script/Utils.sol rename to l1-contracts/deploy-scripts/Utils.sol diff --git a/l1-contracts/foundry.toml b/l1-contracts/foundry.toml index dad521718..82910dad0 100644 --- a/l1-contracts/foundry.toml +++ b/l1-contracts/foundry.toml @@ -2,6 +2,20 @@ src = 'contracts' out = 'out' libs = ['node_modules', 'lib'] +remappings = [ + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", + "l2-contracts/=../l2-contracts/contracts/" +] +allow_paths = ["../l2-contracts/contracts"] +fs_permissions = [ + { access = "read", path = "../system-contracts/bootloader/build/artifacts" }, + { access = "read", path = "../system-contracts/artifacts-zk/contracts-preprocessed" }, + { access = "read", path = "../l2-contracts/artifacts-zk/" }, + { access = "read", path = "./script-config" }, + { access = "read-write", path = "./script-out" }, + { access = "read", path = "./out" } +] cache_path = 'cache-forge' test = 'test/foundry' solc_version = "0.8.24" diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std index 705263c95..52715a217 160000 --- a/l1-contracts/lib/forge-std +++ b/l1-contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit 705263c95892a906d7af65f0f73ce8a4a0c80b80 +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 diff --git a/l1-contracts/lib/murky b/l1-contracts/lib/murky index 40de6e801..5feccd125 160000 --- a/l1-contracts/lib/murky +++ b/l1-contracts/lib/murky @@ -1 +1 @@ -Subproject commit 40de6e80117f39cda69d71b07b7c824adac91b29 +Subproject commit 5feccd1253d7da820f7cccccdedf64471025455d diff --git a/l1-contracts-foundry/lib/openzeppelin-contracts b/l1-contracts/lib/openzeppelin-contracts similarity index 100% rename from l1-contracts-foundry/lib/openzeppelin-contracts rename to l1-contracts/lib/openzeppelin-contracts diff --git a/l1-contracts/lib/openzeppelin-contracts-upgradeable b/l1-contracts/lib/openzeppelin-contracts-upgradeable new file mode 160000 index 000000000..2d081f24c --- /dev/null +++ b/l1-contracts/lib/openzeppelin-contracts-upgradeable @@ -0,0 +1 @@ +Subproject commit 2d081f24cac1a867f6f73d512f2022e1fa987854 diff --git a/l1-contracts/remappings.txt b/l1-contracts/remappings.txt index fa456851c..d866a0c22 100644 --- a/l1-contracts/remappings.txt +++ b/l1-contracts/remappings.txt @@ -1,5 +1,4 @@ @ensdomains/=node_modules/@ensdomains/ -@openzeppelin/=node_modules/@openzeppelin/ ds-test/=lib/forge-std/lib/ds-test/src/ eth-gas-reporter/=node_modules/eth-gas-reporter/ forge-std/=lib/forge-std/src/ diff --git a/l1-contracts-foundry/script-out/.gitkeep b/l1-contracts/script-out/.gitkeep similarity index 100% rename from l1-contracts-foundry/script-out/.gitkeep rename to l1-contracts/script-out/.gitkeep From d97d8cdec8652ce88a73b7213b77958c46cbc552 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 10:15:27 -0400 Subject: [PATCH 53/60] tests and fix merge conflict --- l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol | 3 ++- l1-contracts/test/test_config/constant/hardhat.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol index 92e90085b..51d24592d 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgradeGenesis.sol @@ -28,6 +28,7 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { // slither-disable-next-line unused-return (uint32 previousMajorVersion, uint32 previousMinorVersion, ) = SemVer.unpackSemVer( SafeCast.toUint96(previousProtocolVersion) + ); if (previousMajorVersion != 0) { revert ProtocolMajorVersionNotZero(); @@ -49,7 +50,7 @@ abstract contract BaseZkSyncUpgradeGenesis is BaseZkSyncUpgrade { // While this is implicitly enforced by other checks above, we still double check just in case if (minorDelta > MAX_ALLOWED_MINOR_VERSION_DELTA) { - revert ProtocolVersionDeltaTooLarge(); + revert ProtocolVersionDeltaTooLarge(minorDelta, MAX_ALLOWED_MINOR_VERSION_DELTA); } // If the minor version changes also, we need to ensure that the previous upgrade has been finalized. diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index 0e63431f0..aeb7ec506 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -95,4 +95,4 @@ "decimals": 18, "address": "0x51E83b811930bb4a3aAb3494894ec237Cb6cEc49" } -] +] \ No newline at end of file From 704b41b39a9e47503f1dab1fe5f8c1293f2bf0a4 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 15:16:57 -0400 Subject: [PATCH 54/60] fix merge conflicts and bump hashes --- .../test/test_config/constant/hardhat.json | 2 +- .../contracts/bridge/L2SharedBridge.sol | 10 ++++---- system-contracts/SystemContractsHashes.json | 25 ------------------- 3 files changed, 6 insertions(+), 31 deletions(-) diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index aeb7ec506..0e63431f0 100644 --- a/l1-contracts/test/test_config/constant/hardhat.json +++ b/l1-contracts/test/test_config/constant/hardhat.json @@ -95,4 +95,4 @@ "decimals": 18, "address": "0x51E83b811930bb4a3aAb3494894ec237Cb6cEc49" } -] \ No newline at end of file +] diff --git a/l2-contracts/contracts/bridge/L2SharedBridge.sol b/l2-contracts/contracts/bridge/L2SharedBridge.sol index df0149710..2a0fe1903 100644 --- a/l2-contracts/contracts/bridge/L2SharedBridge.sol +++ b/l2-contracts/contracts/bridge/L2SharedBridge.sol @@ -39,7 +39,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { /// This is non-zero only on Era, and should not be renamed for backward compatibility with the SDKs. address public override l1Bridge; - uint256 internal immutable ERA_CHAIN_ID; + uint256 public immutable ERA_CHAIN_ID; /// @dev Contract is expected to be used as proxy implementation. /// @dev Disable the initialization to prevent Parity hack. @@ -59,7 +59,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { bytes32 _l2TokenProxyBytecodeHash, address _aliasedOwner ) external reinitializer(2) { - if (_l1Bridge == address(0)) { + if (_l1SharedBridge == address(0)) { revert EmptyAddress(); } @@ -79,10 +79,10 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { l2TokenProxyBytecodeHash = _l2TokenProxyBytecodeHash; l2TokenBeacon.transferOwnership(_aliasedOwner); } else { - if (_l1LegacyBridge == address(0)) { + if (_l1Bridge == address(0)) { revert EmptyAddress(); } - l1LegacyBridge = _l1LegacyBridge; + l1Bridge = _l1Bridge; // l2StandardToken and l2TokenBeacon are already deployed on ERA, and stored in the proxy } } @@ -103,7 +103,7 @@ contract L2SharedBridge is IL2SharedBridge, Initializable { // Only the L1 bridge counterpart can initiate and finalize the deposit. if ( AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1Bridge && - AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1LegacyBridge + AddressAliasHelper.undoL1ToL2Alias(msg.sender) != l1SharedBridge ) { revert InvalidCaller(msg.sender); } diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 9cc1eea74..8dd971976 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -178,60 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", -<<<<<<< HEAD "bytecodeHash": "0x010003cbda052f30cd056d0c758c7cc5be2c31f77461591d4be73dc3291b6ca5", "sourceCodeHash": "0xa13475403f910dff1ea0cf7ebf80633d9dcc37b4f8dd9f0c678a935793580932" -======= - "bytecodeHash": "0x010003cbf67ee7370dd2e77fb9ad39f718ded9354be174ea3009c6cb4fb8c06d", - "sourceCodeHash": "0x232e09be0ce4a92a3b77558e5724ab67e9deaf68e12e8be682a999655203b066" ->>>>>>> release-v23 }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", -<<<<<<< HEAD "bytecodeHash": "0x010009519c960b6baa12091cd1f8538d00fa0d7505c81943ba6e379a5f1c9c9e", "sourceCodeHash": "0xbcdce81799656df718b5dfff4ba6ce8aac82087a78c0c33edb0675e55bb8364c" -======= - "bytecodeHash": "0x01000951968c701c02714779299712d9da6e400e56c78d0d07acd984bfe7242a", - "sourceCodeHash": "0x9b2d51a24186af7ef58f7c8f53d77f6732f3a8d2dbde556fc8c1152957855fa5" ->>>>>>> release-v23 }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", -<<<<<<< HEAD "bytecodeHash": "0x010008d7f0ddbde3a633aa89aff433666ba28dcf3adb35deb26a207ea1824454", "sourceCodeHash": "0xe08f6eaca1995981baf257dd86e5dec8b62c1b5ac53a1173142cebca510b7859" -======= - "bytecodeHash": "0x010008d7dffe019f801bf2ee23b93f83afd80ea6d20c8efe82da71fd57cbcb5c", - "sourceCodeHash": "0xf6624fe716eec6bcd5d513f069f33d758271b304009d2bdf5c5b7d0573868a1c" ->>>>>>> release-v23 }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", -<<<<<<< HEAD "bytecodeHash": "0x01000957fe599ea1dfc3fc958c63b11f46a726d9462078b77c3f28c4db21446c", "sourceCodeHash": "0x97e33d4d96f9ee25e171add92ec7d725de58904dfc68466e4aae1807e9997dc2" -======= - "bytecodeHash": "0x01000957420977a293aab097a368f36b123247d87d4695a6cd27ac62598ab171", - "sourceCodeHash": "0x23293faa6627f60f8b4d61657c615cb2327162dd1e33c0968e9ab4d5dd605a20" ->>>>>>> release-v23 }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", -<<<<<<< HEAD "bytecodeHash": "0x010008e756cd4ef7a22e5bf21b357fda5c90223b7947f38cd3749826a6faff68", "sourceCodeHash": "0x62556a75277d8c72961a1fb9e1d0e1f1cef41c0e8f8d26a6e85cda336a734834" -======= - "bytecodeHash": "0x010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e", - "sourceCodeHash": "0x8ac4971296d0546fc6366caa4089489177656cbc33cc21247947d98c28c6dee4" ->>>>>>> release-v23 } ] From ee5667e5a780774a2f0fa414e5123e206a065d4c Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 15:38:09 -0400 Subject: [PATCH 55/60] fixed lint --- .solhintignore | 3 ++ gas-bound-caller/contracts/GasBoundCaller.sol | 2 +- .../IStateTransitionManager.sol | 1 + .../StateTransitionManager.sol | 2 +- .../chain-deps/facets/Executor.sol | 2 +- l1-contracts/deploy-scripts/AcceptAdmin.s.sol | 2 +- .../deploy-scripts/DeployPaymaster.s.sol | 3 +- .../InitializeSharedBridgeOnL2.sol | 5 +-- .../deploy-scripts/RegisterHyperchain.s.sol | 12 ++++--- l1-contracts/deploy-scripts/Utils.sol | 35 +++++++++++-------- 10 files changed, 41 insertions(+), 26 deletions(-) diff --git a/.solhintignore b/.solhintignore index d6471dfce..8e9f84ade 100644 --- a/.solhintignore +++ b/.solhintignore @@ -22,3 +22,6 @@ system-contracts/contracts/openzeppelin system-contracts/contracts/Constants.sol system-contracts/contracts/test-contracts system-contracts/contracts-preprocessed + +# gas-bound-caller +gas-bound-caller/contracts/test-contracts diff --git a/gas-bound-caller/contracts/GasBoundCaller.sol b/gas-bound-caller/contracts/GasBoundCaller.sol index 4d0ef81cd..78af446ca 100644 --- a/gas-bound-caller/contracts/GasBoundCaller.sol +++ b/gas-bound-caller/contracts/GasBoundCaller.sol @@ -21,7 +21,7 @@ contract GasBoundCaller { uint256 internal constant CALL_ENTRY_OVERHEAD = 800; /// @notice We assume that no more than `CALL_RETURN_OVERHEAD` gas are used for the O(1) operations at the end of the execution, /// as such relaying the return. - uint256 constant CALL_RETURN_OVERHEAD = 400; + uint256 internal constant CALL_RETURN_OVERHEAD = 400; /// @notice The function that implements limiting of the total gas expenditure of the call. /// @dev On Era, the gas for pubdata is charged at the end of the execution of the entire transaction, meaning diff --git a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol index 4d7f7fc6b..fef2398a5 100644 --- a/l1-contracts/contracts/state-transition/IStateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/IStateTransitionManager.sol @@ -26,6 +26,7 @@ struct StateTransitionManagerInitializeData { /// @param genesisIndexRepeatedStorageChanges The serial number of the shortcut storage key for the genesis batch /// @param genesisBatchCommitment The zk-proof commitment for the genesis batch /// @param diamondCut The diamond cut for the first upgrade transaction on the newly deployed chain +// solhint-disable-next-line gas-struct-packing struct ChainCreationParams { address genesisUpgrade; bytes32 genesisBatchHash; diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index c0162f468..982e39e58 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; -// solhint-disable gas-custom-errors +// solhint-disable gas-custom-errors, reason-string import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import {SafeCast} from "@openzeppelin/contracts/utils/math/SafeCast.sol"; diff --git a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol index 504093d07..217e08a1a 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -54,7 +54,7 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { if (pricingMode == PubdataPricingMode.Validium) { // skipping data validation for validium, we just check that the data is empty require(_newBatch.pubdataCommitments.length == 1, "EF: v0l"); - for (uint8 i = uint8(SystemLogKey.BLOB_ONE_HASH_KEY); i <= uint8(SystemLogKey.BLOB_SIX_HASH_KEY); i++) { + for (uint8 i = uint8(SystemLogKey.BLOB_ONE_HASH_KEY); i <= uint8(SystemLogKey.BLOB_SIX_HASH_KEY); ++i) { logOutput.blobHashes[i - uint8(SystemLogKey.BLOB_ONE_HASH_KEY)] = bytes32(0); } } else if (pubdataSource == uint8(PubdataSource.Blob)) { diff --git a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol index 00ade426a..0af30c279 100644 --- a/l1-contracts/deploy-scripts/AcceptAdmin.s.sol +++ b/l1-contracts/deploy-scripts/AcceptAdmin.s.sol @@ -16,7 +16,7 @@ contract AcceptAdmin is Script { address governor; } - Config config; + Config internal config; function initConfig() public { string memory root = vm.projectRoot(); diff --git a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol index 52b664bc2..f7115a479 100644 --- a/l1-contracts/deploy-scripts/DeployPaymaster.s.sol +++ b/l1-contracts/deploy-scripts/DeployPaymaster.s.sol @@ -8,8 +8,9 @@ import {Utils} from "./Utils.sol"; contract DeployPaymaster is Script { using stdToml for string; - Config config; + Config internal config; + // solhint-disable-next-line gas-struct-packing struct Config { address bridgehubAddress; address l1SharedBridgeProxy; diff --git a/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol b/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol index 8ca7fce03..344ab59a1 100644 --- a/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol +++ b/l1-contracts/deploy-scripts/InitializeSharedBridgeOnL2.sol @@ -11,9 +11,10 @@ import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; contract DeployL2Script is Script { using stdToml for string; - Config config; - ContractsBytecodes contracts; + Config internal config; + ContractsBytecodes internal contracts; + // solhint-disable-next-line gas-struct-packing struct Config { address bridgehubAddress; address l1SharedBridgeProxy; diff --git a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol index 4dd8c0636..6da3e5d0b 100644 --- a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol +++ b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -// solhint-disable no-console +// solhint-disable no-console, gas-custom-errors, reason-string import {Script, console2 as console} from "forge-std/Script.sol"; import {Vm} from "forge-std/Vm.sol"; @@ -18,9 +18,10 @@ import {PubdataPricingMode} from "contracts/state-transition/chain-deps/ZkSyncHy contract RegisterHyperchainScript is Script { using stdToml for string; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - bytes32 constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + bytes32 internal constant STATE_TRANSITION_NEW_CHAIN_HASH = keccak256("NewHyperchain(uint256,address)"); + // solhint-disable-next-line gas-struct-packing struct Config { address deployerAddress; address ownerAddress; @@ -42,7 +43,7 @@ contract RegisterHyperchainScript is Script { address governance; } - Config config; + Config internal config; function run() public { console.log("Deploying Hyperchain"); @@ -175,7 +176,8 @@ contract RegisterHyperchainScript is Script { // Get new diamond proxy address from emitted events Vm.Log[] memory logs = vm.getRecordedLogs(); address diamondProxyAddress; - for (uint256 i = 0; i < logs.length; i++) { + uint256 logsLength = logs.length; + for (uint256 i = 0; i < logsLength; ++i) { if (logs[i].topics[0] == STATE_TRANSITION_NEW_CHAIN_HASH) { diamondProxyAddress = address(uint160(uint256(logs[i].topics[2]))); break; diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 23bcf0ff8..318be6da3 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -1,6 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; +// solhint-disable gas-custom-errors, reason-string + import {Vm} from "forge-std/Vm.sol"; import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; @@ -20,8 +22,8 @@ library Utils { bytes internal constant CREATE2_FACTORY_BYTECODE = hex"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; - address constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; - uint256 constant MAX_PRIORITY_TX_GAS = 72000000; + address internal constant ADDRESS_ONE = 0x0000000000000000000000000000000000000001; + uint256 internal constant MAX_PRIORITY_TX_GAS = 72000000; /** * @dev Get all selectors from the bytecode. @@ -40,12 +42,13 @@ library Utils { // Extract selectors from the result string[] memory parts = vm.split(stringResult, "\n"); - bytes4[] memory selectors = new bytes4[](parts.length); - for (uint256 i = 0; i < parts.length; i++) { + uint256 partsLength = parts.length; + bytes4[] memory selectors = new bytes4[](partsLength); + for (uint256 i = 0; i < partsLength; ++i) { bytes memory part = bytes(parts[i]); bytes memory extractedSelector = new bytes(10); // Selector length 10 is 0x + 4 bytes - for (uint256 j = 0; j < 10; j++) { + for (uint256 j = 0; j < 10; ++j) { extractedSelector[j] = part[j]; } bytes4 selector = bytes4(vm.parseBytes(string(extractedSelector))); @@ -54,7 +57,8 @@ library Utils { // Remove `getName()` selector if existing bool hasGetName = false; - for (uint256 i = 0; i < selectors.length; i++) { + uint256 selectorsLength = selectors.length; + for (uint256 i = 0; i < selectorsLength; ++i) { if (selectors[i] == bytes4(keccak256("getName()"))) { selectors[i] = selectors[selectors.length - 1]; hasGetName = true; @@ -62,8 +66,8 @@ library Utils { } } if (hasGetName) { - bytes4[] memory newSelectors = new bytes4[](selectors.length - 1); - for (uint256 i = 0; i < selectors.length - 1; i++) { + bytes4[] memory newSelectors = new bytes4[](selectorsLength - 1); + for (uint256 i = 0; i < selectorsLength - 1; ++i) { newSelectors[i] = selectors[i]; } return newSelectors; @@ -86,10 +90,11 @@ library Utils { */ function bytesToUint256(bytes memory bys) internal pure returns (uint256 value) { // Add left padding to 32 bytes if needed - if (bys.length < 32) { + uint256 bysLength = bys.length; + if (bysLength < 32) { bytes memory padded = new bytes(32); - for (uint256 i = 0; i < bys.length; i++) { - padded[i + 32 - bys.length] = bys[i]; + for (uint256 i = 0; i < bysLength; ++i) { + padded[i + 32 - bysLength] = bys[i]; } bys = padded; } @@ -192,12 +197,14 @@ library Utils { keccak256(constructorargs) ); - bytes[] memory _factoryDeps = new bytes[](factoryDeps.length + 1); + uint256 factoryDepsLength = factoryDeps.length; + + bytes[] memory _factoryDeps = new bytes[](factoryDepsLength + 1); - for (uint256 i = 0; i < factoryDeps.length; i++) { + for (uint256 i = 0; i < factoryDepsLength; ++i) { _factoryDeps[i] = factoryDeps[i]; } - _factoryDeps[factoryDeps.length] = bytecode; + _factoryDeps[factoryDepsLength] = bytecode; runL1L2Transaction({ l2Calldata: deployData, From 5c4525a603ab37708640c882a61545b1b399d8f3 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 15:49:56 -0400 Subject: [PATCH 56/60] update system contracts hashes and verifier hash --- .../contracts/state-transition/Verifier.sol | 2 +- system-contracts/SystemContractsHashes.json | 20 +++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/l1-contracts/contracts/state-transition/Verifier.sol b/l1-contracts/contracts/state-transition/Verifier.sol index 475218a67..cfc1f848b 100644 --- a/l1-contracts/contracts/state-transition/Verifier.sol +++ b/l1-contracts/contracts/state-transition/Verifier.sol @@ -9,7 +9,7 @@ import {IVerifier} from "./chain-interfaces/IVerifier.sol"; /// @notice Modified version of the Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of /// Knowledge (PLONK) verifier. /// Modifications have been made to optimize the proof system for zkSync hyperchain circuits. -/// @dev Contract was generated from a verification key with a hash of 0x1d485be42d712856dfe85b3cf7823f020fa5f83cb41c83f9da307fdc2089beee +/// @dev Contract was generated from a verification key with a hash of 0x14f97b81e54b35fe673d8708cc1a19e1ea5b5e348e12d31e39824ed4f42bbca2 /// @dev It uses a custom memory layout inside the inline assembly block. Each reserved memory cell is declared in the /// constants below. /// @dev For a better understanding of the verifier algorithm please refer to the following papers: diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 8dd971976..5c927c10f 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -178,35 +178,35 @@ "contractName": "bootloader_test", "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cbda052f30cd056d0c758c7cc5be2c31f77461591d4be73dc3291b6ca5", - "sourceCodeHash": "0xa13475403f910dff1ea0cf7ebf80633d9dcc37b4f8dd9f0c678a935793580932" + "bytecodeHash": "0x010003cb92f46b717a3351f085b9d0d7cf1b6c164f390487f29da5c3b1f272a1", + "sourceCodeHash": "0xbf798f55f3b5c3d4d29423278bd68c6bb6428f0290f6791b2e20963166b3b21a" }, { "contractName": "fee_estimate", "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x010009519c960b6baa12091cd1f8538d00fa0d7505c81943ba6e379a5f1c9c9e", - "sourceCodeHash": "0xbcdce81799656df718b5dfff4ba6ce8aac82087a78c0c33edb0675e55bb8364c" + "bytecodeHash": "0x01000951d5e14249434340fe5e6be707157f16d66ca10d0e5fcc110cc674def4", + "sourceCodeHash": "0xc7cd680273e89b1dfc3c6941f69611894c885e26656adfc4586c4eb149285d9d" }, { "contractName": "gas_test", "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008d7f0ddbde3a633aa89aff433666ba28dcf3adb35deb26a207ea1824454", - "sourceCodeHash": "0xe08f6eaca1995981baf257dd86e5dec8b62c1b5ac53a1173142cebca510b7859" + "bytecodeHash": "0x010008d7db21670fda613a703321bb109f192ef92a6cef40b07a35a661c4d563", + "sourceCodeHash": "0xaf85e223e2156440f007fed14c9fe8899d33ad2f0aeb7feab3f4fd81d759bfb6" }, { "contractName": "playground_batch", "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000957fe599ea1dfc3fc958c63b11f46a726d9462078b77c3f28c4db21446c", - "sourceCodeHash": "0x97e33d4d96f9ee25e171add92ec7d725de58904dfc68466e4aae1807e9997dc2" + "bytecodeHash": "0x0100095722e18e6831abbece78d3bbaac4fe187db091d6be75d0c6f59aff0f7f", + "sourceCodeHash": "0xac0a99374868ffafa2427f23a7fd1f5f8551402904efbdf84f38638cad00ec14" }, { "contractName": "proved_batch", "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008e756cd4ef7a22e5bf21b357fda5c90223b7947f38cd3749826a6faff68", - "sourceCodeHash": "0x62556a75277d8c72961a1fb9e1d0e1f1cef41c0e8f8d26a6e85cda336a734834" + "bytecodeHash": "0x010008e75c912d19d915dc90467be59c81c8004271b03639354806f669f14ad3", + "sourceCodeHash": "0x25e4cdb4020792f534611de304297e7e0230ed7ea0510bc049862c2540cc458e" } ] From 131f823ef4f91546ce93bc67aaa4b4254cbb22c9 Mon Sep 17 00:00:00 2001 From: Zach Kolodny Date: Wed, 5 Jun 2024 16:01:14 -0400 Subject: [PATCH 57/60] update forge-std --- l1-contracts/lib/forge-std | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l1-contracts/lib/forge-std b/l1-contracts/lib/forge-std index 705263c95..52715a217 160000 --- a/l1-contracts/lib/forge-std +++ b/l1-contracts/lib/forge-std @@ -1 +1 @@ -Subproject commit 705263c95892a906d7af65f0f73ce8a4a0c80b80 +Subproject commit 52715a217dc51d0de15877878ab8213f6cbbbab5 From bfcea79f2107bf27d9b6f199a2907d61b67bd70a Mon Sep 17 00:00:00 2001 From: kelemeno <34402761+kelemeno@users.noreply.github.com> Date: Mon, 10 Jun 2024 23:59:31 +0100 Subject: [PATCH 58/60] chore: cleanup (#519) --- .../contracts/upgrades/UpgradeHyperchains.sol | 44 --- .../contracts/upgrades/Upgrade_v1_4_1.sol | 54 --- l1-contracts/package.json | 6 +- .../scripts/governance-accept-ownership.ts | 141 ------- l1-contracts/scripts/hyperchain-upgrade-1.ts | 71 ---- l1-contracts/scripts/hyperchain-upgrade-2.ts | 68 ---- l1-contracts/scripts/hyperchain-upgrade-3.ts | 68 ---- l1-contracts/scripts/token-migration.ts | 47 ++- .../scripts/upgrade-consistency-checker.ts | 83 ++--- l1-contracts/scripts/verify.ts | 39 +- l1-contracts/src.ts/hyperchain-upgrade.ts | 348 ------------------ l2-contracts/package.json | 4 - .../src/deploy-force-deploy-upgrader.ts | 60 --- ...loy-shared-bridge-implementation-legacy.ts | 206 ----------- .../src/deploy-shared-bridge-on-l2.ts | 55 --- 15 files changed, 116 insertions(+), 1178 deletions(-) delete mode 100644 l1-contracts/contracts/upgrades/UpgradeHyperchains.sol delete mode 100644 l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol delete mode 100644 l1-contracts/scripts/governance-accept-ownership.ts delete mode 100644 l1-contracts/scripts/hyperchain-upgrade-1.ts delete mode 100644 l1-contracts/scripts/hyperchain-upgrade-2.ts delete mode 100644 l1-contracts/scripts/hyperchain-upgrade-3.ts delete mode 100644 l1-contracts/src.ts/hyperchain-upgrade.ts delete mode 100644 l2-contracts/src/deploy-force-deploy-upgrader.ts delete mode 100644 l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts delete mode 100644 l2-contracts/src/deploy-shared-bridge-on-l2.ts diff --git a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol b/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol deleted file mode 100644 index 16ce5f1ca..000000000 --- a/l1-contracts/contracts/upgrades/UpgradeHyperchains.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {Diamond} from "../state-transition/libraries/Diamond.sol"; -import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; -import {ETH_TOKEN_ADDRESS} from "../common/Config.sol"; - -/// @author Matter Labs -/// @custom:security-contact security@matterlabs.dev -/// @notice This upgrade will be used to migrate Era to be part of the hyperchain ecosystem contracts. -contract UpgradeHyperchains is BaseZkSyncUpgrade { - /// @notice The main function that will be called by the upgrade proxy. - /// @param _proposedUpgrade The upgrade to be executed. - function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) { - ( - uint256 chainId, - address bridgehubAddress, - address stateTransitionManager, - address sharedBridgeAddress, - address chainAdmin, - address validatorTimelock - ) = abi.decode(_proposedUpgrade.postUpgradeCalldata, (uint256, address, address, address, address, address)); - require(chainId != 0, "UpgradeHyperchain: 1"); - require(bridgehubAddress != address(0), "UpgradeHyperchain: 2"); - require(stateTransitionManager != address(0), "UpgradeHyperchain: 3"); - require(sharedBridgeAddress != address(0), "UpgradeHyperchain: 4"); - require(chainAdmin != address(0), "UpgradeHyperchains: 5"); - require(validatorTimelock != address(0), "UpgradeHyperchains: 6"); - - s.chainId = chainId; - s.bridgehub = bridgehubAddress; - s.stateTransitionManager = stateTransitionManager; - s.baseTokenBridge = sharedBridgeAddress; - s.baseToken = ETH_TOKEN_ADDRESS; - s.baseTokenGasPriceMultiplierNominator = 1; - s.baseTokenGasPriceMultiplierDenominator = 1; - s.admin = chainAdmin; - s.validators[validatorTimelock] = true; - - super.upgrade(_proposedUpgrade); - return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE; - } -} diff --git a/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol b/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol deleted file mode 100644 index baca21ab6..000000000 --- a/l1-contracts/contracts/upgrades/Upgrade_v1_4_1.sol +++ /dev/null @@ -1,54 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; - -import {Diamond} from "../state-transition/libraries/Diamond.sol"; -import {BaseZkSyncUpgrade, ProposedUpgrade} from "./BaseZkSyncUpgrade.sol"; -import {PubdataPricingMode, FeeParams} from "../state-transition/chain-deps/ZkSyncHyperchainStorage.sol"; - -/// @author Matter Labs -/// @custom:security-contact security@matterlabs.dev -contract Upgrade_v1_4_1 is BaseZkSyncUpgrade { - uint32 constant PRIORITY_TX_BATCH_OVERHEAD_L1_GAS = 1_000_000; - uint32 constant PRIORITY_TX_PUBDATA_PER_BATCH = 120_000; - uint32 constant PRIORITY_TX_MAX_GAS_PER_BATCH = 80_000_000; - uint32 constant PRIORITY_TX_MAX_PUBDATA = 99_000; - uint64 constant PRIORITY_TX_MINIMAL_GAS_PRICE = 250_000_000; - - /// This event is an exact copy of the "IAdmin.NewFeeParams" event. Since they have the same name and parameters, - /// these will be tracked by indexers in the same manner. - event NewFeeParams(FeeParams oldFeeParams, FeeParams newFeeParams); - - /// This function is a copy of the "Admin.changeFeeParams" function. - /// It is to be used once to set the new fee params for the first time as they needed for the correct functioning of the upgrade. - function changeFeeParams(FeeParams memory _newFeeParams) private { - // Double checking that the new fee params are valid, i.e. - // the maximal pubdata per batch is not less than the maximal pubdata per priority transaction. - require(_newFeeParams.maxPubdataPerBatch >= _newFeeParams.priorityTxMaxPubdata, "n6"); - - FeeParams memory oldFeeParams = s.feeParams; - s.feeParams = _newFeeParams; - - emit NewFeeParams(oldFeeParams, _newFeeParams); - } - - /// @notice The main function that will be called by the upgrade proxy. - /// @param _proposedUpgrade The upgrade to be executed. - function upgrade(ProposedUpgrade calldata _proposedUpgrade) public override returns (bytes32) { - // The execution of the next parts of the upgrade does depend on these fee params being already set correctly - changeFeeParams( - FeeParams({ - pubdataPricingMode: PubdataPricingMode.Rollup, - batchOverheadL1Gas: PRIORITY_TX_BATCH_OVERHEAD_L1_GAS, - maxPubdataPerBatch: PRIORITY_TX_PUBDATA_PER_BATCH, - maxL2GasPerBatch: PRIORITY_TX_MAX_GAS_PER_BATCH, - priorityTxMaxPubdata: PRIORITY_TX_MAX_PUBDATA, - minimalL2GasPrice: PRIORITY_TX_MINIMAL_GAS_PRICE - }) - ); - - super.upgrade(_proposedUpgrade); - - return Diamond.DIAMOND_INIT_SUCCESS_RETURN_VALUE; - } -} diff --git a/l1-contracts/package.json b/l1-contracts/package.json index c265b26ea..d30c93950 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -75,13 +75,9 @@ "migrate-governance": "ts-node scripts/migrate-governance.ts", "display-governance": "ts-node scripts/display-governance.ts", "upgrade-system": "ts-node upgrade-system/index.ts", - "hyperchain-upgrade-1": "ts-node scripts/hyperchain-upgrade-1.ts", - "hyperchain-upgrade-2": "ts-node scripts/hyperchain-upgrade-2.ts", - "hyperchain-upgrade-3": "ts-node scripts/hyperchain-upgrade-3.ts", "token-migration": "ts-node scripts/token-migration.ts", "setup-legacy-bridge-era": "ts-node scripts/setup-legacy-bridge-era.ts", - "upgrade-consistency-checker": "ts-node scripts/upgrade-consistency-checker.ts", - "governance-accept-ownership": "ts-node scripts/governance-accept-ownership.ts" + "upgrade-consistency-checker": "ts-node scripts/upgrade-consistency-checker.ts" }, "dependencies": { "dotenv": "^16.0.3", diff --git a/l1-contracts/scripts/governance-accept-ownership.ts b/l1-contracts/scripts/governance-accept-ownership.ts deleted file mode 100644 index 1c366f684..000000000 --- a/l1-contracts/scripts/governance-accept-ownership.ts +++ /dev/null @@ -1,141 +0,0 @@ -/// This script is needed to migrate the ownership for key contracts to the governance multisig - -// hardhat import should be the first import in the file -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as hardhat from "hardhat"; -import { Command } from "commander"; -import { Wallet, ethers } from "ethers"; -import { formatUnits, parseUnits, Interface } from "ethers/lib/utils"; -import { web3Provider, GAS_MULTIPLIER } from "./utils"; -import { ethTestConfig } from "../src.ts/utils"; - -const ownable2StepInterface = new Interface(hardhat.artifacts.readArtifactSync("ValidatorTimelock").abi); -const governanceInterface = new Interface(hardhat.artifacts.readArtifactSync("Governance").abi); - -const provider = web3Provider(); - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("upgrade-shared-bridge-era").description("upgrade shared bridge for era diamond proxy"); - - program - .command("transfer-ownership") - .option("--private-key ") - .option("--gas-price ") - .option("--nonce ") - .option("--owner-address ") - .option("--validator-timelock-addr ") - .option("--stm-addr ") - .option("--l1-shared-bridge-addr ") - .option("--bridgehub-addr ") - .option("--proxy-admin-addr ") - .option("--only-verifier") - .action(async (cmd) => { - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const ownerAddress = ethers.utils.getAddress(cmd.ownerAddress); - console.log(`Using owner address: ${ownerAddress}`); - - const gasPrice = cmd.gasPrice - ? parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); - console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - // Moving ownership for ValidatorTimelock - const validatorTimelockAddr = ethers.utils.getAddress(cmd.validatorTimelockAddr); - console.log(`Using ValidatorTimelock address: ${validatorTimelockAddr}`); - const stmAddr = ethers.utils.getAddress(cmd.stmAddr); - console.log("Using STM address: ", stmAddr); - const l1SharedBridgeAddr = ethers.utils.getAddress(cmd.l1SharedBridgeAddr); - console.log("Using L1 Shared Bridge address: ", l1SharedBridgeAddr); - const bridgehubAddr = ethers.utils.getAddress(cmd.bridgehubAddr); - console.log("Using Bridgehub address: ", bridgehubAddr); - const proxyAdminAddr = ethers.utils.getAddress(cmd.proxyAdminAddr); - console.log("Using Proxy Admin address: ", proxyAdminAddr); - - await transferOwnership1StepTo(deployWallet, validatorTimelockAddr, ownerAddress, true); - await transferOwnership1StepTo(deployWallet, stmAddr, ownerAddress, true); - await transferOwnership1StepTo(deployWallet, l1SharedBridgeAddr, ownerAddress, true); - await transferOwnership1StepTo(deployWallet, bridgehubAddr, ownerAddress, true); - await transferOwnership1StepTo(deployWallet, proxyAdminAddr, ownerAddress, false); - }); - - program - .command("accept-ownership") - .option("--validator-timelock-addr ") - .option("--stm-addr ") - .option("--l1-shared-bridge-addr ") - .option("--bridgehub-addr ") - .action(async (cmd) => { - // Moving ownership for ValidatorTimelock - const validatorTimelockAddr = ethers.utils.getAddress(cmd.validatorTimelockAddr); - console.log(`Using ValidatorTimelock address: ${validatorTimelockAddr}`); - const stmAddr = ethers.utils.getAddress(cmd.stmAddr); - console.log("Using STM address: ", stmAddr); - const l1SharedBridgeAddr = ethers.utils.getAddress(cmd.l1SharedBridgeAddr); - console.log("Using L1 Shared Bridge address: ", l1SharedBridgeAddr); - const bridgehubAddr = ethers.utils.getAddress(cmd.bridgehubAddr); - console.log("Using Bridgehub address: ", bridgehubAddr); - - const addresses = [validatorTimelockAddr, stmAddr, l1SharedBridgeAddr, bridgehubAddr]; - - const govCalls = addresses.map(acceptOwnershipCall); - - const govOperation = { - calls: govCalls, - predecessor: ethers.constants.HashZero, - salt: ethers.constants.HashZero, - }; - - const scheduleData = governanceInterface.encodeFunctionData("scheduleTransparent", [govOperation, 0]); - const executeData = governanceInterface.encodeFunctionData("execute", [govOperation]); - - console.log("Calldata for scheduling: ", scheduleData); - console.log("Calldata for execution: ", executeData); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); - -async function transferOwnership1StepTo( - wallet: ethers.Wallet, - contractAddress: string, - newOwner: string, - printPendingOwner: boolean = true -) { - const contract = new ethers.Contract(contractAddress, ownable2StepInterface, wallet); - console.log("Transferring ownership of contract: ", contractAddress, " to: ", newOwner); - const tx = await contract.transferOwnership(newOwner); - console.log("Tx hash", tx.hash); - await tx.wait(); - if (printPendingOwner) { - const newPendingOwner = await contract.pendingOwner(); - console.log("New pending owner: ", newPendingOwner); - } -} - -function acceptOwnershipCall(target: string) { - const data = ownable2StepInterface.encodeFunctionData("acceptOwnership", []); - return { - target, - value: 0, - data, - }; -} diff --git a/l1-contracts/scripts/hyperchain-upgrade-1.ts b/l1-contracts/scripts/hyperchain-upgrade-1.ts deleted file mode 100644 index 90a398ee3..000000000 --- a/l1-contracts/scripts/hyperchain-upgrade-1.ts +++ /dev/null @@ -1,71 +0,0 @@ -// hardhat import should be the first import in the file -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as hardhat from "hardhat"; -import { Command } from "commander"; -import { Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; -import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { web3Provider, GAS_MULTIPLIER } from "./utils"; -import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; -import { ethTestConfig } from "../src.ts/utils"; -import { upgradeToHyperchains1 } from "../src.ts/hyperchain-upgrade"; - -const provider = web3Provider(); - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("deploy").description("deploy L1 contracts"); - - program - .option("--private-key ") - .option("--chain-id ") - .option("--gas-price ") - .option("--nonce ") - .option("--owner-address ") - .option("--create2-salt ") - .option("--diamond-upgrade-init ") - .option("--only-verifier") - .action(async (cmd) => { - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address; - console.log(`Using owner address: ${ownerAddress}`); - - const gasPrice = cmd.gasPrice - ? parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); - console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - const create2Salt = cmd.create2Salt - ? cmd.create2Salt - : "0x0000000000000000000000000000000000000000000000000000000000000000"; - - const deployer = new Deployer({ - deployWallet, - addresses: deployedAddressesFromEnv(), - ownerAddress, - verbose: true, - }); - - await upgradeToHyperchains1(deployer, gasPrice, create2Salt, nonce); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/l1-contracts/scripts/hyperchain-upgrade-2.ts b/l1-contracts/scripts/hyperchain-upgrade-2.ts deleted file mode 100644 index ae8fd93ad..000000000 --- a/l1-contracts/scripts/hyperchain-upgrade-2.ts +++ /dev/null @@ -1,68 +0,0 @@ -// hardhat import should be the first import in the file -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as hardhat from "hardhat"; -import { Command } from "commander"; -import { Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; -import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { web3Provider, GAS_MULTIPLIER } from "./utils"; -import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; -import { ethTestConfig } from "../src.ts/utils"; -import { upgradeToHyperchains2 } from "../src.ts/hyperchain-upgrade"; - -const provider = web3Provider(); - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("deploy").description("deploy L1 contracts"); - - program - .option("--private-key ") - .option("--chain-id ") - .option("--gas-price ") - .option("--nonce ") - .option("--owner-address ") - .option("--create2-salt ") - .option("--print-file-path ") - .option("--diamond-upgrade-init ") - .option("--only-verifier") - .action(async (cmd) => { - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address; - console.log(`Using owner address: ${ownerAddress}`); - - const gasPrice = cmd.gasPrice - ? parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); - console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - const deployer = new Deployer({ - deployWallet, - addresses: deployedAddressesFromEnv(), - ownerAddress, - verbose: true, - }); - - await upgradeToHyperchains2(deployer, gasPrice, cmd.printFilePath); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/l1-contracts/scripts/hyperchain-upgrade-3.ts b/l1-contracts/scripts/hyperchain-upgrade-3.ts deleted file mode 100644 index e66065d94..000000000 --- a/l1-contracts/scripts/hyperchain-upgrade-3.ts +++ /dev/null @@ -1,68 +0,0 @@ -// hardhat import should be the first import in the file -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as hardhat from "hardhat"; -import { Command } from "commander"; -import { Wallet } from "ethers"; -import { Deployer } from "../src.ts/deploy"; -import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { web3Provider, GAS_MULTIPLIER } from "./utils"; -import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; -import { ethTestConfig } from "../src.ts/utils"; -import { upgradeToHyperchains3 } from "../src.ts/hyperchain-upgrade"; - -const provider = web3Provider(); - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("deploy").description("deploy L1 contracts"); - - program - .option("--private-key ") - .option("--chain-id ") - .option("--gas-price ") - .option("--nonce ") - .option("--owner-address ") - .option("--create2-salt ") - .option("--print-file-path ") - .option("--diamond-upgrade-init ") - .option("--only-verifier") - .action(async (cmd) => { - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const ownerAddress = cmd.ownerAddress ? cmd.ownerAddress : deployWallet.address; - console.log(`Using owner address: ${ownerAddress}`); - - const gasPrice = cmd.gasPrice - ? parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); - console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - const deployer = new Deployer({ - deployWallet, - addresses: deployedAddressesFromEnv(), - ownerAddress, - verbose: true, - }); - - await upgradeToHyperchains3(deployer, cmd.printFilePath); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/l1-contracts/scripts/token-migration.ts b/l1-contracts/scripts/token-migration.ts index d9ec8757a..b18260ca3 100644 --- a/l1-contracts/scripts/token-migration.ts +++ b/l1-contracts/scripts/token-migration.ts @@ -2,10 +2,13 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars import * as hardhat from "hardhat"; import { Command } from "commander"; -import { web3Url } from "./utils"; +import { web3Url, web3Provider } from "./utils"; import { ethers } from "ethers"; import { Provider, utils } from "zksync-ethers"; +import type { Deployer } from "../src.ts/deploy"; +import { IERC20Factory } from "../typechain/IERC20Factory"; + async function main() { const program = new Command(); @@ -218,3 +221,45 @@ async function prepareGovernanceTokenMigrationCall( executeCalldata, }; } + +const provider = web3Provider(); + +/// used together with anvil for local fork tests. Not used at the moment, will be used for next token migration. +// https://www.notion.so/matterlabs/Mainnet-shared-bridge-token-fork-test-aac05561dda64fb4ad38c40d2f479378?pvs=4 +export async function transferTokensOnForkedNetwork(deployer: Deployer) { + // the list of tokens that need to be migrated, use output from `get-confirmed-tokens` command + const tokenList = ["0x5A520e593F89c908cd2bc27D928bc75913C55C42"]; + for (const tokenAddress of tokenList) { + const erc20contract = IERC20Factory.connect(tokenAddress, provider); + console.log(`Migrating token ${tokenAddress}`); + console.log( + `Balance before: ${await erc20contract.balanceOf(deployer.addresses.Bridges.ERC20BridgeProxy)}, ${await erc20contract.balanceOf(deployer.addresses.Bridges.SharedBridgeProxy)}` + ); + await transferTokens(deployer, tokenAddress); + console.log( + `Balance after: ${await erc20contract.balanceOf(deployer.addresses.Bridges.ERC20BridgeProxy)}, ${await erc20contract.balanceOf(deployer.addresses.Bridges.SharedBridgeProxy)}` + ); + } + for (const tokenAddress of tokenList) { + const erc20contract = IERC20Factory.connect(tokenAddress, provider); + if (!(await erc20contract.balanceOf(deployer.addresses.Bridges.ERC20BridgeProxy)).eq(0)) { + console.log(`Failed to transfer all tokens ${tokenAddress}`); + } + } +} + +/// This is used to transfer tokens from the sharedBridge. +/// We're keeping this as we will have another migration of tokens, but it is not used atm. +export async function transferTokens(deployer: Deployer, token: string) { + const eraChainId = "324"; + const sharedBridge = deployer.defaultSharedBridge(deployer.deployWallet); + const tx = await sharedBridge.safeTransferFundsFromLegacy( + token, + deployer.addresses.Bridges.ERC20BridgeProxy, + eraChainId, + "1000000", + { gasLimit: 25_000_000 } + ); + await tx.wait(); + console.log("Receipt", tx.hash); +} diff --git a/l1-contracts/scripts/upgrade-consistency-checker.ts b/l1-contracts/scripts/upgrade-consistency-checker.ts index 3972c8695..5da064a04 100644 --- a/l1-contracts/scripts/upgrade-consistency-checker.ts +++ b/l1-contracts/scripts/upgrade-consistency-checker.ts @@ -16,43 +16,43 @@ import { getCurrentFacetCutsForAdd } from "../src.ts/diamondCut"; // 2. Getter methods in STM. // List the contracts that should become the upgrade targets -const genesisUpgrade = "0xc6aB8b3b93f3E47fb4163eB9Dc7A61E1a5D86369"; -const validatorTimelockDeployTx = "0x420e0dddae4a1565fee430ecafa8f5ddbc3eebee2666d0c91f97a47bf054eeb4"; -const validatorTimelock = "0xc2d7a7Bd59a548249e64C1a587220c0E4F6F439E"; -const upgradeHyperchains = "0xb2963DDc6694a989B527AED0B1E19f9F0675AE4d"; +const genesisUpgrade = process.env.CONTRACTS_GENESIS_UPGRADE_ADDR!; +const validatorTimelockDeployTx = "0xde4ef2b77241b605acaa1658ff8815df0911bf81555a80c9cbdde42fbcaaea30"; +const validatorTimelock = process.env.CONTRACTS_VALIDATOR_TIMELOCK_ADDR!; +const upgradeHyperchains = process.env.CONTRACTS_HYPERCHAIN_UPGRADE_ADDR!; -const verifier = "0x9D6c59D9A234F585B367b4ba3C62e5Ec7A6179FD"; -const proxyAdmin = "0xf2c1d17441074FFb18E9A918db81A17dB1752146"; +const verifier = process.env.CONTRACTS_VERIFIER_ADDR!; +const proxyAdmin = process.env.CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR!; -const bridgeHubImpl = "0xF9D2E98Ed518eC6Daac0579a9707d83da55D5f89"; -const bridgeHub = "0x5B5c82f4Da996e118B127880492a23391376F65c"; +const bridgeHubImpl = process.env.CONTRACTS_BRIDGEHUB_IMPL_ADDR!; +const bridgeHub = process.env.CONTRACTS_BRIDGEHUB_PROXY_ADDR!; -const executorFacet = "0x1a451d9bFBd176321966e9bc540596Ca9d39B4B1"; -const adminFacet = "0x342a09385E9BAD4AD32a6220765A6c333552e565"; -const mailboxFacetDeployTx = "0x2fa6af6e9317089be2734ffae73771c8099382d390d4edbb6c35e2db7f73b152"; -const mailboxFacet = "0x7814399116C17F2750Ca99cBFD2b75bA9a0793d7"; -const gettersFacet = "0x345c6ca2F3E08445614f4299001418F125AD330a"; +const executorFacet = process.env.CONTRACTS_EXECUTOR_FACET_ADDR!; +const adminFacet = process.env.CONTRACTS_ADMIN_FACET_ADDR!; +const mailboxFacetDeployTx = "0x995b23564b30f1551a9705313128e282591b38a1fc9c981d3251a929b190780d"; +const mailboxFacet = process.env.CONTRACTS_MAILBOX_FACET_ADDR!; +const gettersFacet = process.env.CONTRACTS_GETTERS_FACET_ADDR!; -const diamondInit = "0x05D865AE297d236Bc5C7988328d02A00b3D38a4F"; +const diamondInit = process.env.CONTRACTS_DIAMOND_INIT_ADDR!; -const stmImplDeployTx = "0x7a077accd4ee39d14b6c23ef31ece4a84c87aff41cd64fd4d2ac23a3885dd4f8"; -const stmImpl = "0x3060D61538fC91B6580e34C5b5D09651CBB9c609"; -const stmDeployTx = "0x30138b826e8f8f855e7fe9e6153d49376b53bce71c34cb2a78e186b12156c966"; -const stm = "0x280372beAAf440C52a2ed893daa14CDACc0422b8"; +const stmImplDeployTx = "0xe01c0bb497017a25c92bfc712e370e8f900554b107fe0b6022976d05c349f2b6"; +const stmImpl = process.env.CONTRACTS_STATE_TRANSITION_IMPL_ADDR!; +const stmDeployTx = "0x514bbf46d227eee8567825bf5c8ee1855aa8a1916f7fee7b191e2e3d5ecba849"; +const stm = process.env.CONTRACTS_STATE_TRANSITION_PROXY_ADDR!; -const sharedBridgeImplDeployTx = "0xd24d38cab0beb62f6de9a83cd0a5d7e339e985ba84ac6ef07a336efd79ae333a"; -const sharedBridgeImpl = "0x3819200C978d8A589a1e28A2e8fEb9a0CAD700F7"; -const sharedBridgeProxy = "0x241F19eA8CcD04515b309f1C9953A322F51891FC"; +const sharedBridgeImplDeployTx = "0x074204db79298c2f6beccae881c2ad7321c331e97fb4bd93adce2eb23bf17a17"; +const sharedBridgeImpl = process.env.CONTRACTS_L1_SHARED_BRIDGE_IMPL_ADDR!; +const sharedBridgeProxy = process.env.CONTRACTS_L1_SHARED_BRIDGE_PROXY_ADDR!; -const legacyBridgeImplDeployTx = "0xd8cca5843318ca176afd1075ca6fbb941837a641324300d3719f9189e49fd62c"; -const legacyBridgeImpl = "0xbf3d4109D65A66c629D1999fb630bE2eE16d7038"; +const legacyBridgeImplDeployTx = "0x234da786f098fa2e44b9abaf41b7045b4a25570e1a34fd01a101d23570e84d61"; +const legacyBridgeImpl = process.env.CONTRACTS_L1_ERC20_BRIDGE_IMPL_ADDR!; const expectedL1WethAddress = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"; const initialOwner = "0x71d84c3404a6ae258E6471d4934B96a2033F9438"; -const expectedOwner = "0x71d84c3404a6ae258E6471d4934B96a2033F9438"; -const expectedDelay = 0; -const eraChainId = 324; -const expectedSalt = "0x0000000000000000000000000000000000000000000000000000000000000000"; +const expectedOwner = "0x71d84c3404a6ae258E6471d4934B96a2033F9438"; //process.env.CONTRACTS_GOVERNANCE_ADDR!; +const expectedDelay = "75600"; +const eraChainId = process.env.CONTRACTS_ERA_CHAIN_ID!; +const expectedSalt = "0x0000000000000000000000000000000000000000000000000000000000000001"; const expectedHyperchainAddr = "0x32400084c286cf3e17e7b677ea9583e60a000324"; const maxNumberOfHyperchains = 100; const expectedStoredBatchHashZero = "0x1574fa776dec8da2071e5f20d71840bfcbd82c2bca9ad68680edfedde1710bc4"; @@ -60,16 +60,17 @@ const expectedL2BridgeAddress = "0x11f943b2c77b743AB90f4A0Ae7d5A4e7FCA3E102"; const expectedL1LegacyBridge = "0x57891966931Eb4Bb6FB81430E6cE0A03AAbDe063"; const expectedGenesisBatchCommitment = "0x2d00e5f8d77afcebf58a6b82ae56ba967566fe7dfbcb6760319fb0d215d18ffd"; const expectedIndexRepeatedStorageChanges = BigNumber.from(54); -const expectedProtocolVersion = 24; +const expectedProtocolVersion = BigNumber.from(2).pow(32).mul(24); + const expectedGenesisRoot = "0xabdb766b18a479a5c783a4b80e12686bc8ea3cc2d8a3050491b701d72370ebb5"; const expectedRecursionNodeLevelVkHash = "0xf520cd5b37e74e19fdb369c8d676a04dce8a19457497ac6686d2bb95d94109c8"; -const expectedRecursionLeafLevelVkHash = "0x435202d277dd06ef3c64ddd99fda043fc27c2bd8b7c66882966840202c27f4f6"; +const expectedRecursionLeafLevelVkHash = "0xf9664f4324c1400fa5c3822d667f30e873f53f1b8033180cd15fe41c1e2355c6"; const expectedRecursionCircuitsSetVksHash = "0x0000000000000000000000000000000000000000000000000000000000000000"; const expectedBootloaderHash = "0x010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e"; const expectedDefaultAccountHash = "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32"; -const validatorOne = "0x0D3250c3D5FAcb74Ac15834096397a3Ef790ec99"; -const validatorTwo = "0x3527439923a63F8C13CF72b8Fe80a77f6e572092"; +const validatorOne = process.env.ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR!; +const validatorTwo = process.env.ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR!; const l1Provider = new ethers.providers.JsonRpcProvider(web3Url()); @@ -102,7 +103,7 @@ async function extractInitCode(data: string) { const initCode = iface.parseTransaction({ data }).args._initCode; const salt = iface.parseTransaction({ data }).args._salt; if (salt !== expectedSalt) { - throw new Error("Salt is not correct"); + throw new Error(`Salt is not correct ${salt}`); } return initCode; @@ -135,30 +136,30 @@ async function extractProxyInitializationData(contract: ethers.Contract, data: s if (usedValidatorTimelock.toLowerCase() !== validatorTimelock.toLowerCase()) { throw new Error("Validator timelock is not correct"); } - const usedGenesisUpgrade = initializeData.genesisUpgrade; + const usedGenesisUpgrade = initializeData.chainCreationParams.genesisUpgrade; if (usedGenesisUpgrade.toLowerCase() !== genesisUpgrade.toLowerCase()) { throw new Error("Genesis upgrade is not correct"); } - const usedGenesisBatchHash = initializeData.genesisBatchHash; + const usedGenesisBatchHash = initializeData.chainCreationParams.genesisBatchHash; if (usedGenesisBatchHash.toLowerCase() !== expectedGenesisRoot.toLowerCase()) { throw new Error("Genesis batch hash is not correct"); } - const usedGenesisIndexRepeatedStorageChanges = initializeData.genesisIndexRepeatedStorageChanges; + const usedGenesisIndexRepeatedStorageChanges = initializeData.chainCreationParams.genesisIndexRepeatedStorageChanges; if (!usedGenesisIndexRepeatedStorageChanges.eq(expectedIndexRepeatedStorageChanges)) { throw new Error("Genesis index repeated storage changes is not correct"); } - const usedGenesisBatchCommitment = initializeData.genesisBatchCommitment; + const usedGenesisBatchCommitment = initializeData.chainCreationParams.genesisBatchCommitment; if (usedGenesisBatchCommitment.toLowerCase() !== expectedGenesisBatchCommitment.toLowerCase()) { throw new Error("Genesis batch commitment is not correct"); } const usedProtocolVersion = initializeData.protocolVersion; if (!usedProtocolVersion.eq(expectedProtocolVersion)) { - throw new Error("Protocol version is not correct"); + throw new Error(`Protocol version is not correct ${usedProtocolVersion}`); } - const diamondCut = initializeData.diamondCut; + const diamondCut = initializeData.chainCreationParams.diamondCut; if (diamondCut.initAddress.toLowerCase() !== diamondInit.toLowerCase()) { throw new Error("Diamond init address is not correct"); @@ -315,7 +316,7 @@ async function checkBridgehub() { const owner = await contract.owner(); if (owner.toLowerCase() != expectedOwner.toLowerCase()) { - throw new Error("ValidatorTimelock owner is not correct"); + throw new Error("Bridgehub owner is not correct"); } const baseToken = await contract.baseToken(eraChainId); @@ -444,7 +445,7 @@ async function checkLegacyBridge() { await checkCorrectInitCode(legacyBridgeImplDeployTx, contract, artifact.bytecode, [sharedBridgeProxy]); - console.log("L1 shared bridge impl correct!"); + console.log("L1 legacy bridge impl correct!"); } async function checkProxyAdmin() { @@ -476,7 +477,7 @@ async function main() { await checkIdenticalBytecode(gettersFacet, "GettersFacet"); await checkIdenticalBytecode(adminFacet, "AdminFacet"); await checkIdenticalBytecode(bridgeHubImpl, "Bridgehub"); - await checkIdenticalBytecode(verifier, eraChainId == 324 ? "Verifier" : "TestnetVerifier"); + await checkIdenticalBytecode(verifier, eraChainId == "324" ? "Verifier" : "TestnetVerifier"); await checkIdenticalBytecode(diamondInit, "DiamondInit"); await checkMailbox(); diff --git a/l1-contracts/scripts/verify.ts b/l1-contracts/scripts/verify.ts index 82e17283b..e1726a5d6 100644 --- a/l1-contracts/scripts/verify.ts +++ b/l1-contracts/scripts/verify.ts @@ -1,7 +1,7 @@ // hardhat import should be the first import in the file import * as hardhat from "hardhat"; import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; -import { getNumberFromEnv, getHashFromEnv, getAddressFromEnv, ethTestConfig } from "../src.ts/utils"; +import { ethTestConfig, getNumberFromEnv, getHashFromEnv, getAddressFromEnv } from "../src.ts/utils"; import { Interface } from "ethers/lib/utils"; import { Deployer } from "../src.ts/deploy"; @@ -11,14 +11,21 @@ import { getTokens } from "../src.ts/deploy-token"; const provider = web3Provider(); -// eslint-disable-next-line @typescript-eslint/no-explicit-any -function verifyPromise(address: string, constructorArguments?: Array, libraries?: object): Promise { +function verifyPromise( + address: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + constructorArguments?: Array, + libraries?: object, + contract?: string + // eslint-disable-next-line @typescript-eslint/no-explicit-any +): Promise { return new Promise((resolve, reject) => { hardhat .run("verify:verify", { address, constructorArguments, libraries, + contract, }) .then(() => resolve(`Successfully verified ${address}`)) .catch((e) => reject(`Failed to verify ${address}\nError: ${e.message}`)); @@ -72,10 +79,12 @@ async function main() { const promise2 = verifyPromise(addresses.ValidatorTimeLock, [deployWalletAddress, executionDelay, eraChainId]); promises.push(promise2); - console.log("CONTRACTS_HYPERCHAIN_UPGRADE_ADDR", process.env.CONTRACTS_HYPERCHAIN_UPGRADE_ADDR); - const promise3 = verifyPromise(process.env.CONTRACTS_HYPERCHAIN_UPGRADE_ADDR); + const promise3 = verifyPromise(process.env.CONTRACTS_DEFAULT_UPGRADE_ADDR); promises.push(promise3); + const promise4 = verifyPromise(process.env.CONTRACTS_HYPERCHAIN_UPGRADE_ADDR); + promises.push(promise4); + const promise5 = verifyPromise(addresses.TransparentProxyAdmin); promises.push(promise5); @@ -127,11 +136,13 @@ async function main() { { owner: addresses.Governance, validatorTimelock: addresses.ValidatorTimeLock, - genesisUpgrade: addresses.StateTransition.GenesisUpgrade, - genesisBatchHash, - genesisIndexRepeatedStorageChanges: genesisRollupLeafIndex, - genesisBatchCommitment, - diamondCut, + chainCreationParams: { + genesisUpgrade: addresses.StateTransition.GenesisUpgrade, + genesisBatchHash, + genesisIndexRepeatedStorageChanges: genesisRollupLeafIndex, + genesisBatchCommitment, + diamondCut, + }, protocolVersion, }, ]); @@ -144,8 +155,12 @@ async function main() { promises.push(promise9); // bridges - // Note: do this manually and pass in to verify:verify the following: contract:"contracts/bridge/L1ERC20Bridge.sol:L1ERC20Bridge" - const promise10 = verifyPromise(addresses.Bridges.ERC20BridgeImplementation, [addresses.Bridges.SharedBridgeProxy]); + const promise10 = verifyPromise( + addresses.Bridges.ERC20BridgeImplementation, + [addresses.Bridges.SharedBridgeProxy], + undefined, + "contracts/bridge/L1ERC20Bridge.sol:L1ERC20Bridge" + ); promises.push(promise10); const eraDiamondProxy = getAddressFromEnv("CONTRACTS_ERA_DIAMOND_PROXY_ADDR"); diff --git a/l1-contracts/src.ts/hyperchain-upgrade.ts b/l1-contracts/src.ts/hyperchain-upgrade.ts deleted file mode 100644 index 56e8573a9..000000000 --- a/l1-contracts/src.ts/hyperchain-upgrade.ts +++ /dev/null @@ -1,348 +0,0 @@ -// hardhat import should be the first import in the file -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as hardhat from "hardhat"; -import * as path from "path"; - -import "@nomiclabs/hardhat-ethers"; - -import type { BigNumberish } from "ethers"; -import { ethers } from "ethers"; - -import type { Deployer } from "./deploy"; - -import type { ITransparentUpgradeableProxy } from "../typechain/ITransparentUpgradeableProxy"; -import { ITransparentUpgradeableProxyFactory } from "../typechain/ITransparentUpgradeableProxyFactory"; -import { StateTransitionManagerFactory, L1SharedBridgeFactory, ValidatorTimelockFactory } from "../typechain"; - -import { Interface } from "ethers/lib/utils"; -import { ADDRESS_ONE, getAddressFromEnv, readBytecode } from "./utils"; - -import { - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - priorityTxMaxGasLimit, - applyL1ToL2Alias, - hashL2Bytecode, -} from "../../l2-contracts/src/utils"; -import { ETH_ADDRESS_IN_CONTRACTS } from "zksync-ethers/build/src/utils"; - -const contractArtifactsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/l2-contracts/artifacts-zk/"); -const openzeppelinBeaconProxyArtifactsPath = path.join(contractArtifactsPath, "@openzeppelin/contracts/proxy/beacon"); -export const BEACON_PROXY_BYTECODE = readBytecode(openzeppelinBeaconProxyArtifactsPath, "BeaconProxy"); - -/// In the hardhat tests we do the upgrade all at once. -/// On localhost/stage/.. we will call the components and send the calldata to Governance manually -export async function upgradeToHyperchains( - deployer: Deployer, - gasPrice: BigNumberish, - printFileName?: string, - create2Salt?: string, - nonce?: number -) { - await upgradeToHyperchains1(deployer, gasPrice, create2Salt, nonce); - await upgradeToHyperchains2(deployer, gasPrice, printFileName); - await upgradeToHyperchains3(deployer, printFileName); -} - -/// this just deploys the contract ( we do it here instead of using the protocol-upgrade tool, since we are deploying more than just facets, the Bridgehub, STM, etc.) -export async function upgradeToHyperchains1( - deployer: Deployer, - gasPrice: BigNumberish, - create2Salt?: string, - nonce?: number -) { - /// we manually override the governance address so that we can set the variables - deployer.addresses.Governance = deployer.deployWallet.address; - // does not interfere with existing system - // note other contract were already deployed - if (deployer.verbose) { - console.log("Deploying new contracts"); - } - await deployNewContracts(deployer, gasPrice, create2Salt, nonce); - - // register Era in Bridgehub, STM - const stateTransitionManager = deployer.stateTransitionManagerContract(deployer.deployWallet); - - if (deployer.verbose) { - console.log("Registering Era in stateTransitionManager"); - } - const txRegister = await stateTransitionManager.registerAlreadyDeployedHyperchain( - deployer.chainId, - deployer.addresses.StateTransition.DiamondProxy - ); - - await txRegister.wait(); - - const bridgehub = deployer.bridgehubContract(deployer.deployWallet); - if (deployer.verbose) { - console.log("Registering Era in Bridgehub"); - } - - const tx = await bridgehub.createNewChain( - deployer.chainId, - deployer.addresses.StateTransition.StateTransitionProxy, - ETH_ADDRESS_IN_CONTRACTS, - ethers.constants.HashZero, - deployer.addresses.Governance, - ethers.constants.HashZero, - { gasPrice } - ); - await tx.wait(); - - if (deployer.verbose) { - console.log("Setting L1Erc20Bridge data in shared bridge"); - } - const sharedBridge = L1SharedBridgeFactory.connect( - deployer.addresses.Bridges.SharedBridgeProxy, - deployer.deployWallet - ); - const tx1 = await sharedBridge.setL1Erc20Bridge(deployer.addresses.Bridges.ERC20BridgeProxy); - await tx1.wait(); - - if (deployer.verbose) { - console.log("Initializing l2 bridge in shared bridge", deployer.addresses.Bridges.L2SharedBridgeProxy); - } - const tx2 = await sharedBridge.initializeChainGovernance( - deployer.chainId, - deployer.addresses.Bridges.L2SharedBridgeProxy - ); - await tx2.wait(); - - if (deployer.verbose) { - console.log("Setting Validator timelock in STM"); - } - const stm = StateTransitionManagerFactory.connect( - deployer.addresses.StateTransition.StateTransitionProxy, - deployer.deployWallet - ); - const tx3 = await stm.setValidatorTimelock(deployer.addresses.ValidatorTimeLock); - await tx3.wait(); - - if (deployer.verbose) { - console.log("Setting dummy STM in Validator timelock"); - } - - const ethTxOptions: ethers.providers.TransactionRequest = {}; - ethTxOptions.gasLimit ??= 10_000_000; - const migrationSTMAddress = await deployer.deployViaCreate2( - "MigrationSTM", - [deployer.deployWallet.address], - create2Salt, - ethTxOptions - ); - console.log("Migration STM address", migrationSTMAddress); - - const validatorTimelock = ValidatorTimelockFactory.connect( - deployer.addresses.ValidatorTimeLock, - deployer.deployWallet - ); - const tx4 = await validatorTimelock.setStateTransitionManager(migrationSTMAddress); - await tx4.wait(); - - const validatorOneAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR"); - const validatorTwoAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR"); - const tx5 = await validatorTimelock.addValidator(deployer.chainId, validatorOneAddress, { gasPrice }); - const receipt5 = await tx5.wait(); - const tx6 = await validatorTimelock.addValidator(deployer.chainId, validatorTwoAddress, { gasPrice }); - const receipt6 = await tx6.wait(); - - const tx7 = await validatorTimelock.setStateTransitionManager( - deployer.addresses.StateTransition.StateTransitionProxy - ); - const receipt7 = await tx7.wait(); - if (deployer.verbose) { - console.log( - "Validators added, stm transferred back", - receipt5.transactionHash, - receipt6.transactionHash, - receipt7.transactionHash - ); - } -} - -// this should be called after the diamond cut has been proposed and executed -// this simulates the main part of the upgrade, registration into the Bridgehub and STM, and the bridge upgrade -export async function upgradeToHyperchains2(deployer: Deployer, gasPrice: BigNumberish, printFileName?: string) { - // upgrading system contracts on Era only adds setChainId in systemContext, does not interfere with anything - // we first upgrade the DiamondProxy. the Mailbox is backwards compatible, so the L1ERC20 and other bridges should still work. - // this requires the sharedBridge to be deployed. - // In theory, the L1SharedBridge deposits should be disabled until the L2Bridge is upgraded. - // However, without the Portal, UI being upgraded it does not matter (nobody will call it, they will call the legacy bridge) - - // the L2Bridge and L1ERC20Bridge should be updated relatively in sync, as new messages might not be parsed correctly by the old bridge. - // however new bridges can parse old messages. L1->L2 messages are faster, so L2 side is upgraded first. - if (deployer.verbose) { - console.log("Upgrading L2 bridge"); - } - await upgradeL2Bridge(deployer, gasPrice, printFileName); - - if (deployer.verbose) { - console.log("Transferring L1 ERC20 bridge to proxy admin"); - } - await transferERC20BridgeToProxyAdmin(deployer, gasPrice, printFileName); - - if (process.env.CHAIN_ETH_NETWORK != "hardhat") { - if (deployer.verbose) { - console.log("Upgrading L1 ERC20 bridge"); - } - await upgradeL1ERC20Bridge(deployer, gasPrice, printFileName); - } -} - -// This sets the Shared Bridge parameters. We need to do this separately, as these params will be known after the upgrade -export async function upgradeToHyperchains3(deployer: Deployer, printFileName?: string) { - const sharedBridge = L1SharedBridgeFactory.connect( - deployer.addresses.Bridges.SharedBridgeProxy, - deployer.deployWallet - ); - const data2 = sharedBridge.interface.encodeFunctionData("setEraPostDiamondUpgradeFirstBatch", [ - process.env.CONTRACTS_ERA_POST_DIAMOND_UPGRADE_FIRST_BATCH, - ]); - const data3 = sharedBridge.interface.encodeFunctionData("setEraPostLegacyBridgeUpgradeFirstBatch", [ - process.env.CONTRACTS_ERA_POST_LEGACY_BRIDGE_UPGRADE_FIRST_BATCH, - ]); - const data4 = sharedBridge.interface.encodeFunctionData("setEraLegacyBridgeLastDepositTime", [ - process.env.CONTRACTS_ERA_LEGACY_UPGRADE_LAST_DEPOSIT_BATCH, - process.env.CONTRACTS_ERA_LEGACY_UPGRADE_LAST_DEPOSIT_TX_NUMBER, - ]); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data2, printFileName); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data3, printFileName); - await deployer.executeUpgrade(deployer.addresses.Bridges.SharedBridgeProxy, 0, data4, printFileName); -} - -async function deployNewContracts(deployer: Deployer, gasPrice: BigNumberish, create2Salt?: string, nonce?: number) { - nonce = nonce || (await deployer.deployWallet.getTransactionCount()); - create2Salt = create2Salt || ethers.utils.hexlify(ethers.utils.randomBytes(32)); - - // Create2 factory already deployed - - await deployer.deployGenesisUpgrade(create2Salt, { - gasPrice, - nonce, - }); - - await deployer.deployValidatorTimelock(create2Salt, { gasPrice }); - - await deployer.deployHyperchainsUpgrade(create2Salt, { - gasPrice, - }); - await deployer.deployVerifier(create2Salt, { gasPrice }); - - if (process.env.CHAIN_ETH_NETWORK != "hardhat") { - await deployer.deployTransparentProxyAdmin(create2Salt, { gasPrice }); - } - // console.log("Proxy admin is already deployed (not via Create2)", deployer.addresses.TransparentProxyAdmin); - // console.log("CONTRACTS_TRANSPARENT_PROXY_ADMIN_ADDR=0xf2c1d17441074FFb18E9A918db81A17dB1752146"); - await deployer.deployBridgehubContract(create2Salt, gasPrice); - - await deployer.deployStateTransitionManagerContract(create2Salt, [], gasPrice); - await deployer.setStateTransitionManagerInValidatorTimelock({ gasPrice }); - - await deployer.deploySharedBridgeContracts(create2Salt, gasPrice); - await deployer.deployERC20BridgeImplementation(create2Salt, { gasPrice }); -} - -async function upgradeL2Bridge(deployer: Deployer, gasPrice: BigNumberish, printFileName?: string) { - const l2BridgeImplementationAddress = process.env.CONTRACTS_L2_SHARED_BRIDGE_IMPL_ADDR!; - - // upgrade from L1 governance. This has to come from governacne on L1. - const l2BridgeAbi = ["function initialize(address, address, bytes32, address)"]; - const l2BridgeContract = new ethers.Contract(ADDRESS_ONE, l2BridgeAbi, deployer.deployWallet); - const l2Bridge = l2BridgeContract.interface; //L2_SHARED_BRIDGE_INTERFACE; - - const l2BridgeCalldata = l2Bridge.encodeFunctionData("initialize", [ - deployer.addresses.Bridges.SharedBridgeProxy, - deployer.addresses.Bridges.ERC20BridgeProxy, - hashL2Bytecode(BEACON_PROXY_BYTECODE), - applyL1ToL2Alias(deployer.addresses.Governance), - ]); - - const bridgeProxy: ITransparentUpgradeableProxy = ITransparentUpgradeableProxyFactory.connect( - ADDRESS_ONE, - deployer.deployWallet - ); // we just need the interface, so wrong address - - const l2ProxyCalldata = bridgeProxy.interface.encodeFunctionData("upgradeToAndCall", [ - l2BridgeImplementationAddress, - l2BridgeCalldata, - ]); - // console.log("kl todo", l2BridgeImplementationAddress, l2BridgeCalldata) - const factoryDeps = []; - const requiredValueForL2Tx = await deployer - .bridgehubContract(deployer.deployWallet) - .l2TransactionBaseCost(deployer.chainId, gasPrice, priorityTxMaxGasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); //"1000000000000000000"; - - const mailboxFacet = new Interface(hardhat.artifacts.readArtifactSync("MailboxFacet").abi); - const mailboxCalldata = mailboxFacet.encodeFunctionData("requestL2Transaction", [ - process.env.CONTRACTS_L2_ERC20_BRIDGE_ADDR, - 0, - l2ProxyCalldata, - priorityTxMaxGasLimit, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - factoryDeps, - deployer.deployWallet.address, - ]); - - await deployer.executeUpgrade( - deployer.addresses.StateTransition.DiamondProxy, - requiredValueForL2Tx, - mailboxCalldata, - printFileName - ); -} - -async function upgradeL1ERC20Bridge(deployer: Deployer, gasPrice: BigNumberish, printFileName?: string) { - if (process.env.CHAIN_ETH_NETWORK != "hardhat") { - // we need to wait here for a new block - await new Promise((resolve) => setTimeout(resolve, 5000)); - // upgrade ERC20. - const proxyAdminAbi = ["function upgrade(address, address)"]; - const proxyAdmin = new ethers.Contract( - deployer.addresses.TransparentProxyAdmin, - proxyAdminAbi, - deployer.deployWallet - ); - const data1 = await proxyAdmin.interface.encodeFunctionData("upgrade", [ - deployer.addresses.Bridges.ERC20BridgeProxy, - deployer.addresses.Bridges.ERC20BridgeImplementation, - ]); - - await deployer.executeUpgrade(deployer.addresses.TransparentProxyAdmin, 0, data1, printFileName); - - if (deployer.verbose) { - console.log("L1ERC20Bridge upgrade sent"); - } - } -} - -export async function transferERC20BridgeToProxyAdmin( - deployer: Deployer, - gasPrice: BigNumberish, - printFileName?: string -) { - const bridgeProxy: ITransparentUpgradeableProxy = ITransparentUpgradeableProxyFactory.connect( - deployer.addresses.Bridges.ERC20BridgeProxy, - deployer.deployWallet - ); - const data1 = await bridgeProxy.interface.encodeFunctionData("changeAdmin", [ - deployer.addresses.TransparentProxyAdmin, - ]); - - await deployer.executeUpgrade(deployer.addresses.Bridges.ERC20BridgeProxy, 0, data1, printFileName); - - if (deployer.verbose) { - console.log("ERC20Bridge ownership transfer sent"); - } -} - -export async function transferTokens(deployer: Deployer, token: string) { - const sharedBridge = deployer.defaultSharedBridge(deployer.deployWallet); - const tx = await sharedBridge.safeTransferFundsFromLegacy( - token, - deployer.addresses.Bridges.ERC20BridgeProxy, - "324", - "300000", - { gasLimit: 25_000_000 } - ); - await tx.wait(); - console.log("Receipt", tx.hash); -} diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 6f0375390..2f5907461 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -35,13 +35,9 @@ "clean": "hardhat clean", "test": "hardhat test", "verify": "hardhat run src/verify.ts", - "deploy-testnet-paymaster": "ts-node src/deploy-testnet-paymaster.ts", "deploy-testnet-paymaster-through-l1": "ts-node src/deploy-testnet-paymaster-through-l1.ts", - "deploy-force-deploy-upgrader": "ts-node src/deploy-force-deploy-upgrader.ts", "deploy-force-deploy-upgrader-through-l1": "ts-node src/deploy-force-deploy-upgrader-through-l1.ts", - "deploy-shared-bridge-on-l2": "ts-node scripts/deploy-shared-bridge-on-l2.ts", "deploy-shared-bridge-on-l2-through-l1": "ts-node src/deploy-shared-bridge-on-l2-through-l1.ts", - "deploy-shared-bridge-l2-implementation": "ts-node src/deploy-shared-bridge-implementation-legacy.ts", "publish-bridge-preimages": "ts-node src/publish-bridge-preimages.ts", "deploy-l2-weth": "ts-node src/deploy-l2-weth.ts", "upgrade-bridge-contracts": "ts-node src/upgrade-bridge-impl.ts", diff --git a/l2-contracts/src/deploy-force-deploy-upgrader.ts b/l2-contracts/src/deploy-force-deploy-upgrader.ts deleted file mode 100644 index 8545dc44d..000000000 --- a/l2-contracts/src/deploy-force-deploy-upgrader.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { Command } from "commander"; -import { ethers, Wallet } from "ethers"; -import { computeL2Create2Address, create2DeployFromL1, provider, priorityTxMaxGasLimit } from "./utils"; -import { ethTestConfig } from "./deploy-utils"; - -import * as hre from "hardhat"; - -// Script to deploy the force deploy upgrader contract and output its address. -// Note, that this script expects that the L2 contracts have been compiled PRIOR -// to running this script. -async function main() { - const program = new Command(); - - program - .version("0.1.0") - .name("deploy-force-deploy-upgrader") - .option("--chain-id ") - .description("Deploys the force deploy upgrader contract to L2"); - - program.option("--private-key ").action(async (cmd) => { - const chainId: string = cmd.chainId ? cmd.chainId : process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID; - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const forceDeployUpgraderBytecode = hre.artifacts.readArtifactSync("ForceDeployUpgrader").bytecode; - const create2Salt = ethers.constants.HashZero; - const forceDeployUpgraderAddress = computeL2Create2Address( - deployWallet, - forceDeployUpgraderBytecode, - "0x", - create2Salt - ); - - // TODO: request from API how many L2 gas needs for the transaction. - await create2DeployFromL1( - chainId, - deployWallet, - forceDeployUpgraderBytecode, - "0x", - create2Salt, - priorityTxMaxGasLimit - ); - - console.log(`CONTRACTS_L2_DEFAULT_UPGRADE_ADDR=${forceDeployUpgraderAddress}`); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts b/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts deleted file mode 100644 index 84a7df17a..000000000 --- a/l2-contracts/src/deploy-shared-bridge-implementation-legacy.ts +++ /dev/null @@ -1,206 +0,0 @@ -import { Command } from "commander"; -import { artifacts } from "hardhat"; -import type { BigNumberish } from "ethers"; -import { ethers, Wallet } from "ethers"; -import { formatUnits, Interface, parseUnits, defaultAbiCoder } from "ethers/lib/utils"; -import { - computeL2Create2Address, - provider, - priorityTxMaxGasLimit, - hashL2Bytecode, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, -} from "./utils"; - -import { ethTestConfig } from "./deploy-utils"; - -import { Deployer } from "../../l1-contracts/src.ts/deploy"; -import { GAS_MULTIPLIER } from "../../l1-contracts/scripts/utils"; -import { deployedAddressesFromEnv } from "../../l1-contracts/src.ts/deploy-utils"; - -import * as hre from "hardhat"; -import { IZkSyncHyperchainFactory } from "../../l1-contracts/typechain/IZkSyncHyperchainFactory"; - -const DEPLOYER_SYSTEM_CONTRACT_ADDRESS = "0x0000000000000000000000000000000000008006"; - -const L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE = hre.artifacts.readArtifactSync("L2SharedBridge").bytecode; - -async function create2DeployFromL1( - chainId: ethers.BigNumberish, - wallet: ethers.Wallet, - bytecode: ethers.BytesLike, - constructor: ethers.BytesLike, - create2Salt: ethers.BytesLike, - l2GasLimit: ethers.BigNumberish, - gasPrice?: ethers.BigNumberish, - extraFactoryDeps?: ethers.BytesLike[] -) { - const hyperchainAddress = deployedAddressesFromEnv().StateTransition.DiamondProxy; - const hyperchain = IZkSyncHyperchainFactory.connect(hyperchainAddress, wallet); - - const deployerSystemContracts = new Interface(artifacts.readArtifactSync("IContractDeployer").abi); - const bytecodeHash = hashL2Bytecode(bytecode); - const calldata = deployerSystemContracts.encodeFunctionData("create2", [create2Salt, bytecodeHash, constructor]); - gasPrice ??= await wallet.provider.getGasPrice(); - const expectedCost = await hyperchain.l2TransactionBaseCost(gasPrice, l2GasLimit, REQUIRED_L2_GAS_PRICE_PER_PUBDATA); - - const factoryDeps = extraFactoryDeps ? [bytecode, ...extraFactoryDeps] : [bytecode]; - return await hyperchain.requestL2Transaction( - DEPLOYER_SYSTEM_CONTRACT_ADDRESS, - 0, - calldata, - l2GasLimit, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - factoryDeps, - wallet.address, - { value: expectedCost.mul(5), gasPrice } - ); -} - -export async function publishBytecodeFromL1( - wallet: ethers.Wallet, - factoryDeps: ethers.BytesLike[], - gasPrice?: ethers.BigNumberish -) { - const hyperchainAddress = deployedAddressesFromEnv().StateTransition.DiamondProxy; - const hyperchain = IZkSyncHyperchainFactory.connect(hyperchainAddress, wallet); - - const requiredValueToPublishBytecodes = await hyperchain.l2TransactionBaseCost( - gasPrice, - priorityTxMaxGasLimit, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA - ); - - const nonce = await wallet.getTransactionCount(); - const tx1 = await hyperchain.requestL2Transaction( - ethers.constants.AddressZero, - 0, - "0x", - priorityTxMaxGasLimit, - REQUIRED_L2_GAS_PRICE_PER_PUBDATA, - factoryDeps, - wallet.address, - { gasPrice, nonce, value: requiredValueToPublishBytecodes } - ); - await tx1.wait(); -} - -export async function publishL2SharedBridgeDependencyBytecodesOnL2( - deployer: Deployer, - chainId: string, - gasPrice: BigNumberish -) { - /// #################################################################################################################### - - if (deployer.verbose) { - console.log("Providing necessary L2 bytecodes"); - } - - const L2_STANDARD_ERC20_PROXY_FACTORY_BYTECODE = hre.artifacts.readArtifactSync("UpgradeableBeacon").bytecode; - const L2_STANDARD_ERC20_IMPLEMENTATION_BYTECODE = hre.artifacts.readArtifactSync("L2StandardERC20").bytecode; - - await publishBytecodeFromL1( - deployer.deployWallet, - [L2_STANDARD_ERC20_PROXY_FACTORY_BYTECODE, L2_STANDARD_ERC20_IMPLEMENTATION_BYTECODE], - gasPrice - ); - - if (deployer.verbose) { - console.log("Bytecodes published on L2"); - } -} - -export async function deploySharedBridgeImplOnL2ThroughL1(deployer: Deployer, chainId: string, gasPrice: BigNumberish) { - if (deployer.verbose) { - console.log("Deploying L2SharedBridge Implementation"); - } - - if (!L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE) { - throw new Error("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE not found"); - } - if (deployer.verbose) { - console.log("L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE loaded"); - - console.log("Computing L2SharedBridge Implementation Address"); - } - const l2SharedBridgeImplAddress = computeL2Create2Address( - deployer.deployWallet, - L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [deployer.chainId]), - ethers.constants.HashZero - ); - deployer.addresses.Bridges.L2SharedBridgeImplementation = l2SharedBridgeImplAddress; - if (deployer.verbose) { - console.log(`L2SharedBridge Implementation Address: ${l2SharedBridgeImplAddress}`); - - console.log("Deploying L2SharedBridge Implementation"); - } - - /// L2StandardTokenProxy bytecode. We need this bytecode to be accessible on the L2, it is enough to add to factoryDeps - const L2_STANDARD_TOKEN_PROXY_BYTECODE = hre.artifacts.readArtifactSync("BeaconProxy").bytecode; - - // TODO: request from API how many L2 gas needs for the transaction. - const tx2 = await create2DeployFromL1( - chainId, - deployer.deployWallet, - L2_SHARED_BRIDGE_IMPLEMENTATION_BYTECODE, - defaultAbiCoder.encode(["uint256"], [deployer.chainId]), - ethers.constants.HashZero, - priorityTxMaxGasLimit, - gasPrice, - [L2_STANDARD_TOKEN_PROXY_BYTECODE] - ); - - await tx2.wait(); - if (deployer.verbose) { - console.log("Deployed L2SharedBridge Implementation"); - console.log(`CONTRACTS_L2_SHARED_BRIDGE_IMPL_ADDR=${l2SharedBridgeImplAddress}`); - } -} - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("deploy-shared-bridge-on-l2-through-l1"); - - program - .option("--private-key ") - .option("--chain-id ") - .option("--gas-price ") - .option("--nonce ") - .option("--erc20-bridge ") - .action(async (cmd) => { - const chainId: string = cmd.chainId ? cmd.chainId : process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID; - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/1" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const deployer = new Deployer({ - deployWallet, - ownerAddress: deployWallet.address, - verbose: true, - }); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployer.deployWallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - const gasPrice = cmd.gasPrice - ? parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); - console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - await publishL2SharedBridgeDependencyBytecodesOnL2(deployer, chainId, gasPrice); - await deploySharedBridgeImplOnL2ThroughL1(deployer, chainId, gasPrice); - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); diff --git a/l2-contracts/src/deploy-shared-bridge-on-l2.ts b/l2-contracts/src/deploy-shared-bridge-on-l2.ts deleted file mode 100644 index e1fed93d8..000000000 --- a/l2-contracts/src/deploy-shared-bridge-on-l2.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { Command } from "commander"; -import { Wallet } from "ethers"; -import { formatUnits, parseUnits } from "ethers/lib/utils"; -import { Deployer } from "../../l1-contracts/src.ts/deploy"; -import { GAS_MULTIPLIER } from "../../l1-contracts/scripts/utils"; -import { provider } from "./utils"; -import { ethTestConfig } from "./deploy-utils"; - -async function main() { - const program = new Command(); - - program.version("0.1.0").name("initialize-erc20-bridge-chain"); - - program - .option("--private-key ") - .option("--chain-id ") - .option("--gas-price ") - .option("--nonce ") - .option("--erc20-bridge ") - .action(async (cmd) => { - // const chainId: string = cmd.chainId ? cmd.chainId : process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID; - const deployWallet = cmd.privateKey - ? new Wallet(cmd.privateKey, provider) - : Wallet.fromMnemonic( - process.env.MNEMONIC ? process.env.MNEMONIC : ethTestConfig.mnemonic, - "m/44'/60'/0'/0/0" - ).connect(provider); - console.log(`Using deployer wallet: ${deployWallet.address}`); - - const gasPrice = cmd.gasPrice - ? parseUnits(cmd.gasPrice, "gwei") - : (await provider.getGasPrice()).mul(GAS_MULTIPLIER); - console.log(`Using gas price: ${formatUnits(gasPrice, "gwei")} gwei`); - - const nonce = cmd.nonce ? parseInt(cmd.nonce) : await deployWallet.getTransactionCount(); - console.log(`Using nonce: ${nonce}`); - - const deployer = new Deployer({ - deployWallet, - ownerAddress: deployWallet.address, - verbose: true, - }); - - deployer; - }); - - await program.parseAsync(process.argv); -} - -main() - .then(() => process.exit(0)) - .catch((err) => { - console.error("Error:", err); - process.exit(1); - }); From 311b82ed6d433f334c2240d1d698662f48407ee0 Mon Sep 17 00:00:00 2001 From: Bence Haromi <56651250+benceharomi@users.noreply.github.com> Date: Tue, 11 Jun 2024 18:11:47 +0200 Subject: [PATCH 59/60] chore: zksync-ethers 5.8.0-beta.5 (#387) Co-authored-by: Stanislav Breadless --- .../test-contracts/GasBoundCallerTester.sol | 4 +- gas-bound-caller/package.json | 9 +- gas-bound-caller/test/GasBoundCaller.spec.ts | 5 +- l1-contracts/package.json | 2 +- l1-contracts/scripts/display-governance.ts | 2 +- .../scripts/setup-legacy-bridge-era.ts | 2 +- l1-contracts/src.ts/deploy-test-process.ts | 2 +- .../test/unit_tests/l2-upgrade.test.spec.ts | 2 +- l1-contracts/test/unit_tests/utils.ts | 4 +- l2-contracts/package.json | 6 +- l2-contracts/src/update-l2-erc20-metadata.ts | 2 +- l2-contracts/src/upgrade-bridge-impl.ts | 4 +- l2-contracts/src/utils.ts | 6 +- l2-contracts/test/erc20.test.ts | 4 +- l2-contracts/test/weth.test.ts | 2 +- system-contracts/package.json | 9 +- system-contracts/scripts/calculate-hashes.ts | 2 +- system-contracts/scripts/deploy-preimages.ts | 6 +- system-contracts/scripts/utils.ts | 2 +- .../test/BootloaderUtilities.spec.ts | 2 +- system-contracts/test/CodeOracle.spec.ts | 2 +- system-contracts/test/Create2Factory.spec.ts | 2 +- system-contracts/test/DefaultAccount.spec.ts | 2 +- system-contracts/test/EventWriter.spec.ts | 2 +- system-contracts/test/L1Messenger.spec.ts | 4 +- system-contracts/test/L2BaseToken.spec.ts | 2 +- .../test/PubdataChunkPublisher.spec.ts | 2 +- yarn.lock | 239 ++++++++++++------ 28 files changed, 203 insertions(+), 129 deletions(-) diff --git a/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol b/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol index 8c1b790d6..1314bf0c0 100644 --- a/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol +++ b/gas-bound-caller/contracts/test-contracts/GasBoundCallerTester.sol @@ -57,9 +57,9 @@ contract GasBoundCallerTester is GasBoundCaller { } } - function testReturndataOverhead(uint256 len) external { + function testReturndataOverhead(uint256 _len, uint256 _gasForInner) external { uint256 gasbefore = gasleft(); - this.testReturndataOverheadInner(false, len); + this.testReturndataOverheadInner{gas: _gasForInner}(false, _len); lastRecordedGasLeft = gasbefore - gasleft(); } diff --git a/gas-bound-caller/package.json b/gas-bound-caller/package.json index de6220930..555c18d61 100644 --- a/gas-bound-caller/package.json +++ b/gas-bound-caller/package.json @@ -13,12 +13,11 @@ "eslint-plugin-prettier": "^5.0.1", "ethers": "^5.7.0", "fast-glob": "^3.3.2", - "hardhat": "^2.18.3", - "preprocess": "^3.2.0", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "hardhat": "=2.22.2", + "preprocess": "^3.2.0" }, "devDependencies": { - "@matterlabs/hardhat-zksync-chai-matchers": "^0.1.4", + "@matterlabs/hardhat-zksync-chai-matchers": "^0.2.0", "@matterlabs/hardhat-zksync-node": "^0.0.1-beta.7", "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.0", @@ -38,7 +37,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "zksync-ethers": "5.8.0-beta.5" }, "mocha": { "timeout": 240000, diff --git a/gas-bound-caller/test/GasBoundCaller.spec.ts b/gas-bound-caller/test/GasBoundCaller.spec.ts index 1a970f0fc..5b92e298f 100644 --- a/gas-bound-caller/test/GasBoundCaller.spec.ts +++ b/gas-bound-caller/test/GasBoundCaller.spec.ts @@ -39,15 +39,16 @@ describe("GasBoundCaller tests", function () { }); it("test returndata overhead", async () => { + // The tests' behavior depends on the amount of gas provided to its inner part, so we always provide 40kk await ( - await tester.testReturndataOverhead(10, { + await tester.testReturndataOverhead(10, 40_000_000, { gasLimit: 80_000_000, }) ).wait(); const smallBytecodeGas = await tester.lastRecordedGasLeft(); await ( - await tester.testReturndataOverhead(100000, { + await tester.testReturndataOverhead(100000, 40_000_000, { gasLimit: 80_000_000, }) ).wait(); diff --git a/l1-contracts/package.json b/l1-contracts/package.json index d30c93950..948b1cef9 100644 --- a/l1-contracts/package.json +++ b/l1-contracts/package.json @@ -50,7 +50,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "zksync-ethers": "5.8.0-beta.5" }, "scripts": { "build": "hardhat compile", diff --git a/l1-contracts/scripts/display-governance.ts b/l1-contracts/scripts/display-governance.ts index d6b4846f1..0593d580e 100644 --- a/l1-contracts/scripts/display-governance.ts +++ b/l1-contracts/scripts/display-governance.ts @@ -10,7 +10,7 @@ import { applyL1ToL2Alias, getAddressFromEnv } from "../src.ts/utils"; import * as fs from "fs"; import { UpgradeableBeaconFactory } from "../../l2-contracts/typechain/UpgradeableBeaconFactory"; -import { Provider } from "zksync-web3"; +import { Provider } from "zksync-ethers"; const l2SharedBridgeABI = JSON.parse( fs.readFileSync("../zksync/artifacts-zk/contracts/bridge/L2SharedBridge.sol/L2SharedBridge.json").toString() diff --git a/l1-contracts/scripts/setup-legacy-bridge-era.ts b/l1-contracts/scripts/setup-legacy-bridge-era.ts index ffea4ef2d..dde08b6f2 100644 --- a/l1-contracts/scripts/setup-legacy-bridge-era.ts +++ b/l1-contracts/scripts/setup-legacy-bridge-era.ts @@ -15,7 +15,7 @@ import { web3Provider, GAS_MULTIPLIER } from "./utils"; import { deployedAddressesFromEnv } from "../src.ts/deploy-utils"; import { ethTestConfig, getAddressFromEnv } from "../src.ts/utils"; import { hashL2Bytecode } from "../../l2-contracts/src/utils"; -import { Provider } from "zksync-web3"; +import { Provider } from "zksync-ethers"; import beaconProxy = require("../../l2-contracts/artifacts-zk/@openzeppelin/contracts/proxy/beacon/BeaconProxy.sol/BeaconProxy.json"); const provider = web3Provider(); diff --git a/l1-contracts/src.ts/deploy-test-process.ts b/l1-contracts/src.ts/deploy-test-process.ts index fe383e755..d1329d1eb 100644 --- a/l1-contracts/src.ts/deploy-test-process.ts +++ b/l1-contracts/src.ts/deploy-test-process.ts @@ -7,7 +7,7 @@ import * as ethers from "ethers"; import type { BigNumberish, Wallet } from "ethers"; import { Interface } from "ethers/lib/utils"; import * as zkethers from "zksync-ethers"; -import { ETH_ADDRESS_IN_CONTRACTS } from "zksync-ethers/build/src/utils"; +import { ETH_ADDRESS_IN_CONTRACTS } from "zksync-ethers/build/utils"; import * as fs from "fs"; import type { FacetCut } from "./diamondCut"; diff --git a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts index 7352ce8cc..4ea71d99d 100644 --- a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts +++ b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts @@ -3,7 +3,7 @@ import type { BigNumberish } from "ethers"; import { Wallet } from "ethers"; import * as ethers from "ethers"; import * as hardhat from "hardhat"; -import { hashBytecode } from "zksync-ethers/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; import type { AdminFacet, ExecutorFacet, GettersFacet, StateTransitionManager } from "../../typechain"; import { diff --git a/l1-contracts/test/unit_tests/utils.ts b/l1-contracts/test/unit_tests/utils.ts index c42b55c19..2bbf51733 100644 --- a/l1-contracts/test/unit_tests/utils.ts +++ b/l1-contracts/test/unit_tests/utils.ts @@ -1,8 +1,8 @@ import * as hardhat from "hardhat"; import type { BigNumberish, BytesLike } from "ethers"; import { BigNumber, ethers } from "ethers"; -import type { Address } from "zksync-ethers/build/src/types"; -import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/src/utils"; +import type { Address } from "zksync-ethers/build/types"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/utils"; import type { IBridgehub } from "../../typechain/IBridgehub"; import type { IL1ERC20Bridge } from "../../typechain/IL1ERC20Bridge"; diff --git a/l2-contracts/package.json b/l2-contracts/package.json index 2f5907461..8cee30d5a 100644 --- a/l2-contracts/package.json +++ b/l2-contracts/package.json @@ -3,9 +3,9 @@ "version": "0.1.0", "license": "MIT", "devDependencies": { - "@matterlabs/hardhat-zksync-deploy": "^0.6.5", + "@matterlabs/hardhat-zksync-deploy": "^0.7.0", "@matterlabs/hardhat-zksync-solc": "^0.3.15", - "@matterlabs/hardhat-zksync-verify": "^0.2.0", + "@matterlabs/hardhat-zksync-verify": "^0.4.0", "@nomicfoundation/hardhat-chai-matchers": "^1.0.6", "@nomicfoundation/hardhat-ethers": "^3.0.4", "@nomicfoundation/hardhat-verify": "^1.1.0", @@ -28,7 +28,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^5.2.2", - "zksync-web3": "^0.15.4" + "zksync-ethers": "5.8.0-beta.5" }, "scripts": { "build": "hardhat compile", diff --git a/l2-contracts/src/update-l2-erc20-metadata.ts b/l2-contracts/src/update-l2-erc20-metadata.ts index b86589df3..24903acd8 100644 --- a/l2-contracts/src/update-l2-erc20-metadata.ts +++ b/l2-contracts/src/update-l2-erc20-metadata.ts @@ -2,7 +2,7 @@ import * as hre from "hardhat"; import "@nomiclabs/hardhat-ethers"; import { Command } from "commander"; import { Wallet, ethers, BigNumber } from "ethers"; -import { Provider } from "zksync-web3"; +import { Provider } from "zksync-ethers"; import { getNumberFromEnv } from "../../l1-contracts/src.ts/utils"; import { web3Provider } from "../../l1-contracts/scripts/utils"; import { Deployer } from "../../l1-contracts/src.ts/deploy"; diff --git a/l2-contracts/src/upgrade-bridge-impl.ts b/l2-contracts/src/upgrade-bridge-impl.ts index af21fbac0..3d8e77da9 100644 --- a/l2-contracts/src/upgrade-bridge-impl.ts +++ b/l2-contracts/src/upgrade-bridge-impl.ts @@ -6,8 +6,8 @@ import { Command } from "commander"; import { BigNumber, Wallet, ethers } from "ethers"; import * as fs from "fs"; import * as path from "path"; -import { Provider } from "zksync-web3"; -import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-web3/build/src/utils"; +import { Provider } from "zksync-ethers"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT } from "zksync-ethers/build/utils"; import { web3Provider } from "../../l1-contracts/scripts/utils"; import { getAddressFromEnv, getNumberFromEnv } from "../../l1-contracts/src.ts/utils"; import { Deployer } from "../../l1-contracts/src.ts/deploy"; diff --git a/l2-contracts/src/utils.ts b/l2-contracts/src/utils.ts index 30fe0876e..c77817a0b 100644 --- a/l2-contracts/src/utils.ts +++ b/l2-contracts/src/utils.ts @@ -9,11 +9,11 @@ import { web3Provider } from "../../l1-contracts/scripts/utils"; import type { BigNumber, BytesLike, Wallet } from "ethers"; import { ethers } from "ethers"; -import type { Provider } from "zksync-web3"; -import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, sleep } from "zksync-web3/build/src/utils"; -import { IERC20Factory } from "zksync-web3/build/typechain"; +import type { Provider } from "zksync-ethers"; +import { REQUIRED_L1_TO_L2_GAS_PER_PUBDATA_LIMIT, sleep } from "zksync-ethers/build/utils"; import { ERC20Factory } from "../../l1-contracts/typechain"; +import { IERC20Factory } from "../typechain/IERC20Factory"; export const provider = web3Provider(); diff --git a/l2-contracts/test/erc20.test.ts b/l2-contracts/test/erc20.test.ts index 25dfba652..afc5a2ed8 100644 --- a/l2-contracts/test/erc20.test.ts +++ b/l2-contracts/test/erc20.test.ts @@ -2,8 +2,8 @@ import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import { expect } from "chai"; import { ethers } from "ethers"; import * as hre from "hardhat"; -import { Provider, Wallet } from "zksync-web3"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { Provider, Wallet } from "zksync-ethers"; +import { hashBytecode } from "zksync-ethers/build/utils"; import { unapplyL1ToL2Alias } from "./test-utils"; import { L2SharedBridgeFactory, L2StandardERC20Factory } from "../typechain"; import type { L2SharedBridge, L2StandardERC20 } from "../typechain"; diff --git a/l2-contracts/test/weth.test.ts b/l2-contracts/test/weth.test.ts index 00bb921a0..5337b8ae2 100644 --- a/l2-contracts/test/weth.test.ts +++ b/l2-contracts/test/weth.test.ts @@ -2,7 +2,7 @@ import { Deployer } from "@matterlabs/hardhat-zksync-deploy"; import { expect } from "chai"; import { ethers } from "ethers"; import * as hre from "hardhat"; -import { Provider, Wallet } from "zksync-web3"; +import { Provider, Wallet } from "zksync-ethers"; import type { L2WrappedBaseToken } from "../typechain/L2WrappedBaseToken"; import type { L2SharedBridge } from "../typechain/L2SharedBridge"; import { L2SharedBridgeFactory } from "../typechain/L2SharedBridgeFactory"; diff --git a/system-contracts/package.json b/system-contracts/package.json index d0d4ff7da..a4e1c45cd 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -4,7 +4,7 @@ "repository": "git@github.com:matter-labs/system-contracts.git", "license": "MIT", "dependencies": { - "@matterlabs/hardhat-zksync-deploy": "^0.6.5", + "@matterlabs/hardhat-zksync-deploy": "^0.7.0", "@matterlabs/hardhat-zksync-solc": "^1.1.4", "commander": "^9.4.1", "eslint": "^8.51.0", @@ -13,11 +13,10 @@ "ethers": "^5.7.0", "fast-glob": "^3.3.2", "hardhat": "=2.22.2", - "preprocess": "^3.2.0", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "preprocess": "^3.2.0" }, "devDependencies": { - "@matterlabs/hardhat-zksync-chai-matchers": "^0.1.4", + "@matterlabs/hardhat-zksync-chai-matchers": "^0.2.0", "@matterlabs/hardhat-zksync-node": "^0.0.1-beta.7", "@nomicfoundation/hardhat-chai-matchers": "^1.0.3", "@nomiclabs/hardhat-ethers": "^2.0.0", @@ -37,7 +36,7 @@ "ts-node": "^10.1.0", "typechain": "^4.0.0", "typescript": "^4.6.4", - "zksync-ethers": "https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub" + "zksync-ethers": "5.8.0-beta.5" }, "mocha": { "timeout": 240000, diff --git a/system-contracts/scripts/calculate-hashes.ts b/system-contracts/scripts/calculate-hashes.ts index 1fe368d75..a8fc8036f 100644 --- a/system-contracts/scripts/calculate-hashes.ts +++ b/system-contracts/scripts/calculate-hashes.ts @@ -3,7 +3,7 @@ import * as fs from "fs"; import _ from "lodash"; import os from "os"; import { join } from "path"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; type ContractDetails = { contractName: string; diff --git a/system-contracts/scripts/deploy-preimages.ts b/system-contracts/scripts/deploy-preimages.ts index 6803f9a53..7a4a96880 100644 --- a/system-contracts/scripts/deploy-preimages.ts +++ b/system-contracts/scripts/deploy-preimages.ts @@ -8,9 +8,9 @@ import { ethers } from "ethers"; import { formatUnits, parseUnits } from "ethers/lib/utils"; import * as fs from "fs"; import * as path from "path"; -import type { types } from "zksync-web3"; -import { Provider, Wallet } from "zksync-web3"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import type { types } from "zksync-ethers"; +import { Provider, Wallet } from "zksync-ethers"; +import { hashBytecode } from "zksync-ethers/build/utils"; import { Language, SYSTEM_CONTRACTS } from "./constants"; import type { Dependency, DeployedDependency } from "./utils"; import { checkMarkers, filterPublishedFactoryDeps, getBytecodes, publishFactoryDeps, readYulBytecode } from "./utils"; diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts index 3314abb83..8df750e6a 100644 --- a/system-contracts/scripts/utils.ts +++ b/system-contracts/scripts/utils.ts @@ -8,7 +8,7 @@ import type { BigNumberish, BytesLike } from "ethers"; import { BigNumber, ethers } from "ethers"; import * as fs from "fs"; import * as fsPr from "fs/promises"; -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; import type { YulContractDescription, ZasmContractDescription } from "./constants"; import { Language, SYSTEM_CONTRACTS } from "./constants"; import { getCompilersDir } from "hardhat/internal/util/global-dir"; diff --git a/system-contracts/test/BootloaderUtilities.spec.ts b/system-contracts/test/BootloaderUtilities.spec.ts index e47446e33..7c3c8ed69 100644 --- a/system-contracts/test/BootloaderUtilities.spec.ts +++ b/system-contracts/test/BootloaderUtilities.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; import type { Wallet } from "zksync-ethers"; import * as zksync from "zksync-ethers"; -import { serialize } from "zksync-ethers/build/src/utils"; +import { serialize } from "zksync-ethers/build/utils"; import type { BootloaderUtilities } from "../typechain"; import { BootloaderUtilitiesFactory } from "../typechain"; import { TEST_BOOTLOADER_UTILITIES_ADDRESS } from "./shared/constants"; diff --git a/system-contracts/test/CodeOracle.spec.ts b/system-contracts/test/CodeOracle.spec.ts index b4df2ceaf..d9b0c3781 100644 --- a/system-contracts/test/CodeOracle.spec.ts +++ b/system-contracts/test/CodeOracle.spec.ts @@ -1,4 +1,4 @@ -import { hashBytecode } from "zksync-web3/build/src/utils"; +import { hashBytecode } from "zksync-ethers/build/utils"; import type { CodeOracleTest } from "../typechain"; import { REAL_CODE_ORACLE_CONTRACT_ADDRESS } from "./shared/constants"; import { publishBytecode, setCode, getCode, deployContract } from "./shared/utils"; diff --git a/system-contracts/test/Create2Factory.spec.ts b/system-contracts/test/Create2Factory.spec.ts index 7e84478e0..fc2e689f6 100644 --- a/system-contracts/test/Create2Factory.spec.ts +++ b/system-contracts/test/Create2Factory.spec.ts @@ -3,7 +3,7 @@ import { ethers } from "hardhat"; import type { Wallet } from "zksync-ethers"; import type { Create2Factory } from "../typechain"; import { deployContract, getWallets, loadArtifact } from "./shared/utils"; -import { create2Address, getDeployedContracts, hashBytecode } from "zksync-ethers/build/src/utils"; +import { create2Address, getDeployedContracts, hashBytecode } from "zksync-ethers/build/utils"; describe("Create2Factory tests", function () { let wallet: Wallet; diff --git a/system-contracts/test/DefaultAccount.spec.ts b/system-contracts/test/DefaultAccount.spec.ts index 77dafa1ed..9f3d380d3 100644 --- a/system-contracts/test/DefaultAccount.spec.ts +++ b/system-contracts/test/DefaultAccount.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { ethers, network } from "hardhat"; import type { Wallet } from "zksync-ethers"; import * as zksync from "zksync-ethers"; -import { serialize } from "zksync-web3/build/src/utils"; +import { serialize } from "zksync-ethers/build/utils"; import type { DefaultAccount, DelegateCaller, MockContract } from "../typechain"; import { DefaultAccountFactory } from "../typechain"; import { TEST_BOOTLOADER_FORMAL_ADDRESS } from "./shared/constants"; diff --git a/system-contracts/test/EventWriter.spec.ts b/system-contracts/test/EventWriter.spec.ts index 072f8e35b..35c5d66f7 100644 --- a/system-contracts/test/EventWriter.spec.ts +++ b/system-contracts/test/EventWriter.spec.ts @@ -2,7 +2,7 @@ import { expect } from "chai"; import { ethers } from "hardhat"; import type { Wallet } from "zksync-ethers"; import { Contract } from "zksync-ethers"; -import type { TransactionResponse } from "zksync-web3/build/src/types"; +import type { TransactionResponse } from "zksync-ethers/build/types"; import { ONE_BYTES32_HEX, REAL_EVENT_WRITER_CONTRACT_ADDRESS } from "./shared/constants"; import { EXTRA_ABI_CALLER_ADDRESS, encodeExtraAbiCallerCalldata } from "./shared/extraAbiCaller"; import { getCode, getWallets, loadYulBytecode, loadZasmBytecode, setCode } from "./shared/utils"; diff --git a/system-contracts/test/L1Messenger.spec.ts b/system-contracts/test/L1Messenger.spec.ts index 6910bc9f5..678da92a9 100644 --- a/system-contracts/test/L1Messenger.spec.ts +++ b/system-contracts/test/L1Messenger.spec.ts @@ -4,8 +4,8 @@ import { L1MessengerFactory } from "../typechain"; import { prepareEnvironment, setResult } from "./shared/mocks"; import type { StateDiff } from "./shared/utils"; import { compressStateDiffs, deployContractOnAddress, encodeStateDiffs, getCode, getWallets } from "./shared/utils"; -import { utils } from "zksync-web3"; -import type { Wallet } from "zksync-web3"; +import { utils } from "zksync-ethers"; +import type { Wallet } from "zksync-ethers"; import { TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, diff --git a/system-contracts/test/L2BaseToken.spec.ts b/system-contracts/test/L2BaseToken.spec.ts index c1b03fb7e..d73f0444d 100644 --- a/system-contracts/test/L2BaseToken.spec.ts +++ b/system-contracts/test/L2BaseToken.spec.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; import { ethers, network } from "hardhat"; -import type { Wallet } from "zksync-web3"; +import type { Wallet } from "zksync-ethers"; import type { L2BaseToken } from "../typechain"; import { L2BaseTokenFactory } from "../typechain"; import { deployContractOnAddress, getWallets, loadArtifact, provider } from "./shared/utils"; diff --git a/system-contracts/test/PubdataChunkPublisher.spec.ts b/system-contracts/test/PubdataChunkPublisher.spec.ts index f007f2018..8dfbfebf9 100644 --- a/system-contracts/test/PubdataChunkPublisher.spec.ts +++ b/system-contracts/test/PubdataChunkPublisher.spec.ts @@ -1,6 +1,6 @@ import { expect } from "chai"; import { ethers, network } from "hardhat"; -import type { Wallet } from "zksync-web3"; +import type { Wallet } from "zksync-ethers"; import type { PubdataChunkPublisher } from "../typechain"; import { PubdataChunkPublisherFactory } from "../typechain"; import { TEST_L1_MESSENGER_SYSTEM_CONTRACT_ADDRESS, TEST_PUBDATA_CHUNK_PUBLISHER_ADDRESS } from "./shared/constants"; diff --git a/yarn.lock b/yarn.lock index a7f0255e9..903beef88 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,10 +10,10 @@ "@babel/highlight" "^7.24.2" picocolors "^1.0.0" -"@babel/helper-validator-identifier@^7.24.5": - version "7.24.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz#918b1a7fa23056603506370089bd990d8720db62" - integrity sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA== +"@babel/helper-validator-identifier@^7.22.20": + version "7.24.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" + integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== "@babel/highlight@^7.24.2": version "7.24.2" @@ -679,10 +679,20 @@ resolved "https://registry.yarnpkg.com/@matterlabs/eslint-config-typescript/-/eslint-config-typescript-1.1.2.tgz#a9be4e56aedf298800f247c5049fc412f8b301a7" integrity sha512-AhiWJQr+MSE3RVfgp5XwGoMK7kNSKh6a18+T7hkNJtyycP0306I6IGmuFA5ZVbcakGb+K32fQWzepSkrNCTAGg== -"@matterlabs/hardhat-zksync-chai-matchers@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-chai-matchers/-/hardhat-zksync-chai-matchers-0.1.4.tgz#105cb0ec1367c8fcd3ce7e3773f747c71fff675b" - integrity sha512-eGQWiImg51fmayoQ7smIK/T6QZkSu38PK7xjp1RIrewGzw2ZgqFWGp40jb5oomkf8yOQPk52Hu4TwE3Ntp8CtA== +"@matterlabs/hardhat-zksync-chai-matchers@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-chai-matchers/-/hardhat-zksync-chai-matchers-0.2.1.tgz#d05136d6cf9a53c30f5e7ee9bae95abb72c1000d" + integrity sha512-LXm5r53DLTQC/KXRXzSRmVp5mEJ4tsoKAKyGck2YLHQ9CBdPoC0paVjbyB2MaEuK/k8o4lZu4uaYKgWQNUXeyQ== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@matterlabs/hardhat-zksync-deploy" "^0.7.0" + "@matterlabs/hardhat-zksync-solc" "1.0.6" + chai "^4.3.7" + chai-as-promised "^7.1.1" + ethers "~5.7.2" + hardhat "^2.14.0" + ordinal "1.0.3" + zksync-ethers "^5.0.0" "@matterlabs/hardhat-zksync-deploy@^0.6.5": version "0.6.6" @@ -693,6 +703,15 @@ chalk "4.1.2" ts-morph "^19.0.0" +"@matterlabs/hardhat-zksync-deploy@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-deploy/-/hardhat-zksync-deploy-0.7.0.tgz#e56b73d8f8fbd0f809a779d0028418ea7d914017" + integrity sha512-PGZcuhKsVzZ2IWPt931pK2gA+HDxnCtye+7CwvoOnM6diHeO9tB1QHFX/ywR9ErOW9wpezhPYkVDx9myFrdoqQ== + dependencies: + "@matterlabs/hardhat-zksync-solc" "^1.0.5" + chalk "4.1.2" + ts-morph "^19.0.0" + "@matterlabs/hardhat-zksync-node@^0.0.1-beta.7": version "0.0.1" resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-node/-/hardhat-zksync-node-0.0.1.tgz#d44bda3c0069b149e2a67c9697eb81166b169ea6" @@ -703,25 +722,26 @@ chalk "4.1.2" fs-extra "^11.1.1" -"@matterlabs/hardhat-zksync-solc@0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.1.tgz#e8e67d947098d7bb8925f968544d34e522af5a9c" - integrity sha512-fdlGf/2yZR5ihVNc2ubea1R/nNFXRONL29Fgz5FwB3azB13rPb76fkQgcFIg9zSufHsEy6zUUT029NkxLNA9Sw== +"@matterlabs/hardhat-zksync-solc@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.2.tgz#64121082e88c5ab22eb4e9594d120e504f6af499" + integrity sha512-6NFWPSZiOAoo7wNuhMg4ztj7mMEH+tLrx09WuCbcURrHPijj/KxYNsJD6Uw5lapKr7G8H7SQISGid1/MTXVmXQ== dependencies: "@nomiclabs/hardhat-docker" "^2.0.0" chalk "4.1.2" dockerode "^3.3.4" fs-extra "^11.1.1" + proper-lockfile "^4.1.2" semver "^7.5.1" -"@matterlabs/hardhat-zksync-solc@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-0.4.2.tgz#64121082e88c5ab22eb4e9594d120e504f6af499" - integrity sha512-6NFWPSZiOAoo7wNuhMg4ztj7mMEH+tLrx09WuCbcURrHPijj/KxYNsJD6Uw5lapKr7G8H7SQISGid1/MTXVmXQ== +"@matterlabs/hardhat-zksync-solc@1.0.6": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.0.6.tgz#7ef8438e6bb15244691600e2afa77aaff7dff9f0" + integrity sha512-0icYSufXba/Bbb7v2iXuZJ+IbYsiNpR4Wy6UizHnGuFw3OMHgh+saebQphuaN9yyRL2UPGZbPkQFHWBLZj5/xQ== dependencies: "@nomiclabs/hardhat-docker" "^2.0.0" chalk "4.1.2" - dockerode "^3.3.4" + dockerode "^4.0.0" fs-extra "^11.1.1" proper-lockfile "^4.1.2" semver "^7.5.1" @@ -752,16 +772,17 @@ sinon-chai "^3.7.0" undici "^5.14.0" -"@matterlabs/hardhat-zksync-verify@^0.2.0": - version "0.2.2" - resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.2.2.tgz#daa34bc4404096ed0f44461ee366c1cb0e5a4f2f" - integrity sha512-WgcItoZGY702oJ708uCP5uLvmwzDLBfhMqq2D0Kh1U/3fCTlPza9zMGUFHxKMQYsITKTeQ5zKOjKoi8MXOeUdQ== +"@matterlabs/hardhat-zksync-verify@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.4.0.tgz#f812c19950022fc36728f3796f6bdae5633e2fcd" + integrity sha512-GPZmAumFl3ZMPKbECX7Qw8CriwZKWd1DlCRhoG/6YYc6mFy4+MXkF1XsHLMs5r34N+GDOfbVZVMeftIlJC96Kg== dependencies: - "@matterlabs/hardhat-zksync-solc" "0.4.1" + "@matterlabs/hardhat-zksync-solc" "^1.0.5" "@nomicfoundation/hardhat-verify" "^1.0.2" axios "^1.4.0" chalk "4.1.2" dockerode "^3.3.4" + zksync-ethers "^5.0.0" "@matterlabs/prettier-config@^1.0.3": version "1.0.3" @@ -796,21 +817,16 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== -"@noble/hashes@1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" - integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== +"@noble/hashes@1.3.3", "@noble/hashes@~1.3.2": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== "@noble/hashes@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.4.0.tgz#45814aa329f30e4fe0ba49426f49dfccdd066426" integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== -"@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - "@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -842,36 +858,71 @@ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.7.tgz#c204edc79643624dbd431b489b254778817d8244" integrity sha512-6tK9Lv/lSfyBvpEQ4nsTfgxyDT1y1Uv/x8Wa+aB+E8qGo3ToexQ1BMVjxJk6PChXCDOWxB3B4KhqaZFjdhl3Ow== +"@nomicfoundation/edr-darwin-arm64@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.4.0.tgz#bbb43f0e01f40839b0bd38c2c443cb6910ae955f" + integrity sha512-7+rraFk9tCqvfemv9Ita5vTlSBAeO/S5aDKOgGRgYt0JEKZlrX161nDW6UfzMPxWl9GOLEDUzCEaYuNmXseUlg== + "@nomicfoundation/edr-darwin-x64@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.3.7.tgz#c3b394445084270cc5250d6c1869b0574e7ef810" integrity sha512-1RrQ/1JPwxrYO69e0tglFv5H+ggour5Ii3bb727+yBpBShrxtOTQ7fZyfxA5h62LCN+0Z9wYOPeQ7XFcVurMaQ== +"@nomicfoundation/edr-darwin-x64@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.4.0.tgz#b1ffcd9142418fd8498de34a7336b3f977907c86" + integrity sha512-+Hrc0mP9L6vhICJSfyGo/2taOToy1AIzVZawO3lU8Lf7oDQXfhQ4UkZnkWAs9SVu1eUwHUGGGE0qB8644piYgg== + "@nomicfoundation/edr-linux-arm64-gnu@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.3.7.tgz#6d65545a44d1323bb7ab08c3306947165d2071de" integrity sha512-ds/CKlBoVXIihjhflhgPn13EdKWed6r5bgvMs/YwRqT5wldQAQJZWAfA2+nYm0Yi2gMGh1RUpBcfkyl4pq7G+g== +"@nomicfoundation/edr-linux-arm64-gnu@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.4.0.tgz#8173d16d4f6f2b3e82ba7096d2a1ea3619d8bfa7" + integrity sha512-4HUDMchNClQrVRfVTqBeSX92hM/3khCgpZkXP52qrnJPqgbdCxosOehlQYZ65wu0b/kaaZSyvACgvCLSQ5oSzQ== + "@nomicfoundation/edr-linux-arm64-musl@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.3.7.tgz#5368534bceac1a8c18b1be6b908caca5d39b0c03" integrity sha512-e29udiRaPujhLkM3+R6ju7QISrcyOqpcaxb2FsDWBkuD7H8uU9JPZEyyUIpEp5uIY0Jh1eEJPKZKIXQmQAEAuw== +"@nomicfoundation/edr-linux-arm64-musl@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.4.0.tgz#b1ce293a7c3e0d9f70391e1aef1a82b83b997567" + integrity sha512-D4J935ZRL8xfnP3zIFlCI9jXInJ0loDUkCTLeCEbOf2uuDumWDghKNQlF1itUS+EHaR1pFVBbuwqq8hVK0dASg== + "@nomicfoundation/edr-linux-x64-gnu@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.3.7.tgz#42349bf5941dbb54a5719942924c6e4e8cde348e" integrity sha512-/xkjmTyv+bbJ4akBCW0qzFKxPOV4AqLOmqurov+s9umHb16oOv72osSa3SdzJED2gHDaKmpMITT4crxbar4Axg== +"@nomicfoundation/edr-linux-x64-gnu@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.4.0.tgz#4c12c4e4bfd3d837f5663ad7cbf7cb6d5634ef83" + integrity sha512-6x7HPy+uN5Cb9N77e2XMmT6+QSJ+7mRbHnhkGJ8jm4cZvWuj2Io7npOaeHQ3YHK+TiQpTnlbkjoOIpEwpY3XZA== + "@nomicfoundation/edr-linux-x64-musl@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.3.7.tgz#e6babe11c9a8012f1284e6e48c3551861f2a7cd4" integrity sha512-QwBP9xlmsbf/ldZDGLcE4QiAb8Zt46E/+WLpxHBATFhGa7MrpJh6Zse+h2VlrT/SYLPbh2cpHgSmoSlqVxWG9g== +"@nomicfoundation/edr-linux-x64-musl@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.4.0.tgz#8842004aa1a47c504f10863687da28b65dca7baa" + integrity sha512-3HFIJSXgyubOiaN4MWGXx2xhTnhwlJk0PiSYNf9+L/fjBtcRkb2nM910ZJHTvqCb6OT98cUnaKuAYdXIW2amgw== + "@nomicfoundation/edr-win32-x64-msvc@0.3.7": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.3.7.tgz#1504b98f305f03be153b0220a546985660de9dc6" integrity sha512-j/80DEnkxrF2ewdbk/gQ2EOPvgF0XSsg8D0o4+6cKhUVAW6XwtWKzIphNL6dyD2YaWEPgIrNvqiJK/aln0ww4Q== +"@nomicfoundation/edr-win32-x64-msvc@0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.4.0.tgz#29d8bbb2edf9912a95f5453855cf17cdcb269957" + integrity sha512-CP4GsllEfXEz+lidcGYxKe5rDJ60TM5/blB5z/04ELVvw6/CK9eLcYeku7HV0jvV7VE6dADYKSdQyUkvd0El+A== + "@nomicfoundation/edr@^0.3.1": version "0.3.7" resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.3.7.tgz#9c75edf1fcf601617905b2c89acf103f4786d017" @@ -885,6 +936,19 @@ "@nomicfoundation/edr-linux-x64-musl" "0.3.7" "@nomicfoundation/edr-win32-x64-msvc" "0.3.7" +"@nomicfoundation/edr@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.4.0.tgz#4895ecb6ef321136db837458949c37cce4a29459" + integrity sha512-T96DMSogO8TCdbKKctvxfsDljbhFOUKWc9fHJhSeUh71EEho2qR4951LKQF7t7UWEzguVYh/idQr5L/E3QeaMw== + dependencies: + "@nomicfoundation/edr-darwin-arm64" "0.4.0" + "@nomicfoundation/edr-darwin-x64" "0.4.0" + "@nomicfoundation/edr-linux-arm64-gnu" "0.4.0" + "@nomicfoundation/edr-linux-arm64-musl" "0.4.0" + "@nomicfoundation/edr-linux-x64-gnu" "0.4.0" + "@nomicfoundation/edr-linux-x64-musl" "0.4.0" + "@nomicfoundation/edr-win32-x64-msvc" "0.4.0" + "@nomicfoundation/ethereumjs-common@4.0.4": version "4.0.4" resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb" @@ -2084,11 +2148,6 @@ bech32@1.1.4: resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== -big-integer@^1.6.44: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== - bignumber.js@^9.0.0, bignumber.js@^9.0.1: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -2160,20 +2219,6 @@ boxen@^5.1.2: widest-line "^3.1.0" wrap-ansi "^7.0.0" -bplist-parser@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" - integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2375,7 +2420,7 @@ chai-as-promised@^7.1.1: dependencies: check-error "^1.0.2" -chai@^4.3.10, chai@^4.3.6: +chai@^4.3.10, chai@^4.3.6, chai@^4.3.7: version "4.4.1" resolved "https://registry.yarnpkg.com/chai/-/chai-4.4.1.tgz#3603fa6eba35425b0f2ac91a009fe924106e50d1" integrity sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g== @@ -2851,12 +2896,7 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - -define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -2952,7 +2992,7 @@ dockerode@^3.3.4: docker-modem "^3.0.0" tar-fs "~2.0.1" -dockerode@^4.0.2: +dockerode@^4.0.0, dockerode@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/dockerode/-/dockerode-4.0.2.tgz#dedc8529a1db3ac46d186f5912389899bc309f7d" integrity sha512-9wM1BVpVMFr2Pw3eJNXrYYt6DT9k0xMcsSCjtPvyQ+xa1iPg/Mo3T/gUcwI0B2cczqCeCYRPF8yFYDwtFXT0+w== @@ -3498,7 +3538,7 @@ ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.3, ethereumjs-util@^7.1.4, ethereum ethereum-cryptography "^0.1.3" rlp "^2.2.4" -ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0: +ethers@^5.0.2, ethers@^5.7.0, ethers@^5.7.2, ethers@~5.7.0, ethers@~5.7.2: version "5.7.2" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== @@ -4285,6 +4325,55 @@ hardhat@=2.22.2: uuid "^8.3.2" ws "^7.4.6" +hardhat@^2.14.0: + version "2.22.5" + resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.22.5.tgz#7e1a4311fa9e34a1cfe337784eae06706f6469a5" + integrity sha512-9Zq+HonbXCSy6/a13GY1cgHglQRfh4qkzmj1tpPlhxJDwNVnhxlReV6K7hCWFKlOrV13EQwsdcD0rjcaQKWRZw== + dependencies: + "@ethersproject/abi" "^5.1.2" + "@metamask/eth-sig-util" "^4.0.0" + "@nomicfoundation/edr" "^0.4.0" + "@nomicfoundation/ethereumjs-common" "4.0.4" + "@nomicfoundation/ethereumjs-tx" "5.0.4" + "@nomicfoundation/ethereumjs-util" "9.0.4" + "@nomicfoundation/solidity-analyzer" "^0.1.0" + "@sentry/node" "^5.18.1" + "@types/bn.js" "^5.1.0" + "@types/lru-cache" "^5.1.0" + adm-zip "^0.4.16" + aggregate-error "^3.0.0" + ansi-escapes "^4.3.0" + boxen "^5.1.2" + chalk "^2.4.2" + chokidar "^3.4.0" + ci-info "^2.0.0" + debug "^4.1.1" + enquirer "^2.3.0" + env-paths "^2.2.0" + ethereum-cryptography "^1.0.3" + ethereumjs-abi "^0.6.8" + find-up "^2.1.0" + fp-ts "1.19.3" + fs-extra "^7.0.1" + glob "7.2.0" + immutable "^4.0.0-rc.12" + io-ts "1.10.4" + keccak "^3.0.2" + lodash "^4.17.11" + mnemonist "^0.38.0" + mocha "^10.0.0" + p-map "^4.0.0" + raw-body "^2.4.1" + resolve "1.17.0" + semver "^6.3.0" + solc "0.7.3" + source-map-support "^0.5.13" + stacktrace-parser "^0.1.10" + tsort "0.0.1" + undici "^5.14.0" + uuid "^8.3.2" + ws "^7.4.6" + has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -5530,21 +5619,11 @@ nan@^2.17.0, nan@^2.18.0: resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== -nan@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.19.0.tgz#bb58122ad55a6c5bc973303908d5b16cfdd5a8c0" - integrity sha512-nO1xXxfh/RWNxfd/XPfbIfFk5vgLsAxUR9y5O0cHMJu/AW9U95JLXqthYHjEp+8gQ5p96K9jUp8nbVOxCdRbtw== - nanoid@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - napi-macros@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" @@ -5729,7 +5808,7 @@ optionator@^0.9.3: type-check "^0.4.0" word-wrap "^1.2.5" -ordinal@^1.0.3: +ordinal@1.0.3, ordinal@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== @@ -7393,11 +7472,6 @@ unpipe@1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - uri-js@^4.2.2, uri-js@^4.4.1: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -7666,15 +7740,16 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== -"zksync-ethers@https://github.com/zksync-sdk/zksync-ethers#ethers-v5-feat/bridgehub": - version "5.1.0" - resolved "https://github.com/zksync-sdk/zksync-ethers#28ccbe7d67b170c202b17475e06a82002e6e3acc" +zksync-ethers@5.8.0-beta.5: + version "5.8.0-beta.5" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.8.0-beta.5.tgz#4f70193a86bd1e41b25b0aa5aa32f6d41d52f7c6" + integrity sha512-saT/3OwLgifqzrBG7OujvUMapzXnshAaLzAZMycUtdV20eLSSVkyLIARVwh1M6hMQIUvX2htV0JN82QRMyM3Ig== dependencies: ethers "~5.7.0" -zksync-web3@^0.15.4: - version "0.15.5" - resolved "https://registry.yarnpkg.com/zksync-web3/-/zksync-web3-0.15.5.tgz#aabe379464963ab573e15948660a709f409b5316" - integrity sha512-97gB7OKJL4spegl8fGO54g6cvTd/75G6yFWZWEa2J09zhjTrfqabbwE/GwiUJkFQ5BbzoH4JaTlVz1hoYZI+DQ== +zksync-ethers@^5.0.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/zksync-ethers/-/zksync-ethers-5.7.2.tgz#e965a9926e6f8168963ab565dd6ad0d38c4f7f18" + integrity sha512-D+wn4nkGixUOek9ZsVvIZ/MHponQ5xvw74FSbDJDv6SLCI4LZALOAc8lF3b1ml8nOkpeE2pGV0VKmHTSquRNJg== dependencies: ethers "~5.7.0" From ab2f13d72e59f449b19fcf979667b94f9fba4b1e Mon Sep 17 00:00:00 2001 From: Dima Zhornyk <55756184+dimazhornyk@users.noreply.github.com> Date: Wed, 12 Jun 2024 13:05:15 +0200 Subject: [PATCH 60/60] feat: check diamond cut hash locally (#525) --- l1-contracts/scripts/register-hyperchain.ts | 14 +++-- l1-contracts/src.ts/deploy-process.ts | 1 + l1-contracts/src.ts/deploy.ts | 59 +++++++++++++++------ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/l1-contracts/scripts/register-hyperchain.ts b/l1-contracts/scripts/register-hyperchain.ts index 755352f9b..3fea4b9f8 100644 --- a/l1-contracts/scripts/register-hyperchain.ts +++ b/l1-contracts/scripts/register-hyperchain.ts @@ -59,12 +59,9 @@ async function main() { program .option("--private-key ") - .option("--chain-id ") .option("--gas-price ") .option("--nonce ") .option("--governor-address ") - .option("--create2-salt ") - .option("--diamond-upgrade-init ") .option("--only-verifier") .option("--validium-mode") .option("--base-token-name ") @@ -106,7 +103,16 @@ async function main() { await deployer.registerToken(baseTokenAddress, useGovernance); } - await deployer.registerHyperchain(baseTokenAddress, cmd.validiumMode, null, gasPrice, useGovernance); + await deployer.registerHyperchain( + baseTokenAddress, + cmd.validiumMode, + null, + gasPrice, + true, + null, + null, + useGovernance + ); await deployer.transferAdminFromDeployerToGovernance(); }); diff --git a/l1-contracts/src.ts/deploy-process.ts b/l1-contracts/src.ts/deploy-process.ts index f495bb69a..94a403fb8 100644 --- a/l1-contracts/src.ts/deploy-process.ts +++ b/l1-contracts/src.ts/deploy-process.ts @@ -93,6 +93,7 @@ export async function registerHyperchain( validiumMode, extraFacets, gasPrice, + false, null, chainId, useGovernance diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 4ff958560..6e3106127 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -34,10 +34,11 @@ import { L1SharedBridgeFactory } from "../typechain/L1SharedBridgeFactory"; import { SingletonFactoryFactory } from "../typechain/SingletonFactoryFactory"; import { ValidatorTimelockFactory } from "../typechain/ValidatorTimelockFactory"; + import type { FacetCut } from "./diamondCut"; import { getCurrentFacetCutsForAdd } from "./diamondCut"; -import { ERC20Factory } from "../typechain"; +import { ERC20Factory, StateTransitionManagerFactory } from "../typechain"; import type { Contract, Overrides } from "@ethersproject/contracts"; let L2_BOOTLOADER_BYTECODE_HASH: string; @@ -81,7 +82,7 @@ export class Deployer { this.chainId = parseInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!); } - public async initialZkSyncHyperchainDiamondCut(extraFacets?: FacetCut[]) { + public async initialZkSyncHyperchainDiamondCut(extraFacets?: FacetCut[], compareDiamondCutHash: boolean = false) { let facetCuts: FacetCut[] = Object.values( await getCurrentFacetCutsForAdd( this.addresses.StateTransition.AdminFacet, @@ -99,7 +100,7 @@ export class Deployer { }; const priorityTxMaxGasLimit = getNumberFromEnv("CONTRACTS_PRIORITY_TX_MAX_GAS_LIMIT"); - return compileInitialCutHash( + const diamondCut = compileInitialCutHash( facetCuts, verifierParams, L2_BOOTLOADER_BYTECODE_HASH, @@ -110,6 +111,25 @@ export class Deployer { this.addresses.StateTransition.DiamondInit, false ); + + if (compareDiamondCutHash) { + const hash = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCut]) + ); + + console.log(`Diamond cut hash: ${hash}`); + const stm = StateTransitionManagerFactory.connect( + this.addresses.StateTransition.StateTransitionProxy, + this.deployWallet + ); + + const hashFromSTM = await stm.initialCutHash(); + if (hash != hashFromSTM) { + throw new Error(`Has from STM ${hashFromSTM} does not match the computed hash ${hash}`); + } + } + + return diamondCut; } public async deployCreate2Factory(ethTxOptions?: ethers.providers.TransactionRequest) { @@ -685,6 +705,7 @@ export class Deployer { validiumMode: boolean, extraFacets?: FacetCut[], gasPrice?: BigNumberish, + compareDiamondCutHash: boolean = false, nonce?, predefinedChainId?: string, useGovernance: boolean = false @@ -698,7 +719,7 @@ export class Deployer { const inputChainId = predefinedChainId || getNumberFromEnv("CHAIN_ETH_ZKSYNC_NETWORK_ID"); const admin = process.env.CHAIN_ADMIN_ADDRESS || this.ownerAddress; - const diamondCutData = await this.initialZkSyncHyperchainDiamondCut(extraFacets); + const diamondCutData = await this.initialZkSyncHyperchainDiamondCut(extraFacets, compareDiamondCutHash); const initialDiamondCut = new ethers.utils.AbiCoder().encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCutData]); const receipt = await this.executeDirectOrGovernance( @@ -751,7 +772,8 @@ export class Deployer { console.log(`CONTRACTS_DIAMOND_PROXY_ADDR=${diamondProxyAddress}`); } } - this.chainId = parseInt(chainId, 16); + const intChainId = parseInt(chainId, 16); + this.chainId = intChainId; const validatorOneAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR"); const validatorTwoAddress = getAddressFromEnv("ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR"); @@ -783,18 +805,25 @@ export class Deployer { } const diamondProxy = this.stateTransitionContract(this.deployWallet); - const tx4 = await diamondProxy.setTokenMultiplier(1, 1); - const receipt4 = await tx4.wait(); - if (this.verbose) { - console.log(`BaseTokenMultiplier set, gas used: ${receipt4.gasUsed.toString()}`); - } - - if (validiumMode) { - const tx5 = await diamondProxy.setPubdataPricingMode(PubdataPricingMode.Validium); - const receipt5 = await tx5.wait(); + // if we are using governance, the deployer will not be the admin, so we can't call the diamond proxy directly + if (admin == this.deployWallet.address) { + const tx4 = await diamondProxy.setTokenMultiplier(1, 1); + const receipt4 = await tx4.wait(); if (this.verbose) { - console.log(`Validium mode set, gas used: ${receipt5.gasUsed.toString()}`); + console.log(`BaseTokenMultiplier set, gas used: ${receipt4.gasUsed.toString()}`); } + + if (validiumMode) { + const tx5 = await diamondProxy.setPubdataPricingMode(PubdataPricingMode.Validium); + const receipt5 = await tx5.wait(); + if (this.verbose) { + console.log(`Validium mode set, gas used: ${receipt5.gasUsed.toString()}`); + } + } + } else { + console.warn( + "BaseTokenMultiplier and Validium mode can't be set through the governance, please set it separately, using the admin account" + ); } }