diff --git a/.github/workflows/system-contracts-ci.yaml b/.github/workflows/system-contracts-ci.yaml index d1338983e..018a556e4 100644 --- a/.github/workflows/system-contracts-ci.yaml +++ b/.github/workflows/system-contracts-ci.yaml @@ -80,7 +80,7 @@ jobs: - name: Install rust uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: nightly-2023-04-17 + toolchain: nightly-2024-08-01 - name: Restore artifacts cache uses: actions/cache/restore@v3 @@ -143,3 +143,37 @@ jobs: - name: Print output logs of era_test_node if: always() run: cat era_test_node.log + + check-hashes: + needs: [build] + 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: Install dependencies + run: yarn + + - name: Restore artifacts cache + uses: actions/cache/restore@v3 + with: + fail-on-cache-miss: true + key: artifacts-system-${{ github.sha }} + path: | + system-contracts/zkout + system-contracts/cache-forge + system-contracts/bootloader/build + system-contracts/artifacts-zk + system-contracts/cache-zk + system-contracts/typechain + system-contracts/contracts-preprocessed + + - name: Check hashes + run: yarn sc calculate-hashes:check diff --git a/.gitignore b/.gitignore index 21c173828..21516dc8e 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ l1-contracts/script-config/* l1-contracts/script-out/* !l1-contracts/script-out/.gitkeep *.timestamp +l1-contracts/test/foundry/l1/integration/deploy-scripts/script-out/* +l1-contracts/zkout/* diff --git a/.solhintignore b/.solhintignore index abcb64f98..785a7e178 100644 --- a/.solhintignore +++ b/.solhintignore @@ -8,6 +8,7 @@ l1-contracts/lib l1-contracts/node_modules l1-contracts/contracts/dev-contracts l1-contracts/test +l1-contracts/deploy-scripts # l1-contracts-foundry l1-contracts-foundry/cache @@ -16,6 +17,7 @@ l1-contracts-foundry/lib # l2-contracts l2-contracts/cache-zk l2-contracts/node_modules +l2-contracts/contracts/dev-contracts # system-contracts system-contracts/contracts/openzeppelin diff --git a/l1-contracts/contracts/bridge/L1SharedBridge.sol b/l1-contracts/contracts/bridge/L1SharedBridge.sol index eaddcccc7..1f81887bb 100644 --- a/l1-contracts/contracts/bridge/L1SharedBridge.sol +++ b/l1-contracts/contracts/bridge/L1SharedBridge.sol @@ -22,7 +22,7 @@ import {ETH_TOKEN_ADDRESS, TWO_BRIDGES_MAGIC_VALUE} from "../common/Config.sol"; import {IBridgehub, L2TransactionRequestTwoBridgesInner, L2TransactionRequestDirect} from "../bridgehub/IBridgehub.sol"; import {IGetters} from "../state-transition/chain-interfaces/IGetters.sol"; import {L2_BASE_TOKEN_SYSTEM_CONTRACT_ADDR} from "../common/L2ContractAddresses.sol"; -import {Unauthorized, ZeroAddress, SharedBridgeValueAlreadySet, SharedBridgeKey, NoFundsTransferred, ZeroBalance, ValueMismatch, TokensWithFeesNotSupported, NonEmptyMsgValue, L2BridgeNotSet, TokenNotSupported, DepositIncorrectAmount, EmptyDeposit, DepositExists, AddressAlreadyUsed, InvalidProof, DepositDoesNotExist, InsufficientChainBalance, SharedBridgeValueNotSet, WithdrawalAlreadyFinalized, WithdrawFailed, L2WithdrawalMessageWrongLength, InvalidSelector, SharedBridgeBalanceMismatch, SharedBridgeValueNotSet} from "../common/L1ContractErrors.sol"; +import {Unauthorized, ZeroAddress, SharedBridgeValueAlreadySet, SharedBridgeKey, NoFundsTransferred, ZeroBalance, ValueMismatch, TokensWithFeesNotSupported, NonEmptyMsgValue, L2BridgeNotSet, TokenNotSupported, DepositIncorrectAmount, EmptyDeposit, DepositExists, AddressAlreadyUsed, InvalidProof, DepositDoesNotExist, InsufficientChainBalance, SharedBridgeValueNotSet, WithdrawalAlreadyFinalized, WithdrawFailed, L2WithdrawalMessageWrongLength, InvalidSelector, SharedBridgeBalanceMismatch, SharedBridgeValueNotSet, NotPendingAdmin, L2BridgeAlreadySet} from "../common/L1ContractErrors.sol"; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -130,7 +130,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @notice Checks that the message sender is either the owner or admin. modifier onlyOwnerOrAdmin() { - require(msg.sender == owner() || msg.sender == admin, "ShB not owner or admin"); + if (msg.sender != owner() && msg.sender != admin) { + revert Unauthorized(msg.sender); + } _; } @@ -174,7 +176,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @notice Accepts transfer of admin rights. Only pending admin can accept the role. function acceptAdmin() external { address currentPendingAdmin = pendingAdmin; - require(msg.sender == currentPendingAdmin, "ShB not pending admin"); // Only proposed by current admin address can claim the admin rights + if (msg.sender != currentPendingAdmin) { + revert NotPendingAdmin(); + } address previousAdmin = admin; admin = currentPendingAdmin; @@ -276,8 +280,12 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @param _chainId The chain ID for which the l2Bridge address is being initialized. /// @param _l2BridgeAddress The address of the L2 bridge contract. function initializeChainGovernance(uint256 _chainId, address _l2BridgeAddress) external onlyOwnerOrAdmin { - require(l2BridgeAddress[_chainId] == address(0), "ShB: l2 bridge already set"); - require(_l2BridgeAddress != address(0), "ShB: l2 bridge 0"); + if (l2BridgeAddress[_chainId] != address(0)) { + revert L2BridgeAlreadySet(_chainId); + } + if (_l2BridgeAddress == address(0)) { + revert ZeroAddress(); + } l2BridgeAddress[_chainId] = _l2BridgeAddress; } @@ -287,7 +295,9 @@ contract L1SharedBridge is IL1SharedBridge, ReentrancyGuard, Ownable2StepUpgrade /// @param _chainId The chain ID for which the l2Bridge address is being initialized. /// @param _l2BridgeAddress The address of the L2 bridge contract. function reinitializeChainGovernance(uint256 _chainId, address _l2BridgeAddress) external onlyOwner { - require(l2BridgeAddress[_chainId] != address(0), "ShB: l2 bridge not yet set"); + if (l2BridgeAddress[_chainId] == address(0)) { + revert L2BridgeNotSet(_chainId); + } l2BridgeAddress[_chainId] = _l2BridgeAddress; } diff --git a/l1-contracts/contracts/common/Config.sol b/l1-contracts/contracts/common/Config.sol index c0e05f1fc..e6e3118bb 100644 --- a/l1-contracts/contracts/common/Config.sol +++ b/l1-contracts/contracts/common/Config.sol @@ -108,3 +108,6 @@ bytes32 constant TWO_BRIDGES_MAGIC_VALUE = bytes32(uint256(keccak256("TWO_BRIDGE /// @dev https://eips.ethereum.org/EIPS/eip-1352 address constant BRIDGEHUB_MIN_SECOND_BRIDGE_ADDRESS = address(uint160(type(uint16).max)); + +/// @dev Used as the `msg.sender` for system service transactions. +address constant SERVICE_TRANSACTION_SENDER = address(uint160(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF)); diff --git a/l1-contracts/contracts/common/L1ContractErrors.sol b/l1-contracts/contracts/common/L1ContractErrors.sol index 73ff72cc9..62ff78917 100644 --- a/l1-contracts/contracts/common/L1ContractErrors.sol +++ b/l1-contracts/contracts/common/L1ContractErrors.sol @@ -1,6 +1,28 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.21; +// 0x5ecf2d7a +error AccessToFallbackDenied(address target, address invoker); +// 0x3995f750 +error AccessToFunctionDenied(address target, bytes4 selector, address invoker); +// 0x6c167909 +error OnlySelfAllowed(); +// 0x52e22c98 +error RestrictionWasNotPresent(address restriction); +// 0xf126e113 +error RestrictionWasAlreadyPresent(address restriction); +// 0x3331e9c0 +error CallNotAllowed(bytes call); +// 0x59e1b0d2 +error ChainZeroAddress(); +// 0xff4bbdf1 +error NotAHyperchain(address chainAddress); +// 0xa3decdf3 +error NotAnAdmin(address expected, address actual); +// 0xf6fd7071 +error RemovingPermanentRestriction(); +// 0xfcb9b2e1 +error UnallowedImplementation(bytes32 implementationHash); // 0x1ff9d522 error AddressAlreadyUsed(address addr); // 0x86bb51b8 @@ -115,6 +137,8 @@ error InvalidValue(); error L2BridgeNotDeployed(uint256 chainId); // 0xff8811ff error L2BridgeNotSet(uint256 chainId); +// 0x685577fa +error L2BridgeAlreadySet(uint256 chainId); // 0xcb5e4247 error L2BytecodeHashMismatch(bytes32 expected, bytes32 provided); // 0xfb5c22e6 @@ -171,6 +195,8 @@ error NonZeroAddress(address); error NotEnoughGas(); // 0xdd7e3621 error NotInitializedReentrancyGuard(); +// 0x058d9a1b +error NotPendingAdmin(); // 0xf3ed9dfa error OnlyEraSupported(); // 0x1a21feed diff --git a/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol index 3d5b597df..7aa5c1cc0 100644 --- a/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol +++ b/l1-contracts/contracts/common/interfaces/IL2ContractDeployer.sol @@ -2,6 +2,14 @@ // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; +/// @notice Defines what types of bytecode are allowed to be deployed on this chain +/// - `EraVm` means that only native contracts can be deployed +/// - `EraVmAndEVM` means that native contracts and EVM contracts can be deployed +enum AllowedBytecodeTypes { + EraVm, + EraVmAndEVM +} + /** * @author Matter Labs * @notice System smart contract that is responsible for deploying other smart contracts on a ZKsync hyperchain. @@ -29,4 +37,8 @@ interface IL2ContractDeployer { /// @param _bytecodeHash The correctly formatted hash of the bytecode. /// @param _input The constructor calldata. function create2(bytes32 _salt, bytes32 _bytecodeHash, bytes calldata _input) external; + + /// @notice Changes what types of bytecodes are allowed to be deployed on the chain. + /// @param newAllowedBytecodeTypes The new allowed bytecode types mode. + function setAllowedBytecodeTypesToDeploy(AllowedBytecodeTypes newAllowedBytecodeTypes) external; } diff --git a/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol b/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol index 7055ce557..875e81715 100644 --- a/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol +++ b/l1-contracts/contracts/dev-contracts/test/CustomUpgradeTest.sol @@ -31,7 +31,12 @@ contract CustomUpgradeTest is BaseZkSyncUpgrade { (uint32 newMinorVersion, bool isPatchOnly) = _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); _upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata); _upgradeVerifier(_proposedUpgrade.verifier, _proposedUpgrade.verifierParams); - _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash, isPatchOnly); + _setBaseSystemContracts( + _proposedUpgrade.bootloaderHash, + _proposedUpgrade.defaultAccountHash, + _proposedUpgrade.evmEmulatorHash, + isPatchOnly + ); bytes32 txHash; txHash = _setL2SystemContractUpgrade( diff --git a/l1-contracts/contracts/dev-contracts/test/ExecutorProvingTest.sol b/l1-contracts/contracts/dev-contracts/test/ExecutorProvingTest.sol index 50bccb744..5970e6be4 100644 --- a/l1-contracts/contracts/dev-contracts/test/ExecutorProvingTest.sol +++ b/l1-contracts/contracts/dev-contracts/test/ExecutorProvingTest.sol @@ -32,10 +32,15 @@ contract ExecutorProvingTest is ExecutorFacet { return _processL2Logs(_newBatch, _expectedSystemContractUpgradeTxHash); } - /// Sets the DefaultAccount Hash and Bootloader Hash. - function setHashes(bytes32 l2DefaultAccountBytecodeHash, bytes32 l2BootloaderBytecodeHash) external { + /// Sets the DefaultAccount Hash, Bootloader Hash and EVM emulator Hash. + function setHashes( + bytes32 l2DefaultAccountBytecodeHash, + bytes32 l2BootloaderBytecodeHash, + bytes32 l2EvmEmulatorBytecode + ) external { s.l2DefaultAccountBytecodeHash = l2DefaultAccountBytecodeHash; s.l2BootloaderBytecodeHash = l2BootloaderBytecodeHash; + s.l2EvmEmulatorBytecodeHash = l2EvmEmulatorBytecode; s.zkPorterIsAvailable = false; } } diff --git a/l1-contracts/contracts/dev-contracts/test/ReenterGovernance.sol b/l1-contracts/contracts/dev-contracts/test/ReenterGovernance.sol index 0d619c5ba..193f8085f 100644 --- a/l1-contracts/contracts/dev-contracts/test/ReenterGovernance.sol +++ b/l1-contracts/contracts/dev-contracts/test/ReenterGovernance.sol @@ -3,6 +3,7 @@ pragma solidity 0.8.24; import {IGovernance} from "../../governance/IGovernance.sol"; +import {Call} from "../../governance/Common.sol"; contract ReenterGovernance { // add this to be excluded from coverage report @@ -12,7 +13,7 @@ contract ReenterGovernance { // Store call, predecessor and salt separately, // because Operation struct can't be stored on storage. - IGovernance.Call call; + Call call; bytes32 predecessor; bytes32 salt; @@ -45,7 +46,7 @@ contract ReenterGovernance { fallback() external payable { if (!alreadyReentered) { alreadyReentered = true; - IGovernance.Call[] memory calls = new IGovernance.Call[](1); + Call[] memory calls = new Call[](1); calls[0] = call; IGovernance.Operation memory op = IGovernance.Operation({ calls: calls, diff --git a/l1-contracts/contracts/governance/ChainAdmin.sol b/l1-contracts/contracts/governance/ChainAdmin.sol index 4d9ff858f..c322477a7 100644 --- a/l1-contracts/contracts/governance/ChainAdmin.sol +++ b/l1-contracts/contracts/governance/ChainAdmin.sol @@ -48,6 +48,13 @@ contract ChainAdmin is IChainAdmin, Ownable2Step { emit UpdateUpgradeTimestamp(_protocolVersion, _upgradeTimestamp); } + /// @notice Enable EVM emulation on chain. + /// @param _chainContract The chain contract address where the EVM emulator will be enabled. + function enableEvmEmulator(IAdmin _chainContract) external onlyOwner returns (bytes32 canonicalTxHash) { + canonicalTxHash = _chainContract.allowEvmEmulation(); + emit EnableEvmEmulator(); + } + /// @notice Execute multiple calls as part of contract administration. /// @param _calls Array of Call structures defining target, value, and data for each call. /// @param _requireSuccess If true, reverts transaction on any call failure. diff --git a/l1-contracts/contracts/governance/Common.sol b/l1-contracts/contracts/governance/Common.sol new file mode 100644 index 000000000..fd73dd793 --- /dev/null +++ b/l1-contracts/contracts/governance/Common.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.24; + +/// @dev Represents a call to be made during multicall. +/// @param target The address to which the call will be made. +/// @param value The amount of Ether (in wei) to be sent along with the call. +/// @param data The calldata to be executed on the `target` address. +struct Call { + address target; + uint256 value; + bytes data; +} diff --git a/l1-contracts/contracts/governance/Governance.sol b/l1-contracts/contracts/governance/Governance.sol index 790b79a26..d6e9d9b44 100644 --- a/l1-contracts/contracts/governance/Governance.sol +++ b/l1-contracts/contracts/governance/Governance.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import {Ownable2Step} from "@openzeppelin/contracts-v4/access/Ownable2Step.sol"; import {IGovernance} from "./IGovernance.sol"; +import {Call} from "./Common.sol"; import {ZeroAddress, Unauthorized, OperationMustBeReady, OperationMustBePending, OperationExists, InvalidDelay, PreviousOperationNotExecuted} from "../common/L1ContractErrors.sol"; /// @author Matter Labs diff --git a/l1-contracts/contracts/governance/IChainAdmin.sol b/l1-contracts/contracts/governance/IChainAdmin.sol index d5d8f117c..5bdd15ac9 100644 --- a/l1-contracts/contracts/governance/IChainAdmin.sol +++ b/l1-contracts/contracts/governance/IChainAdmin.sol @@ -27,6 +27,9 @@ interface IChainAdmin { /// @notice Emitted when the new token multiplier address is set. event NewTokenMultiplierSetter(address _oldTokenMultiplierSetter, address _newTokenMultiplierSetter); + /// @notice The EVM emulator has been enabled + event EnableEvmEmulator(); + function setTokenMultiplierSetter(address _tokenMultiplierSetter) external; function setUpgradeTimestamp(uint256 _protocolVersion, uint256 _upgradeTimestamp) external; @@ -34,4 +37,6 @@ interface IChainAdmin { function multicall(Call[] calldata _calls, bool _requireSuccess) external payable; function setTokenMultiplier(IAdmin _chainContract, uint128 _nominator, uint128 _denominator) external; + + function enableEvmEmulator(IAdmin _chainContract) external returns (bytes32 canonicalTxHash); } diff --git a/l1-contracts/contracts/governance/IGovernance.sol b/l1-contracts/contracts/governance/IGovernance.sol index 2b03ed4c9..0cb478573 100644 --- a/l1-contracts/contracts/governance/IGovernance.sol +++ b/l1-contracts/contracts/governance/IGovernance.sol @@ -2,6 +2,8 @@ // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.21; +import {Call} from "./Common.sol"; + /// @title Governance contract interface /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev @@ -18,16 +20,6 @@ interface IGovernance { Done } - /// @dev Represents a call to be made during an operation. - /// @param target The address to which the call will be made. - /// @param value The amount of Ether (in wei) to be sent along with the call. - /// @param data The calldata to be executed on the `target` address. - struct Call { - address target; - uint256 value; - bytes data; - } - /// @dev Defines the structure of an operation that Governance executes. /// @param calls An array of `Call` structs, each representing a call to be made during the operation. /// @param predecessor The hash of the predecessor operation, that should be executed before this operation. diff --git a/l1-contracts/contracts/state-transition/StateTransitionManager.sol b/l1-contracts/contracts/state-transition/StateTransitionManager.sol index 0dbdd2ad1..a14298f2a 100644 --- a/l1-contracts/contracts/state-transition/StateTransitionManager.sol +++ b/l1-contracts/contracts/state-transition/StateTransitionManager.sol @@ -356,6 +356,7 @@ contract StateTransitionManager is IStateTransitionManager, ReentrancyGuard, Own factoryDeps: bytesEmptyArray, bootloaderHash: bytes32(0), defaultAccountHash: bytes32(0), + evmEmulatorHash: bytes32(0), verifier: address(0), verifierParams: VerifierParams({ recursionNodeLevelVkHash: bytes32(0), diff --git a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol index 663cf260a..48eabd4e1 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/DiamondInit.sol @@ -62,6 +62,7 @@ contract DiamondInit is ZkSyncHyperchainBase, IDiamondInit { s.__DEPRECATED_verifierParams = _initializeData.verifierParams; s.l2BootloaderBytecodeHash = _initializeData.l2BootloaderBytecodeHash; s.l2DefaultAccountBytecodeHash = _initializeData.l2DefaultAccountBytecodeHash; + s.l2EvmEmulatorBytecodeHash = _initializeData.l2EvmEmulatorBytecodeHash; s.priorityTxMaxGasLimit = _initializeData.priorityTxMaxGasLimit; s.feeParams = _initializeData.feeParams; s.blobVersionedHashRetriever = _initializeData.blobVersionedHashRetriever; diff --git a/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol b/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol index a06921fdb..952472e54 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/ZkSyncHyperchainStorage.sol @@ -98,6 +98,9 @@ struct ZkSyncHyperchainStorage { /// @notice Bytecode hash of default account (bytecode for EOA). /// @dev Used as an input to zkp-circuit. bytes32 l2DefaultAccountBytecodeHash; + /// @notice Bytecode hash of evm emulator. + /// @dev Used as an input to zkp-circuit. + bytes32 l2EvmEmulatorBytecodeHash; /// @dev Indicates that the porter may be touched on L2 transactions. /// @dev Used as an input to zkp-circuit. bool zkPorterIsAvailable; 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 9f98c00ec..479f4bbdb 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Admin.sol @@ -3,12 +3,15 @@ pragma solidity 0.8.24; import {IAdmin} from "../../chain-interfaces/IAdmin.sol"; +import {IMailbox} from "../../chain-interfaces/IMailbox.sol"; import {Diamond} from "../../libraries/Diamond.sol"; import {MAX_GAS_PER_TRANSACTION} from "../../../common/Config.sol"; import {FeeParams, PubdataPricingMode} from "../ZkSyncHyperchainStorage.sol"; import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; import {IStateTransitionManager} from "../../IStateTransitionManager.sol"; import {Unauthorized, TooMuchGas, PriorityTxPubdataExceedsMaxPubDataPerBatch, InvalidPubdataPricingMode, ProtocolIdMismatch, ChainAlreadyLive, HashMismatch, ProtocolIdNotGreater, DenominatorIsZero, DiamondAlreadyFrozen, DiamondNotFrozen} from "../../../common/L1ContractErrors.sol"; +import {L2_DEPLOYER_SYSTEM_CONTRACT_ADDR} from "../../../common/L2ContractAddresses.sol"; +import {IL2ContractDeployer, AllowedBytecodeTypes} from "../../../common/interfaces/IL2ContractDeployer.sol"; // While formally the following import is not used, it is needed to inherit documentation from it import {IZkSyncHyperchainBase} from "../../chain-interfaces/IZkSyncHyperchainBase.sol"; @@ -119,6 +122,15 @@ contract AdminFacet is ZkSyncHyperchainBase, IAdmin { emit NewTransactionFilterer(oldTransactionFilterer, _transactionFilterer); } + /// @inheritdoc IAdmin + function allowEvmEmulation() external onlyAdmin returns (bytes32 canonicalTxHash) { + canonicalTxHash = IMailbox(address(this)).requestL2ServiceTransaction( + L2_DEPLOYER_SYSTEM_CONTRACT_ADDR, + abi.encodeCall(IL2ContractDeployer.setAllowedBytecodeTypesToDeploy, AllowedBytecodeTypes.EraVmAndEVM) + ); + emit EnableEvmEmulator(); + } + /*////////////////////////////////////////////////////////////// UPGRADE EXECUTION //////////////////////////////////////////////////////////////*/ 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 07995642b..bcef798f4 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Executor.sol @@ -600,13 +600,13 @@ contract ExecutorFacet is ZkSyncHyperchainBase, IExecutor { function _batchMetaParameters() internal view returns (bytes memory) { bytes32 l2DefaultAccountBytecodeHash = s.l2DefaultAccountBytecodeHash; + bytes32 l2EvmEmulatorBytecodeHash = s.l2EvmEmulatorBytecodeHash; return abi.encodePacked( s.zkPorterIsAvailable, s.l2BootloaderBytecodeHash, l2DefaultAccountBytecodeHash, - // VM 1.5.0 requires us to pass the EVM simulator code hash. For now it is the same as the default account. - l2DefaultAccountBytecodeHash + l2EvmEmulatorBytecodeHash ); } 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 9cb2a2da8..5e7350edd 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Getters.sol @@ -52,6 +52,11 @@ contract GettersFacet is ZkSyncHyperchainBase, IGetters, ILegacyGetters { return s.bridgehub; } + /// @inheritdoc IGetters + function getChainId() external view returns (uint256) { + return s.chainId; + } + /// @inheritdoc IGetters function getStateTransitionManager() external view returns (address) { return s.stateTransitionManager; @@ -137,6 +142,11 @@ contract GettersFacet is ZkSyncHyperchainBase, IGetters, ILegacyGetters { return s.l2DefaultAccountBytecodeHash; } + /// @inheritdoc IGetters + function getL2EvmEmulatorBytecodeHash() external view returns (bytes32) { + return s.l2EvmEmulatorBytecodeHash; + } + /// @inheritdoc IGetters function getVerifierParams() external view returns (VerifierParams memory) { return s.__DEPRECATED_verifierParams; 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 43f6b04e7..771c66176 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/Mailbox.sol @@ -15,7 +15,7 @@ import {UncheckedMath} from "../../../common/libraries/UncheckedMath.sol"; import {L2ContractHelper} from "../../../common/libraries/L2ContractHelper.sol"; import {AddressAliasHelper} from "../../../vendor/AddressAliasHelper.sol"; import {ZkSyncHyperchainBase} from "./ZkSyncHyperchainBase.sol"; -import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, ETH_TOKEN_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, PRIORITY_OPERATION_L2_TX_TYPE, PRIORITY_EXPIRATION, MAX_NEW_FACTORY_DEPS} from "../../../common/Config.sol"; +import {REQUIRED_L2_GAS_PRICE_PER_PUBDATA, ETH_TOKEN_ADDRESS, L1_GAS_PER_PUBDATA_BYTE, L2_L1_LOGS_TREE_DEFAULT_LEAF_HASH, PRIORITY_OPERATION_L2_TX_TYPE, PRIORITY_EXPIRATION, MAX_NEW_FACTORY_DEPS, SERVICE_TRANSACTION_SENDER} from "../../../common/Config.sol"; import {L2_BOOTLOADER_ADDRESS, L2_TO_L1_MESSENGER_SYSTEM_CONTRACT_ADDR} from "../../../common/L2ContractAddresses.sol"; import {IL1SharedBridge} from "../../../bridge/interfaces/IL1SharedBridge.sol"; @@ -248,6 +248,28 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { ); } + /// @inheritdoc IMailbox + function requestL2ServiceTransaction( + address _contractL2, + bytes calldata _l2Calldata + ) external onlySelf returns (bytes32 canonicalTxHash) { + canonicalTxHash = _requestL2TransactionFree( + BridgehubL2TransactionRequest({ + sender: SERVICE_TRANSACTION_SENDER, + contractL2: _contractL2, + mintValue: 0, + l2Value: 0, + // Very large amount + l2GasLimit: 72_000_000, + l2Calldata: _l2Calldata, + l2GasPerPubdataByteLimit: REQUIRED_L2_GAS_PRICE_PER_PUBDATA, + factoryDeps: new bytes[](0), + // Tx is free, so no refund recipient needed + refundRecipient: address(0) + }) + ); + } + function _requestL2TransactionSender( BridgehubL2TransactionRequest memory _request ) internal nonReentrant returns (bytes32 canonicalTxHash) { @@ -313,6 +335,19 @@ contract MailboxFacet is ZkSyncHyperchainBase, IMailbox { canonicalTxHash = _writePriorityOp(_params); } + function _requestL2TransactionFree( + BridgehubL2TransactionRequest memory _request + ) internal nonReentrant returns (bytes32 canonicalTxHash) { + WritePriorityOpParams memory params = WritePriorityOpParams({ + request: _request, + txId: s.priorityQueue.getTotalPriorityTxs(), + l2GasPrice: 0, + expirationTimestamp: uint64(block.timestamp + PRIORITY_EXPIRATION) + }); + + canonicalTxHash = _writePriorityOp(params); + } + function _serializeL2Transaction( WritePriorityOpParams memory _priorityOpParams ) internal pure returns (L2CanonicalTransaction memory transaction) { 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 0910fcab3..8d6bbb4ce 100644 --- a/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol +++ b/l1-contracts/contracts/state-transition/chain-deps/facets/ZkSyncHyperchainBase.sol @@ -64,4 +64,11 @@ contract ZkSyncHyperchainBase is ReentrancyGuard { } _; } + + modifier onlySelf() { + if (msg.sender != address(this)) { + revert Unauthorized(msg.sender); + } + _; + } } diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol index 643c6114d..6771c349f 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IAdmin.sol @@ -46,6 +46,9 @@ interface IAdmin is IZkSyncHyperchainBase { /// @notice Set the transaction filterer function setTransactionFilterer(address _transactionFilterer) external; + /// @notice Allow EVM emulation on chain + function allowEvmEmulation() external returns (bytes32 canonicalTxHash); + /// @notice Perform the upgrade from the current protocol version with the corresponding upgrade data /// @param _protocolVersion The current protocol version from which upgrade is executed /// @param _cutData The diamond cut parameters that is executed in the upgrade @@ -105,4 +108,7 @@ interface IAdmin is IZkSyncHyperchainBase { /// @notice Emitted when the contract is unfrozen. event Unfreeze(); + + /// @notice The EVM emulator has been enabled + event EnableEvmEmulator(); } diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol index 189ae69fa..893ff7b7b 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IDiamondInit.sol @@ -18,6 +18,7 @@ import {FeeParams} from "../chain-deps/ZkSyncHyperchainStorage.sol"; /// @param verifierParams Verifier config parameters that describes the circuit to be verified /// @param l2BootloaderBytecodeHash The hash of bootloader L2 bytecode /// @param l2DefaultAccountBytecodeHash The hash of default account L2 bytecode +/// @param l2EvmEmulatorBytecodeHash The hash of EVM emulator L2 bytecode /// @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. @@ -36,6 +37,7 @@ struct InitializeData { VerifierParams verifierParams; bytes32 l2BootloaderBytecodeHash; bytes32 l2DefaultAccountBytecodeHash; + bytes32 l2EvmEmulatorBytecodeHash; uint256 priorityTxMaxGasLimit; FeeParams feeParams; address blobVersionedHashRetriever; @@ -45,6 +47,7 @@ struct InitializeData { /// @param verifierParams Verifier config parameters that describes the circuit to be verified /// @param l2BootloaderBytecodeHash The hash of bootloader L2 bytecode /// @param l2DefaultAccountBytecodeHash The hash of default account L2 bytecode +/// @param l2EvmEmulatorBytecodeHash The hash of EVM emulator L2 bytecode /// @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. @@ -53,6 +56,7 @@ struct InitializeDataNewChain { VerifierParams verifierParams; bytes32 l2BootloaderBytecodeHash; bytes32 l2DefaultAccountBytecodeHash; + bytes32 l2EvmEmulatorBytecodeHash; uint256 priorityTxMaxGasLimit; FeeParams feeParams; address blobVersionedHashRetriever; diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol index 4d06f9e8e..d2e692978 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IGetters.sol @@ -33,6 +33,9 @@ interface IGetters is IZkSyncHyperchainBase { /// @return The address of the base token function getBaseToken() external view returns (address); + /// @return The chain id of the ZK Chain. + function getChainId() external view returns (uint256); + /// @return The address of the base token bridge function getBaseTokenBridge() external view returns (address); @@ -78,6 +81,9 @@ interface IGetters is IZkSyncHyperchainBase { /// @return Bytecode hash of default account (bytecode for EOA). function getL2DefaultAccountBytecodeHash() external view returns (bytes32); + /// @return Bytecode hash of EVM emulator. + function getL2EvmEmulatorBytecodeHash() external view returns (bytes32); + /// @return Verifier parameters. /// @dev This function is deprecated and will soon be removed. function getVerifierParams() external view returns (VerifierParams memory); diff --git a/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol b/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol index 9daffebcf..563fcb12e 100644 --- a/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol +++ b/l1-contracts/contracts/state-transition/chain-interfaces/IMailbox.sol @@ -95,6 +95,15 @@ interface IMailbox is IZkSyncHyperchainBase { address _refundRecipient ) external payable returns (bytes32 canonicalTxHash); + /// @notice Request execution of service L2 transaction from L1. + /// @dev Used for chain configuration. Can be called only by DiamondProxy itself. + /// @param _contractL2 The L2 receiver address + /// @param _l2Calldata The input of the L2 transaction + function requestL2ServiceTransaction( + address _contractL2, + bytes calldata _l2Calldata + ) external returns (bytes32 canonicalTxHash); + function bridgehubRequestL2Transaction( BridgehubL2TransactionRequest calldata _request ) external returns (bytes32 canonicalTxHash); diff --git a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol index 4534884d5..85b38fcfc 100644 --- a/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol +++ b/l1-contracts/contracts/upgrades/BaseZkSyncUpgrade.sol @@ -11,7 +11,7 @@ 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_MINOR_VERSION_DELTA} from "../common/Config.sol"; import {L2CanonicalTransaction} from "../common/Messaging.sol"; -import {ProtocolVersionMinorDeltaTooBig, TimeNotReached, InvalidTxType, L2UpgradeNonceNotEqualToNewProtocolVersion, TooManyFactoryDeps, UnexpectedNumberOfFactoryDeps, ProtocolVersionTooSmall, PreviousUpgradeNotFinalized, PreviousUpgradeNotCleaned, L2BytecodeHashMismatch, PatchCantSetUpgradeTxn, PreviousProtocolMajorVersionNotZero, NewProtocolMajorVersionNotZero, PatchUpgradeCantSetDefaultAccount, PatchUpgradeCantSetBootloader} from "./ZkSyncUpgradeErrors.sol"; +import {ProtocolVersionMinorDeltaTooBig, TimeNotReached, InvalidTxType, L2UpgradeNonceNotEqualToNewProtocolVersion, TooManyFactoryDeps, UnexpectedNumberOfFactoryDeps, ProtocolVersionTooSmall, PreviousUpgradeNotFinalized, PreviousUpgradeNotCleaned, L2BytecodeHashMismatch, PatchCantSetUpgradeTxn, PreviousProtocolMajorVersionNotZero, NewProtocolMajorVersionNotZero, PatchUpgradeCantSetDefaultAccount, PatchUpgradeCantSetBootloader, PatchUpgradeCantSetEvmEmulator} from "./ZkSyncUpgradeErrors.sol"; import {SemVer} from "../common/libraries/SemVer.sol"; /// @notice The struct that represents the upgrade proposal. @@ -19,6 +19,7 @@ import {SemVer} from "../common/libraries/SemVer.sol"; /// @param factoryDeps The list of factory deps for the l2ProtocolUpgradeTx. /// @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. +/// @param evmEmulatorHash The hash of the new EVM emulator bytecode. If zero, it will not be updated. /// @param verifier The address of the new verifier. If zero, the verifier will not be updated. /// @param verifierParams The new verifier params. If all of its fields are 0, the params will not be updated. /// @param l1ContractsUpgradeCalldata Custom calldata for L1 contracts upgrade, it may be interpreted differently @@ -33,6 +34,7 @@ struct ProposedUpgrade { bytes[] factoryDeps; bytes32 bootloaderHash; bytes32 defaultAccountHash; + bytes32 evmEmulatorHash; address verifier; VerifierParams verifierParams; bytes l1ContractsUpgradeCalldata; @@ -54,6 +56,9 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { /// @notice Сhanges to the bytecode that is used in L2 as a default account event NewL2DefaultAccountBytecodeHash(bytes32 indexed previousBytecodeHash, bytes32 indexed newBytecodeHash); + /// @notice Сhanges to the bytecode that is used in L2 as an EVM emulator + event NewL2EvmEmulatorBytecodeHash(bytes32 indexed previousBytecodeHash, bytes32 indexed newBytecodeHash); + /// @notice Verifier address changed event NewVerifier(address indexed oldVerifier, address indexed newVerifier); @@ -79,7 +84,12 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { (uint32 newMinorVersion, bool isPatchOnly) = _setNewProtocolVersion(_proposedUpgrade.newProtocolVersion); _upgradeL1Contract(_proposedUpgrade.l1ContractsUpgradeCalldata); _upgradeVerifier(_proposedUpgrade.verifier, _proposedUpgrade.verifierParams); - _setBaseSystemContracts(_proposedUpgrade.bootloaderHash, _proposedUpgrade.defaultAccountHash, isPatchOnly); + _setBaseSystemContracts( + _proposedUpgrade.bootloaderHash, + _proposedUpgrade.defaultAccountHash, + _proposedUpgrade.evmEmulatorHash, + isPatchOnly + ); txHash = _setL2SystemContractUpgrade( _proposedUpgrade.l2ProtocolUpgradeTx, @@ -115,6 +125,28 @@ abstract contract BaseZkSyncUpgrade is ZkSyncHyperchainBase { emit NewL2DefaultAccountBytecodeHash(previousDefaultAccountBytecodeHash, _l2DefaultAccountBytecodeHash); } + /// @notice Change EVM emulator bytecode hash, that is used on L2 + /// @param _l2EvmEmulatorBytecodeHash The hash of EVM emulator L2 bytecode + /// @param _patchOnly Whether only the patch part of the protocol version semver has changed + function _setL2EvmEmulatorBytecodeHash(bytes32 _l2EvmEmulatorBytecodeHash, bool _patchOnly) private { + if (_l2EvmEmulatorBytecodeHash == bytes32(0)) { + return; + } + + if (_patchOnly) { + revert PatchUpgradeCantSetEvmEmulator(); + } + + L2ContractHelper.validateBytecodeHash(_l2EvmEmulatorBytecodeHash); + + // Save previous value into the stack to put it into the event later + bytes32 previousL2EvmEmulatorBytecodeHash = s.l2EvmEmulatorBytecodeHash; + + // Change the EVM emulator bytecode hash + s.l2EvmEmulatorBytecodeHash = _l2EvmEmulatorBytecodeHash; + emit NewL2EvmEmulatorBytecodeHash(previousL2EvmEmulatorBytecodeHash, _l2EvmEmulatorBytecodeHash); + } + /// @notice Change bootloader bytecode hash, that is used on L2 /// @param _l2BootloaderBytecodeHash The hash of bootloader L2 bytecode /// @param _patchOnly Whether only the patch part of the protocol version semver has changed @@ -184,10 +216,17 @@ 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. + /// @param _evmEmulatorHash The hash of the new EVM emulator bytecode. If zero, it will not be updated. /// @param _patchOnly Whether only the patch part of the protocol version semver has changed. - function _setBaseSystemContracts(bytes32 _bootloaderHash, bytes32 _defaultAccountHash, bool _patchOnly) internal { + function _setBaseSystemContracts( + bytes32 _bootloaderHash, + bytes32 _defaultAccountHash, + bytes32 _evmEmulatorHash, + bool _patchOnly + ) internal { _setL2BootloaderBytecodeHash(_bootloaderHash, _patchOnly); _setL2DefaultAccountBytecodeHash(_defaultAccountHash, _patchOnly); + _setL2EvmEmulatorBytecodeHash(_evmEmulatorHash, _patchOnly); } /// @notice Sets the hash of the L2 system contract upgrade transaction for the next batch to be committed diff --git a/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol index b30c882e7..fe39d7844 100644 --- a/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol +++ b/l1-contracts/contracts/upgrades/ZkSyncUpgradeErrors.sol @@ -32,6 +32,8 @@ error ProtocolVersionShouldBeGreater(uint256 _oldProtocolVersion, uint256 _newPr error PatchUpgradeCantSetDefaultAccount(); // 0x962fd7d0 error PatchUpgradeCantSetBootloader(); +// 0xc231eccd +error PatchUpgradeCantSetEvmEmulator(); // 0x101ba748 error PreviousUpgradeNotFinalized(bytes32 txHash); // 0xa0f47245 diff --git a/l1-contracts/deploy-scripts/DeployL1.s.sol b/l1-contracts/deploy-scripts/DeployL1.s.sol index 416ffd6a3..085bebfac 100644 --- a/l1-contracts/deploy-scripts/DeployL1.s.sol +++ b/l1-contracts/deploy-scripts/DeployL1.s.sol @@ -120,6 +120,7 @@ contract DeployL1Script is Script { bytes diamondCutData; bytes32 bootloaderHash; bytes32 defaultAAHash; + bytes32 evmEmulatorHash; } struct TokensConfig { @@ -214,6 +215,7 @@ contract DeployL1Script is Script { 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.contracts.evmEmulatorHash = toml.readBytes32("$.contracts.evm_emulator_hash"); config.tokens.tokenWethAddress = toml.readAddress("$.tokens.token_weth_address"); } @@ -435,6 +437,7 @@ contract DeployL1Script is Script { verifierParams: verifierParams, l2BootloaderBytecodeHash: config.contracts.bootloaderHash, l2DefaultAccountBytecodeHash: config.contracts.defaultAAHash, + l2EvmEmulatorBytecodeHash: config.contracts.evmEmulatorHash, priorityTxMaxGasLimit: config.contracts.priorityTxMaxGasLimit, feeParams: feeParams, blobVersionedHashRetriever: addresses.blobVersionedHashRetriever diff --git a/l1-contracts/deploy-scripts/EnableEvmEmulator.s.sol b/l1-contracts/deploy-scripts/EnableEvmEmulator.s.sol new file mode 100644 index 000000000..5e9d466ce --- /dev/null +++ b/l1-contracts/deploy-scripts/EnableEvmEmulator.s.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.21; + +import {Script} from "forge-std/Script.sol"; + +import {IZkSyncHyperchain} from "contracts/state-transition/chain-interfaces/IZkSyncHyperchain.sol"; +import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; + +contract EnableEvmEmulator is Script { + // This function should be called by the owner to update token multiplier setter role + function chainAllowEvmEmulation(address chainAdmin, address target) public { + IChainAdmin admin = IChainAdmin(chainAdmin); + + vm.startBroadcast(); + admin.enableEvmEmulator(IZkSyncHyperchain(target)); + vm.stopBroadcast(); + } +} diff --git a/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol b/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol index 0a7e20a53..c2d48f322 100644 --- a/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol +++ b/l1-contracts/deploy-scripts/PrepareZKChainRegistrationCalldata.s.sol @@ -13,6 +13,7 @@ import {AddressAliasHelper} from "contracts/vendor/AddressAliasHelper.sol"; import {L1SharedBridge} from "contracts/bridge/L1SharedBridge.sol"; import {IStateTransitionManager} from "contracts/state-transition/IStateTransitionManager.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {Call} from "contracts/governance/Common.sol"; import {Utils} from "./Utils.sol"; /** @@ -74,6 +75,8 @@ contract PrepareZKChainRegistrationCalldataScript is Script { bytes diamondCutData; // Address of the L1 ERC20 bridge proxy (required for the L2 bridge deployment) address erc20BridgeProxy; + // Should be EVM emulator supported or not + bool allowEvmEmulator; } // Addresses of the contracts in the L1 ecosystem that are fetched from the chain @@ -106,24 +109,24 @@ contract PrepareZKChainRegistrationCalldataScript is Script { checkBaseTokenAddress(); - IGovernance.Call[] memory calls; + Call[] memory calls; uint256 cnt = 0; if (!IBridgehub(ecosystem.bridgehub).tokenIsRegistered(config.baseToken)) { - calls = new IGovernance.Call[](2); + calls = new Call[](2); console.log("Adding a call to register base token on the bridgehub"); - IGovernance.Call memory baseTokenRegistrationCall = prepareRegisterBaseTokenCall(); + Call memory baseTokenRegistrationCall = prepareRegisterBaseTokenCall(); calls[cnt] = baseTokenRegistrationCall; ++cnt; } else { - calls = new IGovernance.Call[](1); + calls = new Call[](1); } - IGovernance.Call memory registerChainCall = prepareRegisterHyperchainCall(); + Call memory registerChainCall = prepareRegisterHyperchainCall(); calls[cnt] = registerChainCall; ++cnt; address l2SharedBridgeProxy = computeL2BridgeAddress(); - IGovernance.Call memory initChainCall = prepareInitializeChainGovernanceCall(l2SharedBridgeProxy); + Call memory initChainCall = prepareInitializeChainGovernanceCall(l2SharedBridgeProxy); scheduleTransparentCalldata(calls, initChainCall); } @@ -151,6 +154,7 @@ contract PrepareZKChainRegistrationCalldataScript is Script { config.diamondCutData = toml.readBytes("$.chain.diamond_cut_data"); config.bridgehubCreateNewChainSalt = toml.readUint("$.chain.bridgehub_create_new_chain_salt"); config.baseToken = toml.readAddress("$.chain.base_token_addr"); + config.allowEvmEmulator = toml.readBool("$.chain.allow_evm_emulator"); bytecodes.l2SharedBridgeBytecode = Utils.readHardhatBytecode("/script-config/artifacts/L2SharedBridge.json"); bytecodes.beaconProxy = Utils.readHardhatBytecode("/script-config/artifacts/BeaconProxy.json"); @@ -178,12 +182,12 @@ contract PrepareZKChainRegistrationCalldataScript is Script { console.log("Using base token address:", config.baseToken); } - function prepareRegisterBaseTokenCall() internal view returns (IGovernance.Call memory) { + function prepareRegisterBaseTokenCall() internal view returns (Call memory) { Bridgehub bridgehub = Bridgehub(ecosystem.bridgehub); bytes memory data = abi.encodeCall(bridgehub.addToken, (config.baseToken)); - return IGovernance.Call({target: ecosystem.bridgehub, value: 0, data: data}); + return Call({target: ecosystem.bridgehub, value: 0, data: data}); } // @dev Computes the address of the L2 bridge and the L2 bridge proxy @@ -267,7 +271,7 @@ contract PrepareZKChainRegistrationCalldataScript is Script { return proxyContractAddress; } - function prepareRegisterHyperchainCall() internal view returns (IGovernance.Call memory) { + function prepareRegisterHyperchainCall() internal view returns (Call memory) { Bridgehub bridgehub = Bridgehub(ecosystem.bridgehub); bytes memory data = abi.encodeCall( @@ -282,26 +286,21 @@ contract PrepareZKChainRegistrationCalldataScript is Script { ) ); - return IGovernance.Call({target: ecosystem.bridgehub, value: 0, data: data}); + return Call({target: ecosystem.bridgehub, value: 0, data: data}); } - function prepareInitializeChainGovernanceCall( - address l2SharedBridgeProxy - ) internal view returns (IGovernance.Call memory) { + function prepareInitializeChainGovernanceCall(address l2SharedBridgeProxy) internal view returns (Call memory) { L1SharedBridge bridge = L1SharedBridge(ecosystem.l1SharedBridgeProxy); bytes memory data = abi.encodeCall(bridge.initializeChainGovernance, (config.chainId, l2SharedBridgeProxy)); - return IGovernance.Call({target: ecosystem.l1SharedBridgeProxy, value: 0, data: data}); + return Call({target: ecosystem.l1SharedBridgeProxy, value: 0, data: data}); } // @dev Prepares a call to schedule a transparent operation on the governance contract // `calls` is an array of calls that will be executed in the first stage (add a token to BH, create a new chain) // `initChainGovCall` is a call that will be executed in the second stage (register the L2 bridge on the L1 shared bridge) - function scheduleTransparentCalldata( - IGovernance.Call[] memory calls, - IGovernance.Call memory initChainGovCall - ) internal { + function scheduleTransparentCalldata(Call[] memory calls, Call memory initChainGovCall) internal { IGovernance governance = IGovernance(ecosystem.governance); IGovernance.Operation memory operation = IGovernance.Operation({ @@ -313,7 +312,7 @@ contract PrepareZKChainRegistrationCalldataScript is Script { bytes memory scheduleCalldata = abi.encodeCall(governance.scheduleTransparent, (operation, 0)); bytes memory executeCalldata = abi.encodeCall(governance.execute, (operation)); - IGovernance.Call[] memory initChainGovArray = new IGovernance.Call[](1); + Call[] memory initChainGovArray = new Call[](1); initChainGovArray[0] = initChainGovCall; IGovernance.Operation memory operation2 = IGovernance.Operation({ diff --git a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol index bbc01226d..9a8c5f781 100644 --- a/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol +++ b/l1-contracts/deploy-scripts/RegisterHyperchain.s.sol @@ -42,6 +42,7 @@ contract RegisterHyperchainScript is Script { address newDiamondProxy; address governance; address chainAdmin; + bool allowEvmEmulator; } Config internal config; @@ -98,6 +99,7 @@ contract RegisterHyperchainScript is Script { ); config.governanceMinDelay = uint256(toml.readUint("$.chain.governance_min_delay")); config.governanceSecurityCouncilAddress = toml.readAddress("$.chain.governance_security_council_address"); + config.allowEvmEmulator = toml.readBool("$.chain.allow_evm_emulator"); } function checkTokenAddress() internal view { @@ -148,7 +150,6 @@ contract RegisterHyperchainScript is Script { function deployChainAdmin() internal { vm.broadcast(); ChainAdmin chainAdmin = new ChainAdmin(config.ownerAddress, address(0)); - console.log("ChainAdmin deployed at:", address(chainAdmin)); config.chainAdmin = address(chainAdmin); } diff --git a/l1-contracts/deploy-scripts/Utils.sol b/l1-contracts/deploy-scripts/Utils.sol index 5f509b0db..24bd49607 100644 --- a/l1-contracts/deploy-scripts/Utils.sol +++ b/l1-contracts/deploy-scripts/Utils.sol @@ -8,6 +8,7 @@ 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 {Call} from "contracts/governance/Common.sol"; import {IERC20} from "@openzeppelin/contracts-v4/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"; @@ -125,13 +126,6 @@ library Utils { } } - /** - * @dev Returns the bytecode hash of the batch bootloader. - */ - function getBatchBootloaderBytecodeHash() internal view returns (bytes memory) { - return vm.readFileBinary("../system-contracts/bootloader/build/artifacts/proved_batch.yul.zbin"); - } - /** * @dev Returns the bytecode of a given system contract. */ @@ -346,8 +340,8 @@ library Utils { ) internal { IGovernance governance = IGovernance(_governor); - IGovernance.Call[] memory calls = new IGovernance.Call[](1); - calls[0] = IGovernance.Call({target: _target, value: _value, data: _data}); + Call[] memory calls = new Call[](1); + calls[0] = Call({target: _target, value: _value, data: _data}); IGovernance.Operation memory operation = IGovernance.Operation({ calls: calls, diff --git a/l1-contracts/scripts/register-hyperchain.ts b/l1-contracts/scripts/register-hyperchain.ts index 1c60ad58d..485eb3579 100644 --- a/l1-contracts/scripts/register-hyperchain.ts +++ b/l1-contracts/scripts/register-hyperchain.ts @@ -68,6 +68,7 @@ async function main() { .option("--base-token-address ") .option("--use-governance ") .option("--token-multiplier-setter-address ") + .option("--allow-evm-emulation") .action(async (cmd) => { const deployWallet = cmd.privateKey ? new Wallet(cmd.privateKey, provider) @@ -106,11 +107,26 @@ async function main() { const tokenMultiplierSetterAddress = cmd.tokenMultiplierSetterAddress || ""; - await deployer.registerHyperchain(baseTokenAddress, cmd.validiumMode, null, gasPrice, useGovernance); + await deployer.registerHyperchain( + baseTokenAddress, + cmd.validiumMode, + null, + gasPrice, + null, + null, + null, + useGovernance + ); if (tokenMultiplierSetterAddress != "") { console.log(`Using token multiplier setter address: ${tokenMultiplierSetterAddress}`); await deployer.setTokenMultiplierSetterAddress(tokenMultiplierSetterAddress); } + + if (cmd.allowEvmEmulation) { + console.log("Allowing EVM emulation"); + await deployer.enableEvmEmulation(); + } + await deployer.transferAdminFromDeployerToChainAdmin(); }); diff --git a/l1-contracts/scripts/token-migration.ts b/l1-contracts/scripts/token-migration.ts index b18260ca3..1ea0d1a12 100644 --- a/l1-contracts/scripts/token-migration.ts +++ b/l1-contracts/scripts/token-migration.ts @@ -233,11 +233,15 @@ export async function transferTokensOnForkedNetwork(deployer: Deployer) { 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)}` + `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)}` + `Balance after: ${await erc20contract.balanceOf( + deployer.addresses.Bridges.ERC20BridgeProxy + )}, ${await erc20contract.balanceOf(deployer.addresses.Bridges.SharedBridgeProxy)}` ); } for (const tokenAddress of tokenList) { diff --git a/l1-contracts/scripts/upgrade-consistency-checker.ts b/l1-contracts/scripts/upgrade-consistency-checker.ts index 530d47dc3..96d19d43d 100644 --- a/l1-contracts/scripts/upgrade-consistency-checker.ts +++ b/l1-contracts/scripts/upgrade-consistency-checker.ts @@ -66,8 +66,9 @@ const expectedGenesisRoot = "0xabdb766b18a479a5c783a4b80e12686bc8ea3cc2d8a305049 const expectedRecursionNodeLevelVkHash = "0xf520cd5b37e74e19fdb369c8d676a04dce8a19457497ac6686d2bb95d94109c8"; const expectedRecursionLeafLevelVkHash = "0xf9664f4324c1400fa5c3822d667f30e873f53f1b8033180cd15fe41c1e2355c6"; const expectedRecursionCircuitsSetVksHash = "0x0000000000000000000000000000000000000000000000000000000000000000"; -const expectedBootloaderHash = "0x010008e742608b21bf7eb23c1a9d0602047e3618b464c9b59c0fba3b3d7ab66e"; -const expectedDefaultAccountHash = "0x01000563374c277a2c1e34659a2a1e87371bb6d852ce142022d497bfb50b9e32"; +const expectedBootloaderHash = "0x010008e7894d0dd14681c76bdb4d5e4e7f6b51bfe40c957d50eed3fec829fdb0"; +const expectedDefaultAccountHash = "0x0100058deb36e1f2eeb48bf3846d0e8eb38e9176754b73116bb41a472459a4dd"; +const expectedEvmEmulatorHash = "0x01000f197081a9906cc411d0698c4961aeb5c74877f37f7071681da6e8ef3f31"; const validatorOne = process.env.ETH_SENDER_SENDER_OPERATOR_COMMIT_ETH_ADDR!; const validatorTwo = process.env.ETH_SENDER_SENDER_OPERATOR_BLOBS_ETH_ADDR!; @@ -221,6 +222,7 @@ async function extractProxyInitializationData(contract: ethers.Contract, data: s recursionCircuitsSetVksHash, l2BootloaderBytecodeHash, l2DefaultAccountBytecodeHash, + l2EvmEmulatorBytecodeHash, // priorityTxMaxGasLimit, // // We unpack fee params @@ -240,6 +242,7 @@ async function extractProxyInitializationData(contract: ethers.Contract, data: s "bytes32", "bytes32", "bytes32", + "bytes32", "uint256", "uint256", "uint256", @@ -276,6 +279,10 @@ async function extractProxyInitializationData(contract: ethers.Contract, data: s throw new Error("L2 default account bytecode hash is not correct"); } + if (l2EvmEmulatorBytecodeHash.toLowerCase() !== expectedEvmEmulatorHash.toLowerCase()) { + throw new Error("L2 EVM emulator bytecode hash is not correct"); + } + console.log("STM init data correct!"); } diff --git a/l1-contracts/scripts/utils.ts b/l1-contracts/scripts/utils.ts index 5ae1bceac..b86be8e15 100644 --- a/l1-contracts/scripts/utils.ts +++ b/l1-contracts/scripts/utils.ts @@ -59,7 +59,12 @@ export function web3Provider() { export function readBatchBootloaderBytecode() { const bootloaderPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/system-contracts/bootloader"); - return fs.readFileSync(`${bootloaderPath}/build/artifacts/proved_batch.yul.zbin`); + + return readBytecodeUtf8(`${bootloaderPath}/build/artifacts/proved_batch.yul/proved_batch.yul.zbin`); +} + +export function readBytecodeUtf8(path: string) { + return ethers.utils.hexlify(fs.readFileSync(path).toString(), { allowMissingPrefix: true }); } export function readSystemContractsBytecode(fileName: string) { @@ -70,6 +75,13 @@ export function readSystemContractsBytecode(fileName: string) { return JSON.parse(artifact.toString()).bytecode; } +export function readEvmEmulatorbytecode() { + const systemContractsPath = path.join(process.env.ZKSYNC_HOME as string, "contracts/system-contracts"); + return readBytecodeUtf8( + `${systemContractsPath}/contracts-preprocessed/artifacts/EvmEmulator.yul/EvmEmulator.yul.zbin` + ); +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any export function print(name: string, data: any) { console.log(`${name}:\n`, JSON.stringify(data, null, 4), "\n"); diff --git a/l1-contracts/src.ts/deploy-process.ts b/l1-contracts/src.ts/deploy-process.ts index d30762a15..e9622bfbe 100644 --- a/l1-contracts/src.ts/deploy-process.ts +++ b/l1-contracts/src.ts/deploy-process.ts @@ -16,6 +16,7 @@ import { ADDRESS_ONE } from "../src.ts/utils"; export const L2_BOOTLOADER_BYTECODE_HASH = "0x1000100000000000000000000000000000000000000000000000000000000000"; export const L2_DEFAULT_ACCOUNT_BYTECODE_HASH = "0x1001000000000000000000000000000000000000000000000000000000000000"; +export const L2_EVM_EMULATOR_BYTECODE_HASH = "0x1010000000000000000000000000000000000000000000000000000000000000"; export async function initialBridgehubDeployment( deployer: Deployer, @@ -58,9 +59,8 @@ export async function initialBridgehubDeployment( nonce++; await deployer.deployGovernance(create2Salt, { gasPrice, nonce }); - nonce++; - await deployer.deployChainAdmin(create2Salt, { gasPrice, nonce }); + await deployer.deployChainAdmin(create2Salt, { gasPrice }); await deployer.deployTransparentProxyAdmin(create2Salt, { gasPrice }); await deployer.deployBridgehubContract(create2Salt, gasPrice); await deployer.deployBlobVersionedHashRetriever(create2Salt, { gasPrice }); diff --git a/l1-contracts/src.ts/deploy-test-process.ts b/l1-contracts/src.ts/deploy-test-process.ts index b8af27b34..db37fc5e1 100644 --- a/l1-contracts/src.ts/deploy-test-process.ts +++ b/l1-contracts/src.ts/deploy-test-process.ts @@ -15,6 +15,7 @@ import { Deployer } from "./deploy"; import { L2_BOOTLOADER_BYTECODE_HASH, L2_DEFAULT_ACCOUNT_BYTECODE_HASH, + L2_EVM_EMULATOR_BYTECODE_HASH, initialBridgehubDeployment, registerHyperchain, } from "./deploy-process"; @@ -65,6 +66,7 @@ export async function defaultDeployerForTests(deployWallet: Wallet, ownerAddress addresses: addressConfig, bootloaderBytecodeHash: L2_BOOTLOADER_BYTECODE_HASH, defaultAccountBytecodeHash: L2_DEFAULT_ACCOUNT_BYTECODE_HASH, + evmEmulatorBytecodeHash: L2_EVM_EMULATOR_BYTECODE_HASH, }); } @@ -76,6 +78,7 @@ export async function defaultEraDeployerForTests(deployWallet: Wallet, ownerAddr addresses: addressConfig, bootloaderBytecodeHash: L2_BOOTLOADER_BYTECODE_HASH, defaultAccountBytecodeHash: L2_DEFAULT_ACCOUNT_BYTECODE_HASH, + evmEmulatorBytecodeHash: L2_EVM_EMULATOR_BYTECODE_HASH, }); const l2_rpc_addr = "http://localhost:3050"; const web3Provider = new zkethers.Provider(l2_rpc_addr); @@ -315,6 +318,7 @@ export class EraDeployer extends Deployer { verifierParams, l2BootloaderBytecodeHash: L2_BOOTLOADER_BYTECODE_HASH, l2DefaultAccountBytecodeHash: L2_DEFAULT_ACCOUNT_BYTECODE_HASH, + l2EvmEmulatorBytecodeHash: L2_EVM_EMULATOR_BYTECODE_HASH, priorityTxMaxGasLimit, feeParams, blobVersionedHashRetriever: this.addresses.BlobVersionedHashRetriever, diff --git a/l1-contracts/src.ts/deploy-utils.ts b/l1-contracts/src.ts/deploy-utils.ts index 71b4d0c31..c431acc5e 100644 --- a/l1-contracts/src.ts/deploy-utils.ts +++ b/l1-contracts/src.ts/deploy-utils.ts @@ -72,7 +72,9 @@ export async function deployBytecodeViaCreate2( const gasUsed = receipt.gasUsed; log( - `${contractName} deployed, gasUsed: ${gasUsed.toString()}, tx hash: ${tx.hash}, expected address: ${expectedAddress}` + `${contractName} deployed, gasUsed: ${gasUsed.toString()}, tx hash: ${ + tx.hash + }, expected address: ${expectedAddress}` ); const deployedBytecodeAfter = await deployWallet.provider.getCode(expectedAddress); diff --git a/l1-contracts/src.ts/deploy.ts b/l1-contracts/src.ts/deploy.ts index 3ee3bb07b..dfc16a810 100644 --- a/l1-contracts/src.ts/deploy.ts +++ b/l1-contracts/src.ts/deploy.ts @@ -10,6 +10,7 @@ import { packSemver, readBatchBootloaderBytecode, readSystemContractsBytecode, + readEvmEmulatorbytecode, unpackStringSemVer, } from "../scripts/utils"; import { getTokens } from "./deploy-token"; @@ -43,6 +44,7 @@ import type { Contract, Overrides } from "@ethersproject/contracts"; let L2_BOOTLOADER_BYTECODE_HASH: string; let L2_DEFAULT_ACCOUNT_BYTECODE_HASH: string; +let L2_EVM_EMULATOR_BYTECODE_HASH: string; export interface DeployerConfig { deployWallet: Wallet; @@ -51,6 +53,7 @@ export interface DeployerConfig { verbose?: boolean; bootloaderBytecodeHash?: string; defaultAccountBytecodeHash?: string; + evmEmulatorBytecodeHash?: string; } export interface Operation { @@ -78,6 +81,9 @@ export class Deployer { L2_DEFAULT_ACCOUNT_BYTECODE_HASH = config.defaultAccountBytecodeHash ? config.defaultAccountBytecodeHash : hexlify(hashL2Bytecode(readSystemContractsBytecode("DefaultAccount"))); + L2_EVM_EMULATOR_BYTECODE_HASH = config.evmEmulatorBytecodeHash + ? config.evmEmulatorBytecodeHash + : hexlify(hashL2Bytecode(readEvmEmulatorbytecode())); this.ownerAddress = config.ownerAddress != null ? config.ownerAddress : this.deployWallet.address; this.chainId = parseInt(process.env.CHAIN_ETH_ZKSYNC_NETWORK_ID!); } @@ -105,6 +111,7 @@ export class Deployer { verifierParams, L2_BOOTLOADER_BYTECODE_HASH, L2_DEFAULT_ACCOUNT_BYTECODE_HASH, + L2_EVM_EMULATOR_BYTECODE_HASH, this.addresses.StateTransition.Verifier, this.addresses.BlobVersionedHashRetriever, +priorityTxMaxGasLimit, @@ -212,6 +219,8 @@ export class Deployer { public async deployChainAdmin(create2Salt: string, ethTxOptions: ethers.providers.TransactionRequest) { ethTxOptions.gasLimit ??= 10_000_000; + + // We deploy the ChainAdmin contract itself const contractAddress = await this.deployViaCreate2( "ChainAdmin", [this.ownerAddress, ethers.constants.AddressZero], @@ -737,7 +746,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, compareDiamondCutHash); - const initialDiamondCut = new ethers.utils.AbiCoder().encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCutData]); + const diamondCutDataEncoded = new ethers.utils.AbiCoder().encode([DIAMOND_CUT_DATA_ABI_STRING], [diamondCutData]); const receipt = await this.executeDirectOrGovernance( useGovernance, @@ -749,7 +758,7 @@ export class Deployer { baseTokenAddress, Date.now(), admin, - initialDiamondCut, + diamondCutDataEncoded, ], 0, { @@ -855,6 +864,17 @@ export class Deployer { } } + public async enableEvmEmulation() { + 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.allowEvmEmulation()).wait(); + if (this.verbose) { + console.log(`EVM emulation allowed, gas used: ${receipt.gasUsed.toString()}`); + } + } + public async transferAdminFromDeployerToChainAdmin() { const stm = this.stateTransitionManagerContract(this.deployWallet); const diamondProxyAddress = await stm.getHyperchain(this.chainId); diff --git a/l1-contracts/src.ts/diamondCut.ts b/l1-contracts/src.ts/diamondCut.ts index c2a8e8728..0bc960fc0 100644 --- a/l1-contracts/src.ts/diamondCut.ts +++ b/l1-contracts/src.ts/diamondCut.ts @@ -35,6 +35,7 @@ export interface InitializeData { allowList: BigNumberish; l2BootloaderBytecodeHash: string; l2DefaultAccountBytecodeHash: string; + l2EvmEmulatorBytecodeHash: string; priorityTxMaxGasLimit: BigNumberish; } diff --git a/l1-contracts/src.ts/utils.ts b/l1-contracts/src.ts/utils.ts index ca18bc7e4..41bca767b 100644 --- a/l1-contracts/src.ts/utils.ts +++ b/l1-contracts/src.ts/utils.ts @@ -136,6 +136,7 @@ export interface ProposedUpgrade { factoryDeps: BytesLike[]; bootloaderHash: BytesLike; defaultAccountHash: BytesLike; + evmEmulatorHash: BytesLike; verifier: string; verifierParams: VerifierParams; l1ContractsUpgradeCalldata: BytesLike; @@ -187,6 +188,7 @@ function checkValidInitialCutHashParams( verifierParams: VerifierParams, l2BootloaderBytecodeHash: string, l2DefaultAccountBytecodeHash: string, + l2EvmEmulatorBytecodeHash: string, verifier: string, blobVersionedHashRetriever: string, priorityTxMaxGasLimit: number @@ -215,6 +217,9 @@ function checkValidInitialCutHashParams( if (l2DefaultAccountBytecodeHash === ethers.constants.HashZero) { throw new Error("L2 default account bytecode hash is zero"); } + if (l2EvmEmulatorBytecodeHash === ethers.constants.HashZero) { + throw new Error("L2 evm emulator bytecode hash is zero"); + } if (verifier === ethers.constants.AddressZero) { throw new Error("Verifier address is zero"); } @@ -234,6 +239,7 @@ export function compileInitialCutHash( verifierParams: VerifierParams, l2BootloaderBytecodeHash: string, l2DefaultAccountBytecodeHash: string, + l2EvmEmulatorBytecodeHash: string, verifier: string, blobVersionedHashRetriever: string, priorityTxMaxGasLimit: number, @@ -246,6 +252,7 @@ export function compileInitialCutHash( verifierParams, l2BootloaderBytecodeHash, l2DefaultAccountBytecodeHash, + l2EvmEmulatorBytecodeHash, verifier, blobVersionedHashRetriever, priorityTxMaxGasLimit @@ -279,6 +286,7 @@ export function compileInitialCutHash( verifierParams, l2BootloaderBytecodeHash, l2DefaultAccountBytecodeHash, + l2EvmEmulatorBytecodeHash, priorityTxMaxGasLimit, feeParams, blobVersionedHashRetriever, 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 7a4badf5f..5025af8a5 100644 --- a/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/DiamondCut/UpgradeLogic.t.sol @@ -91,6 +91,7 @@ contract UpgradeLogicTest is DiamondCutTest { // zkPorterIsAvailable: false, l2BootloaderBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, l2DefaultAccountBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, + l2EvmEmulatorBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, priorityTxMaxGasLimit: 500000, // priority tx max L2 gas limit // initialProtocolVersion: 0, feeParams: FeeParams({ diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/ExecutorProof.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/ExecutorProof.t.sol index 6c6d8a935..fcf039155 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/ExecutorProof.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/ExecutorProof.t.sol @@ -75,9 +75,12 @@ contract ExecutorProofTest is Test { /// This test is based on a block generated in a local system. function test_Hashes() public { utilsFacet.util_setL2DefaultAccountBytecodeHash( - 0x0100065d134a862a777e50059f5e0fbe68b583f3617a67820f7edda0d7f253a0 + 0x0100058d1abd41a9984b37939862f99c18237dc6951c3d5a3d81593c798a8f81 ); - utilsFacet.util_setL2BootloaderBytecodeHash(0x010009416e909e0819593a9806bbc841d25c5cdfed3f4a1523497c6814e5194a); + utilsFacet.util_setL2EvmEmulatorBytecodeHash( + 0x01000f196acd122635a752fcb275be0cc95fd3bba348c1d0908a517fe316418e + ); + utilsFacet.util_setL2BootloaderBytecodeHash(0x010008ddde4acc465cde1c420883701caadb41954567c0b4e3a0d1093a7afde7); utilsFacet.util_setZkPorterAvailability(false); IExecutor.CommitBatchInfo memory nextBatch = IExecutor.CommitBatchInfo({ @@ -86,7 +89,7 @@ contract ExecutorProofTest is Test { // ignored timestamp: 100, indexRepeatedStorageChanges: 84, - newStateRoot: 0x9cf7bb72401a56039ca097cabed20a72221c944ed9b0e515c083c04663ab45a6, + newStateRoot: 0x1df8761352f4d39602beaf619e6b7a96111d3a54550bcf21f2623860cf3ed3d8, // ignored numberOfLayer1Txs: 10, // ignored @@ -118,12 +121,16 @@ contract ExecutorProofTest is Test { ); assertEq( nextCommitment, - 0xa1dcde434352cda8e331e721232ff2d457d4074efae1e3d06ef5b10ffada0c9a, + 0x3073bec0e225ab1e393420a8458f386b76f6e7ba784a2fbcc0ea24a6fd6a32a1, "nextCommitment computation failed" ); - bytes32 prevCommitment = 0x6ebf945305689a8c3ac993df7f002d41d311a762cd6bf39bb054ead8d1f54404; + bytes32 prevCommitment = 0x8199d18dbc01ea80a635f515d6a12312daa1aa32b5404944477dcd41fd7b2bdf; uint256 result = executor.getBatchProofPublicInput(prevCommitment, nextCommitment); - assertEq(result, 0xAC7931F2C11013FC24963E41B86E5325A79F1150350CB41E4F0876A7, "getBatchProofPublicInput"); + assertEq( + result, + 4788207466353486800513567418370563062194355012625279630180492433957, + "getBatchProofPublicInput" + ); } } diff --git a/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol index d81e9cc30..e9a63985a 100644 --- a/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/Executor/_Executor_Shared.t.sol @@ -67,7 +67,7 @@ contract ExecutorTest is Test { } function getGettersSelectors() public view returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](29); + bytes4[] memory selectors = new bytes4[](30); selectors[0] = getters.getVerifier.selector; selectors[1] = getters.getAdmin.selector; selectors[2] = getters.getPendingAdmin.selector; @@ -83,20 +83,21 @@ contract ExecutorTest is Test { selectors[12] = getters.storedBatchHash.selector; selectors[13] = getters.getL2BootloaderBytecodeHash.selector; selectors[14] = getters.getL2DefaultAccountBytecodeHash.selector; - selectors[15] = getters.getVerifierParams.selector; - selectors[16] = getters.isDiamondStorageFrozen.selector; - selectors[17] = getters.getPriorityTxMaxGasLimit.selector; - selectors[18] = getters.isEthWithdrawalFinalized.selector; - selectors[19] = getters.facets.selector; - selectors[20] = getters.facetFunctionSelectors.selector; - selectors[21] = getters.facetAddresses.selector; - selectors[22] = getters.facetAddress.selector; - selectors[23] = getters.isFunctionFreezable.selector; - selectors[24] = getters.isFacetFreezable.selector; - selectors[25] = getters.getTotalBatchesCommitted.selector; - selectors[26] = getters.getTotalBatchesVerified.selector; - selectors[27] = getters.getTotalBatchesExecuted.selector; - selectors[28] = getters.storedBlockHash.selector; + selectors[15] = getters.getL2EvmEmulatorBytecodeHash.selector; + selectors[16] = getters.getVerifierParams.selector; + selectors[17] = getters.isDiamondStorageFrozen.selector; + selectors[18] = getters.getPriorityTxMaxGasLimit.selector; + selectors[19] = getters.isEthWithdrawalFinalized.selector; + selectors[20] = getters.facets.selector; + selectors[21] = getters.facetFunctionSelectors.selector; + selectors[22] = getters.facetAddresses.selector; + selectors[23] = getters.facetAddress.selector; + selectors[24] = getters.isFunctionFreezable.selector; + selectors[25] = getters.isFacetFreezable.selector; + selectors[26] = getters.getTotalBatchesCommitted.selector; + selectors[27] = getters.getTotalBatchesVerified.selector; + selectors[28] = getters.getTotalBatchesExecuted.selector; + selectors[29] = getters.storedBlockHash.selector; return selectors; } @@ -177,6 +178,7 @@ contract ExecutorTest is Test { }), l2BootloaderBytecodeHash: dummyHash, l2DefaultAccountBytecodeHash: dummyHash, + l2EvmEmulatorBytecodeHash: dummyHash, priorityTxMaxGasLimit: 1000000, feeParams: defaultFeeParams(), blobVersionedHashRetriever: blobVersionedHashRetriever diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol index 1260334fd..915264aa9 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/Utils.sol @@ -210,7 +210,7 @@ library Utils { } function getGettersSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](29); + bytes4[] memory selectors = new bytes4[](31); selectors[0] = GettersFacet.getVerifier.selector; selectors[1] = GettersFacet.getAdmin.selector; selectors[2] = GettersFacet.getPendingAdmin.selector; @@ -226,20 +226,22 @@ library Utils { selectors[12] = GettersFacet.storedBatchHash.selector; selectors[13] = GettersFacet.getL2BootloaderBytecodeHash.selector; selectors[14] = GettersFacet.getL2DefaultAccountBytecodeHash.selector; - selectors[15] = GettersFacet.getVerifierParams.selector; - selectors[16] = GettersFacet.isDiamondStorageFrozen.selector; - selectors[17] = GettersFacet.getPriorityTxMaxGasLimit.selector; - selectors[18] = GettersFacet.isEthWithdrawalFinalized.selector; - selectors[19] = GettersFacet.facets.selector; - selectors[20] = GettersFacet.facetFunctionSelectors.selector; - selectors[21] = GettersFacet.facetAddresses.selector; - selectors[22] = GettersFacet.facetAddress.selector; - selectors[23] = GettersFacet.isFunctionFreezable.selector; - selectors[24] = GettersFacet.isFacetFreezable.selector; - selectors[25] = GettersFacet.getTotalBatchesCommitted.selector; - selectors[26] = GettersFacet.getTotalBatchesVerified.selector; - selectors[27] = GettersFacet.getTotalBatchesExecuted.selector; - selectors[28] = GettersFacet.getL2SystemContractsUpgradeTxHash.selector; + selectors[15] = GettersFacet.getL2EvmEmulatorBytecodeHash.selector; + selectors[16] = GettersFacet.getVerifierParams.selector; + selectors[17] = GettersFacet.isDiamondStorageFrozen.selector; + selectors[18] = GettersFacet.getPriorityTxMaxGasLimit.selector; + selectors[19] = GettersFacet.isEthWithdrawalFinalized.selector; + selectors[20] = GettersFacet.facets.selector; + selectors[21] = GettersFacet.facetFunctionSelectors.selector; + selectors[22] = GettersFacet.facetAddresses.selector; + selectors[23] = GettersFacet.facetAddress.selector; + selectors[24] = GettersFacet.isFunctionFreezable.selector; + selectors[25] = GettersFacet.isFacetFreezable.selector; + selectors[26] = GettersFacet.getTotalBatchesCommitted.selector; + selectors[27] = GettersFacet.getTotalBatchesVerified.selector; + selectors[28] = GettersFacet.getTotalBatchesExecuted.selector; + selectors[29] = GettersFacet.getL2SystemContractsUpgradeTxHash.selector; + selectors[30] = GettersFacet.getChainId.selector; return selectors; } @@ -257,7 +259,7 @@ library Utils { } function getUtilsFacetSelectors() public pure returns (bytes4[] memory) { - bytes4[] memory selectors = new bytes4[](41); + bytes4[] memory selectors = new bytes4[](43); selectors[0] = UtilsFacet.util_setChainId.selector; selectors[1] = UtilsFacet.util_getChainId.selector; selectors[2] = UtilsFacet.util_setBridgehub.selector; @@ -276,29 +278,31 @@ library Utils { selectors[15] = UtilsFacet.util_getL2BootloaderBytecodeHash.selector; selectors[16] = UtilsFacet.util_setL2DefaultAccountBytecodeHash.selector; selectors[17] = UtilsFacet.util_getL2DefaultAccountBytecodeHash.selector; - selectors[18] = UtilsFacet.util_setPendingAdmin.selector; - selectors[19] = UtilsFacet.util_getPendingAdmin.selector; - selectors[20] = UtilsFacet.util_setAdmin.selector; - selectors[21] = UtilsFacet.util_getAdmin.selector; - selectors[22] = UtilsFacet.util_setValidator.selector; - selectors[23] = UtilsFacet.util_getValidator.selector; - selectors[24] = UtilsFacet.util_setZkPorterAvailability.selector; - selectors[25] = UtilsFacet.util_getZkPorterAvailability.selector; - selectors[26] = UtilsFacet.util_setStateTransitionManager.selector; - selectors[27] = UtilsFacet.util_getStateTransitionManager.selector; - selectors[28] = UtilsFacet.util_setPriorityTxMaxGasLimit.selector; - selectors[29] = UtilsFacet.util_getPriorityTxMaxGasLimit.selector; - selectors[30] = UtilsFacet.util_setFeeParams.selector; - selectors[31] = UtilsFacet.util_getFeeParams.selector; - selectors[32] = UtilsFacet.util_setProtocolVersion.selector; - selectors[33] = UtilsFacet.util_getProtocolVersion.selector; - selectors[34] = UtilsFacet.util_setIsFrozen.selector; - selectors[35] = UtilsFacet.util_getIsFrozen.selector; - selectors[36] = UtilsFacet.util_setTransactionFilterer.selector; - selectors[37] = UtilsFacet.util_setBaseTokenGasPriceMultiplierDenominator.selector; - selectors[38] = UtilsFacet.util_setTotalBatchesExecuted.selector; - selectors[39] = UtilsFacet.util_setL2LogsRootHash.selector; - selectors[40] = UtilsFacet.util_setBaseTokenGasPriceMultiplierNominator.selector; + selectors[18] = UtilsFacet.util_getL2EvmEmulatorBytecodeHash.selector; + selectors[19] = UtilsFacet.util_setL2EvmEmulatorBytecodeHash.selector; + selectors[20] = UtilsFacet.util_setPendingAdmin.selector; + selectors[21] = UtilsFacet.util_getPendingAdmin.selector; + selectors[22] = UtilsFacet.util_setAdmin.selector; + selectors[23] = UtilsFacet.util_getAdmin.selector; + selectors[24] = UtilsFacet.util_setValidator.selector; + selectors[25] = UtilsFacet.util_getValidator.selector; + selectors[26] = UtilsFacet.util_setZkPorterAvailability.selector; + selectors[27] = UtilsFacet.util_getZkPorterAvailability.selector; + selectors[28] = UtilsFacet.util_setStateTransitionManager.selector; + selectors[29] = UtilsFacet.util_getStateTransitionManager.selector; + selectors[30] = UtilsFacet.util_setPriorityTxMaxGasLimit.selector; + selectors[31] = UtilsFacet.util_getPriorityTxMaxGasLimit.selector; + selectors[32] = UtilsFacet.util_setFeeParams.selector; + selectors[33] = UtilsFacet.util_getFeeParams.selector; + selectors[34] = UtilsFacet.util_setProtocolVersion.selector; + selectors[35] = UtilsFacet.util_getProtocolVersion.selector; + selectors[36] = UtilsFacet.util_setIsFrozen.selector; + selectors[37] = UtilsFacet.util_getIsFrozen.selector; + selectors[38] = UtilsFacet.util_setTransactionFilterer.selector; + selectors[39] = UtilsFacet.util_setBaseTokenGasPriceMultiplierDenominator.selector; + selectors[40] = UtilsFacet.util_setTotalBatchesExecuted.selector; + selectors[41] = UtilsFacet.util_setL2LogsRootHash.selector; + selectors[42] = UtilsFacet.util_setBaseTokenGasPriceMultiplierNominator.selector; return selectors; } @@ -339,6 +343,7 @@ library Utils { verifierParams: makeVerifierParams(), l2BootloaderBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, l2DefaultAccountBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, + l2EvmEmulatorBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, priorityTxMaxGasLimit: 500000, feeParams: makeFeeParams(), blobVersionedHashRetriever: address(0x23746765237749923040872834) @@ -354,6 +359,7 @@ library Utils { verifierParams: makeVerifierParams(), l2BootloaderBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, l2DefaultAccountBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, + l2EvmEmulatorBytecodeHash: 0x0100000000000000000000000000000000000000000000000000000000000000, priorityTxMaxGasLimit: 80000000, feeParams: makeFeeParams(), blobVersionedHashRetriever: address(0x23746765237749923040872834) diff --git a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol index ce9e659a0..25a2be4fb 100644 --- a/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol +++ b/l1-contracts/test/foundry/unit/concrete/Utils/UtilsFacet.sol @@ -80,6 +80,14 @@ contract UtilsFacet is ZkSyncHyperchainBase { return s.l2DefaultAccountBytecodeHash; } + function util_setL2EvmEmulatorBytecodeHash(bytes32 _l2EvmEmulatorBytecodeHash) external { + s.l2EvmEmulatorBytecodeHash = _l2EvmEmulatorBytecodeHash; + } + + function util_getL2EvmEmulatorBytecodeHash() external view returns (bytes32) { + return s.l2EvmEmulatorBytecodeHash; + } + function util_setPendingAdmin(address _pendingAdmin) external { s.pendingAdmin = _pendingAdmin; } diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/Authorization.t.sol similarity index 100% rename from l1-contracts/test/foundry/unit/concrete/Governance/Authorization.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/Authorization.t.sol diff --git a/l1-contracts/test/foundry/unit/concrete/governance/Governance/ChainAdmin.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/ChainAdmin.t.sol new file mode 100644 index 000000000..735d54328 --- /dev/null +++ b/l1-contracts/test/foundry/unit/concrete/governance/Governance/ChainAdmin.t.sol @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.24; + +import {Test} from "forge-std/Test.sol"; + +import "openzeppelin-contracts/contracts/utils/Strings.sol"; +import {IChainAdmin} from "contracts/governance/IChainAdmin.sol"; +import {ChainAdmin} from "contracts/governance/ChainAdmin.sol"; +import {GettersFacet} from "contracts/state-transition/chain-deps/facets/Getters.sol"; +import {Call} from "contracts/governance/Common.sol"; +import {NoCallsProvided, RestrictionWasAlreadyPresent, RestrictionWasNotPresent, AccessToFallbackDenied, AccessToFunctionDenied} from "contracts/common/L1ContractErrors.sol"; +import {Utils} from "test/foundry/unit/concrete/Utils/Utils.sol"; + +contract ChainAdminTest is Test { + ChainAdmin internal chainAdmin; + GettersFacet internal gettersFacet; + + address internal owner; + uint32 internal major; + uint32 internal minor; + uint32 internal patch; + bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; + + function setUp() public { + owner = makeAddr("random address"); + + chainAdmin = new ChainAdmin(owner, address(0)); + + gettersFacet = new GettersFacet(); + } + + function test_setUpgradeTimestamp(uint256 semverMinorVersionMultiplier, uint256 timestamp) public { + (major, minor, patch) = gettersFacet.getSemverProtocolVersion(); + uint256 protocolVersion = packSemver(major, minor, patch + 1, semverMinorVersionMultiplier); + + vm.expectEmit(true, false, false, true); + emit IChainAdmin.UpdateUpgradeTimestamp(protocolVersion, timestamp); + + vm.prank(address(owner)); + chainAdmin.setUpgradeTimestamp(protocolVersion, timestamp); + } + + function test_multicallRevertNoCalls() public { + IChainAdmin.Call[] memory calls = new IChainAdmin.Call[](0); + + vm.prank(owner); + vm.expectRevert(NoCallsProvided.selector); + chainAdmin.multicall(calls, false); + } + + function test_multicallRevertFailedCall() public { + IChainAdmin.Call[] memory calls = new IChainAdmin.Call[](1); + calls[0] = IChainAdmin.Call({ + target: address(chainAdmin), + value: 0, + data: abi.encodeCall(gettersFacet.getAdmin, ()) + }); + + vm.expectRevert(); + vm.prank(owner); + chainAdmin.multicall(calls, true); + } + + function test_multicall() public { + IChainAdmin.Call[] memory calls = new IChainAdmin.Call[](2); + calls[0] = IChainAdmin.Call({ + target: address(gettersFacet), + value: 0, + data: abi.encodeCall(gettersFacet.getAdmin, ()) + }); + calls[1] = IChainAdmin.Call({ + target: address(gettersFacet), + value: 0, + data: abi.encodeCall(gettersFacet.getVerifier, ()) + }); + + vm.prank(owner); + chainAdmin.multicall(calls, true); + } + + function packSemver( + uint32 major, + uint32 minor, + uint32 patch, + uint256 semverMinorVersionMultiplier + ) public returns (uint256) { + if (major != 0) { + revert("Major version must be 0"); + } + + return minor * semverMinorVersionMultiplier + patch; + } +} diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/Executing.t.sol similarity index 99% rename from l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/Executing.t.sol index 9a1e5eeb2..09d6c0267 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/Executing.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/governance/Governance/Executing.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.24; import {StdStorage, stdStorage} from "forge-std/Test.sol"; -import {Utils} from "../Utils/Utils.sol"; +import {Utils} from "../../Utils/Utils.sol"; import {GovernanceTest} from "./_Governance_Shared.t.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Fallback.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/Fallback.t.sol similarity index 100% rename from l1-contracts/test/foundry/unit/concrete/Governance/Fallback.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/Fallback.t.sol diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/OperationStatus.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/OperationStatus.t.sol similarity index 99% rename from l1-contracts/test/foundry/unit/concrete/Governance/OperationStatus.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/OperationStatus.t.sol index 131bb6465..9b4ee36e9 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/OperationStatus.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/governance/Governance/OperationStatus.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {Utils} from "../Utils/Utils.sol"; +import {Utils} from "../../Utils/Utils.sol"; import {GovernanceTest} from "./_Governance_Shared.t.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/Reentrancy.t.sol similarity index 100% rename from l1-contracts/test/foundry/unit/concrete/Governance/Reentrancy.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/Reentrancy.t.sol diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/SelfUpgrades.t.sol similarity index 97% rename from l1-contracts/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/SelfUpgrades.t.sol index 04a909f57..a37acf150 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/SelfUpgrades.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/governance/Governance/SelfUpgrades.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.24; -import {Utils} from "../Utils/Utils.sol"; +import {Utils} from "../../Utils/Utils.sol"; import {GovernanceTest} from "./_Governance_Shared.t.sol"; diff --git a/l1-contracts/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/governance/Governance/_Governance_Shared.t.sol similarity index 93% rename from l1-contracts/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol rename to l1-contracts/test/foundry/unit/concrete/governance/Governance/_Governance_Shared.t.sol index e7f499254..2a34bc2ff 100644 --- a/l1-contracts/test/foundry/unit/concrete/Governance/_Governance_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/governance/Governance/_Governance_Shared.t.sol @@ -6,6 +6,7 @@ import {Test} from "forge-std/Test.sol"; import {Governance} from "contracts/governance/Governance.sol"; import {IGovernance} from "contracts/governance/IGovernance.sol"; +import {Call} from "contracts/governance/Common.sol"; import {EventOnFallback} from "contracts/dev-contracts/EventOnFallback.sol"; import {Forwarder} from "contracts/dev-contracts/Forwarder.sol"; import {RevertFallback} from "contracts/dev-contracts/RevertFallback.sol"; @@ -58,8 +59,8 @@ contract GovernanceTest is Test, EventOnFallback { uint256 _value, bytes memory _data ) internal pure returns (IGovernance.Operation memory) { - IGovernance.Call[] memory calls = new IGovernance.Call[](1); - calls[0] = IGovernance.Call({target: _target, value: _value, data: _data}); + Call[] memory calls = new Call[](1); + calls[0] = Call({target: _target, value: _value, data: _data}); return IGovernance.Operation({calls: calls, salt: bytes32(0), predecessor: bytes32(0)}); } 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 ba69c6bd7..bce302a9b 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 @@ -6,6 +6,10 @@ import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; import {Unauthorized, HashMismatch} from "contracts/common/L1ContractErrors.sol"; contract createNewChainTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_RevertWhen_InitialDiamondCutHashMismatch() public { Diamond.DiamondCutData memory initialDiamondCutData = getDiamondCutData(sharedBridge); Diamond.DiamondCutData memory correctDiamondCutData = getDiamondCutData(address(diamondInit)); @@ -42,4 +46,14 @@ contract createNewChainTest is StateTransitionManagerTest { assertEq(newChainAdmin, admin); assertNotEq(newChainAddress, address(0)); } + + function test_SuccessfulCreationOfNewChainWithEvmEmulator() public { + createNewChainWithEvmEmulator(getDiamondCutData(diamondInit)); + + address admin = chainContractAddress.getChainAdmin(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 1bf8c8a40..98dc2661e 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 @@ -7,6 +7,10 @@ import {IAdmin} from "contracts/state-transition/chain-interfaces/IAdmin.sol"; import {FacetIsFrozen} from "contracts/common/L1ContractErrors.sol"; contract freezeChainTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_FreezingChain() public { createNewChain(getDiamondCutData(diamondInit)); 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 2113f3467..78aef87c3 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 @@ -26,6 +26,10 @@ contract revertBatchesTest is StateTransitionManagerTest { ExecutorFacet internal executorFacet; GettersFacet internal gettersFacet; + function setUp() public { + deploy(); + } + function test_SuccessfulBatchReverting() public { createNewChain(getDiamondCutData(diamondInit)); 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 index 85fa1a316..eeee06beb 100644 --- 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 @@ -8,6 +8,10 @@ import {IExecutor} from "contracts/state-transition/chain-interfaces/IExecutor.s import {EMPTY_STRING_KECCAK, DEFAULT_L2_LOGS_TREE_ROOT_HASH} from "contracts/common/Config.sol"; contract SetChainCreationParamsTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_SettingInitialCutHash() public { bytes32 initialCutHash = keccak256(abi.encode(getDiamondCutData(address(diamondInit)))); address randomDiamondInit = address(0x303030303030303030303); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetNewVersionUpgrade.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetNewVersionUpgrade.t.sol index ced7e3f7d..ceac175df 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetNewVersionUpgrade.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetNewVersionUpgrade.t.sol @@ -5,6 +5,10 @@ import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; contract setNewVersionUpgradeTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_SettingNewVersionUpgrade() public { assertEq(chainContractAddress.protocolVersion(), 0, "Initial protocol version is not correct"); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetUpgradeDiamondCut.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetUpgradeDiamondCut.t.sol index a71f35d2e..32d7614b5 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetUpgradeDiamondCut.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetUpgradeDiamondCut.t.sol @@ -5,6 +5,10 @@ import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol import {Diamond} from "contracts/state-transition/libraries/Diamond.sol"; contract setUpgradeDiamondCutTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_SettingUpgradeDiamondCut() public { assertEq(chainContractAddress.protocolVersion(), 0, "Initial protocol version is not correct"); diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetValidatorTimelock.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetValidatorTimelock.t.sol index d290a8767..2741b3f72 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetValidatorTimelock.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/StateTransitionManager/SetValidatorTimelock.t.sol @@ -4,6 +4,10 @@ pragma solidity 0.8.24; import {StateTransitionManagerTest} from "./_StateTransitionManager_Shared.t.sol"; contract setValidatorTimelockTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_SettingValidatorTimelock() public { assertEq( chainContractAddress.validatorTimelock(), 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 d8fb6e187..8b0e0ce09 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 @@ -8,6 +8,10 @@ import {StateTransitionManagerInitializeData, ChainCreationParams} from "contrac import {ZeroAddress} from "contracts/common/L1ContractErrors.sol"; contract initializingSTMOwnerZeroTest is StateTransitionManagerTest { + function setUp() public { + deploy(); + } + function test_InitializingSTMWithGovernorZeroShouldRevert() public { ChainCreationParams memory chainCreationParams = ChainCreationParams({ genesisUpgrade: address(genesisUpgradeContract), 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 999336642..80195e850 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 @@ -7,6 +7,7 @@ import {Test} from "forge-std/Test.sol"; import {TransparentUpgradeableProxy} from "@openzeppelin/contracts-v4/proxy/transparent/TransparentUpgradeableProxy.sol"; import {Utils} from "foundry-test/unit/concrete/Utils/Utils.sol"; +import {Bridgehub} from "contracts/bridgehub/Bridgehub.sol"; import {UtilsFacet} from "foundry-test/unit/concrete/Utils/UtilsFacet.sol"; import {AdminFacet} from "contracts/state-transition/chain-deps/facets/Admin.sol"; import {ExecutorFacet} from "contracts/state-transition/chain-deps/facets/Executor.sol"; @@ -24,7 +25,7 @@ contract StateTransitionManagerTest is Test { StateTransitionManager internal stateTransitionManager; StateTransitionManager internal chainContractAddress; GenesisUpgrade internal genesisUpgradeContract; - address internal bridgehub; + Bridgehub internal bridgehub; address internal diamondInit; address internal constant governor = address(0x1010101); address internal constant admin = address(0x2020202); @@ -37,12 +38,12 @@ contract StateTransitionManagerTest is Test { Diamond.FacetCut[] internal facetCuts; - function setUp() public { - bridgehub = makeAddr("bridgehub"); + function deploy() public { + bridgehub = new Bridgehub(); newChainAdmin = makeAddr("chainadmin"); - vm.startPrank(bridgehub); - stateTransitionManager = new StateTransitionManager(bridgehub, type(uint256).max); + vm.startPrank(address(bridgehub)); + stateTransitionManager = new StateTransitionManager(address(bridgehub), type(uint256).max); diamondInit = address(new DiamondInit()); genesisUpgradeContract = new GenesisUpgrade(); @@ -128,8 +129,16 @@ contract StateTransitionManagerTest is Test { } function createNewChain(Diamond.DiamondCutData memory _diamondCut) internal { + _createNewChain(_diamondCut, false); + } + + function createNewChainWithEvmEmulator(Diamond.DiamondCutData memory _diamondCut) internal { + _createNewChain(_diamondCut, true); + } + + function _createNewChain(Diamond.DiamondCutData memory _diamondCut, bool allowEvmEmulator) private { vm.stopPrank(); - vm.startPrank(bridgehub); + vm.startPrank(address(bridgehub)); chainContractAddress.createNewChain({ _chainId: chainId, diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol index 205752a9f..9433175cf 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/DiamondInit/Initialize.t.sol @@ -100,6 +100,7 @@ contract InitializeTest is DiamondInitTest { ); assertEq(utilsFacet.util_getL2BootloaderBytecodeHash(), initializeData.l2BootloaderBytecodeHash); assertEq(utilsFacet.util_getL2DefaultAccountBytecodeHash(), initializeData.l2DefaultAccountBytecodeHash); + assertEq(utilsFacet.util_getL2EvmEmulatorBytecodeHash(), initializeData.l2EvmEmulatorBytecodeHash); assertEq(utilsFacet.util_getPriorityTxMaxGasLimit(), initializeData.priorityTxMaxGasLimit); assertEq( keccak256(abi.encode(utilsFacet.util_getFeeParams())), 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 d09b6f204..edf687dd4 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 @@ -45,6 +45,7 @@ contract ExecuteUpgradeTest is AdminTest { factoryDeps: new bytes[](0), bootloaderHash: bytes32(0), defaultAccountHash: bytes32(0), + evmEmulatorHash: bytes32(0), verifier: address(0), verifierParams: verifierParams, l1ContractsUpgradeCalldata: hex"", diff --git a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/_Getters_Shared.t.sol b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/_Getters_Shared.t.sol index 1d64711fe..5bf4d7639 100644 --- a/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/_Getters_Shared.t.sol +++ b/l1-contracts/test/foundry/unit/concrete/state-transition/chain-deps/facets/Getters/_Getters_Shared.t.sol @@ -90,6 +90,10 @@ contract GettersFacetWrapper is GettersFacet { s.l2DefaultAccountBytecodeHash = _l2DefaultAccountBytecodeHash; } + function utils_setL2EvmEmulatorBytecodeHash(bytes32 _l2EvmEmulatorBytecodeHash) external { + s.l2EvmEmulatorBytecodeHash = _l2EvmEmulatorBytecodeHash; + } + function util_setVerifierParams(VerifierParams memory _verifierParams) external { s.__DEPRECATED_verifierParams = _verifierParams; } diff --git a/l1-contracts/test/test_config/constant/hardhat.json b/l1-contracts/test/test_config/constant/hardhat.json index 0e63431f0..d73350137 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": "0xD6E49dd4fb0CA1549566869725d1820aDEb92Ae9" + "address": "0x9F5d1DA449A6c22CCCCE139acD98adD82797fEec" }, { "name": "wBTC", "symbol": "wBTC", "decimals": 8, - "address": "0xcee1f75F30B6908286Cd003C4228A5D9a2851FA4" + "address": "0x275E5aa56a705c8726eE35B3DC6530DE0a0e5f6c" }, { "name": "BAT", "symbol": "BAT", "decimals": 18, - "address": "0x0Bc76A4EfE0748f1697F237fB100741ea6Ceda2d" + "address": "0x18d8b7878Ee8D1cf3c32b177e0B0EC2379084B11" }, { "name": "GNT", "symbol": "GNT", "decimals": 18, - "address": "0x51ae50BcCEE10ac5BEFFA1E4a64106a5f83bc3F8" + "address": "0xe4B41b2c8e3831cbEdC8b3D82047fA30B6B22946" }, { "name": "MLTT", "symbol": "MLTT", "decimals": 18, - "address": "0xa9c7fEEf8586E17D93A05f873BA65f28f48ED259" + "address": "0xe8c976ce9F855825e52015bd1E88Fc84Da1946d2" }, { "name": "DAIK", "symbol": "DAIK", "decimals": 18, - "address": "0x99Efb27598804Aa408A1066550e9d01c45f21b05" + "address": "0xd012f213dDD34858A1357e30B4c491dbFCba8Ee3" }, { "name": "wBTCK", "symbol": "wBTCK", "decimals": 8, - "address": "0x4B701928Da6B3e72775b462A15b8b76ba2d16BbD" + "address": "0x8fbdf8cEAf04E3cc9ac53C90b344c0c2489a0645" }, { "name": "BATK", "symbol": "BATS", "decimals": 18, - "address": "0xf7B03c921dfefB4286b13075BA0335099708368D" + "address": "0x91D6cBBb7006A3fC6686d65375A067624b8D405A" }, { "name": "GNTK", "symbol": "GNTS", "decimals": 18, - "address": "0xc0581Ee28c519533B06cc0aAC1ace98cF63C817b" + "address": "0xEbD3994f1a9d85458bD2a40Fc6927C4048291067" }, { "name": "MLTTK", "symbol": "MLTTS", "decimals": 18, - "address": "0xeB6394F2E8DA607b94dBa2Cf345A965d6D9b3aCD" + "address": "0x194475D0de71858B134e2084fa627B5A7d04334c" }, { "name": "DAIL", "symbol": "DAIL", "decimals": 18, - "address": "0x4311643C5eD7cD0813B4E3Ff5428de71c7d7b8bB" + "address": "0xfB6306147E50e7042E74eA6Cc3db38a8489F8D78" }, { "name": "wBTCL", "symbol": "wBTCP", "decimals": 8, - "address": "0x6b3fbfC9Bb89Ab5F11BE782a1f67c1615c2A5fc3" + "address": "0xA50C21DE8a2d575F915E5f8D6D5ec8eF2935D58e" }, { "name": "BATL", "symbol": "BATW", "decimals": 18, - "address": "0xE003698b7831829843B69D3fB4f9a3133d97b257" + "address": "0xCBaDEF24FA67dB5a56fD84c72b22797A125C3132" }, { "name": "GNTL", "symbol": "GNTW", "decimals": 18, - "address": "0x2417626170675Ccf6022d9db1eFC8f3c59836368" + "address": "0x80C92D6E8d4015660506Cf4F4503eBF3bc073190" }, { "name": "MLTTL", "symbol": "MLTTW", "decimals": 18, - "address": "0x28106C39BE5E51C31D9a289313361D86C9bb7C8E" + "address": "0x44bD975d5735ab2E1b61787228f538e13bF263DC" }, { "name": "Wrapped Ether", "symbol": "WETH", "decimals": 18, - "address": "0x51E83b811930bb4a3aAb3494894ec237Cb6cEc49" + "address": "0xDbEBD56A3068c71f6F71973171c6880a238Ff742" } ] diff --git a/l1-contracts/test/unit_tests/custom_base_token.spec.ts b/l1-contracts/test/unit_tests/custom_base_token.spec.ts index 464298482..b7dce29b1 100644 --- a/l1-contracts/test/unit_tests/custom_base_token.spec.ts +++ b/l1-contracts/test/unit_tests/custom_base_token.spec.ts @@ -147,7 +147,8 @@ describe("Custom base token chain and bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", []) ); - expect(revertReason).contains("MalformedMessage"); + console.log(revertReason); + expect(revertReason).contains("L2WithdrawalMessageWrongLength"); }); it("Should revert on finalizing a withdrawal with wrong function selector", async () => { diff --git a/l1-contracts/test/unit_tests/executor_proof.spec.ts b/l1-contracts/test/unit_tests/executor_proof.spec.ts index 01ac20fc7..d99b7c197 100644 --- a/l1-contracts/test/unit_tests/executor_proof.spec.ts +++ b/l1-contracts/test/unit_tests/executor_proof.spec.ts @@ -15,9 +15,11 @@ describe("Executor test", function () { /// This test is based on a block generated in a local system. it("Test hashes (Rollup)", async () => { - const bootloaderHash = "0x010009416e909e0819593a9806bbc841d25c5cdfed3f4a1523497c6814e5194a"; - const aaHash = "0x0100065d134a862a777e50059f5e0fbe68b583f3617a67820f7edda0d7f253a0"; - const setResult = await executor.setHashes(aaHash, bootloaderHash); + const bootloaderHash = "0x010008bbde6fc402ea3a3d6cb15cb97e70245d3d4e48fb74362d4961b74c16b1"; + const aaHash = "0x0100058d9eee51f4b9e9a9ecb7fd7e8301e90bef018c2bd913ed36e583fec8c2"; + const evmEmulatorHash = "0x01000ccb740e2345754450eda583f59b31a346920a22f968dfcfc63feae303ee"; + + const setResult = await executor.setHashes(aaHash, bootloaderHash, evmEmulatorHash); const finish = await setResult.wait(); expect(finish.status == 1); diff --git a/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts b/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts index 31475e241..fb5cf437d 100644 --- a/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts +++ b/l1-contracts/test/unit_tests/l1_shared_bridge_test.spec.ts @@ -129,7 +129,7 @@ describe("Shared Bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [ethers.constants.HashZero]) ); - expect(revertReason).contains("MalformedMessage"); + expect(revertReason).contains("L2WithdrawalMessageWrongLength"); }); it("Should revert on finalizing a withdrawal with wrong message length", async () => { @@ -145,7 +145,7 @@ describe("Shared Bridge tests", () => { [ethers.constants.HashZero] ) ); - expect(revertReason).contains("MalformedMessage"); + expect(revertReason).contains("L2WithdrawalMessageWrongLength"); }); it("Should revert on finalizing a withdrawal with wrong function selector", async () => { @@ -183,7 +183,7 @@ describe("Shared Bridge tests", () => { const revertReason = await getCallRevertReason( l1SharedBridge.connect(randomSigner).finalizeWithdrawal(chainId, 0, 0, 0, "0x", [ethers.constants.HashZero]) ); - expect(revertReason).contains("MalformedMessage"); + expect(revertReason).contains("L2WithdrawalMessageWrongLength"); }); it("Should revert on finalizing a withdrawal with wrong function signature", async () => { 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 b5d97bf7d..3a0b18aa8 100644 --- a/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts +++ b/l1-contracts/test/unit_tests/l2-upgrade.test.spec.ts @@ -42,7 +42,7 @@ import { } from "./utils"; import { packSemver, unpackStringSemVer, addToProtocolVersion } from "../../scripts/utils"; -describe.only("L2 upgrade test", function () { +describe("L2 upgrade test", function () { let proxyExecutor: ExecutorFacet; let proxyAdmin: AdminFacet; let proxyGetters: GettersFacet; @@ -416,6 +416,7 @@ describe.only("L2 upgrade test", function () { it("Should successfully perform an upgrade", async () => { const bootloaderHash = ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))); const defaultAccountHash = ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))); + const evmEmulatorHash = ethers.utils.hexlify(hashBytecode(ethers.utils.randomBytes(32))); const testnetVerifierFactory = await hardhat.ethers.getContractFactory("TestnetVerifier"); const testnetVerifierContract = await testnetVerifierFactory.deploy(); const newVerifier = testnetVerifierContract.address; @@ -435,6 +436,7 @@ describe.only("L2 upgrade test", function () { const upgrade = { bootloaderHash, defaultAccountHash, + evmEmulatorHash, verifier: newVerifier, verifierParams: newerVerifierParams, executeUpgradeTx: true, @@ -466,6 +468,7 @@ describe.only("L2 upgrade test", function () { // Now, we check that all the data was set as expected expect(await proxyGetters.getL2BootloaderBytecodeHash()).to.equal(bootloaderHash); expect(await proxyGetters.getL2DefaultAccountBytecodeHash()).to.equal(defaultAccountHash); + expect(await proxyGetters.getL2EvmEmulatorBytecodeHash()).to.equal(evmEmulatorHash); expect((await proxyGetters.getVerifier()).toLowerCase()).to.equal(newVerifier.toLowerCase()); expect(await proxyGetters.getProtocolVersion()).to.equal(addToProtocolVersion(initialProtocolVersion, 5, 0)); @@ -499,6 +502,7 @@ describe.only("L2 upgrade test", function () { expect(upgradeEvents[3].args.newBytecodeHash).to.eq(bootloaderHash); expect(upgradeEvents[4].name).to.eq("NewL2DefaultAccountBytecodeHash"); + expect(upgradeEvents[4].args.previousBytecodeHash).to.eq(L2_DEFAULT_ACCOUNT_BYTECODE_HASH); expect(upgradeEvents[4].args.newBytecodeHash).to.eq(defaultAccountHash); }); @@ -508,6 +512,7 @@ describe.only("L2 upgrade test", function () { const currentVerifierParams = await proxyGetters.getVerifierParams(); const currentBootloaderHash = await proxyGetters.getL2BootloaderBytecodeHash(); const currentL2DefaultAccountBytecodeHash = await proxyGetters.getL2DefaultAccountBytecodeHash(); + const currentL2EvmEmulatorBytecodeHash = await proxyGetters.getL2EvmEmulatorBytecodeHash(); const testnetVerifierFactory = await hardhat.ethers.getContractFactory("TestnetVerifier"); const testnetVerifierContract = await testnetVerifierFactory.deploy(); @@ -552,6 +557,7 @@ describe.only("L2 upgrade test", function () { // 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.getL2EvmEmulatorBytecodeHash()).to.equal(currentL2EvmEmulatorBytecodeHash); expect((await proxyGetters.getVerifier()).toLowerCase()).to.equal(newVerifier.toLowerCase()); expect(await proxyGetters.getProtocolVersion()).to.equal(addToProtocolVersion(initialProtocolVersion, 5, 1)); @@ -942,6 +948,7 @@ function buildProposeUpgrade(proposedUpgrade: PartialProposedUpgrade): ProposedU l2ProtocolUpgradeTx: buildL2CanonicalTransaction({ nonce: newProtocolVersion }), bootloaderHash: ethers.constants.HashZero, defaultAccountHash: ethers.constants.HashZero, + evmEmulatorHash: ethers.constants.HashZero, verifier: ethers.constants.AddressZero, verifierParams: buildVerifierParams({}), l1ContractsUpgradeCalldata: "0x", 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 0f4f26bd9..44469df8c 100644 --- a/l1-contracts/test/unit_tests/legacy_era_test.spec.ts +++ b/l1-contracts/test/unit_tests/legacy_era_test.spec.ts @@ -164,7 +164,7 @@ describe("Legacy Era tests", function () { const revertReason = await getCallRevertReason( l1ERC20Bridge.connect(randomSigner).finalizeWithdrawal(0, 0, 0, "0x", [ethers.constants.HashZero]) ); - expect(revertReason).contains("MalformedMessage"); + expect(revertReason).contains("L2WithdrawalMessageWrongLength"); }); it("Should revert on finalizing a withdrawal with wrong function signature", async () => { diff --git a/l1-contracts/test/unit_tests/mailbox_test.spec.ts b/l1-contracts/test/unit_tests/mailbox_test.spec.ts index 5bb874381..230f4e46e 100644 --- a/l1-contracts/test/unit_tests/mailbox_test.spec.ts +++ b/l1-contracts/test/unit_tests/mailbox_test.spec.ts @@ -105,7 +105,7 @@ describe("Mailbox tests", function () { ) ); - expect(revertReason).contains("MalformedBytecode"); + expect(revertReason).contains("LengthIsNotDivisibleBy32"); }); it("Should not accept bytecode of even length in words", async () => { diff --git a/l1-contracts/test/unit_tests/proxy_test.spec.ts b/l1-contracts/test/unit_tests/proxy_test.spec.ts index e63abe0bb..30cb909d2 100644 --- a/l1-contracts/test/unit_tests/proxy_test.spec.ts +++ b/l1-contracts/test/unit_tests/proxy_test.spec.ts @@ -96,6 +96,7 @@ describe("Diamond proxy tests", function () { verifierParams: dummyVerifierParams, l2BootloaderBytecodeHash: "0x0100000000000000000000000000000000000000000000000000000000000000", l2DefaultAccountBytecodeHash: "0x0100000000000000000000000000000000000000000000000000000000000000", + l2EvmEmulatorBytecodeHash: "0x0100000000000000000000000000000000000000000000000000000000000000", priorityTxMaxGasLimit: 500000, // priority tx max L2 gas limit feeParams: defaultFeeParams(), blobVersionedHashRetriever: "0x0000000000000000000000000000000000000001", @@ -134,14 +135,14 @@ describe("Diamond proxy tests", function () { const proxyAsERC20 = TestnetERC20TokenFactory.connect(proxy.address, proxy.signer); const revertReason = await getCallRevertReason(proxyAsERC20.transfer(proxyAsERC20.address, 0)); - expect(revertReason).contains("InvalidSelector"); + expect(revertReason).contains("F"); }); it("check that proxy reject data with no selector", async () => { const dataWithoutSelector = "0x1122"; const revertReason = await getCallRevertReason(proxy.fallback({ data: dataWithoutSelector })); - expect(revertReason).contains("MalformedCalldata"); + expect(revertReason).contains("Ut"); }); it("should freeze the diamond storage", async () => { @@ -178,7 +179,7 @@ describe("Diamond proxy tests", function () { data: executorFacetSelector3 + "0000000000000000000000000000000000000000000000000000000000000000", }) ); - expect(revertReason).contains("FacetIsFrozen"); + expect(revertReason).contains("q1"); }); it("should be able to call an unfreezable facet when diamondStorage is frozen", async () => { diff --git a/l2-contracts/contracts/interfaces/IConsensusRegistry.sol b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol index 34afc0abe..a5e017484 100644 --- a/l2-contracts/contracts/interfaces/IConsensusRegistry.sol +++ b/l2-contracts/contracts/interfaces/IConsensusRegistry.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT - -pragma solidity 0.8.24; +// We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. +pragma solidity ^0.8.20; /// @author Matter Labs /// @custom:security-contact security@matterlabs.dev diff --git a/l2-contracts/foundry.toml b/l2-contracts/foundry.toml index deb178a12..5e7be2051 100644 --- a/l2-contracts/foundry.toml +++ b/l2-contracts/foundry.toml @@ -10,4 +10,4 @@ remappings = [ ] [profile.default.zksync] -zksolc = "1.5.0" +zksolc = "1.5.7" diff --git a/l2-contracts/hardhat.config.ts b/l2-contracts/hardhat.config.ts index 282ab7b96..3e05a558a 100644 --- a/l2-contracts/hardhat.config.ts +++ b/l2-contracts/hardhat.config.ts @@ -12,7 +12,7 @@ if (!process.env.CHAIN_ETH_NETWORK) { export default { zksolc: { - version: "1.5.0", + version: "1.5.7", compilerSource: "binary", settings: { isSystem: true, diff --git a/system-contracts/SystemContractsHashes.json b/system-contracts/SystemContractsHashes.json index 18da55393..1bc5f5115 100644 --- a/system-contracts/SystemContractsHashes.json +++ b/system-contracts/SystemContractsHashes.json @@ -1,212 +1,247 @@ [ { "contractName": "AccountCodeStorage", - "bytecodePath": "artifacts-zk/contracts-preprocessed/AccountCodeStorage.sol/AccountCodeStorage.json", + "bytecodePath": "zkout/AccountCodeStorage.sol/AccountCodeStorage.json", "sourceCodePath": "contracts-preprocessed/AccountCodeStorage.sol", - "bytecodeHash": "0x0100005d05a277543946914759aa4a6c403604b828f80d00b900c669c3d224e1", - "sourceCodeHash": "0x2e0e09d57a04bd1e722d8bf8c6423fdf3f8bca44e5e8c4f6684f987794be066e" + "bytecodeHash": "0x0100007360eb189d11c57c8b45bdd29ae2a996786b55e21847fbbe8e7b285ce2", + "sourceCodeHash": "0xfdac12f45b5cfd4abd12923206f2d6f253d11a6624783e079b55e975d573ceb6" }, { "contractName": "BootloaderUtilities", - "bytecodePath": "artifacts-zk/contracts-preprocessed/BootloaderUtilities.sol/BootloaderUtilities.json", + "bytecodePath": "zkout/BootloaderUtilities.sol/BootloaderUtilities.json", "sourceCodePath": "contracts-preprocessed/BootloaderUtilities.sol", - "bytecodeHash": "0x010007c7bb63f64649098bf75f4baa588db20f445b4d20b7cca972d5d8f973ce", - "sourceCodeHash": "0x0f1213c4b95acb71f4ab5d4082cc1aeb2bd5017e1cccd46afc66e53268609d85" + "bytecodeHash": "0x010006f3bacfc75db6a91f2f2c05485c8f6d7ed0dd259b5d1a7de5bb5f0170a2", + "sourceCodeHash": "0x10f30ac1a7098c7fddec2659ac43422783e8d3fdde02a3ba4d3ff45d451d7001" }, { "contractName": "ComplexUpgrader", - "bytecodePath": "artifacts-zk/contracts-preprocessed/ComplexUpgrader.sol/ComplexUpgrader.json", + "bytecodePath": "zkout/ComplexUpgrader.sol/ComplexUpgrader.json", "sourceCodePath": "contracts-preprocessed/ComplexUpgrader.sol", - "bytecodeHash": "0x0100004da9f3aa5e4febcc53522cb7ee6949369fde25dd79e977752b82b9fd5d", + "bytecodeHash": "0x01000047cfddb4597ec1fcff6ce1b13c404b128f8c7349943f00c8e702fcecd5", "sourceCodeHash": "0x796046a914fb676ba2bbd337b2924311ee2177ce54571c18a2c3945755c83614" }, { "contractName": "Compressor", - "bytecodePath": "artifacts-zk/contracts-preprocessed/Compressor.sol/Compressor.json", + "bytecodePath": "zkout/Compressor.sol/Compressor.json", "sourceCodePath": "contracts-preprocessed/Compressor.sol", - "bytecodeHash": "0x0100014fb4f05ae09288cbcf4fa7a09ca456910f6e69be5ac2c2dfc8d71d1576", + "bytecodeHash": "0x0100013f5b38355d5720b282db0cf3869b78e2c8d631550ef7a0f33e5757f6be", "sourceCodeHash": "0xc6f7cd8b21aae52ed3dd5083c09b438a7af142a4ecda6067c586770e8be745a5" }, { "contractName": "ContractDeployer", - "bytecodePath": "artifacts-zk/contracts-preprocessed/ContractDeployer.sol/ContractDeployer.json", + "bytecodePath": "zkout/ContractDeployer.sol/ContractDeployer.json", "sourceCodePath": "contracts-preprocessed/ContractDeployer.sol", - "bytecodeHash": "0x010004e5d52d692822d5c54ac87de3297f39be0e4a6f72f2830ae5ac856684ee", - "sourceCodeHash": "0x82f81fbf5fb007a9cac97462d50907ca5d7a1af62d82d2645e093ed8647a5209" + "bytecodeHash": "0x01000655cfaee8879d6d5f020e8cac9b00e5830a8aef6d01f9406b4583fa4bd8", + "sourceCodeHash": "0x22f96404a0527177f635c81315349ee274806e7462c5e5ae087a005f991bc157" }, { "contractName": "Create2Factory", - "bytecodePath": "artifacts-zk/contracts-preprocessed/Create2Factory.sol/Create2Factory.json", + "bytecodePath": "zkout/Create2Factory.sol/Create2Factory.json", "sourceCodePath": "contracts-preprocessed/Create2Factory.sol", - "bytecodeHash": "0x010000495bd172e90725e6bfafe73e36a288d616d4673f5347eeb819a78bf546", + "bytecodeHash": "0x0100003f53ff30da1f9c344e63c5a031affbf8af76baf0a92c977fefc8665a0c", "sourceCodeHash": "0x114d9322a9ca654989f3e0b3b21f1311dbc4db84f443d054cd414f6414d84de3" }, { "contractName": "DefaultAccount", - "bytecodePath": "artifacts-zk/contracts-preprocessed/DefaultAccount.sol/DefaultAccount.json", + "bytecodePath": "zkout/DefaultAccount.sol/DefaultAccount.json", "sourceCodePath": "contracts-preprocessed/DefaultAccount.sol", - "bytecodeHash": "0x0100055dba11508480be023137563caec69debc85f826cb3a4b68246a7cabe30", - "sourceCodeHash": "0xebffe840ebbd9329edb1ebff8ca50f6935e7dabcc67194a896fcc2e968d46dfb" + "bytecodeHash": "0x0100050b06623d83e54b5752821bc70b493f31989359002205a2f9264dba83f4", + "sourceCodeHash": "0x300c864fcb3bc6a562875c7b1d83df15d466515da0a878a426b1aaeac26f3656" }, { "contractName": "EmptyContract", - "bytecodePath": "artifacts-zk/contracts-preprocessed/EmptyContract.sol/EmptyContract.json", + "bytecodePath": "zkout/EmptyContract.sol/EmptyContract.json", "sourceCodePath": "contracts-preprocessed/EmptyContract.sol", - "bytecodeHash": "0x010000078f32964c38fbd138a0369f4723f07ac6f4919c45ef738c18bf874ccd", + "bytecodeHash": "0x01000007eb54e2d3bac886a8bc01a7fa41d3c1effb129cc72edc600bd9866af9", "sourceCodeHash": "0xcac36c5afafbcff83601f4fbfdff660aa66d8c80ed97b9322d3011c1926b554d" }, { "contractName": "ImmutableSimulator", - "bytecodePath": "artifacts-zk/contracts-preprocessed/ImmutableSimulator.sol/ImmutableSimulator.json", + "bytecodePath": "zkout/ImmutableSimulator.sol/ImmutableSimulator.json", "sourceCodePath": "contracts-preprocessed/ImmutableSimulator.sol", - "bytecodeHash": "0x01000039785a8e0d342a49b6b6c6e156801b816434d93bee85d33f56d56b4f9a", + "bytecodeHash": "0x0100003345f92c227817a46a1cb0ee12cac25cb8516251a028f24d6cb1feb77b", "sourceCodeHash": "0x9659e69f7db09e8f60a8bb95314b1ed26afcc689851665cf27f5408122f60c98" }, { "contractName": "KnownCodesStorage", - "bytecodePath": "artifacts-zk/contracts-preprocessed/KnownCodesStorage.sol/KnownCodesStorage.json", + "bytecodePath": "zkout/KnownCodesStorage.sol/KnownCodesStorage.json", "sourceCodePath": "contracts-preprocessed/KnownCodesStorage.sol", - "bytecodeHash": "0x0100006f0f209c9e6d06b1327db1257b15fa7a8b9864ee5ccd12cd3f8bc40ac9", - "sourceCodeHash": "0xb39b5b81168653e0c5062f7b8e1d6d15a4e186df3317f192f0cb2fc3a74f5448" + "bytecodeHash": "0x010000cde320e4772a0ef635bff69f07fd908a6140480cf2c17f2cf0214d86a3", + "sourceCodeHash": "0x851fb5e170dfde39f1f9bc74654ec0b8f8f1d4c2fb20c06c77844c1e3ee0659a" }, { "contractName": "L1Messenger", - "bytecodePath": "artifacts-zk/contracts-preprocessed/L1Messenger.sol/L1Messenger.json", + "bytecodePath": "zkout/L1Messenger.sol/L1Messenger.json", "sourceCodePath": "contracts-preprocessed/L1Messenger.sol", - "bytecodeHash": "0x010002955993e8ff8190e388e94a6bb791fbe9c6388e5011c52cb587a4ebf05e", + "bytecodeHash": "0x0100026320ad1a050ca08117bb57a06684839b3ab3f3095e17deb1ebeb53d4ac", "sourceCodeHash": "0xa8768fdaac6d8804782f14e2a51bbe2b6be31dee9103b6d02d149ea8dc46eb6a" }, { "contractName": "L2BaseToken", - "bytecodePath": "artifacts-zk/contracts-preprocessed/L2BaseToken.sol/L2BaseToken.json", + "bytecodePath": "zkout/L2BaseToken.sol/L2BaseToken.json", "sourceCodePath": "contracts-preprocessed/L2BaseToken.sol", - "bytecodeHash": "0x01000103174a90beadc2cffe3e81bdb7b8a576174e888809c1953175fd3015b4", - "sourceCodeHash": "0x8bdd2b4d0b53dba84c9f0af250bbaa2aad10b3de6747bba957f0bd3721090dfa" + "bytecodeHash": "0x010000db58a5798e8cf03299e84c32288bd535f03140112d8461b84ec164887a", + "sourceCodeHash": "0xdea518b1ea16718b0f0ec6155b227a8bc8f51374a9eebf7bc17cfe84433df740" }, { "contractName": "MsgValueSimulator", - "bytecodePath": "artifacts-zk/contracts-preprocessed/MsgValueSimulator.sol/MsgValueSimulator.json", + "bytecodePath": "zkout/MsgValueSimulator.sol/MsgValueSimulator.json", "sourceCodePath": "contracts-preprocessed/MsgValueSimulator.sol", - "bytecodeHash": "0x0100005da36075675b98f85fe90df11c1d526f6b12925da3a55a8b9c02aaac5f", + "bytecodeHash": "0x0100005964d673fb20cd2c77df6f9aa4c178bd8ffa54eb582505df704b1f3b5b", "sourceCodeHash": "0x082f3dcbc2fe4d93706c86aae85faa683387097d1b676e7ebd00f71ee0f13b71" }, { "contractName": "NonceHolder", - "bytecodePath": "artifacts-zk/contracts-preprocessed/NonceHolder.sol/NonceHolder.json", + "bytecodePath": "zkout/NonceHolder.sol/NonceHolder.json", "sourceCodePath": "contracts-preprocessed/NonceHolder.sol", - "bytecodeHash": "0x010000d97de8c14cd36b1ce06cd7f44a09f6093ec8eb4041629c0fc2116d0c73", + "bytecodeHash": "0x010000cfa9aff9356b0ef66e9ca32df21ae4bcbb2a8d03d3acf74e2d060a3028", "sourceCodeHash": "0xcd0c0366effebf2c98c58cf96322cc242a2d1c675620ef5514b7ed1f0a869edc" }, { "contractName": "PubdataChunkPublisher", - "bytecodePath": "artifacts-zk/contracts-preprocessed/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", + "bytecodePath": "zkout/PubdataChunkPublisher.sol/PubdataChunkPublisher.json", "sourceCodePath": "contracts-preprocessed/PubdataChunkPublisher.sol", - "bytecodeHash": "0x010000470e396f376539289b7975b6866914a8a0994008a02987edac8be81db7", + "bytecodeHash": "0x010000419856be032b7143f70782d129e260d6e99e6bbe7c4787884ccd949ce9", "sourceCodeHash": "0xd7161e2c8092cf57b43c6220bc605c0e7e540bddcde1af24e2d90f75633b098e" }, { "contractName": "SystemContext", - "bytecodePath": "artifacts-zk/contracts-preprocessed/SystemContext.sol/SystemContext.json", + "bytecodePath": "zkout/SystemContext.sol/SystemContext.json", "sourceCodePath": "contracts-preprocessed/SystemContext.sol", - "bytecodeHash": "0x010001a5eabf9e28288b7ab7e1db316148021347460cfb4314570956867d5af5", - "sourceCodeHash": "0xf308743981ef5cea2f7a3332b8e51695a5e47e811a63974437fc1cceee475e7a" + "bytecodeHash": "0x010001a5305c969f525ba5afc3c7496c520d77ca71bdebc9c3b8e71c7a0d3364", + "sourceCodeHash": "0xaf04a52c660f48de04c29b6c88632b4e002e94f58e0f8de034fd73959671c984" }, { "contractName": "EventWriter", - "bytecodePath": "contracts-preprocessed/artifacts/EventWriter.yul.zbin", + "bytecodePath": "zkout/EventWriter.yul/contracts-preprocessed/EventWriter.yul.json", "sourceCodePath": "contracts-preprocessed/EventWriter.yul", - "bytecodeHash": "0x010000159b30cba9e2096353695b63ca5cbf566416a545a6bcb2ff2e4e672f98", + "bytecodeHash": "0x01000017575446d56eb4e640189c5e356449975b957ae5262924567f4f664d75", "sourceCodeHash": "0xfcf4828bcc109dea5f88c38f428d9ac5e18d5a2767fa4909277802c7e38c1f93" }, + { + "contractName": "EvmEmulator", + "bytecodePath": "zkout/EvmEmulator.yul/contracts-preprocessed/EvmEmulator.yul.json", + "sourceCodePath": "contracts-preprocessed/EvmEmulator.yul", + "bytecodeHash": "0x01000bef3afffa6dcca82a514f5f388101dd3498e9117be2073975d8ae791970", + "sourceCodeHash": "0x7cad60f966f85be729468ca5f3500ffd4a4b2d0ef6df5ca0656ac7f46c0d2402" + }, + { + "contractName": "EvmGasManager", + "bytecodePath": "zkout/EvmGasManager.yul/contracts-preprocessed/EvmGasManager.yul.json", + "sourceCodePath": "contracts-preprocessed/EvmGasManager.yul", + "bytecodeHash": "0x01000073ec5f4ae42b87e9ef80c92506f25710cce88d32a510f79093633260bf", + "sourceCodeHash": "0x825dc1d9bec5128457a8b96eaf7ebf7c89dbb95a9bd7aab0f1601bc06455abfb" + }, { "contractName": "CodeOracle", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/CodeOracle.yul.zbin", + "bytecodePath": "zkout/CodeOracle.yul/contracts-preprocessed/precompiles/CodeOracle.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/CodeOracle.yul", - "bytecodeHash": "0x01000023d652655672eafbb0adc385bd423a4a59f752a28f3dde16e74fa205e3", - "sourceCodeHash": "0x476063e7907f2b7a532c4da6f606fa07186b5a10d77af8fdd83dbea3d9f23f93" + "bytecodeHash": "0x01000023fa893b49736f6009966b73613fe2b1ffd6d57ffb7a03dd4cd48940a9", + "sourceCodeHash": "0xf4b21b6712a6e2a001a1b8214ac15959e670bd0ff125984486a28e128cb8846d" }, { "contractName": "EcAdd", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcAdd.yul.zbin", + "bytecodePath": "zkout/EcAdd.yul/contracts-preprocessed/precompiles/EcAdd.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/EcAdd.yul", - "bytecodeHash": "0x01000087be6181fcb16bebb0567c58b658eec345822aec1d42d471e84f758b85", + "bytecodeHash": "0x01000085bf765ff04ad45979da71816fba3bdee901366c5cce73c94f3ee37bb9", "sourceCodeHash": "0xdfec1c5f8c6a93df1c8821f1ac15058a18a640bcbdeb67dc4a017f2153ff1c86" }, { "contractName": "EcMul", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcMul.yul.zbin", + "bytecodePath": "zkout/EcMul.yul/contracts-preprocessed/precompiles/EcMul.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/EcMul.yul", - "bytecodeHash": "0x010000bd553a916fcda3726f7b6b3ccfc17887166982915ced63abc78ba43b66", + "bytecodeHash": "0x010000bbb84f463e70d100c271744ab9827d4c9b66ee4356a0c697dcb54e3b87", "sourceCodeHash": "0x0e3f320c8a9532425b85809bf0a2136e707046a01bf20491ec03c77887516c43" }, { "contractName": "EcPairing", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/EcPairing.yul.zbin", + "bytecodePath": "zkout/EcPairing.yul/contracts-preprocessed/precompiles/EcPairing.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/EcPairing.yul", - "bytecodeHash": "0x01000f1b5f8dd50a00b502d2663746a49a81a01857b6ee1e1b38c9959142b299", + "bytecodeHash": "0x01000ef37666c6447ad953d8be7ca75d4a0de3d5fd57a3966906d2c5577111ab", "sourceCodeHash": "0x5d008cedc44e0e52c2567fd2b877916b2ec5e7c80294cf99b66485e50a6f2c12" }, { "contractName": "Ecrecover", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Ecrecover.yul.zbin", + "bytecodePath": "zkout/Ecrecover.yul/contracts-preprocessed/precompiles/Ecrecover.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/Ecrecover.yul", - "bytecodeHash": "0x010000113d6b03e34605f26aa1fc6fb8953561eb55bb5ea192a5a38f7de3053b", + "bytecodeHash": "0x01000013409fe778437b58e5819ee48a658fb09b86bb7badf93cb334c16cc632", "sourceCodeHash": "0x21e03ab7a5f518a21258669c82506b1d4d1141f8fd4f30bb385f9730580ddd3c" }, + { + "contractName": "Identity", + "bytecodePath": "zkout/Identity.yul/contracts-preprocessed/precompiles/Identity.yul.json", + "sourceCodePath": "contracts-preprocessed/precompiles/Identity.yul", + "bytecodeHash": "0x0100000d9a79ff7daa1faef10d70906e871307162ea56e796c674a6c123e719f", + "sourceCodeHash": "0xcdf59308c83593ed41d9742411fdf41cfd9863932f948d20d08a11f6dcbd8f46" + }, { "contractName": "Keccak256", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/Keccak256.yul.zbin", + "bytecodePath": "zkout/Keccak256.yul/contracts-preprocessed/precompiles/Keccak256.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/Keccak256.yul", - "bytecodeHash": "0x0100000ff991d5847f1e9c10c5969d0f03b34a25411ad86d5cb3e0d9c3931e0b", + "bytecodeHash": "0x0100000fb95dd6f46682ea2f0b187124613531b459091a6c38dc9d0260e5fff1", "sourceCodeHash": "0xb454e7760732ce1fffc75174c8cf54dca422206cf1e52a29d274b310b574f26d" }, { "contractName": "P256Verify", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/P256Verify.yul.zbin", + "bytecodePath": "zkout/P256Verify.yul/contracts-preprocessed/precompiles/P256Verify.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/P256Verify.yul", - "bytecodeHash": "0x010000116595cfcc96291f95d47ede2ce630f25ccbd7428f00dc7f8135fb565a", + "bytecodeHash": "0x0100000f72c45ba0985fe38394a29445cb337c127afb0da5e94211d518a00949", "sourceCodeHash": "0x976b68d0362307313fd1aaea309eaa2d849187f37da451618c70dd3a6ac3cf3c" }, { "contractName": "SHA256", - "bytecodePath": "contracts-preprocessed/precompiles/artifacts/SHA256.yul.zbin", + "bytecodePath": "zkout/SHA256.yul/contracts-preprocessed/precompiles/SHA256.yul.json", "sourceCodePath": "contracts-preprocessed/precompiles/SHA256.yul", - "bytecodeHash": "0x010000171e4e61b14feacd43cb555bffa5f194d38117132957708dcef83ac15a", + "bytecodeHash": "0x010000176a7caf23abe1829a27684e6172e72e3b8a1d201364c5bbe53615202b", "sourceCodeHash": "0xfd4290467e26e992f39db9ca132e78ce99ce042b0254a368f1d7832dc94ddefb" }, { "contractName": "bootloader_test", - "bytecodePath": "bootloader/build/artifacts/bootloader_test.yul.zbin", + "bytecodePath": "zkout/bootloader_test.yul/contracts-preprocessed/bootloader/bootloader_test.yul.json", "sourceCodePath": "bootloader/build/bootloader_test.yul", - "bytecodeHash": "0x010003cbe67434b2848054322cbc311385851bbfbf70d17f92cd5f1f9836b25e", - "sourceCodeHash": "0x006fdf461899dec5fdb34301c23e6819eb93e275907cbfc67d73fccfb47cae68" + "bytecodeHash": "0x010003ad66485b2f2802f2028e7da75e226fae47b815627f05ac541dd646a1dd", + "sourceCodeHash": "0xe4a10be4e60eccc1ec39dbf7b07c12a16f2202f1904eba045ea66d13adfe5659" + }, + { + "contractName": "dummy", + "bytecodePath": "zkout/dummy.yul/contracts-preprocessed/bootloader/dummy.yul.json", + "sourceCodePath": "bootloader/build/dummy.yul", + "bytecodeHash": "0x0100000799df180103cb4323acaa77800d219c3e00d3eeed7774d1fbdad4b930", + "sourceCodeHash": "0xfac5ca11a9882425af93fe5bac6d10055b119cf13af79e6a2f4e74e8411b9c85" }, { "contractName": "fee_estimate", - "bytecodePath": "bootloader/build/artifacts/fee_estimate.yul.zbin", + "bytecodePath": "zkout/fee_estimate.yul/contracts-preprocessed/bootloader/fee_estimate.yul.json", "sourceCodePath": "bootloader/build/fee_estimate.yul", - "bytecodeHash": "0x0100092d9b8ae575bca569f68fe60fbef1dc7d4aad6aa02cc4836f56afcf0a38", - "sourceCodeHash": "0x8a858319bac2924a3dee778218a7fe5e23898db0d87b02d7b783f94c5a02d257" + "bytecodeHash": "0x010008fdfeb9d95c6ff3801b96a1a5ad3917132ac5abb0df4f5da81f5c565978", + "sourceCodeHash": "0xb1ae1f7bccf8f5d75dfe36c33322937bc2b3565a59ea23d8360caa8f9565f348" }, { "contractName": "gas_test", - "bytecodePath": "bootloader/build/artifacts/gas_test.yul.zbin", + "bytecodePath": "zkout/gas_test.yul/contracts-preprocessed/bootloader/gas_test.yul.json", "sourceCodePath": "bootloader/build/gas_test.yul", - "bytecodeHash": "0x010008b3e1b8bdd393f2f8d6f5c994c8b9c287df7310dee75d0c52a245fc7cb1", - "sourceCodeHash": "0x89f5ad470f10e755fa57b82507518e571c24409a328bc33aeba26e9518ad1c3e" + "bytecodeHash": "0x010008693e2b453a622a5ec0ac8b79844750f21a3b7476786388d17b59c17f0f", + "sourceCodeHash": "0x8797a5687a30f46369f8248093537162c3ebc512fb89c0fe8662e2cbe4525ada" }, { "contractName": "playground_batch", - "bytecodePath": "bootloader/build/artifacts/playground_batch.yul.zbin", + "bytecodePath": "zkout/playground_batch.yul/contracts-preprocessed/bootloader/playground_batch.yul.json", "sourceCodePath": "bootloader/build/playground_batch.yul", - "bytecodeHash": "0x01000933061c23d700f3f647c45068e22f5506ff33bb516ac13f11069b163986", - "sourceCodeHash": "0x769448c4fd2b65c43d758ca5f34dd29d9b9dd3000fd0ec89cffcaf8d365a64fd" + "bytecodeHash": "0x010009031e40639e1d7d6a38a16aa2777f26b37ad8a4dce4bcdbec9bbaf2dbf8", + "sourceCodeHash": "0x6babd6fcf22f0b28fcbcdf5f085a7fb354aacc5f95d7ab0b6fe36f24254a30ce" }, { "contractName": "proved_batch", - "bytecodePath": "bootloader/build/artifacts/proved_batch.yul.zbin", + "bytecodePath": "zkout/proved_batch.yul/contracts-preprocessed/bootloader/proved_batch.yul.json", "sourceCodePath": "bootloader/build/proved_batch.yul", - "bytecodeHash": "0x010008c3be57ae5800e077b6c2056d9d75ad1a7b4f0ce583407961cc6fe0b678", - "sourceCodeHash": "0x908bc6ddb34ef89b125e9637239a1149deacacd91255781d82a65a542a39036e" + "bytecodeHash": "0x0100087b7bb1d234655ca6c31e3ba8cb383c13f9738b1de7e5e2b39b34648677", + "sourceCodeHash": "0x9b17825ead64bf51912bc549ea9981e2b91301f0c937defe8202fe2f5678ce63" + }, + { + "contractName": "transfer_test", + "bytecodePath": "zkout/transfer_test.yul/contracts-preprocessed/bootloader/transfer_test.yul.json", + "sourceCodePath": "bootloader/build/transfer_test.yul", + "bytecodeHash": "0x01000015904f1cc3ac2c66713ca1eaf00c27988a8d00515a743fb81a9919bdcc", + "sourceCodeHash": "0xb828600c6f7366971580b68da39c3e449b9a0f922f52dd9841f33ae7f51ee71c" } ] diff --git a/system-contracts/bootloader/bootloader.yul b/system-contracts/bootloader/bootloader.yul index e995e7151..429532b6d 100644 --- a/system-contracts/bootloader/bootloader.yul +++ b/system-contracts/bootloader/bootloader.yul @@ -3126,7 +3126,7 @@ object "Bootloader" { assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") - assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + // reserved1 used as marker that tx doesn't have field "to" assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") assertEq(getFactoryDepsBytesLength(innerTxDataOffset), 0, "factory deps non zero") @@ -3151,9 +3151,8 @@ object "Bootloader" { assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") - assertEq(getReserved0(innerTxDataOffset), 0, "reserved0 non zero") - assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + // reserved1 used as marker that tx doesn't have field "to" assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") assertEq(getFactoryDepsBytesLength(innerTxDataOffset), 0, "factory deps non zero") @@ -3176,7 +3175,7 @@ object "Bootloader" { assertEq(getReserved0(innerTxDataOffset), 0, "reserved0 non zero") - assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + // reserved1 used as marker that tx doesn't have field "to" assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") assertEq(getFactoryDepsBytesLength(innerTxDataOffset), 0, "factory deps non zero") @@ -3195,7 +3194,7 @@ object "Bootloader" { assertEq(gt(getFrom(innerTxDataOffset), MAX_SYSTEM_CONTRACT_ADDR()), 1, "from in kernel space") assertEq(getReserved0(innerTxDataOffset), 0, "reserved0 non zero") - assertEq(getReserved1(innerTxDataOffset), 0, "reserved1 non zero") + // reserved1 used as marker that tx doesn't have field "to" assertEq(getReserved2(innerTxDataOffset), 0, "reserved2 non zero") assertEq(getReserved3(innerTxDataOffset), 0, "reserved3 non zero") } diff --git a/system-contracts/bootloader/test_infra/Cargo.lock b/system-contracts/bootloader/test_infra/Cargo.lock index 6fa43fd45..f7a9e30ee 100644 --- a/system-contracts/bootloader/test_infra/Cargo.lock +++ b/system-contracts/bootloader/test_infra/Cargo.lock @@ -2,26 +2,37 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addchain" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2e69442aa5628ea6951fa33e24efe8313f4321a91bd729fc2f75bdfc858570" +dependencies = [ + "num-bigint 0.3.3", + "num-integer", + "num-traits", +] + [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "ahash" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ "getrandom", "once_cell", @@ -30,12 +41,11 @@ dependencies = [ [[package]] name = "ahash" -version = "0.8.6" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ - "cfg-if 1.0.0", - "getrandom", + "cfg-if", "once_cell", "version_check", "zerocopy", @@ -43,18 +53,18 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] [[package]] name = "allocator-api2" -version = "0.2.16" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" [[package]] name = "android-tzdata" @@ -73,15 +83,45 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.75" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "arr_macro" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a105bfda48707cf19220129e78fca01e9639433ffaef4163546ed8fb04120a5" +dependencies = [ + "arr_macro_impl", + "proc-macro-hack", +] + +[[package]] +name = "arr_macro_impl" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +checksum = "0609c78bd572f4edc74310dfb63a01f5609d53fa8b4dd7c4d98aef3b3e8d72d1" +dependencies = [ + "proc-macro-hack", + "quote 1.0.37", + "syn 1.0.109", +] [[package]] name = "arrayref" -version = "0.3.7" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" +checksum = "cd9fd44efafa8690358b7408d253adf110036b88f55672a933f01d616ad9b1b9" +dependencies = [ + "nodrop", +] [[package]] name = "arrayvec" @@ -91,19 +131,41 @@ checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", +] [[package]] name = "async-trait" -version = "0.1.74" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -116,35 +178,30 @@ dependencies = [ ] [[package]] -name = "atomic-write-file" -version = "0.1.2" +name = "atomic-waker" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcdbedc2236483ab103a53415653d6b4442ea6141baf1ffa85df29635e88436" -dependencies = [ - "nix", - "rand 0.8.5", -] +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.6.20" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" dependencies = [ "async-trait", "axum-core", - "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "itoa", "matchit", "memchr", @@ -153,42 +210,57 @@ dependencies = [ "pin-project-lite", "rustversion", "serde", - "sync_wrapper", - "tower", + "sync_wrapper 1.0.1", + "tower 0.5.1", "tower-layer", "tower-service", ] [[package]] name = "axum-core" -version = "0.3.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", "mime", + "pin-project-lite", "rustversion", + "sync_wrapper 1.0.1", "tower-layer", "tower-service", ] +[[package]] +name = "backon" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d67782c3f868daa71d3533538e98a8e13713231969def7536e8039606fc46bf0" +dependencies = [ + "fastrand", + "futures-core", + "pin-project", + "tokio", +] + [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", - "cfg-if 1.0.0", + "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -211,9 +283,15 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" @@ -227,36 +305,15 @@ 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=dev#5520aa2274afe73d281373c92b007a2ecdebfbea" -dependencies = [ - "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 = "bigdecimal" -version = "0.3.1" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +checksum = "51d712318a27c7150326677b321a5fa91b55f6d9034ffd67f20319e147d40cee" dependencies = [ - "num-bigint", + "autocfg", + "libm", + "num-bigint 0.4.6", "num-integer", "num-traits", ] @@ -283,12 +340,12 @@ dependencies = [ "lazycell", "peeking_take_while", "prettyplease", - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "regex", "rustc-hash", "shlex", - "syn 2.0.40", + "syn 2.0.79", ] [[package]] @@ -308,9 +365,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" dependencies = [ "serde", ] @@ -329,31 +386,44 @@ dependencies = [ [[package]] name = "blake2" -version = "0.10.6" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" dependencies = [ - "digest 0.10.7", + "crypto-mac", + "digest 0.9.0", + "opaque-debug", ] [[package]] name = "blake2" version = "0.10.6" -source = "git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e#1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ "digest 0.10.7", ] [[package]] -name = "blake2s_const" -version = "0.6.0" -source = "git+https://github.com/matter-labs/bellman?branch=dev#5520aa2274afe73d281373c92b007a2ecdebfbea" +name = "blake2-rfc_bellman_edition" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc60350286c7c3db13b98e91dbe5c8b6830a6821bc20af5b0c310ce94d74915" dependencies = [ - "arrayref", - "arrayvec 0.5.2", + "arrayvec 0.4.12", + "byteorder", "constant_time_eq", ] +[[package]] +name = "blake2_ce" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90cef65f11dd09a6c58914148161dbf190e5dcc02c87ed2aa47b3b97d3e7ce76" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "blake2s_simd" version = "0.5.11" @@ -371,6 +441,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ + "block-padding", "generic-array", ] @@ -383,11 +454,17 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + [[package]] name = "blst" -version = "0.3.11" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c94087b935a822949d3291a9989ad2b2051ea141eda0fd4e478a75f6aa3e604b" +checksum = "4378725facc195f1a538864863f6de233b500a8862747e7f165078a419d5e874" dependencies = [ "cc", "glob", @@ -397,17 +474,17 @@ dependencies = [ [[package]] name = "boojum" -version = "0.2.0" -source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ec2f007ff8f90cc459f03e9f30ca1065440170f013c868823646e2e48d0234" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bincode", - "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "blake2 0.10.6", "const_format", "convert_case", - "crossbeam 0.8.2", + "crossbeam", "crypto-bigint 0.5.5", - "cs_derive", "derivative", "ethereum-types", "firestorm", @@ -415,22 +492,22 @@ dependencies = [ "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", + "sha3_ce", "smallvec", "unroll", + "zksync_cs_derive", + "zksync_pairing", ] [[package]] name = "borsh" -version = "1.3.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d4d6dafc1a3bb54687538972158f07b2c948bc57d5890df22c0739098b3028" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" dependencies = [ "borsh-derive", "cfg_aliases", @@ -438,23 +515,23 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.3.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", - "proc-macro-crate 2.0.1", - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro-crate 3.2.0", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", "syn_derive", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byte-slice-cast" @@ -464,9 +541,9 @@ checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -475,20 +552,20 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", ] [[package]] name = "bytecount" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205" +checksum = "5ce89b21cab1437276d2650d57e971f9d548a2d9037cc231abdc0562b97498ce" [[package]] name = "byteorder" @@ -498,9 +575,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "bzip2-sys" @@ -515,18 +592,18 @@ dependencies = [ [[package]] name = "camino" -version = "1.1.6" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.5" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34637b3140142bdf929fb439e8aa4ebad7651ebf7b1080b3930aa16ac1459ff" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" dependencies = [ "serde", ] @@ -546,12 +623,13 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.83" +version = "1.1.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "58e804ac3194a48bb129643eb1d62fcc20d18c6b8c181704489353d13120bcd1" dependencies = [ "jobserver", "libc", + "shlex", ] [[package]] @@ -563,12 +641,6 @@ dependencies = [ "nom", ] -[[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" @@ -577,15 +649,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "cfg_aliases" -version = "0.1.1" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -593,121 +665,130 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[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" +version = "0.140.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf6b7cc842eadb4c250cdc6a8bc1dd97624d9f08bbe54db3e11fb23c3a72be07" dependencies = [ "derivative", "serde", - "zk_evm 1.4.0", - "zkevm_circuits 1.4.0", + "zk_evm 0.140.0", + "zkevm_circuits 0.140.3", ] [[package]] name = "circuit_encodings" -version = "0.1.41" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.1#f7bd71fd4216e2c51ab7b09a95909fe48c75f35b" +version = "0.141.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7898ffbf3cd413576b4b674fe1545a35488c67eb16bd5a4148425e42c2a2b65b" dependencies = [ "derivative", "serde", - "zk_evm 1.4.1", - "zkevm_circuits 1.4.1", + "zk_evm 0.141.0", + "zkevm_circuits 0.141.2", ] [[package]] name = "circuit_encodings" -version = "0.1.42" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.2#3149a162a729581005fbad6dbcef027a3ee1b214" +version = "0.142.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8364ecafcc4b2c896023f8d3af952c52a500aa55f14fd268bb5d9ab07f837369" dependencies = [ "derivative", "serde", - "zk_evm 1.4.1", - "zkevm_circuits 1.4.1", + "zk_evm 0.141.0", + "zkevm_circuits 0.141.2", ] [[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" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67617688c66640c84f9b98ff26d48f7898dca4faeb45241a4f21ec333788e7b" dependencies = [ "derivative", "serde", - "zk_evm 1.5.0", - "zkevm_circuits 1.5.0", + "zk_evm 0.150.5", + "zkevm_circuits 0.150.5", ] [[package]] name = "circuit_sequencer_api" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.3.3#aba8f2a32767b79838aca7d7d00d9d23144df32f" +version = "0.133.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb959b1f8c6bbd8be711994d182e85452a26a5d2213a709290b71c8262af1331" dependencies = [ - "bellman_ce", "derivative", "rayon", "serde", - "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.3.3)", + "zk_evm 0.133.0", + "zksync_bellman", ] [[package]] name = "circuit_sequencer_api" -version = "0.1.40" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.0#39665dffd576cff5007c80dd0e1b5334e230bd3b" +version = "0.140.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa5f22311ce609d852d7d9f4943535ea4610aeb785129ae6ff83d5201c4fb387" dependencies = [ - "bellman_ce", - "circuit_encodings 0.1.40", + "circuit_encodings 0.140.3", "derivative", "rayon", "serde", - "zk_evm 1.4.0", + "zk_evm 0.140.0", + "zksync_bellman", ] [[package]] name = "circuit_sequencer_api" -version = "0.1.41" -source = "git+https://github.com/matter-labs/era-zkevm_test_harness.git?branch=v1.4.1#f7bd71fd4216e2c51ab7b09a95909fe48c75f35b" +version = "0.141.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c47c71d6ba83a8beb0af13af70beffd627f5497caf3d44c6f96363e788b07ea" dependencies = [ - "bellman_ce", - "circuit_encodings 0.1.41", + "circuit_encodings 0.141.2", "derivative", "rayon", "serde", - "zk_evm 1.4.1", + "zk_evm 0.141.0", + "zksync_bellman", ] [[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#3149a162a729581005fbad6dbcef027a3ee1b214" +version = "0.142.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e264723359e6a1aad98110bdccf1ae3ad596e93e7d31da9e40f6adc07e4add54" dependencies = [ - "bellman_ce", - "circuit_encodings 0.1.42", + "circuit_encodings 0.142.2", "derivative", "rayon", "serde", - "zk_evm 1.4.1", + "zk_evm 0.141.0", + "zksync_bellman", ] [[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" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21017310971d4a051e4a52ad70eed11d1ae69defeca8314f73a3a4bad16705a9" dependencies = [ - "bellman_ce", - "circuit_encodings 0.1.50", + "circuit_encodings 0.150.5", "derivative", "rayon", "serde", + "zksync_bellman", ] [[package]] name = "clang-sys" -version = "1.6.1" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" dependencies = [ "glob", "libc", @@ -730,30 +811,39 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bed69047ed42e52c7e38d6421eeb8ceefb4f2a2b52eed59137f7bad7908f6800" +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "const-oid" -version = "0.9.5" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const_format" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3a214c7af3d04997541b18d432afaff4c455e79e2029079647e72fc2bd27673" +checksum = "50c655d81ff1114fb0dcdea9225ea9f0cc712a6f8d189378e82bdf62a473a64b" dependencies = [ "const_format_proc_macros", ] [[package]] name = "const_format_proc_macros" -version = "0.2.32" +version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7f6ff08fd20f4f299298a28e2dfa8a8ba1036e6cd2460ac1de7b425d76f2500" +checksum = "eff1a44b93f47b1bac19a27932f5c591e43d1ba357ee4f61526c8a25603f0eb1" dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", + "proc-macro2 1.0.87", + "quote 1.0.37", + "unicode-xid 0.2.6", ] [[package]] @@ -764,9 +854,12 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" [[package]] name = "convert_case" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "core-foundation" @@ -780,24 +873,24 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce420fe07aecd3e67c5f910618fe65e94158f6dcc0adf44e00d69ce2bdfe0fd0" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] [[package]] name = "crc" -version = "3.0.1" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" dependencies = [ "crc-catalog", ] @@ -809,143 +902,69 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] -name = "crossbeam" -version = "0.7.3" +name = "crc32fast" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69323bff1fb41c635347b8ead484a5ca6c3f11914d784170b158d8449ab07f8e" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 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", + "cfg-if", ] [[package]] name = "crossbeam" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-channel 0.5.8", - "crossbeam-deque 0.8.3", - "crossbeam-epoch 0.9.15", - "crossbeam-queue 0.3.8", - "crossbeam-utils 0.8.16", -] - -[[package]] -name = "crossbeam-channel" -version = "0.4.4" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" dependencies = [ - "crossbeam-utils 0.7.2", - "maybe-uninit", + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", ] [[package]] name = "crossbeam-channel" -version = "0.5.8" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", + "crossbeam-utils", ] [[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.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce6fd6f855243022dcecf8702fef0c297d4338e226845fe067f6341ad9fa0cef" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-epoch 0.9.15", - "crossbeam-utils 0.8.16", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "crossbeam-utils 0.7.2", - "lazy_static", - "maybe-uninit", - "memoffset 0.5.6", - "scopeguard", + "crossbeam-epoch", + "crossbeam-utils", ] [[package]] name = "crossbeam-epoch" -version = "0.9.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" -dependencies = [ - "autocfg", - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", - "memoffset 0.9.0", - "scopeguard", -] - -[[package]] -name = "crossbeam-queue" -version = "0.2.3" +version = "0.9.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "774ba60a54c213d409d5353bda12d49cd68d14e45036a285234c8d6f91f92570" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" dependencies = [ - "cfg-if 0.1.10", - "crossbeam-utils 0.7.2", - "maybe-uninit", + "crossbeam-utils", ] [[package]] name = "crossbeam-queue" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" -dependencies = [ - "cfg-if 1.0.0", - "crossbeam-utils 0.8.16", -] - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" dependencies = [ - "autocfg", - "cfg-if 0.1.10", - "lazy_static", + "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.16" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a22b2d63d4d1dc0b7f1b6b2747dd0088008a9be28b6ddf0b1e7d335e3037294" -dependencies = [ - "cfg-if 1.0.0", -] +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crunchy" @@ -988,28 +1007,36 @@ dependencies = [ ] [[package]] -name = "cs_derive" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-boojum.git?branch=main#19988079852ea22576da6b09e39365e6cdc1368f" +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" dependencies = [ - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", + "generic-array", + "subtle", +] + +[[package]] +name = "ctor" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb49164822f3ee45b17acd4a208cfc1251410cf0cad9a833234c9890774dd9f" +dependencies = [ + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "curve25519-dalek" -version = "4.1.1" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", - "platforms", "rustc_version", "subtle", "zeroize", @@ -1021,9 +1048,44 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", +] + +[[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 1.0.87", + "quote 1.0.37", + "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 1.0.37", + "syn 1.0.109", ] [[package]] @@ -1032,8 +1094,8 @@ version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" dependencies = [ - "cfg-if 1.0.0", - "hashbrown 0.14.3", + "cfg-if", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -1061,9 +1123,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ "const-oid", "pem-rfc7468", @@ -1072,11 +1134,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.10" +version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -1085,44 +1148,37 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version", - "syn 1.0.109", + "derive_more-impl", ] [[package]] -name = "derive_more" -version = "1.0.0-beta.6" +name = "derive_more-impl" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7abbfc297053be59290e3152f8cbcd52c8642e0728b69ee187d991d4c1af08d" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "derive_more-impl", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", + "unicode-xid 0.2.6", ] [[package]] -name = "derive_more-impl" -version = "1.0.0-beta.6" +name = "diff" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bba3e9872d7c58ce7ef0fcf1844fcc3e23ef2a58377b50df35dd98e42a5726e" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", - "unicode-xid", -] +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" [[package]] name = "digest" @@ -1175,7 +1231,7 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der 0.7.8", + "der 0.7.9", "digest 0.10.7", "elliptic-curve 0.13.8", "rfc6979 0.4.0", @@ -1195,9 +1251,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", @@ -1210,9 +1266,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" dependencies = [ "serde", ] @@ -1259,20 +1315,32 @@ dependencies = [ [[package]] name = "elsa" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714f766f3556b44e7e4776ad133fcc3445a489517c25c704ace411bb14790194" +checksum = "d98e71ae4df57d214182a2e5cb90230c0192c6ddfcaa05c36453d46a54713e10" dependencies = [ "stable_deref_trait", ] [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum_dispatch" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ - "cfg-if 1.0.0", + "once_cell", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -1292,9 +1360,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1315,7 +1383,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "home", "windows-sys 0.48.0", ] @@ -1366,15 +1434,20 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.3" +version = "5.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "ff" @@ -1396,39 +1469,11 @@ dependencies = [ "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", - "num-integer", - "num-traits", - "proc-macro2", - "quote", - "serde", - "syn 1.0.109", -] - [[package]] name = "fiat-crypto" -version = "0.2.5" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "findshlibs" @@ -1442,12 +1487,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "firestorm" version = "0.5.1" @@ -1472,6 +1511,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "flume" version = "0.11.0" @@ -1480,7 +1529,7 @@ checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ "futures-core", "futures-sink", - "spin 0.9.8", + "spin", ] [[package]] @@ -1513,6 +1562,39 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "franklin-crypto" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "971289216ea5c91872e5e0bb6989214b537bbce375d09fabea5c3ccfe031b204" +dependencies = [ + "arr_macro", + "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.6", + "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", + "zksync_bellman", +] + [[package]] name = "fuchsia-cprng" version = "0.1.1" @@ -1527,9 +1609,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0290714b38af9b4a7b094b8a37086d1b4e61f2df9122c3cad2577669145335" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", @@ -1542,9 +1624,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff4dd66668b557604244583e3e1e1eada8c5c2e96a6d0d6653ede395b78bbacb" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", "futures-sink", @@ -1552,15 +1634,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1d22c66e66d9d72e1758f0bd7d4fd0bee04cad842ee34587d68c07e45d088c" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-executor" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4fb8693db0cf099eadcca0efe2a5a22e4550f98ed16aba6c48700da29597bc" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" dependencies = [ "futures-core", "futures-task", @@ -1581,44 +1663,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bf34a163b5c4c52d0478a4d757da8fb65cabef42ba90515efee0f6f9fa45aaa" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-macro" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "futures-sink" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e36d3378ee38c2a36ad710c5d30c2911d752cb941c00c72dbabfb786a7970817" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efd193069b0ddadc69c46389b740bbccdd97203899b48d09c5f7969591d6bae2" - -[[package]] -name = "futures-timer" -version = "3.0.2" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.29" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a19526d624e703a3179b3d322efec918b6246ea0fa51d41124525f00f1cc8104" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-channel", "futures-core", @@ -1645,20 +1721,22 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.11" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "glob" @@ -1666,6 +1744,81 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "google-cloud-auth" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1112c453c2e155b3e683204ffff52bcc6d6495d04b68d9e90cd24161270c5058" +dependencies = [ + "async-trait", + "base64 0.21.7", + "google-cloud-metadata", + "google-cloud-token", + "home", + "jsonwebtoken", + "reqwest 0.12.8", + "serde", + "serde_json", + "thiserror", + "time", + "tokio", + "tracing", + "urlencoding", +] + +[[package]] +name = "google-cloud-metadata" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f945a208886a13d07636f38fb978da371d0abc3e34bad338124b9f8c135a8f" +dependencies = [ + "reqwest 0.12.8", + "thiserror", + "tokio", +] + +[[package]] +name = "google-cloud-storage" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc0c5b7469142d91bd77959e69375bede324a5def07c7f29aa0d582586cba305" +dependencies = [ + "anyhow", + "async-stream", + "async-trait", + "base64 0.21.7", + "bytes", + "futures-util", + "google-cloud-auth", + "google-cloud-metadata", + "google-cloud-token", + "hex", + "once_cell", + "percent-encoding", + "pkcs8 0.10.2", + "regex", + "reqwest 0.12.8", + "reqwest-middleware", + "ring", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "time", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "google-cloud-token" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f49c12ba8b21d128a2ce8585955246977fbce4415f680ebf9199b6f9d6d725f" +dependencies = [ + "async-trait", +] + [[package]] name = "group" version = "0.12.1" @@ -1690,17 +1843,17 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", - "indexmap 2.1.0", + "http 0.2.12", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -1708,64 +1861,70 @@ dependencies = [ ] [[package]] -name = "hashbrown" -version = "0.12.3" +name = "h2" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ - "ahash 0.7.7", + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] -name = "hashbrown" -version = "0.14.3" +name = "handlebars" +version = "3.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3" dependencies = [ - "ahash 0.8.6", - "allocator-api2", + "log", + "pest", + "pest_derive", + "quick-error", + "serde", + "serde_json", ] [[package]] -name = "hashlink" -version = "0.8.4" +name = "hashbrown" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "hashbrown 0.14.3", + "ahash 0.7.8", ] [[package]] -name = "headers" -version = "0.3.9" +name = "hashbrown" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "base64 0.21.5", - "bytes", - "headers-core", - "http", - "httpdate", - "mime", - "sha1", + "ahash 0.8.11", + "allocator-api2", ] [[package]] -name = "headers-core" -version = "0.2.0" +name = "hashbrown" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429" -dependencies = [ - "http", -] +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] -name = "heck" -version = "0.4.1" +name = "hashlink" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "6ba4ff7128dee98c7dc9794b6a411377e1404dba1c97deb8d1a55297bd25d8af" dependencies = [ - "unicode-segmentation", + "hashbrown 0.14.5", ] [[package]] @@ -1776,9 +1935,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" [[package]] name = "hex" @@ -1788,9 +1947,9 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ "hmac", ] @@ -1806,11 +1965,11 @@ dependencies = [ [[package]] name = "home" -version = "0.5.5" +version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -1826,9 +1985,20 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1842,15 +2012,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1860,52 +2053,77 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "0.14.27" +version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.10", + "socket2", "tokio", "tower-service", "tracing", "want", ] +[[package]] +name = "hyper" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" -version = "0.24.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.4.1", + "hyper-util", "rustls", + "rustls-pki-types", "tokio", "tokio-rustls", + "tower-service", ] [[package]] name = "hyper-timeout" -version = "0.4.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" dependencies = [ - "hyper", + "hyper 1.4.1", + "hyper-util", "pin-project-lite", "tokio", - "tokio-io-timeout", + "tower-service", ] [[package]] @@ -1915,17 +2133,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.30", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.4.1", + "hyper-util", "native-tls", "tokio", "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.1", + "hyper 1.4.1", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.58" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1945,14 +2198,10 @@ dependencies = [ ] [[package]] -name = "idna" -version = "0.4.0" +name = "ident_case" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" @@ -1997,8 +2246,8 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", ] @@ -2014,19 +2263,19 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown 0.15.0", ] [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" [[package]] name = "ipnetwork" @@ -2048,59 +2297,59 @@ dependencies = [ [[package]] name = "itertools" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] [[package]] name = "itertools" -version = "0.12.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" dependencies = [ "either", ] [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jobserver" -version = "0.1.27" +version = "0.1.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" dependencies = [ "libc", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" dependencies = [ "wasm-bindgen", ] [[package]] -name = "jsonrpc-core" -version = "18.0.0" +name = "jsonwebtoken" +version = "9.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f" dependencies = [ - "futures", - "futures-executor", - "futures-util", - "log", + "base64 0.21.7", + "js-sys", + "pem", + "ring", "serde", - "serde_derive", "serde_json", + "simple_asn1", ] [[package]] @@ -2109,7 +2358,7 @@ version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "ecdsa 0.14.8", "elliptic-curve 0.12.3", "sha2 0.10.8", @@ -2117,11 +2366,11 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "ecdsa 0.16.9", "elliptic-curve 0.13.8", "once_cell", @@ -2131,20 +2380,20 @@ dependencies = [ [[package]] name = "keccak" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ "cpufeatures", ] [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" dependencies = [ - "spin 0.5.2", + "spin", ] [[package]] @@ -2155,18 +2404,18 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "libc" -version = "0.2.151" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libloading" -version = "0.7.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" dependencies = [ - "cfg-if 1.0.0", - "winapi", + "cfg-if", + "windows-targets 0.52.6", ] [[package]] @@ -2193,9 +2442,9 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", @@ -2204,46 +2453,26 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "d2d16453e800a8cf6dd2fc3eb4bc99b786a9b90c663b8559a5b1a041bf89e472" dependencies = [ "cc", "pkg-config", "vcpkg", ] -[[package]] -name = "linkme" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e6b0bb9ca88d3c5ae88240beb9683821f903b824ee8381ef9ab4e8522fbfa9" -dependencies = [ - "linkme-impl", -] - -[[package]] -name = "linkme-impl" -version = "0.3.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3b3f61e557a617ec6ba36c79431e1f3b5e100d67cfbdb61ed6ef384298af016" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", -] - [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -2251,9 +2480,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logos" @@ -2272,10 +2501,10 @@ checksum = "dc487311295e0002e452025d6b580b77bb17286de87b57138f3b5db711cded68" dependencies = [ "beef", "fnv", - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "regex-syntax 0.6.29", - "syn 2.0.40", + "syn 2.0.79", ] [[package]] @@ -2289,9 +2518,9 @@ dependencies = [ [[package]] name = "lz4-sys" -version = "1.9.4" +version = "1.11.1+lz4-1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d27b317e207b10f69f5e75494119e391a96f48861ae870d1da6edac98ca900" +checksum = "6bd8c0d6c6ed0cd30b3652886bb8711dc4bb01d637a68105a3d5158039b418e6" dependencies = [ "cc", "libc", @@ -2318,45 +2547,21 @@ 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", + "cfg-if", "digest 0.10.7", ] [[package]] name = "memchr" -version = "2.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" - -[[package]] -name = "memoffset" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa" -dependencies = [ - "autocfg", -] - -[[package]] -name = "memoffset" -version = "0.9.0" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" -dependencies = [ - "autocfg", -] +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miette" @@ -2376,9 +2581,9 @@ version = "5.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49e7bc1560b95a3c4a25d03de42fe76ca718ab92d1a22a55b9b4cf67b3ae635c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -2387,14 +2592,24 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "mini-moka" -version = "0.10.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23e0b72e7c9042467008b10279fc732326bd605459ae03bda88825909dd19b56" +checksum = "c325dfab65f261f386debee8b0969da215b3fa0037e74c8a1234db7ba986d803" dependencies = [ - "crossbeam-channel 0.5.8", - "crossbeam-utils 0.8.16", + "crossbeam-channel", + "crossbeam-utils", "dashmap", "skeptic", "smallvec", @@ -2410,66 +2625,37 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.10" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ + "hermit-abi", "libc", "wasi", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "multimap" -version = "0.8.3" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" - -[[package]] -name = "multivm" -version = "0.1.0" -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", - "thiserror", - "tracing", - "vise", - "zk_evm 1.3.1", - "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2)", - "zk_evm 1.4.0", - "zk_evm 1.4.1", - "zk_evm 1.5.0", - "zksync_contracts", - "zksync_state", - "zksync_system_constants", - "zksync_types", - "zksync_utils", -] +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -2482,15 +2668,10 @@ dependencies = [ ] [[package]] -name = "nix" -version = "0.27.1" +name = "nodrop" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" -dependencies = [ - "bitflags 2.4.1", - "cfg-if 1.0.0", - "libc", -] +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" [[package]] name = "nom" @@ -2514,11 +2695,11 @@ dependencies = [ [[package]] name = "num" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-complex", "num-integer", "num-iter", @@ -2528,13 +2709,23 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "5f6f7833f2cbf2360a6cfd58cd41a53aa7a90bd4c202f5b1c7dd2ed73c57b2c3" dependencies = [ "autocfg", "num-integer", "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", "serde", ] @@ -2557,29 +2748,45 @@ dependencies = [ [[package]] name = "num-complex" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ba157ca0885411de85d6ca030ba7e2a83a28636056c7c699b07c8b6f7383214" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" 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.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-iter" -version = "0.1.43" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d03e6c028c5dc5cac6e2dec0efda81fc887605bb3d884578bb6d6bf7514e252" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" dependencies = [ "autocfg", "num-integer", @@ -2598,12 +2805,11 @@ dependencies = [ [[package]] name = "num-rational" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "autocfg", - "num-bigint", + "num-bigint 0.4.6", "num-integer", "num-traits", "serde", @@ -2611,9 +2817,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", "libm", @@ -2640,11 +2846,11 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ - "num_enum_derive 0.7.2", + "num_enum_derive 0.7.3", ] [[package]] @@ -2654,52 +2860,52 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate 1.3.1", - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 2.0.1", - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro-crate 3.2.0", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "object" -version = "0.32.1" +version = "0.36.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "opaque-debug" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.61" +version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b8419dc8cc6d866deb801274bba2e6f8f6108c1bb7fcc10ee5ab864931dbb45" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.1", - "cfg-if 1.0.0", + "bitflags 2.6.0", + "cfg-if", "foreign-types", "libc", "once_cell", @@ -2713,9 +2919,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -2726,9 +2932,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.97" +version = "0.9.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3eaad34cdd97d81de97964fc7f29e2d104f483840d906ef56daa1912338460b" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" dependencies = [ "cc", "libc", @@ -2738,43 +2944,58 @@ dependencies = [ [[package]] name = "opentelemetry" -version = "0.20.0" +version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9591d937bc0e6d2feb6f71a559540ab300ea49955229c347a517a28d27784c54" +checksum = "4c365a63eec4f55b7efeceb724f1336f26a9cf3427b70e59e2cd2a5b947fba96" dependencies = [ - "opentelemetry_api", - "opentelemetry_sdk", + "futures-core", + "futures-sink", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "opentelemetry-appender-tracing" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b84de945cb3a6f1e0d6317cbd998bbd0519ab00f4b790db67e0ff4fdcf7cedb6" +dependencies = [ + "opentelemetry", + "tracing", + "tracing-core", + "tracing-subscriber", ] [[package]] name = "opentelemetry-http" -version = "0.9.0" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7594ec0e11d8e33faf03530a4c49af7064ebba81c1480e01be67d90b356508b" +checksum = "ad31e9de44ee3538fb9d64fe3376c1362f406162434609e79aea2a41a0af78ab" dependencies = [ "async-trait", "bytes", - "http", - "opentelemetry_api", - "reqwest", + "http 1.1.0", + "opentelemetry", + "reqwest 0.12.8", ] [[package]] name = "opentelemetry-otlp" -version = "0.13.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e5e5a5c4135864099f3faafbe939eb4d7f9b80ebf68a8448da961b32a7c1275" +checksum = "6b925a602ffb916fb7421276b86756027b37ee708f9dce2dbdcc51739f07e727" dependencies = [ "async-trait", "futures-core", - "http", + "http 1.1.0", + "opentelemetry", "opentelemetry-http", "opentelemetry-proto", - "opentelemetry-semantic-conventions", - "opentelemetry_api", "opentelemetry_sdk", - "prost 0.11.9", - "reqwest", + "prost 0.13.3", + "reqwest 0.12.8", "thiserror", "tokio", "tonic", @@ -2782,58 +3003,37 @@ dependencies = [ [[package]] name = "opentelemetry-proto" -version = "0.3.0" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e3f814aa9f8c905d0ee4bde026afd3b2577a97c10e1699912e3e44f0c4cbeb" +checksum = "30ee9f20bff9c984511a02f082dc8ede839e4a9bf15cc2487c8d6fea5ad850d9" dependencies = [ - "opentelemetry_api", + "opentelemetry", "opentelemetry_sdk", - "prost 0.11.9", + "prost 0.13.3", "tonic", ] [[package]] name = "opentelemetry-semantic-conventions" -version = "0.12.0" +version = "0.16.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", -] +checksum = "1cefe0543875379e47eb5f1e68ff83f45cc41366a92dfd0d073d513bf68e9a05" [[package]] name = "opentelemetry_sdk" -version = "0.20.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa8e705a0612d48139799fcbaba0d4a90f06277153e43dd2bdc16c6f0edd8026" +checksum = "692eac490ec80f24a17828d49b40b60f5aeaccdfe6a503f939713afd22bc28df" dependencies = [ "async-trait", - "crossbeam-channel 0.5.8", "futures-channel", "futures-executor", "futures-util", + "glob", "once_cell", - "opentelemetry_api", - "ordered-float 3.9.2", + "opentelemetry", "percent-encoding", "rand 0.8.5", - "regex", "serde_json", "thiserror", "tokio", @@ -2849,24 +3049,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" +version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "006e42d5b888366f1880eda20371fedde764ed2213dc8496f49622fa0c99cd5e" +checksum = "ae99c7fa6dd38c7cafe1ec085e804f8f555a2f8659b0dbe03f1f9963a9b51092" dependencies = [ "log", "serde", - "winapi", + "windows-sys 0.52.0", ] [[package]] @@ -2887,60 +3078,13 @@ dependencies = [ "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?rev=d24f2c5871089c4cd4f54c0ca266bb9fef6115eb#d24f2c5871089c4cd4f54c0ca266bb9fef6115eb" -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" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "881331e34fa842a2fb61cc2db9643a8fedc615e47cfcc52597d1af0db9a7e8fe" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bitvec", "byte-slice-cast", "impl-trait-for-tuples", @@ -2950,21 +3094,27 @@ dependencies = [ [[package]] name = "parity-scale-codec-derive" -version = "3.6.9" +version = "3.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be30eaf4b0a9fba5336683b38de57bb86d179a35862ba6bfcf57625d006bde5b" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ - "proc-macro-crate 2.0.1", - "proc-macro2", - "quote", + "proc-macro-crate 3.2.0", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", ] +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2972,22 +3122,22 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "libc", "redox_syscall", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "peeking_take_while" @@ -2995,6 +3145,16 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.1", + "serde", +] + [[package]] name = "pem-rfc7468" version = "0.7.0" @@ -3010,41 +3170,86 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "pest" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "pest_meta" +version = "2.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + [[package]] name = "petgraph" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.6.0", ] [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "baf123a161dde1e524adf36f90bc5d8d3462824a9c43553ad07a8183161189ec" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "a4502d8515ca9f32f1fb543d987f63d95a14934883db45bdb48060b6b69257f8" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -3058,7 +3263,7 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der 0.7.8", + "der 0.7.9", "pkcs8 0.10.2", "spki 0.7.3", ] @@ -3079,21 +3284,15 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", + "der 0.7.9", "spki 0.7.3", ] [[package]] name = "pkg-config" -version = "0.3.27" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" - -[[package]] -name = "platforms" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "powerfmt" @@ -3103,18 +3302,31 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] [[package]] name = "prettyplease" -version = "0.2.15" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d" +checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ - "proc-macro2", - "syn 2.0.40", + "proc-macro2 1.0.87", + "syn 2.0.79", ] [[package]] @@ -3151,12 +3363,11 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97dc5fea232fc28d2f597b37c4876b348a40e33f3b02cc975c8d006d78d94b1a" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.22.22", ] [[package]] @@ -3166,8 +3377,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", "version_check", ] @@ -3178,25 +3389,40 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "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.70" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" +checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" dependencies = [ "unicode-ident", ] [[package]] name = "prometheus-client" -version = "0.22.2" +version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1ca959da22a332509f2a73ae9e5f23f9dcfc31fd3a54d71f159495bd5909baa" +checksum = "504ee9ff529add891127c4827eb481bd69dc0ebc72e9a682e187db4caa60c3ca" dependencies = [ "dtoa", "itoa", @@ -3210,77 +3436,76 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "prost" -version = "0.11.9" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" dependencies = [ "bytes", - "prost-derive 0.11.9", + "prost-derive 0.12.6", ] [[package]] name = "prost" -version = "0.12.3" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f" dependencies = [ "bytes", - "prost-derive 0.12.3", + "prost-derive 0.13.3", ] [[package]] name = "prost-build" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c55e02e35260070b6f716a2423c2ff1c3bb1642ddca6f99e1f26d06268a0e2d2" +checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes", - "heck 0.4.1", - "itertools 0.11.0", + "heck", + "itertools 0.12.1", "log", "multimap", "once_cell", "petgraph", "prettyplease", - "prost 0.12.3", + "prost 0.12.6", "prost-types", "regex", - "syn 2.0.40", + "syn 2.0.79", "tempfile", - "which", ] [[package]] name = "prost-derive" -version = "0.11.9" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", - "itertools 0.10.5", - "proc-macro2", - "quote", - "syn 1.0.109", + "itertools 0.12.1", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "prost-derive" -version = "0.12.3" +version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5" dependencies = [ "anyhow", - "itertools 0.11.0", - "proc-macro2", - "quote", - "syn 2.0.40", + "itertools 0.13.0", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -3289,11 +3514,11 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "057237efdb71cf4b3f9396302a3d6599a92fa94063ba537b66130980ea9909f3" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "logos", "miette", "once_cell", - "prost 0.12.3", + "prost 0.12.6", "prost-types", "serde", "serde-value", @@ -3301,11 +3526,11 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.12.3" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +checksum = "9091c90b0a32608e984ff2fa4091273cbdd755d54935c51d520887f4a1dbd5b0" dependencies = [ - "prost 0.12.3", + "prost 0.12.6", ] [[package]] @@ -3316,7 +3541,7 @@ checksum = "00bb76c5f6221de491fe2c8f39b106330bbd9762c6511119c07940e10eb9ff11" dependencies = [ "bytes", "miette", - "prost 0.12.3", + "prost 0.12.6", "prost-reflect", "prost-types", "protox-parse", @@ -3350,22 +3575,28 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", ] [[package]] name = "pulldown-cmark" -version = "0.9.3" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a1a2f1f0a7ecff9c31abbe177637be0e97a0aef46cf8738ece09327985d998" +checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "memchr", "unicase", ] +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-protobuf" version = "0.8.1" @@ -3377,11 +3608,20 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +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.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ - "proc-macro2", + "proc-macro2 1.0.87", ] [[package]] @@ -3450,9 +3690,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3460,12 +3700,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "crossbeam-deque 0.8.3", - "crossbeam-utils 0.8.16", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] @@ -3479,23 +3719,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", - "regex-syntax 0.8.2", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -3509,13 +3749,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.2", + "regex-syntax 0.8.5", ] [[package]] @@ -3526,36 +3766,35 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.22" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046cd98826c46c2ac8ddecae268eb5c2e58628688a5fc7a2643704a73faba95b" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-rustls", - "hyper-tls", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.30", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -3564,24 +3803,109 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "system-configuration", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", - "tokio-rustls", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", + "hyper-rustls", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "mime_guess", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "windows-registry", +] + +[[package]] +name = "reqwest-middleware" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562ceb5a604d3f7c885a792d42c199fd8af239d0a51b2fa6a78aafa092452b04" +dependencies = [ + "anyhow", + "async-trait", + "http 1.1.0", + "reqwest 0.12.8", + "serde", + "thiserror", + "tower-service", +] + +[[package]] +name = "rescue_poseidon" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82900c877a0ba5362ac5756efbd82c5b795dc509011c1253e2389d8708f1389d" +dependencies = [ + "addchain", + "arrayvec 0.7.6", + "blake2 0.10.6", + "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" @@ -3605,23 +3929,24 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", - "spin 0.9.8", + "spin", "untrusted", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" dependencies = [ "bitvec", "bytecheck", @@ -3637,12 +3962,12 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "syn 1.0.109", ] @@ -3688,11 +4013,11 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.33.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "borsh", "bytes", "num-traits", @@ -3704,9 +4029,9 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" @@ -3722,20 +4047,20 @@ checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -3744,14 +4069,15 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.23.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "415d9944693cb90382053259f89fbb077ea730ad7273047ec63b19bc9b160ba8" dependencies = [ - "log", - "ring", + "once_cell", + "rustls-pki-types", "rustls-webpki", - "sct", + "subtle", + "zeroize", ] [[package]] @@ -3760,30 +4086,46 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.5", + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", ] +[[package]] +name = "rustls-pki-types" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" + [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring", + "rustls-pki-types", "untrusted", ] [[package]] name = "rustversion" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -3796,11 +4138,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.22" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c3733bf4cf7ea0880754e19cb5a462007c4a8c1914bff372ccc95b464f1df88" +checksum = "01227be5826fa0690321a2ba6c5cd57a19cf3f6a09e76973b58e61de6ab9d1c1" dependencies = [ - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3809,16 +4151,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "seahash" version = "4.1.0" @@ -3846,7 +4178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct 0.2.0", - "der 0.7.8", + "der 0.7.9", "generic-array", "pkcs8 0.10.2", "subtle", @@ -3871,13 +4203,22 @@ dependencies = [ "cc", ] +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "zeroize", +] + [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -3886,9 +4227,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -3896,9 +4237,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -3911,7 +4252,7 @@ checksum = "6ce4b57f1b521f674df7a1d200be8ff5d74e3712020ee25b553146657b5377d5" dependencies = [ "httpdate", "native-tls", - "reqwest", + "reqwest 0.11.27", "sentry-backtrace", "sentry-contexts", "sentry-core", @@ -4019,9 +4360,9 @@ checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" [[package]] name = "serde" -version = "1.0.193" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] @@ -4032,28 +4373,29 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" dependencies = [ - "ordered-float 2.10.1", + "ordered-float", "serde", ] [[package]] name = "serde_derive" -version = "1.0.193" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -4071,29 +4413,40 @@ dependencies = [ ] [[package]] -name = "serde_yaml" -version = "0.9.29" +name = "serde_with" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a15e0ef66bf939a7c890a0bf6d5a733c70202225f9888a89ed5c62298b019129" +checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" dependencies = [ - "indexmap 2.1.0", - "itoa", - "ryu", + "base64 0.13.1", + "hex", "serde", - "unsafe-libyaml", + "serde_with_macros", ] [[package]] -name = "sha-1" -version = "0.9.8" +name = "serde_with_macros" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", + "darling", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.6.0", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", ] [[package]] @@ -4102,19 +4455,22 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.10.7", ] [[package]] name = "sha2" -version = "0.10.6" -source = "git+https://github.com/RustCrypto/hashes.git?rev=1731ced4a116d61ba9dc6ee6d0f38fb8102e357a#1731ced4a116d61ba9dc6ee6d0f38fb8102e357a" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ - "cfg-if 1.0.0", + "block-buffer 0.9.0", + "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -4123,18 +4479,32 @@ version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "cpufeatures", "digest 0.10.7", ] [[package]] -name = "sha3" +name = "sha2_ce" version = "0.10.6" -source = "git+https://github.com/RustCrypto/hashes.git?rev=7a187e934c1f6c68e4b4e5cf37541b7a0d64d303#7a187e934c1f6c68e4b4e5cf37541b7a0d64d303" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca2daa77078f4ddff27e75c4bf59e4c2697525f56dbb3c842d34a5d1f2b04a2" dependencies = [ + "cfg-if", + "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", ] [[package]] @@ -4147,6 +4517,16 @@ dependencies = [ "keccak", ] +[[package]] +name = "sha3_ce" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34c9a08202c50378d8a07a5f458193a5f542d2828ac6640263dbc0c2533ea25e" +dependencies = [ + "digest 0.10.7", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -4158,15 +4538,15 @@ dependencies = [ [[package]] name = "shlex" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -4193,9 +4573,21 @@ dependencies = [ [[package]] name = "simdutf8" -version = "0.1.4" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "simple_asn1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "thiserror", + "time", +] [[package]] name = "skeptic" @@ -4223,54 +4615,23 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" dependencies = [ "serde", ] [[package]] name = "socket2" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "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", + "windows-sys 0.52.0", ] -[[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" @@ -4297,25 +4658,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der 0.7.8", + "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 = "sqlformat" -version = "0.2.3" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +checksum = "7bba3a93db0cc4f7bdece8bb09e77e2e785c20bfebf79eb8340ed80708048790" dependencies = [ - "itertools 0.12.0", "nom", "unicode_categories", ] [[package]] name = "sqlx" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba03c279da73694ef99763320dea58b51095dfe87d001b1d4b5fe78ba8763cf" +checksum = "93334716a037193fac19df402f8571269c84a00852f6a7066b5d2616dcd64d3e" dependencies = [ "sqlx-core", "sqlx-macros", @@ -4326,19 +4692,17 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd" +checksum = "d4d8060b456358185f7d50c55d9b5066ad956956fddec42ee2e8567134a8936e" dependencies = [ - "ahash 0.8.6", "atoi", "bigdecimal", "byteorder", "bytes", "chrono", "crc", - "crossbeam-queue 0.3.8", - "dotenvy", + "crossbeam-queue", "either", "event-listener", "futures-channel", @@ -4346,9 +4710,10 @@ dependencies = [ "futures-intrusive", "futures-io", "futures-util", + "hashbrown 0.14.5", "hashlink", "hex", - "indexmap 2.1.0", + "indexmap 2.6.0", "ipnetwork", "log", "memchr", @@ -4371,31 +4736,30 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89961c00dc4d7dffb7aee214964b065072bff69e36ddb9e2c107541f75e4f2a5" +checksum = "cac0692bcc9de3b073e8d747391827297e075c7710ff6276d9f7a1f3d58c6657" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "sqlx-core", "sqlx-macros-core", - "syn 1.0.109", + "syn 2.0.79", ] [[package]] name = "sqlx-macros-core" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0bd4519486723648186a08785143599760f7cc81c52334a55d6a83ea1e20841" +checksum = "1804e8a7c7865599c9c79be146dc8a9fd8cc86935fa641d3ea58e5f0688abaa5" dependencies = [ - "atomic-write-file", "dotenvy", "either", - "heck 0.4.1", + "heck", "hex", "once_cell", - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "serde", "serde_json", "sha2 0.10.8", @@ -4403,7 +4767,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 1.0.109", + "syn 2.0.79", "tempfile", "tokio", "url", @@ -4411,14 +4775,14 @@ dependencies = [ [[package]] name = "sqlx-mysql" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37195395df71fd068f6e2082247891bc11e3289624bbc776a0cdfa1ca7f1ea4" +checksum = "64bb4714269afa44aef2755150a0fc19d756fb580a67db8885608cf02f47d06a" dependencies = [ "atoi", - "base64 0.21.5", + "base64 0.22.1", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "bytes", "chrono", @@ -4456,14 +4820,14 @@ dependencies = [ [[package]] name = "sqlx-postgres" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ac0ac3b7ccd10cc96c7ab29791a7dd236bd94021f31eec7ba3d46a74aa1c24" +checksum = "6fa91a732d854c5d7726349bb4bb879bb9478993ceb764247660aee25f67c2f8" dependencies = [ "atoi", - "base64 0.21.5", + "base64 0.22.1", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.6.0", "byteorder", "chrono", "crc", @@ -4482,13 +4846,12 @@ dependencies = [ "log", "md-5", "memchr", - "num-bigint", + "num-bigint 0.4.6", "once_cell", "rand 0.8.5", "rust_decimal", "serde", "serde_json", - "sha1", "sha2 0.10.8", "smallvec", "sqlx-core", @@ -4500,9 +4863,9 @@ dependencies = [ [[package]] name = "sqlx-sqlite" -version = "0.7.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "210976b7d948c7ba9fced8ca835b11cbb2d677c59c79de41ac0d397e14547490" +checksum = "d5b2cf34a45953bfd3daaf3db0f7a7878ab9b7a6b91b422d24a7a9e4c857b680" dependencies = [ "atoi", "chrono", @@ -4516,10 +4879,10 @@ dependencies = [ "log", "percent-encoding", "serde", + "serde_urlencoded", "sqlx-core", "tracing", "url", - "urlencoding", ] [[package]] @@ -4536,42 +4899,59 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] +[[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" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" dependencies = [ "strum_macros", ] [[package]] name = "strum_macros" -version = "0.24.3" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.4.1", - "proc-macro2", - "quote", + "heck", + "proc-macro2 1.0.87", + "quote 1.0.37", "rustversion", - "syn 1.0.109", + "syn 2.0.79", ] [[package]] name = "subtle" -version = "2.4.1" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "0.15.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] [[package]] name = "syn" @@ -4579,19 +4959,19 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.40" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13fa70a4ee923979ffb522cacce59d34421ebdea5625e1073c4326ef9d2dd42e" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ - "proc-macro2", - "quote", + "proc-macro2 1.0.87", + "quote 1.0.37", "unicode-ident", ] @@ -4602,9 +4982,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" dependencies = [ "proc-macro-error", - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -4613,6 +4993,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sync_wrapper" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -4621,7 +5010,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -4634,6 +5034,16 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tagptr" version = "0.2.0" @@ -4648,15 +5058,15 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.8.1" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -4665,46 +5075,46 @@ version = "0.1.0" dependencies = [ "colored", "hex", - "multivm", "once_cell", "serde", "serde_json", "tracing", "tracing-subscriber", - "vlog", "zksync_contracts", + "zksync_multivm", "zksync_state", "zksync_types", "zksync_utils", + "zksync_vlog", ] [[package]] name = "thiserror" -version = "1.0.50" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9a7210f5c9a7156bb50aa36aed4c95afb51df0df00713949448cf9e97d382d2" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.50" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "thread_local" -version = "1.1.7" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "once_cell", ] @@ -4719,12 +5129,13 @@ dependencies = [ [[package]] name = "time" -version = "0.3.30" +version = "0.3.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4a34ab300f2dee6e562c10a046fc05e358b29f9bf92277f30c3c8d82275f6f5" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" dependencies = [ "deranged", "itoa", + "num-conv", "powerfmt", "serde", "time-core", @@ -4739,10 +5150,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.15" +version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" dependencies = [ + "num-conv", "time-core", ] @@ -4766,9 +5178,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -4781,42 +5193,31 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.0" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d45b238a16291a4e1584e61820b8ae57d696cc5015c459c229ccc6990cc1c" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", "libc", "mio", - "num_cpus", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.5", + "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", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -4831,19 +5232,20 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.24.1" +version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls", + "rustls-pki-types", "tokio", ] [[package]] name = "tokio-stream" -version = "0.1.14" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite", @@ -4852,24 +5254,22 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ "bytes", "futures-core", - "futures-io", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" [[package]] name = "toml_edit" @@ -4877,45 +5277,47 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.6.0", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.6.0", "toml_datetime", - "winnow", + "winnow 0.6.20", ] [[package]] name = "tonic" -version = "0.9.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" dependencies = [ + "async-stream", "async-trait", "axum", - "base64 0.21.5", + "base64 0.22.1", "bytes", - "futures-core", - "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.4.6", + "http 1.1.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.4.1", "hyper-timeout", + "hyper-util", "percent-encoding", "pin-project", - "prost 0.11.9", + "prost 0.13.3", + "socket2", "tokio", "tokio-stream", - "tower", + "tower 0.4.13", "tower-layer", "tower-service", "tracing", @@ -4941,17 +5343,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2873938d487c3cfb9aed7546dc9f2711d867c9f90c46b889989a2cb84eba6b4f" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 0.1.2", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -4971,9 +5387,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] @@ -4986,17 +5402,6 @@ 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" @@ -5010,18 +5415,20 @@ dependencies = [ [[package]] name = "tracing-opentelemetry" -version = "0.21.0" +version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75327c6b667828ddc28f5e3f169036cb793c3f588d83bf0f262a7f062ffed3c8" +checksum = "a9784ed4da7d921bc8df6963f8c80a0e4ce34ba6ba76668acadd3edbd985ff3b" dependencies = [ + "js-sys", "once_cell", "opentelemetry", "opentelemetry_sdk", "smallvec", "tracing", "tracing-core", - "tracing-log 0.1.4", + "tracing-log", "tracing-subscriber", + "web-time", ] [[package]] @@ -5052,15 +5459,15 @@ dependencies = [ "time", "tracing", "tracing-core", - "tracing-log 0.2.0", + "tracing-log", "tracing-serde", ] [[package]] name = "triomphe" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" +checksum = "ef8f7726da4807b58ea5c96fdc122f80702030edc33b35aff9190a51148ccc85" [[package]] name = "try-lock" @@ -5068,12 +5475,24 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[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.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + [[package]] name = "uint" version = "0.9.5" @@ -5106,42 +5525,54 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" + [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.1.11" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unicode_categories" @@ -5155,7 +5586,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ad948c1cb799b1a70f836077721a92a35ac177d4daddf4c20a633786d4cf618" dependencies = [ - "quote", + "quote 1.0.37", "syn 1.0.109", ] @@ -5173,11 +5604,11 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ - "base64 0.21.5", + "base64 0.22.1", "log", "native-tls", "once_cell", @@ -5186,12 +5617,12 @@ dependencies = [ [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna", "percent-encoding", "serde", ] @@ -5204,9 +5635,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "uuid" -version = "1.6.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" dependencies = [ "serde", ] @@ -5225,54 +5656,53 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "vise" -version = "0.1.0" -source = "git+https://github.com/matter-labs/vise.git?rev=a5bb80c9ce7168663114ee30e794d6dc32159ee4#a5bb80c9ce7168663114ee30e794d6dc32159ee4" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ade36f3548b1524396f4de7b36f4f210c8a01dfab568eb2bff466af64eb6e5" dependencies = [ "compile-fmt", + "ctor", "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" +name = "vise-exporter" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671d3b894d5d0849f0a597f56bf071f42d4f2a1cbcf2f78ca21f870ab7c0cc2b" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "hyper 0.14.30", + "once_cell", + "tokio", + "tracing", + "vise", ] [[package]] -name = "vlog" -version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +name = "vise-macros" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a511871dc5de990a3b2a0e715facfbc5da848c0c0395597a1415029fb7c250a" dependencies = [ - "chrono", - "opentelemetry", - "opentelemetry-otlp", - "opentelemetry-semantic-conventions", - "sentry", - "serde_json", - "tracing", - "tracing-opentelemetry", - "tracing-subscriber", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -5293,38 +5723,45 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "js-sys", "wasm-bindgen", "web-sys", @@ -5332,115 +5769,76 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" dependencies = [ - "quote", + "quote 1.0.37", "wasm-bindgen-macro-support", ] [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" [[package]] -name = "web-sys" -version = "0.3.66" +name = "wasm-streams" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" dependencies = [ + "futures-util", "js-sys", "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", ] [[package]] -name = "web3" -version = "0.19.0" +name = "web-sys" +version = "0.3.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5388522c899d1e1c96a4c307e3797e0f697ba7c77dd8e0e625ecba9dd0342937" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" dependencies = [ - "arrayvec 0.7.4", - "base64 0.21.5", - "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", - "pin-project", - "reqwest", - "rlp", - "secp256k1", - "serde", - "serde_json", - "soketto", - "tiny-keccak 2.0.2", - "tokio", - "tokio-stream", - "tokio-util", - "url", - "web3-async-native-tls", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "web3-async-native-tls" -version = "0.4.0" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6d8d1636b2627fe63518d5a9b38a569405d9c9bc665c43c9c341de57227ebb" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ - "native-tls", - "thiserror", - "tokio", - "url", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "webpki-roots" -version = "0.25.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" - -[[package]] -name = "which" -version = "4.4.2" +name = "whoami" +version = "1.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" dependencies = [ - "either", - "home", - "once_cell", - "rustix", + "redox_syscall", + "wasite", ] -[[package]] -name = "whoami" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" - [[package]] name = "winapi" version = "0.3.9" @@ -5459,11 +5857,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -5474,11 +5872,41 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-core" -version = "0.51.1" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.48.5", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -5496,7 +5924,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -5516,17 +5953,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -5537,9 +5975,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -5549,9 +5987,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -5561,9 +5999,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -5573,9 +6017,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -5585,9 +6029,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -5597,9 +6041,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -5609,15 +6053,24 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] [[package]] name = "winnow" -version = "0.5.26" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67b5f0a4e7a27a64c651977932b9dc5667ca7fc31ac44b03ed37a0cf42fdfff" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" dependencies = [ "memchr", ] @@ -5628,7 +6081,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" dependencies = [ - "cfg-if 1.0.0", + "cfg-if", "windows-sys 0.48.0", ] @@ -5642,30 +6095,37 @@ dependencies = [ ] [[package]] -name = "zerocopy" -version = "0.7.30" +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "zerocopy" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306dca4455518f1f31635ec308b6b3e4eb1b11758cefafc782827d0aa7acb5c7" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.30" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be912bf68235a88fbefd1b73415cb218405958d1655b2ece9035a19920bdf6ba" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" dependencies = [ "zeroize_derive", ] @@ -5676,47 +6136,34 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.40", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 2.0.79", ] [[package]] name = "zk_evm" -version = "1.3.1" -source = "git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.1-rc2#0a7c775932db4839ff6b7fb0db9bdb3583ab54c0" +version = "0.131.0-rc.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b83ee7887fb29fda57c6b26a0f64c9b211459d718f8a26310f962e69f0b764" dependencies = [ - "blake2 0.10.6 (git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e)", + "blake2_ce", "k256 0.11.6", "lazy_static", "num", "serde", "serde_json", - "sha2 0.10.6", - "sha3 0.10.6", - "static_assertions", - "zkevm_opcode_defs 1.3.1", -] - -[[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", + "sha2_ce", + "sha3_ce", "static_assertions", - "zk_evm_abstractions 0.1.0", - "zkevm_opcode_defs 1.3.2", + "zkevm_opcode_defs 0.131.0", ] [[package]] name = "zk_evm" -version = "1.3.3" -source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.3.3#fbee20f5bac7d6ca3e22ae69b2077c510a07de4e" +version = "0.133.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9af08e9284686a1b0c89ec4931eb915ac0729367f1247abd06164874fe738106" dependencies = [ "anyhow", "lazy_static", @@ -5724,14 +6171,15 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.1.0", - "zkevm_opcode_defs 1.3.2", + "zk_evm_abstractions 0.140.0", + "zkevm_opcode_defs 0.132.0", ] [[package]] name = "zk_evm" -version = "1.4.0" -source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.4.0#dd76fc5badf2c05278a21b38015a7798fe2fe358" +version = "0.140.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349bb8320d12578537658792df708f43c52e6330f0df071f812cb93b04ade962" dependencies = [ "anyhow", "lazy_static", @@ -5739,14 +6187,15 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 0.1.0", - "zkevm_opcode_defs 1.3.2", + "zk_evm_abstractions 0.140.0", + "zkevm_opcode_defs 0.132.0", ] [[package]] name = "zk_evm" -version = "1.4.1" -source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.4.1#6250dbf64b2d14ced87a127735da559f27a432d5" +version = "0.141.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8886ba5989b952b7b76096469eeb6fdfaf3369770e9e22a6f67dc4b7d65f9243" dependencies = [ "anyhow", "lazy_static", @@ -5754,14 +6203,15 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 1.4.1", - "zkevm_opcode_defs 1.4.1", + "zk_evm_abstractions 0.141.0", + "zkevm_opcode_defs 0.141.0", ] [[package]] name = "zk_evm" -version = "1.5.0" -source = "git+https://github.com/matter-labs/era-zk_evm.git?branch=v1.5.0#0448e26ffd8e2f1935ff8cd3303fe5a504cd5d7b" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6e69931f24db5cf333b714721e8d80ff88bfdb7da8c3dc7882612ffddb8d27" dependencies = [ "anyhow", "lazy_static", @@ -5769,54 +6219,57 @@ dependencies = [ "serde", "serde_json", "static_assertions", - "zk_evm_abstractions 1.5.0", + "zk_evm_abstractions 0.150.5", ] [[package]] name = "zk_evm_abstractions" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git#32dd320953841aa78579d9da08abbc70bcaed175" +version = "0.140.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be696258861eba4e6625a5665084b2266720bb67f4ba69819469700ac5c6a401" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 1.3.2", + "zkevm_opcode_defs 0.132.0", ] [[package]] name = "zk_evm_abstractions" -version = "1.4.1" -source = "git+https://github.com/matter-labs/era-zk_evm_abstractions.git?branch=v1.4.1#0aac08c3b097ee8147e748475117ac46bddcdcef" +version = "0.141.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637a3cb6cb475bb238bee3e450763205d36fe6c92dc1b23300655927915baf03" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 1.4.1", + "zkevm_opcode_defs 0.141.0", ] [[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" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6b0720261ab55490fe3a96e96de30d5d7b277940b52ea7f52dbf564eb1748" dependencies = [ "anyhow", "num_enum 0.6.1", "serde", "static_assertions", - "zkevm_opcode_defs 1.5.0", + "zkevm_opcode_defs 0.150.5", ] [[package]] name = "zkevm_circuits" -version = "1.4.0" -source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.4.0#fb3e2574b5c890342518fc930c145443f039a105" +version = "0.140.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c365c801e0c6eda83fbd153df45575172beb406bfb663d386f9154b4325eda" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bincode", "boojum", - "cs_derive", "derivative", "hex", "itertools 0.10.5", @@ -5826,18 +6279,19 @@ dependencies = [ "serde", "serde_json", "smallvec", - "zkevm_opcode_defs 1.3.2", + "zkevm_opcode_defs 0.132.0", + "zksync_cs_derive", ] [[package]] name = "zkevm_circuits" -version = "1.4.1" -source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.4.1#8bf24543ffc5bafab34182388394e887ecb37d17" +version = "0.141.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ccd0352e122a4e6f0046d2163b7e692e627b23fc3264faa77331a21b65833fd" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "bincode", "boojum", - "cs_derive", "derivative", "hex", "itertools 0.10.5", @@ -5847,17 +6301,18 @@ dependencies = [ "serde", "serde_json", "smallvec", - "zkevm_opcode_defs 1.4.1", + "zkevm_opcode_defs 0.141.0", + "zksync_cs_derive", ] [[package]] name = "zkevm_circuits" -version = "1.5.0" -source = "git+https://github.com/matter-labs/era-zkevm_circuits.git?branch=v1.5.0#861f81029bf3a916dae55afa5bd7f82b2eaca98b" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784fa7cfb51e17c5ced112bca43da30b3468b2347b7af0427ad9638759fb140e" dependencies = [ - "arrayvec 0.7.4", + "arrayvec 0.7.6", "boojum", - "cs_derive", "derivative", "hex", "itertools 0.10.5", @@ -5866,13 +6321,15 @@ dependencies = [ "seq-macro", "serde", "smallvec", - "zkevm_opcode_defs 1.5.0", + "zkevm_opcode_defs 0.150.5", + "zksync_cs_derive", ] [[package]] name = "zkevm_opcode_defs" -version = "1.3.1" -source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.3.1#00d4ad2292bd55374a0fa10fe11686d7a109d8a0" +version = "0.131.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e0154bd4ae8202c96c52b29dd44f944bfd08c1c233fef843744463964de957" dependencies = [ "bitflags 1.3.2", "ethereum-types", @@ -5882,27 +6339,29 @@ dependencies = [ [[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" +version = "0.132.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0769f7b27d8fb06e715da3290c575cac5d04d10a557faef180e847afce50ac4" dependencies = [ - "bitflags 2.4.1", - "blake2 0.10.6 (git+https://github.com/RustCrypto/hashes.git?rev=1f727ce37ff40fa0cce84eb8543a45bdd3ca4a4e)", + "bitflags 2.6.0", + "blake2 0.10.6", "ethereum-types", "k256 0.11.6", "lazy_static", - "sha2 0.10.6", - "sha3 0.10.6", + "sha2_ce", + "sha3_ce", ] [[package]] name = "zkevm_opcode_defs" -version = "1.4.1" -source = "git+https://github.com/matter-labs/era-zkevm_opcode_defs.git?branch=v1.4.1#ba8228ff0582d21f64d6a319d50d0aec48e9e7b6" +version = "0.141.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6be7bd5f0e0b61211f544147289640b4712715589d7f2fe5229d92a7a3ac64c0" dependencies = [ - "bitflags 2.4.1", - "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.6.0", + "blake2 0.10.6", "ethereum-types", - "k256 0.13.3", + "k256 0.13.4", "lazy_static", "sha2 0.10.8", "sha3 0.10.8", @@ -5910,13 +6369,14 @@ 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#109d9f734804a8b9dc0531c0b576e2a0f55a40de" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79055eae1b6c1ab80793ed9d77d2964c9c896afa4b5dfed278cf58cd10acfe8f" dependencies = [ - "bitflags 2.4.1", - "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 2.6.0", + "blake2 0.10.6", "ethereum-types", - "k256 0.13.3", + "k256 0.13.4", "lazy_static", "p256", "serde", @@ -5927,20 +6387,51 @@ dependencies = [ [[package]] name = "zksync_basic_types" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ + "anyhow", "chrono", - "num_enum 0.7.2", + "ethabi", + "hex", + "num_enum 0.7.3", + "secrecy", "serde", "serde_json", + "serde_with", "strum", - "web3", + "thiserror", + "tiny-keccak 2.0.2", + "url", +] + +[[package]] +name = "zksync_bellman" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffa03efe9bdb137a4b36b97d1a74237e18c9ae42b755163d903a9d48c1a5d80" +dependencies = [ + "arrayvec 0.7.6", + "bit-vec", + "blake2s_simd", + "byteorder", + "cfg-if", + "crossbeam", + "futures", + "hex", + "lazy_static", + "num_cpus", + "rand 0.4.6", + "serde", + "smallvec", + "tiny-keccak 1.5.0", + "zksync_pairing", ] [[package]] name = "zksync_concurrency" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "035269d811b3770debca372141ab64cad067dce8e58cb39a48cb7617d30c626b" dependencies = [ "anyhow", "once_cell", @@ -5958,43 +6449,55 @@ dependencies = [ [[package]] name = "zksync_config" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", "rand 0.8.5", + "secrecy", "serde", + "strum", + "strum_macros", + "time", + "url", + "vise", "zksync_basic_types", + "zksync_concurrency", "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=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e38d1b5ed28c66e785caff53ea4863375555d818aafa03290397192dd3e665" dependencies = [ "anyhow", "blst", "ed25519-dalek", - "ff_ce", + "elliptic-curve 0.13.8", "hex", - "pairing_ce 0.28.5 (git+https://github.com/matter-labs/pairing.git?rev=d24f2c5871089c4cd4f54c0ca266bb9fef6115eb)", - "rand 0.4.6", + "k256 0.13.4", + "num-bigint 0.4.6", + "num-traits", "rand 0.8.5", "sha3 0.10.8", "thiserror", "tracing", + "zeroize", ] [[package]] name = "zksync_consensus_roles" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e49fbd4e69b276058f3dfc06cf6ada0e8caa6ed826e81289e4d596da95a0f17a" dependencies = [ "anyhow", "bit-vec", "hex", - "prost 0.12.3", + "num-bigint 0.4.6", + "prost 0.12.6", "rand 0.8.5", "serde", "thiserror", @@ -6008,17 +6511,19 @@ dependencies = [ [[package]] name = "zksync_consensus_storage" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b2aab4ed18b13cd584f4edcc2546c8da82f89ac62e525063e12935ff28c9be" dependencies = [ "anyhow", "async-trait", - "prost 0.12.3", + "prost 0.12.6", "rand 0.8.5", "thiserror", "tracing", "vise", "zksync_concurrency", + "zksync_consensus_crypto", "zksync_consensus_roles", "zksync_protobuf", "zksync_protobuf_build", @@ -6026,9 +6531,11 @@ dependencies = [ [[package]] name = "zksync_consensus_utils" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10bac8f471b182d4fa3d40cf158aac3624fe636a1ff0b4cf3fe26a0e20c68a42" dependencies = [ + "anyhow", "rand 0.8.5", "thiserror", "zksync_concurrency", @@ -6037,7 +6544,7 @@ dependencies = [ [[package]] name = "zksync_contracts" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "envy", "ethabi", @@ -6048,40 +6555,40 @@ dependencies = [ "zksync_utils", ] -[[package]] -name = "zksync_crypto" -version = "0.1.0" -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.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" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", + "blake2 0.10.6", "hex", + "rand 0.8.5", "secp256k1", "serde", "serde_json", + "sha2 0.10.8", "thiserror", - "web3", "zksync_basic_types", "zksync_utils", ] +[[package]] +name = "zksync_cs_derive" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5939e2df4288c263c706ff18ac718e984149223ad4289d6d957d767dcfc04c81" +dependencies = [ + "proc-macro-error", + "proc-macro2 1.0.87", + "quote 1.0.37", + "syn 1.0.109", +] + [[package]] name = "zksync_dal" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", "bigdecimal", @@ -6089,7 +6596,7 @@ dependencies = [ "chrono", "hex", "itertools 0.10.5", - "prost 0.12.3", + "prost 0.12.6", "rand 0.8.5", "serde", "serde_json", @@ -6099,21 +6606,26 @@ dependencies = [ "tokio", "tracing", "vise", + "zksync_concurrency", + "zksync_consensus_crypto", "zksync_consensus_roles", "zksync_consensus_storage", + "zksync_consensus_utils", "zksync_contracts", "zksync_db_connection", + "zksync_l1_contract_interface", "zksync_protobuf", "zksync_protobuf_build", "zksync_system_constants", "zksync_types", "zksync_utils", + "zksync_vm_interface", ] [[package]] name = "zksync_db_connection" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", "rand 0.8.5", @@ -6123,45 +6635,159 @@ dependencies = [ "thiserror", "tokio", "tracing", - "url", "vise", - "zksync_health_check", + "zksync_basic_types", ] [[package]] -name = "zksync_health_check" -version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +name = "zksync_ff" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9524b06780b5e164e84b38840c7c428c739f051f35af6efc4d1285f629ceb88e" dependencies = [ - "async-trait", - "futures", + "byteorder", + "hex", + "rand 0.4.6", + "serde", + "zksync_ff_derive", +] + +[[package]] +name = "zksync_ff_derive" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f91e58e75d65877f09f83bc3dca8f054847ae7ec4f3e64bfa610a557edd8e8e" +dependencies = [ + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "proc-macro2 1.0.87", + "quote 1.0.37", + "serde", + "syn 1.0.109", +] + +[[package]] +name = "zksync_kzg" +version = "0.150.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edb8a9c76c172a6d639855ee342b9a670e3ba472f5ae302f771b1c3ee777dc88" +dependencies = [ + "boojum", + "derivative", + "hex", + "once_cell", + "rayon", "serde", "serde_json", - "thiserror", - "tokio", - "tracing", - "vise", + "serde_with", + "zkevm_circuits 0.150.5", +] + +[[package]] +name = "zksync_l1_contract_interface" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" +dependencies = [ + "anyhow", + "hex", + "once_cell", + "sha2 0.10.8", + "sha3 0.10.8", + "zksync_kzg", + "zksync_prover_interface", + "zksync_solidity_vk_codegen", + "zksync_types", ] [[package]] name = "zksync_mini_merkle_tree" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "once_cell", "zksync_basic_types", - "zksync_crypto", + "zksync_crypto_primitives", ] [[package]] -name = "zksync_protobuf" +name = "zksync_multivm" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" +dependencies = [ + "anyhow", + "circuit_sequencer_api 0.133.1", + "circuit_sequencer_api 0.140.3", + "circuit_sequencer_api 0.141.2", + "circuit_sequencer_api 0.142.2", + "circuit_sequencer_api 0.150.5", + "ethabi", + "hex", + "itertools 0.10.5", + "once_cell", + "thiserror", + "tracing", + "vise", + "zk_evm 0.131.0-rc.2", + "zk_evm 0.133.0", + "zk_evm 0.140.0", + "zk_evm 0.141.0", + "zk_evm 0.150.5", + "zksync_contracts", + "zksync_system_constants", + "zksync_types", + "zksync_utils", + "zksync_vm2", + "zksync_vm_interface", +] + +[[package]] +name = "zksync_object_store" version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" +dependencies = [ + "anyhow", + "async-trait", + "bincode", + "flate2", + "google-cloud-auth", + "google-cloud-storage", + "http 1.1.0", + "prost 0.12.6", + "rand 0.8.5", + "reqwest 0.12.8", + "serde_json", + "tokio", + "tracing", + "vise", + "zksync_config", + "zksync_protobuf", + "zksync_types", +] + +[[package]] +name = "zksync_pairing" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8412ae5574472fa567a097e183f9a01974b99dd0b5da3bfa1bbe6c57c579aa2" +dependencies = [ + "byteorder", + "cfg-if", + "rand 0.4.6", + "serde", + "zksync_ff", +] + +[[package]] +name = "zksync_protobuf" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abd55c64f54cb10967a435422f66ff5880ae14a232b245517c7ce38da32e0cab" dependencies = [ "anyhow", "bit-vec", "once_cell", - "prost 0.12.3", + "prost 0.12.6", "prost-reflect", "quick-protobuf", "rand 0.8.5", @@ -6175,37 +6801,73 @@ dependencies = [ [[package]] name = "zksync_protobuf_build" -version = "0.1.0" -source = "git+https://github.com/matter-labs/era-consensus.git?rev=1dcda70c1c25d0e4db6781ba8d2645d7e8966d49#1dcda70c1c25d0e4db6781ba8d2645d7e8966d49" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4121952bcaf711005dd554612fc6e2de9b30cb58088508df87f1d38046ce8ac8" dependencies = [ "anyhow", - "heck 0.5.0", + "heck", "prettyplease", - "proc-macro2", + "proc-macro2 1.0.87", "prost-build", "prost-reflect", "protox", - "quote", - "syn 2.0.40", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "zksync_prover_interface" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" +dependencies = [ + "chrono", + "circuit_sequencer_api 0.150.5", + "serde", + "serde_with", + "strum", + "zksync_multivm", + "zksync_object_store", + "zksync_types", ] [[package]] name = "zksync_shared_metrics" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ + "rustc_version", + "tracing", "vise", "zksync_dal", "zksync_types", ] +[[package]] +name = "zksync_solidity_vk_codegen" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b310ab8a21681270e73f177ddf7974cabb7a96f0624ab8b008fd6ee1f9b4f687" +dependencies = [ + "ethereum-types", + "franklin-crypto", + "handlebars", + "hex", + "paste", + "rescue_poseidon", + "serde", + "serde_derive", + "serde_json", +] + [[package]] name = "zksync_state" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", "async-trait", + "backon", "chrono", "itertools 0.10.5", "mini-moka", @@ -6218,12 +6880,13 @@ dependencies = [ "zksync_storage", "zksync_types", "zksync_utils", + "zksync_vm_interface", ] [[package]] name = "zksync_storage" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "num_cpus", "once_cell", @@ -6236,7 +6899,7 @@ dependencies = [ [[package]] name = "zksync_system_constants" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "once_cell", "zksync_basic_types", @@ -6246,24 +6909,27 @@ dependencies = [ [[package]] name = "zksync_types" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", - "blake2 0.10.6 (registry+https://github.com/rust-lang/crates.io-index)", + "bigdecimal", + "blake2 0.10.6", "chrono", - "derive_more 1.0.0-beta.6", + "derive_more", "hex", "itertools 0.10.5", "num", - "num_enum 0.7.2", + "num_enum 0.7.3", "once_cell", - "prost 0.12.3", + "prost 0.12.6", "rlp", "secp256k1", "serde", "serde_json", + "serde_with", "strum", "thiserror", + "tracing", "zksync_basic_types", "zksync_config", "zksync_contracts", @@ -6278,29 +6944,93 @@ dependencies = [ [[package]] name = "zksync_utils" version = "0.1.0" -source = "git+https://github.com/matter-labs/zksync-era.git?rev=c4d1c49282a3710be5d491636ba26207efb1f9ce#c4d1c49282a3710be5d491636ba26207efb1f9ce" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" dependencies = [ "anyhow", "bigdecimal", "futures", "hex", - "itertools 0.10.5", "num", - "reqwest", + "once_cell", + "reqwest 0.12.8", "serde", + "serde_json", "thiserror", "tokio", "tracing", - "vlog", - "zk_evm 1.3.3 (git+https://github.com/matter-labs/era-zk_evm.git?tag=v1.3.3-rc2)", + "zk_evm 0.133.0", "zksync_basic_types", + "zksync_vlog", +] + +[[package]] +name = "zksync_vlog" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" +dependencies = [ + "anyhow", + "chrono", + "opentelemetry", + "opentelemetry-appender-tracing", + "opentelemetry-otlp", + "opentelemetry-semantic-conventions", + "opentelemetry_sdk", + "sentry", + "serde", + "serde_json", + "thiserror", + "time", + "tokio", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", + "url", + "vise", + "vise-exporter", +] + +[[package]] +name = "zksync_vm2" +version = "0.2.1" +source = "git+https://github.com/matter-labs/vm2.git?rev=a233d44bbe61dc6a758a754c3b78fe4f83e56699#a233d44bbe61dc6a758a754c3b78fe4f83e56699" +dependencies = [ + "enum_dispatch", + "primitive-types", + "zk_evm_abstractions 0.150.5", + "zkevm_opcode_defs 0.150.5", + "zksync_vm2_interface", +] + +[[package]] +name = "zksync_vm2_interface" +version = "0.2.1" +source = "git+https://github.com/matter-labs/vm2.git?rev=a233d44bbe61dc6a758a754c3b78fe4f83e56699#a233d44bbe61dc6a758a754c3b78fe4f83e56699" +dependencies = [ + "primitive-types", +] + +[[package]] +name = "zksync_vm_interface" +version = "0.1.0" +source = "git+https://github.com/matter-labs/zksync-era.git?rev=c1ab99d8d72509ccb9a537025cc6df9df141dd96#c1ab99d8d72509ccb9a537025cc6df9df141dd96" +dependencies = [ + "anyhow", + "async-trait", + "hex", + "pretty_assertions", + "serde", + "thiserror", + "tracing", + "zksync_contracts", + "zksync_system_constants", + "zksync_types", ] [[package]] name = "zstd-sys" -version = "2.0.10+zstd.1.5.6" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/system-contracts/bootloader/test_infra/Cargo.toml b/system-contracts/bootloader/test_infra/Cargo.toml index cfcd2c9a3..8ca71ef8a 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 = "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" } +zksync_multivm = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c1ab99d8d72509ccb9a537025cc6df9df141dd96" } +zksync_types = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c1ab99d8d72509ccb9a537025cc6df9df141dd96" } +zksync_contracts = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c1ab99d8d72509ccb9a537025cc6df9df141dd96" } +zksync_utils = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c1ab99d8d72509ccb9a537025cc6df9df141dd96" } +zksync_state = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c1ab99d8d72509ccb9a537025cc6df9df141dd96" } +zksync_vlog = { git = "https://github.com/matter-labs/zksync-era.git", rev = "c1ab99d8d72509ccb9a537025cc6df9df141dd96" } colored = "2.0" hex = "0.4" diff --git a/system-contracts/bootloader/test_infra/rust-toolchain b/system-contracts/bootloader/test_infra/rust-toolchain index 9a87fb21c..226a309c8 100644 --- a/system-contracts/bootloader/test_infra/rust-toolchain +++ b/system-contracts/bootloader/test_infra/rust-toolchain @@ -1 +1 @@ -nightly-2023-08-21 +nightly-2024-08-01 \ No newline at end of file diff --git a/system-contracts/bootloader/test_infra/src/hook.rs b/system-contracts/bootloader/test_infra/src/hook.rs index 04bacc90c..b1f0f1078 100644 --- a/system-contracts/bootloader/test_infra/src/hook.rs +++ b/system-contracts/bootloader/test_infra/src/hook.rs @@ -1,9 +1,9 @@ -use multivm::vm_latest::{ - constants::{BOOTLOADER_HEAP_PAGE, get_vm_hook_start_position_latest}, +use zksync_multivm::vm_latest::{ + constants::{get_vm_hook_start_position_latest, BOOTLOADER_HEAP_PAGE}, HistoryMode, SimpleMemory, }; -use multivm::zk_evm_latest::{ +use zksync_multivm::zk_evm_latest::{ aux_structures::MemoryPage, tracing::{BeforeExecutionData, VmLocalStateData}, zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode}, diff --git a/system-contracts/bootloader/test_infra/src/main.rs b/system-contracts/bootloader/test_infra/src/main.rs index 3928200e4..4e55b0ed3 100644 --- a/system-contracts/bootloader/test_infra/src/main.rs +++ b/system-contracts/bootloader/test_infra/src/main.rs @@ -1,25 +1,25 @@ use crate::{test_count_tracer::TestCountTracer, tracer::BootloaderTestTracer}; use colored::Colorize; -use multivm::interface::{ - L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmInterface, -}; -use multivm::vm_latest::{HistoryDisabled, ToTracerPointer, Vm}; use once_cell::sync::OnceCell; -use zksync_types::fee_model::BatchFeeInput; use std::process; +use zksync_multivm::interface::{ + L1BatchEnv, L2BlockEnv, SystemEnv, TxExecutionMode, VmExecutionMode, VmFactory, VmInterface, +}; +use zksync_multivm::vm_latest::{HistoryDisabled, ToTracerPointer, TracerDispatcher, Vm}; +use zksync_state::interface::{ + InMemoryStorage, StoragePtr, StorageView, IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID, +}; +use zksync_types::fee_model::BatchFeeInput; -use multivm::interface::{ExecutionResult, Halt}; use std::{env, sync::Arc}; use tracing_subscriber::fmt; use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; use zksync_contracts::{ - read_zbin_bytecode, BaseSystemContracts, ContractLanguage, SystemContractCode, + read_yul_bytecode, BaseSystemContracts, ContractLanguage, SystemContractCode, SystemContractsRepo, }; -use zksync_state::{ - InMemoryStorage, StoragePtr, StorageView, IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID, -}; +use zksync_multivm::interface::{ExecutionResult, Halt}; use zksync_types::system_contracts::get_system_smart_contracts_from_dir; use zksync_types::{block::L2BlockHasher, Address, L1BatchNumber, L2BlockNumber, U256}; use zksync_types::{L2ChainId, Transaction}; @@ -32,11 +32,13 @@ mod tracer; // Executes bootloader unittests. fn execute_internal_bootloader_test() { - let test_location = env::current_dir() - .unwrap() - .join("../build/artifacts/bootloader_test.yul.zbin"); - println!("Current dir is {:?}", test_location); - let bytecode = read_zbin_bytecode(test_location.as_path()); + let artifacts_location_path = env::current_dir().unwrap().join("../build/artifacts"); + let artifacts_location = artifacts_location_path + .to_str() + .expect("Invalid path: {artifacts_location_path:?}"); + println!("Current dir is {:?}", artifacts_location); + + let bytecode = read_yul_bytecode(artifacts_location, "bootloader_test"); let hash = hash_bytecode(&bytecode); let bootloader = SystemContractCode { code: bytes_to_be_words(bytecode), @@ -57,6 +59,7 @@ fn execute_internal_bootloader_test() { let base_system_contract = BaseSystemContracts { bootloader, default_aa, + evm_emulator: None, }; let system_env = SystemEnv { @@ -91,19 +94,23 @@ fn execute_internal_bootloader_test() { StorageView::new(InMemoryStorage::with_custom_system_contracts_and_chain_id( L2ChainId::from(IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID), hash_bytecode, - get_system_smart_contracts_from_dir(env::current_dir().unwrap().join("../../")), + get_system_smart_contracts_from_dir( + env::current_dir().unwrap().join("../../"), + false, + ), )) .to_rc_ptr(); let mut vm: Vm<_, HistoryDisabled> = - Vm::new(l1_batch_env.clone(), system_env.clone(), storage.clone()); + VmFactory::new(l1_batch_env.clone(), system_env.clone(), storage.clone()); let test_count = Arc::new(OnceCell::default()); let custom_tracers = TestCountTracer::new(test_count.clone()).into_tracer_pointer(); // We're using a TestCountTracer (and passing 0 as fee account) - this should cause the bootloader // test framework to report number of tests via VM hook. - vm.inspect(custom_tracers.into(), VmExecutionMode::Bootloader); + let mut tracer_dispatcher = TracerDispatcher::from(custom_tracers); + vm.inspect(&mut tracer_dispatcher, VmExecutionMode::Bootloader); test_count.get().unwrap().clone() }; @@ -119,7 +126,10 @@ fn execute_internal_bootloader_test() { StorageView::new(InMemoryStorage::with_custom_system_contracts_and_chain_id( L2ChainId::from(IN_MEMORY_STORAGE_DEFAULT_NETWORK_ID), hash_bytecode, - get_system_smart_contracts_from_dir(env::current_dir().unwrap().join("../../")), + get_system_smart_contracts_from_dir( + env::current_dir().unwrap().join("../../"), + false, + ), )) .to_rc_ptr(); @@ -138,13 +148,16 @@ fn execute_internal_bootloader_test() { test_name.clone(), ) .into_tracer_pointer(); + let mut tracer_dispatcher = TracerDispatcher::from(custom_tracers); // Let's insert transactions into slots. They are not executed, but the tests can run functions against them. let json_str = include_str!("test_transactions/0.json"); let tx: Transaction = serde_json::from_str(json_str).unwrap(); vm.push_transaction(tx); - let result = vm.inspect(custom_tracers.into(), VmExecutionMode::Bootloader); + let result = vm.inspect(&mut tracer_dispatcher, VmExecutionMode::Bootloader); + drop(tracer_dispatcher); + let mut test_result = Arc::into_inner(test_result).unwrap().into_inner(); let requested_assert = Arc::into_inner(requested_assert).unwrap().into_inner(); let test_name = Arc::into_inner(test_name) diff --git a/system-contracts/bootloader/test_infra/src/test_count_tracer.rs b/system-contracts/bootloader/test_infra/src/test_count_tracer.rs index 1c2dfa523..f82a4df6a 100644 --- a/system-contracts/bootloader/test_infra/src/test_count_tracer.rs +++ b/system-contracts/bootloader/test_infra/src/test_count_tracer.rs @@ -1,10 +1,10 @@ use std::sync::Arc; -use multivm::interface::dyn_tracers::vm_1_5_0::DynTracer; -use multivm::vm_latest::{HistoryMode, SimpleMemory, VmTracer}; -use multivm::zk_evm_latest::tracing::{BeforeExecutionData, VmLocalStateData}; use once_cell::sync::OnceCell; -use zksync_state::{StoragePtr, WriteStorage}; +use zksync_multivm::tracers::dynamic::vm_1_5_0::DynTracer; +use zksync_multivm::vm_latest::{HistoryMode, SimpleMemory, VmTracer}; +use zksync_multivm::zk_evm_latest::tracing::{BeforeExecutionData, VmLocalStateData}; +use zksync_state::interface::{StoragePtr, WriteStorage}; use crate::hook::TestVmHook; diff --git a/system-contracts/bootloader/test_infra/src/tracer.rs b/system-contracts/bootloader/test_infra/src/tracer.rs index c38875235..8b26cba35 100644 --- a/system-contracts/bootloader/test_infra/src/tracer.rs +++ b/system-contracts/bootloader/test_infra/src/tracer.rs @@ -3,14 +3,15 @@ use std::sync::Arc; use colored::Colorize; use once_cell::sync::OnceCell; -use multivm::interface::{ - dyn_tracers::vm_1_5_0::DynTracer, - tracer::{TracerExecutionStatus, TracerExecutionStopReason}, +use zksync_multivm::tracers::dynamic::vm_1_5_0::DynTracer; + +use zksync_multivm::interface::tracer::{TracerExecutionStatus, TracerExecutionStopReason}; +use zksync_multivm::vm_latest::{ + BootloaderState, HistoryMode, SimpleMemory, VmTracer, ZkSyncVmState, }; -use multivm::vm_latest::{BootloaderState, HistoryMode, SimpleMemory, VmTracer, ZkSyncVmState}; -use multivm::zk_evm_latest::tracing::{BeforeExecutionData, VmLocalStateData}; +use zksync_multivm::zk_evm_latest::tracing::{BeforeExecutionData, VmLocalStateData}; -use zksync_state::{StoragePtr, WriteStorage}; +use zksync_state::interface::{StoragePtr, WriteStorage}; use crate::hook::TestVmHook; diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 4c55279c4..52879df1f 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -115,6 +115,8 @@ contract AccountCodeStorage is IAccountCodeStorage { // so set `keccak256("")` as a code hash. The EVM has the same behavior. else if (Utils.isContractConstructing(codeHash)) { codeHash = EMPTY_STRING_KECCAK; + } else if (Utils.isCodeHashEVM(codeHash)) { + codeHash = DEPLOYER_SYSTEM_CONTRACT.evmCodeHash(account); } return codeHash; @@ -145,4 +147,10 @@ contract AccountCodeStorage is IAccountCodeStorage { codeSize = Utils.bytecodeLenInBytes(codeHash); } } + + /// @notice Method for detecting whether an address is an EVM contract + function isAccountEVM(address _addr) external view override returns (bool) { + bytes32 bytecodeHash = getRawCodeHash(_addr); + return Utils.isCodeHashEVM(bytecodeHash); + } } diff --git a/system-contracts/contracts/BootloaderUtilities.sol b/system-contracts/contracts/BootloaderUtilities.sol index 4fd38da74..554a79aba 100644 --- a/system-contracts/contracts/BootloaderUtilities.sol +++ b/system-contracts/contracts/BootloaderUtilities.sol @@ -59,7 +59,11 @@ contract BootloaderUtilities is IBootloaderUtilities { encodedGasParam = bytes.concat(encodedGasPrice, encodedGasLimit); } - bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + // "to" field is empty if it is EVM deploy tx + bytes memory encodedTo = _transaction.reserved[1] == 1 + ? bytes(hex"80") + : RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); // Encode only the length of the transaction data, and not the data itself, // so as not to copy to memory a potentially huge transaction data twice. @@ -148,7 +152,10 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); bytes memory encodedGasPrice = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); - bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + // "to" field is empty if it is EVM deploy tx + bytes memory encodedTo = _transaction.reserved[1] == 1 + ? bytes(hex"80") + : RLPEncoder.encodeAddress(address(uint160(_transaction.to))); bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); // solhint-disable-next-line func-named-parameters encodedFixedLengthParams = bytes.concat( @@ -246,7 +253,10 @@ contract BootloaderUtilities is IBootloaderUtilities { bytes memory encodedMaxPriorityFeePerGas = RLPEncoder.encodeUint256(_transaction.maxPriorityFeePerGas); bytes memory encodedMaxFeePerGas = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); - bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + // "to" field is empty if it is EVM deploy tx + bytes memory encodedTo = _transaction.reserved[1] == 1 + ? bytes(hex"80") + : RLPEncoder.encodeAddress(address(uint160(_transaction.to))); bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); // solhint-disable-next-line func-named-parameters encodedFixedLengthParams = bytes.concat( diff --git a/system-contracts/contracts/Constants.sol b/system-contracts/contracts/Constants.sol index 00145480b..fbaabc091 100644 --- a/system-contracts/contracts/Constants.sol +++ b/system-contracts/contracts/Constants.sol @@ -30,10 +30,12 @@ uint160 constant MAX_SYSTEM_CONTRACT_ADDRESS = 0xffff; // 2^16 - 1 address constant ECRECOVER_SYSTEM_CONTRACT = address(0x01); address constant SHA256_SYSTEM_CONTRACT = address(0x02); +address constant IDENTITY_SYSTEM_CONTRACT = address(0x04); address constant ECADD_SYSTEM_CONTRACT = address(0x06); address constant ECMUL_SYSTEM_CONTRACT = address(0x07); address constant ECPAIRING_SYSTEM_CONTRACT = address(0x08); +address constant CODE_ORACLE_SYSTEM_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x12); /// @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: @@ -83,6 +85,7 @@ address constant EVENT_WRITER_CONTRACT = address(SYSTEM_CONTRACTS_OFFSET + 0x0d) ICompressor constant COMPRESSOR_CONTRACT = ICompressor(address(SYSTEM_CONTRACTS_OFFSET + 0x0e)); IComplexUpgrader constant COMPLEX_UPGRADER_CONTRACT = IComplexUpgrader(address(SYSTEM_CONTRACTS_OFFSET + 0x0f)); +address constant EVM_GAS_MANAGER = address(SYSTEM_CONTRACTS_OFFSET + 0x13); IPubdataChunkPublisher constant PUBDATA_CHUNK_PUBLISHER = IPubdataChunkPublisher( address(SYSTEM_CONTRACTS_OFFSET + 0x11) @@ -102,6 +105,9 @@ bytes32 constant CREATE2_PREFIX = 0x2020dba91b30cc0006188af794c2fb30dd8520db7e2c /// @dev keccak256("zksyncCreate") bytes32 constant CREATE_PREFIX = 0x63bae3a9951d38e8a3fbb7b70909afc1200610fc5bc55ade242f815974674f23; +/// @dev Prefix used during derivation of account addresses using CREATE2 within the EVM +bytes1 constant CREATE2_EVM_PREFIX = 0xff; + /// @dev Each state diff consists of 156 bytes of actual data and 116 bytes of unused padding, needed for circuit efficiency. uint256 constant STATE_DIFF_ENTRY_SIZE = 272; @@ -157,3 +163,10 @@ uint256 constant BLOB_SIZE_BYTES = 126_976; /// @dev Max number of blobs currently supported uint256 constant MAX_NUMBER_OF_BLOBS = 6; + +/// @dev Marker of EraVM bytecode +uint8 constant ERA_VM_BYTECODE_FLAG = 1; +/// @dev Marker of EVM bytecode +uint8 constant EVM_BYTECODE_FLAG = 2; + +address constant SERVICE_CALL_PSEUDO_CALLER = 0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF; \ No newline at end of file diff --git a/system-contracts/contracts/ContractDeployer.sol b/system-contracts/contracts/ContractDeployer.sol index 8e9bda169..f909e3fb0 100644 --- a/system-contracts/contracts/ContractDeployer.sol +++ b/system-contracts/contracts/ContractDeployer.sol @@ -4,13 +4,13 @@ pragma solidity 0.8.24; import {ImmutableData} from "./interfaces/IImmutableSimulator.sol"; import {IContractDeployer} from "./interfaces/IContractDeployer.sol"; -import {CREATE2_PREFIX, CREATE_PREFIX, NONCE_HOLDER_SYSTEM_CONTRACT, ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT, FORCE_DEPLOYER, MAX_SYSTEM_CONTRACT_ADDRESS, KNOWN_CODE_STORAGE_CONTRACT, BASE_TOKEN_SYSTEM_CONTRACT, IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT, COMPLEX_UPGRADER_CONTRACT} from "./Constants.sol"; +import {CREATE2_PREFIX, CREATE_PREFIX, NONCE_HOLDER_SYSTEM_CONTRACT, ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT, FORCE_DEPLOYER, MAX_SYSTEM_CONTRACT_ADDRESS, KNOWN_CODE_STORAGE_CONTRACT, BASE_TOKEN_SYSTEM_CONTRACT, IMMUTABLE_SIMULATOR_SYSTEM_CONTRACT, COMPLEX_UPGRADER_CONTRACT, SERVICE_CALL_PSEUDO_CALLER} from "./Constants.sol"; import {Utils} from "./libraries/Utils.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; -import {Unauthorized, InvalidNonceOrderingChange, ValueMismatch, EmptyBytes32, NotAllowedToDeployInKernelSpace, HashIsNonZero, NonEmptyAccount, UnknownCodeHash, NonEmptyMsgValue} from "./SystemContractErrors.sol"; +import {Unauthorized, InvalidNonceOrderingChange, ValueMismatch, EmptyBytes32, EVMEmulationNotSupported, NotAllowedToDeployInKernelSpace, HashIsNonZero, NonEmptyAccount, UnknownCodeHash, NonEmptyMsgValue} from "./SystemContractErrors.sol"; /** * @author Matter Labs @@ -22,6 +22,12 @@ import {Unauthorized, InvalidNonceOrderingChange, ValueMismatch, EmptyBytes32, N * do not need to be published anymore. */ contract ContractDeployer is IContractDeployer, SystemContractBase { + /// @dev Prefix for EVM contracts hashes storage slots. + uint256 private constant EVM_HASHES_PREFIX = 1 << 254; + /// @dev keccak256("ALLOWED_BYTECODE_TYPES_MODE_SLOT"). + bytes32 private constant ALLOWED_BYTECODE_TYPES_MODE_SLOT = + 0xd70708d0b933e26eab552567ce3a8ad69e6fbec9a2a68f16d51bd417a47d9d3b; + /// @notice Information about an account contract. /// @dev For EOA and simple contracts (i.e. not accounts) this value is 0. mapping(address => AccountInfo) internal accountInfo; @@ -33,6 +39,16 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { _; } + /// @notice Returns what types of bytecode are allowed to be deployed on this chain. + function allowedBytecodeTypesToDeploy() external view returns (AllowedBytecodeTypes mode) { + mode = _getAllowedBytecodeTypesMode(); + } + + /// @notice Returns keccak of EVM bytecode at address if it is an EVM contract. Returns bytes32(0) if it isn't a EVM contract. + function evmCodeHash(address _address) external view returns (bytes32 _hash) { + _hash = _getEvmCodeHash(_address); + } + /// @notice Returns information about a certain account. function getAccountInfo(address _address) external view returns (AccountInfo memory info) { return accountInfo[_address]; @@ -157,6 +173,92 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { return createAccount(_salt, _bytecodeHash, _input, AccountAbstractionVersion.None); } + /// @notice Deploys an EVM contract using address derivation of EVM's `CREATE` opcode. + /// @param _initCode The init code for the contract. + /// Note: this method may be callable only in system mode. + /// @return The amount of EVM gas used. + /// @return The address of created contract. + function createEVM(bytes calldata _initCode) external payable override onlySystemCall returns (uint256, address) { + uint256 senderNonce; + // If the account is an EOA, use the min nonce. If it's a contract, use deployment nonce + if (msg.sender == tx.origin) { + // Subtract 1 for EOA since the nonce has already been incremented for this transaction + senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.getMinNonce(msg.sender) - 1; + } else { + // Deploy from EraVM context + senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); + } + + address newAddress = Utils.getNewAddressCreateEVM(msg.sender, senderNonce); + + uint256 evmGasUsed = _evmDeployOnAddress(msg.sender, newAddress, _initCode); + + return (evmGasUsed, newAddress); + } + + /// @notice Deploys an EVM contract using address derivation of EVM's `CREATE2` opcode. + /// @param _salt The CREATE2 salt. + /// @param _initCode The init code for the contract. + /// Note: this method may be callable only in system mode. + /// @return The amount of EVM gas used. + /// @return The address of created contract. + function create2EVM( + bytes32 _salt, + bytes calldata _initCode + ) external payable override onlySystemCall returns (uint256, address) { + NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); + // No collision is possible with the zksync's non-EVM CREATE2, since the prefixes are different + bytes32 bytecodeHash = EfficientCall.keccak(_initCode); + address newAddress = Utils.getNewAddressCreate2EVM(msg.sender, _salt, bytecodeHash); + + uint256 evmGasUsed = _evmDeployOnAddress(msg.sender, newAddress, _initCode); + + return (evmGasUsed, newAddress); + } + + /// @notice Method used by EVM emulator to check if contract can be deployed. + /// @param _salt The CREATE2 salt. + /// @param _evmBytecodeHash The keccak of EVM code to be deployed (initCode). + /// Note: this method may be callable only by the EVM emulator. + function precreateEvmAccountFromEmulator( + bytes32 _salt, + bytes32 _evmBytecodeHash + ) public onlySystemCallFromEvmEmulator returns (address newAddress) { + if (_getAllowedBytecodeTypesMode() != AllowedBytecodeTypes.EraVmAndEVM) { + revert EVMEmulationNotSupported(); + } + + uint256 senderNonce = NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(msg.sender); + + if (_evmBytecodeHash != bytes32(0)) { + // Create2 case + newAddress = Utils.getNewAddressCreate2EVM(msg.sender, _salt, _evmBytecodeHash); + } else { + // Create case + newAddress = Utils.getNewAddressCreateEVM(msg.sender, senderNonce); + } + + return newAddress; + } + + /// @notice Method used by EVM emulator to deploy contracts. + /// @param _newAddress The address of the contract to be deployed. + /// @param _initCode The EVM code to be deployed (initCode). + /// Note: only possible revert case should be due to revert in the called constructor. + /// Note: this method may be callable only by the EVM emulator. + function createEvmFromEmulator( + address _newAddress, + bytes calldata _initCode + ) external payable onlySystemCallFromEvmEmulator returns (uint256, address) { + uint256 constructorReturnEvmGas = _performDeployOnAddressEVM( + msg.sender, + _newAddress, + AccountAbstractionVersion.None, + _initCode + ); + return (constructorReturnEvmGas, _newAddress); + } + /// @notice Deploys a contract account with similar address derivation rules to the EVM's `CREATE2` opcode. /// @param _salt The CREATE2 salt /// @param _bytecodeHash The correctly formatted hash of the bytecode. @@ -261,6 +363,26 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { } } + /// @notice Changes what types of bytecodes are allowed to be deployed on the chain. Can be used only during upgrades. + /// @param newAllowedBytecodeTypes The new allowed bytecode types mode. + function setAllowedBytecodeTypesToDeploy(AllowedBytecodeTypes newAllowedBytecodeTypes) external { + if ( + msg.sender != FORCE_DEPLOYER && + msg.sender != address(COMPLEX_UPGRADER_CONTRACT) && + msg.sender != SERVICE_CALL_PSEUDO_CALLER + ) { + revert Unauthorized(msg.sender); + } + + if (_getAllowedBytecodeTypesMode() != newAllowedBytecodeTypes) { + assembly { + sstore(ALLOWED_BYTECODE_TYPES_MODE_SLOT, newAllowedBytecodeTypes) + } + + emit AllowedBytecodeTypesModeUpdated(AllowedBytecodeTypes(newAllowedBytecodeTypes)); + } + } + function _nonSystemDeployOnAddress( bytes32 _bytecodeHash, address _newAddress, @@ -284,7 +406,25 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { revert NonEmptyAccount(); } - _performDeployOnAddress(_bytecodeHash, _newAddress, _aaVersion, _input); + // solhint-disable-next-line func-named-parameters + _performDeployOnAddress(_bytecodeHash, _newAddress, _aaVersion, _input, true); + } + + function _evmDeployOnAddress( + address _sender, + address _newAddress, + bytes calldata _initCode + ) internal returns (uint256 constructorReturnEvmGas) { + if (_getAllowedBytecodeTypesMode() != AllowedBytecodeTypes.EraVmAndEVM) { + revert EVMEmulationNotSupported(); + } + + // Unfortunately we can not provide revert reason as it would break EVM compatibility + // solhint-disable-next-line reason-string, gas-custom-errors + require(NONCE_HOLDER_SYSTEM_CONTRACT.getRawNonce(_newAddress) == 0x0); + // solhint-disable-next-line reason-string, gas-custom-errors + require(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getCodeHash(uint256(uint160(_newAddress))) == 0x0); + return _performDeployOnAddressEVM(_sender, _newAddress, AccountAbstractionVersion.None, _initCode); } /// @notice Deploy a certain bytecode on the address. @@ -296,7 +436,8 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { bytes32 _bytecodeHash, address _newAddress, AccountAbstractionVersion _aaVersion, - bytes calldata _input + bytes calldata _input, + bool _callConstructor ) internal { _ensureBytecodeIsKnown(_bytecodeHash); @@ -312,10 +453,34 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { _bytecodeHash: _bytecodeHash, _input: _input, _isSystem: false, - _callConstructor: true + _callConstructor: _callConstructor }); } + /// @notice Deploy a certain EVM bytecode on the address. + /// @param _sender The deployer address. + /// @param _newAddress The address of the contract to be deployed. + /// @param _aaVersion The version of the account abstraction protocol to use. + /// @param _input The constructor calldata. + function _performDeployOnAddressEVM( + address _sender, + address _newAddress, + AccountAbstractionVersion _aaVersion, + bytes calldata _input + ) internal returns (uint256 constructorReturnEvmGas) { + AccountInfo memory newAccountInfo; + newAccountInfo.supportedAAVersion = _aaVersion; + // Accounts have sequential nonces by default. + newAccountInfo.nonceOrdering = AccountNonceOrdering.Sequential; + _storeAccountInfo(_newAddress, newAccountInfo); + + // Note, that for contracts the "nonce" is set as deployment nonce. + NONCE_HOLDER_SYSTEM_CONTRACT.incrementDeploymentNonce(_newAddress); + + // We will store dummy constructing bytecode hash to trigger EVM emulator in constructor call + return _constructEVMContract(_sender, _newAddress, _input); + } + /// @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); @@ -384,4 +549,83 @@ contract ContractDeployer is IContractDeployer, SystemContractBase { emit ContractDeployed(_sender, _bytecodeHash, _newAddress); } + + /// @notice Transfers the `msg.value` ETH to the deployed account & invokes its constructor. + /// This function must revert in case the deployment fails. + /// @param _sender The msg.sender to be used in the constructor. + /// @param _newAddress The address of the deployed contract. + /// @param _input The constructor calldata. + function _constructEVMContract( + address _sender, + address _newAddress, + bytes calldata _input + ) internal returns (uint256 constructorReturnEvmGas) { + uint256 value = msg.value; + // 1. Transfer the balance to the new address on the constructor call. + if (value > 0) { + BASE_TOKEN_SYSTEM_CONTRACT.transferFromTo(address(this), _newAddress, value); + } + + // 2. Set the constructed code hash on the account + _storeConstructingByteCodeHashOnAddress( + _newAddress, + // Dummy EVM bytecode hash just to call emulator. + // The second byte is `0x01` to indicate that it is being constructed. + bytes32(0x0201000000000000000000000000000000000000000000000000000000000000) + ); + + // 3. Call the constructor on behalf of the account + if (value > 0) { + // Safe to cast value, because `msg.value` <= `uint128.max` due to `MessageValueSimulator` invariant + SystemContractHelper.setValueForNextFarCall(uint128(value)); + } + + bytes memory paddedBytecode = EfficientCall.mimicCall({ + _gas: gasleft(), // note: native gas, not EVM gas + _address: _newAddress, + _data: _input, + _whoToMimic: _sender, + _isConstructor: true, + _isSystem: false + }); + + uint256 evmBytecodeLen; + // Returned data bytes have structure: paddedBytecode.evmBytecodeLen.constructorReturnEvmGas + assembly { + let dataLen := mload(paddedBytecode) + evmBytecodeLen := mload(add(paddedBytecode, sub(dataLen, 0x20))) + constructorReturnEvmGas := mload(add(paddedBytecode, dataLen)) + mstore(paddedBytecode, sub(dataLen, 0x40)) // shrink paddedBytecode + } + + bytes32 versionedBytecodeHash = KNOWN_CODE_STORAGE_CONTRACT.publishEVMBytecode(evmBytecodeLen, paddedBytecode); + ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.storeAccountConstructedCodeHash(_newAddress, versionedBytecodeHash); + + bytes32 evmBytecodeHash; + assembly { + evmBytecodeHash := keccak256(add(paddedBytecode, 0x20), evmBytecodeLen) + } + + _setEvmCodeHash(_newAddress, evmBytecodeHash); + + emit ContractDeployed(_sender, versionedBytecodeHash, _newAddress); + } + + function _setEvmCodeHash(address _address, bytes32 _hash) internal { + assembly { + sstore(or(EVM_HASHES_PREFIX, _address), _hash) + } + } + + function _getEvmCodeHash(address _address) internal view returns (bytes32 _hash) { + assembly { + _hash := sload(or(EVM_HASHES_PREFIX, _address)) + } + } + + function _getAllowedBytecodeTypesMode() internal view returns (AllowedBytecodeTypes mode) { + assembly { + mode := sload(ALLOWED_BYTECODE_TYPES_MODE_SLOT) + } + } } diff --git a/system-contracts/contracts/DefaultAccount.sol b/system-contracts/contracts/DefaultAccount.sol index 40a38e49b..58731d929 100644 --- a/system-contracts/contracts/DefaultAccount.sol +++ b/system-contracts/contracts/DefaultAccount.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.24; import {IAccount, ACCOUNT_VALIDATION_SUCCESS_MAGIC} from "./interfaces/IAccount.sol"; -import {TransactionHelper, Transaction} from "./libraries/TransactionHelper.sol"; +import {TransactionHelper, Transaction, EIP_712_TX_TYPE, L1_TO_L2_TX_TYPE} from "./libraries/TransactionHelper.sol"; import {SystemContractsCaller} from "./libraries/SystemContractsCaller.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; import {EfficientCall} from "./libraries/EfficientCall.sol"; @@ -139,6 +139,21 @@ contract DefaultAccount is IAccount { bytes calldata data = _transaction.data; uint32 gas = Utils.safeCastToU32(gasleft()); + if (to == address(0)) { + if (_transaction.txType != EIP_712_TX_TYPE && _transaction.txType != L1_TO_L2_TX_TYPE) { + if (_transaction.reserved[1] == 1) { + // Note, that createEVM can only be called with "isSystem" flag. + SystemContractsCaller.systemCallWithPropagatedRevert( + gas, + address(DEPLOYER_SYSTEM_CONTRACT), + value, + abi.encodeCall(DEPLOYER_SYSTEM_CONTRACT.createEVM, (data)) + ); + return; + } + } + } + // Note, that the deployment method from the deployer contract can only be called with a "systemCall" flag. bool isSystemCall; if (to == address(DEPLOYER_SYSTEM_CONTRACT) && data.length >= 4) { diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul new file mode 100644 index 000000000..5b41e6643 --- /dev/null +++ b/system-contracts/contracts/EvmEmulator.yul @@ -0,0 +1,6335 @@ +object "EvmEmulator" { + code { + function MAX_POSSIBLE_ACTIVE_BYTECODE() -> max { + max := MAX_POSSIBLE_INIT_BYTECODE_LEN() + } + + /// @dev This function is used to get the initCode. + /// @dev It assumes that the initCode has been passed via the calldata and so we use the pointer + /// to obtain the bytecode. + function getConstructorBytecode() { + loadCalldataIntoActivePtr() + + let size := getActivePtrDataSize() + + if gt(size, MAX_POSSIBLE_INIT_BYTECODE_LEN()) { + panic() + } + + mstore(BYTECODE_LEN_OFFSET(), size) + mstore(EMPTY_CODE_OFFSET(), 0) + copyActivePtrData(BYTECODE_OFFSET(), 0, size) + } + + function padBytecode(offset, len) -> blobLen { + let trueLastByte := add(offset, len) + + // clearing out additional bytes + mstore(trueLastByte, 0) + mstore(add(trueLastByte, 32), 0) + + blobLen := len + + if iszero(eq(mod(blobLen, 32), 0)) { + blobLen := add(blobLen, sub(32, mod(blobLen, 32))) + } + + // Now it is divisible by 32, but we must make sure that the number of 32 byte words is odd + if iszero(eq(mod(blobLen, 64), 32)) { + blobLen := add(blobLen, 32) + } + } + + function validateBytecodeAndChargeGas(offset, deployedCodeLen, gasToReturn) -> returnGas { + if deployedCodeLen { + // EIP-3860 + if gt(deployedCodeLen, MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN()) { + panic() + } + + // EIP-3541 + let firstByte := shr(248, mload(offset)) + if eq(firstByte, 0xEF) { + panic() + } + } + + let gasForCode := mul(deployedCodeLen, 200) + returnGas := chargeGas(gasToReturn, gasForCode) + } + + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + function ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008002 + } + + function NONCE_HOLDER_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008003 + } + + function DEPLOYER_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008006 + } + + function CODE_ORACLE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008012 + } + + function EVM_GAS_MANAGER_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008013 + } + + function MSG_VALUE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008009 + } + + function ORIGIN_CACHE_OFFSET() -> offset { + offset := mul(23, 32) + } + + function GASPRICE_CACHE_OFFSET() -> offset { + offset := mul(24, 32) + } + + function COINBASE_CACHE_OFFSET() -> offset { + offset := mul(25, 32) + } + + function BLOCKTIMESTAMP_CACHE_OFFSET() -> offset { + offset := mul(26, 32) + } + + function BLOCKNUMBER_CACHE_OFFSET() -> offset { + offset := mul(27, 32) + } + + function PREVRANDAO_CACHE_OFFSET() -> offset { + offset := mul(28, 32) + } + + function GASLIMIT_CACHE_OFFSET() -> offset { + offset := mul(29, 32) + } + + function CHAINID_CACHE_OFFSET() -> offset { + offset := mul(30, 32) + } + + function BASEFEE_CACHE_OFFSET() -> offset { + offset := mul(31, 32) + } + + function LAST_RETURNDATA_SIZE_OFFSET() -> offset { + offset := add(BASEFEE_CACHE_OFFSET(), 32) + } + + function STACK_OFFSET() -> offset { + offset := add(LAST_RETURNDATA_SIZE_OFFSET(), 64) + } + + function MAX_STACK_SLOT_OFFSET() -> offset { + offset := add(STACK_OFFSET(), mul(1023, 32)) + } + + function BYTECODE_LEN_OFFSET() -> offset { + offset := add(MAX_STACK_SLOT_OFFSET(), 32) + } + + function BYTECODE_OFFSET() -> offset { + offset := add(BYTECODE_LEN_OFFSET(), 32) + } + + // reserved empty slot to simplify PUSH N opcodes + function EMPTY_CODE_OFFSET() -> offset { + offset := add(BYTECODE_OFFSET(), MAX_POSSIBLE_ACTIVE_BYTECODE()) + } + + function MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() -> max { + max := 24576 // EIP-170 + } + + function MAX_POSSIBLE_INIT_BYTECODE_LEN() -> max { + max := mul(2, MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN()) // EIP-3860 + } + + function MEM_LEN_OFFSET() -> offset { + offset := add(EMPTY_CODE_OFFSET(), 32) + } + + function MEM_OFFSET() -> offset { + offset := add(MEM_LEN_OFFSET(), 32) + } + + // Used to simplify gas calculations for memory expansion. + // The cost to increase the memory to 12 MB is close to 277M EVM gas + function MAX_POSSIBLE_MEM_LEN() -> max { + max := 0xC00000 // 12MB + } + + function MAX_UINT() -> max_uint { + max_uint := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + } + + function MAX_UINT64() -> max { + max := sub(shl(64, 1), 1) + } + + // Each evm gas is 5 zkEVM one + function GAS_DIVISOR() -> gas_div { gas_div := 5 } + + // We need to pass some gas for MsgValueSimulator internal logic to decommit emulator etc + function MSG_VALUE_SIMULATOR_STIPEND_GAS() -> gas_stipend { + gas_stipend := 35000 // 27000 + a little bit more + } + + function OVERHEAD() -> overhead { overhead := 2000 } + + function UINT32_MAX() -> ret { ret := 4294967295 } // 2^32 - 1 + + function EMPTY_KECCAK() -> value { // keccak("") + value := 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 + } + + + //////////////////////////////////////////////////////////////// + // GENERAL FUNCTIONS + //////////////////////////////////////////////////////////////// + + // abort the whole EVM execution environment, including parent frames + function abortEvmEnvironment() { + revert(0, 0) + } + + function $llvm_NoInline_llvm$_panic() { // revert consuming all EVM gas + mstore(0, 0) + revert(0, 32) + } + + function revertWithGas(evmGasLeft) { + mstore(0, evmGasLeft) + revert(0, 32) + } + + function panic() { // revert consuming all EVM gas + mstore(0, 0) + revert(0, 32) + } + + function cached(cacheIndex, value) -> _value { + _value := value + mstore(cacheIndex, _value) + } + + function chargeGas(prevGas, toCharge) -> gasRemaining { + if lt(prevGas, toCharge) { + panic() + } + + gasRemaining := sub(prevGas, toCharge) + } + + function getEvmGasFromContext() -> evmGas { + // Caller must pass at least OVERHEAD() ergs + let _gas := gas() + if gt(_gas, OVERHEAD()) { + evmGas := div(sub(_gas, OVERHEAD()), GAS_DIVISOR()) + } + } + + // This function can overflow, it is the job of the caller to ensure that it does not. + // The argument to this function is the offset into the memory region IN BYTES. + function expandMemory(offset, size) -> gasCost { + // memory expansion costs 0 if size is 0 + if size { + let oldSizeInWords := mload(MEM_LEN_OFFSET()) + + // div rounding up + let newSizeInWords := div(add(add(offset, size), 31), 32) + + // memory_size_word = (memory_byte_size + 31) / 32 + // memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word) + // memory_expansion_cost = new_memory_cost - last_memory_cost + if gt(newSizeInWords, oldSizeInWords) { + let linearPart := mul(3, sub(newSizeInWords, oldSizeInWords)) + let quadraticPart := sub( + div( + mul(newSizeInWords, newSizeInWords), + 512 + ), + div( + mul(oldSizeInWords, oldSizeInWords), + 512 + ) + ) + + gasCost := add(linearPart, quadraticPart) + + mstore(MEM_LEN_OFFSET(), newSizeInWords) + } + } + } + + function expandMemory2(retOffset, retSize, argsOffset, argsSize) -> maxExpand { + switch lt(add(retOffset, retSize), add(argsOffset, argsSize)) + case 0 { + maxExpand := expandMemory(retOffset, retSize) + } + default { + maxExpand := expandMemory(argsOffset, argsSize) + } + } + + function checkMemIsAccessible(relativeOffset, size) { + if size { + checkOverflow(relativeOffset, size) + + if gt(add(relativeOffset, size), MAX_POSSIBLE_MEM_LEN()) { + panic() + } + } + } + + function checkOverflow(data1, data2) { + if lt(add(data1, data2), data2) { + panic() + } + } + + function insufficientBalance(value) -> res { + if value { + res := gt(value, selfbalance()) + } + } + + // It is the responsibility of the caller to ensure that ip is correct + function readIP(ip, bytecodeEndOffset) -> opcode { + if lt(ip, bytecodeEndOffset) { + opcode := and(mload(sub(ip, 31)), 0xff) + } + // STOP else + } + + // It is the responsibility of the caller to ensure that start and length is correct + function readBytes(start, length) -> value { + value := shr(mul(8, sub(32, length)), mload(start)) + // will be padded by zeroes if out of bounds (we have reserved EMPTY_CODE_OFFSET() slot) + } + + function getCodeAddress() -> addr { + addr := verbatim_0i_1o("code_source") + } + + function loadReturndataIntoActivePtr() { + verbatim_0i_0o("return_data_ptr_to_active") + } + + function loadCalldataIntoActivePtr() { + verbatim_0i_0o("calldata_ptr_to_active") + } + + function getActivePtrDataSize() -> size { + size := verbatim_0i_1o("active_ptr_data_size") + } + + function copyActivePtrData(_dest, _source, _size) { + verbatim_3i_0o("active_ptr_data_copy", _dest, _source, _size) + } + + function ptrAddIntoActive(_dest) { + verbatim_1i_0o("active_ptr_add_assign", _dest) + } + + function ptrShrinkIntoActive(_dest) { + verbatim_1i_0o("active_ptr_shrink_assign", _dest) + } + + function getIsStaticFromCallFlags() -> isStatic { + isStatic := verbatim_0i_1o("get_global::call_flags") + isStatic := iszero(iszero(and(isStatic, 0x04))) + } + + function fetchFromSystemContract(to, argSize) -> res { + let success := staticcall(gas(), to, 0, argSize, 0, 0) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + + returndatacopy(0, 0, 32) + res := mload(0) + } + + function isAddrEmpty(addr) -> isEmpty { + // We treat constructing EraVM contracts as non-existing + if iszero(extcodesize(addr)) { // YUL doesn't have short-circuit evaluation + if iszero(balance(addr)) { + if iszero(getRawNonce(addr)) { + isEmpty := 1 + } + } + } + } + + // returns minNonce + 2^128 * deployment nonce. + function getRawNonce(addr) -> nonce { + // selector for function getRawNonce(address addr) + mstore(0, 0x5AA9B6B500000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + nonce := fetchFromSystemContract(NONCE_HOLDER_SYSTEM_CONTRACT(), 36) + } + + function getRawCodeHash(addr) -> hash { + mstore(0, 0x4DE2E46800000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + hash := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) + } + + function getEvmExtcodehash(addr) -> evmCodeHash { + mstore(0, 0x54A3314700000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + evmCodeHash := fetchFromSystemContract(DEPLOYER_SYSTEM_CONTRACT(), 36) + } + + function isEvmContract(addr) -> isEVM { + // function isAccountEVM(address addr) external view returns (bool); + mstore(0, 0x8C04047700000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + isEVM := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) + } + + function isHashOfConstructedEvmContract(rawCodeHash) -> isConstructedEVM { + let version := shr(248, rawCodeHash) + let isConstructedFlag := xor(shr(240, rawCodeHash), 1) + isConstructedEVM := and(eq(version, 2), isConstructedFlag) + } + + // Basically performs an extcodecopy, while returning the length of the copied bytecode. + function fetchDeployedCode(addr, dstOffset, srcOffset, len) -> copiedLen { + let rawCodeHash := getRawCodeHash(addr) + mstore(0, rawCodeHash) + + let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) + // it fails if we don't have any code deployed at this address + if success { + // The length of the bytecode is encoded in versioned bytecode hash + let codeLen := and(shr(224, rawCodeHash), 0xffff) + + if eq(shr(248, rawCodeHash), 1) { + // For native zkVM contracts length encoded in words, not bytes + codeLen := shl(5, codeLen) // * 32 + } + + if gt(len, codeLen) { + len := codeLen + } + + let _returndatasize := returndatasize() + if gt(srcOffset, _returndatasize) { + srcOffset := _returndatasize + } + + if gt(add(len, srcOffset), _returndatasize) { + len := sub(_returndatasize, srcOffset) + } + + if len { + returndatacopy(dstOffset, srcOffset, len) + } + + copiedLen := len + } + } + + function getMax(a, b) -> max { + max := b + if gt(a, b) { + max := a + } + } + + function build_farcall_abi(isSystemCall, gas, dataStart, dataLength) -> farCallAbi { + farCallAbi := shl(248, isSystemCall) + // dataOffset is 0 + farCallAbi := or(farCallAbi, shl(64, dataStart)) + farCallAbi := or(farCallAbi, shl(96, dataLength)) + farCallAbi := or(farCallAbi, shl(192, gas)) + // shardId is 0 + // forwardingMode is 0 + } + + function performSystemCall(to, dataLength) { + let success := performSystemCallRevertable(to, dataLength) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + } + + function performSystemCallRevertable(to, dataLength) -> success { + // system call, dataStart is 0 + let farCallAbi := build_farcall_abi(1, gas(), 0, dataLength) + success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) + } + + function rawCall(gas, to, value, dataStart, dataLength, outputOffset, outputLen) -> success { + switch iszero(value) + case 0 { + // system call to MsgValueSimulator, but call to "to" will be non-system + let farCallAbi := build_farcall_abi(1, gas, dataStart, dataLength) + success := verbatim_6i_1o("system_call", MSG_VALUE_SYSTEM_CONTRACT(), farCallAbi, value, to, 0, 0) + if outputLen { + if success { + let rtdz := returndatasize() + switch lt(rtdz, outputLen) + case 0 { returndatacopy(outputOffset, 0, outputLen) } + default { returndatacopy(outputOffset, 0, rtdz) } + } + } + } + default { + // not a system call + let farCallAbi := build_farcall_abi(0, gas, dataStart, dataLength) + success := verbatim_4i_1o("raw_call", to, farCallAbi, outputOffset, outputLen) + } + } + + function rawStaticcall(gas, to, dataStart, dataLength, outputOffset, outputLen) -> success { + // not a system call + let farCallAbi := build_farcall_abi(0, gas, dataStart, dataLength) + success := verbatim_4i_1o("raw_static_call", to, farCallAbi, outputOffset, outputLen) + } + + //////////////////////////////////////////////////////////////// + // STACK OPERATIONS + //////////////////////////////////////////////////////////////// + + function dupStackItem(sp, evmGas, position, oldStackHead) -> newSp, evmGasLeft, stackHead { + evmGasLeft := chargeGas(evmGas, 3) + + if iszero(lt(sp, MAX_STACK_SLOT_OFFSET())) { + panic() + } + + let tempSp := sub(sp, mul(0x20, sub(position, 1))) + + if lt(tempSp, STACK_OFFSET()) { + panic() + } + + mstore(sp, oldStackHead) + stackHead := mload(tempSp) + newSp := add(sp, 0x20) + } + + function swapStackItem(sp, evmGas, position, oldStackHead) -> evmGasLeft, stackHead { + evmGasLeft := chargeGas(evmGas, 3) + let tempSp := sub(sp, mul(0x20, position)) + + if lt(tempSp, STACK_OFFSET()) { + panic() + } + + stackHead := mload(tempSp) + mstore(tempSp, oldStackHead) + } + + function popStackItem(sp, oldStackHead) -> a, newSp, stackHead { + // We can not return any error here, because it would break compatibility + if lt(sp, STACK_OFFSET()) { + panic() + } + + a := oldStackHead + newSp := sub(sp, 0x20) + stackHead := mload(newSp) + } + + function pushStackItem(sp, item, oldStackHead) -> newSp, stackHead { + if iszero(lt(sp, MAX_STACK_SLOT_OFFSET())) { + panic() + } + + mstore(sp, oldStackHead) + stackHead := item + newSp := add(sp, 0x20) + } + + function popStackItemWithoutCheck(sp, oldStackHead) -> a, newSp, stackHead { + a := oldStackHead + newSp := sub(sp, 0x20) + stackHead := mload(newSp) + } + + function pushStackItemWithoutCheck(sp, item, oldStackHead) -> newSp, stackHead { + mstore(sp, oldStackHead) + stackHead := item + newSp := add(sp, 0x20) + } + + function popStackCheck(sp, numInputs) { + if lt(sub(sp, mul(0x20, sub(numInputs, 1))), STACK_OFFSET()) { + panic() + } + } + + function accessStackHead(sp, stackHead) -> value { + if lt(sp, STACK_OFFSET()) { + panic() + } + + value := stackHead + } + + //////////////////////////////////////////////////////////////// + // EVM GAS MANAGER FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function $llvm_AlwaysInline_llvm$_warmAddress(addr) -> isWarm { + // function warmAccount(address account) + // non-standard selector 0x00 + // addr is packed in the same word with selector + mstore(0, and(addr, 0xffffffffffffffffffffffffffffffffffffffff)) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 32) + + if returndatasize() { + isWarm := true + } + } + + function isSlotWarm(key) -> isWarm { + // non-standard selector 0x01 + mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) + mstore(1, key) + // should be call since we use TSTORE in gas manager + let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 33, 0, 0) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + + if returndatasize() { + isWarm := true + } + } + + function warmSlot(key, currentValue) -> isWarm, originalValue { + // non-standard selector 0x02 + mstore(0, 0x0200000000000000000000000000000000000000000000000000000000000000) + mstore(1, key) + mstore(33, currentValue) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 65) + + originalValue := currentValue + if returndatasize() { + isWarm := true + returndatacopy(0, 0, 32) + originalValue := mload(0) + } + } + + function pushEvmFrame(passGas, isStatic) { + // function pushEVMFrame + // non-standard selector 0x03 + mstore(0, or(0x0300000000000000000000000000000000000000000000000000000000000000, isStatic)) + mstore(32, passGas) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 64) + } + + function consumeEvmFrame() -> passGas, isStatic, callerEVM { + // function consumeEvmFrame() external returns (uint256 passGas, uint256 auxDataRes) + // non-standard selector 0x04 + mstore(0, 0x0400000000000000000000000000000000000000000000000000000000000000) + mstore(1, caller()) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 33) + + let _returndatasize := returndatasize() + if _returndatasize { + callerEVM := true + + returndatacopy(0, 0, 32) + passGas := mload(0) + + isStatic := gt(_returndatasize, 32) + } + } + + function resetEvmFrame() { + // function resetEvmFrame() + // non-standard selector 0x05 + mstore(0, 0x0500000000000000000000000000000000000000000000000000000000000000) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 1) + } + + //////////////////////////////////////////////////////////////// + // CALLS FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function performCall(oldSp, evmGasLeft, oldStackHead, isStatic) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, value, argsOffset, argsSize, retOffset, retSize + + popStackCheck(oldSp, 7) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + retOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + // static_gas = 0 + // dynamic_gas = memory_expansion_cost + code_execution_cost + address_access_cost + positive_value_cost + value_to_empty_account_cost + // code_execution_cost is the cost of the called code execution (limited by the gas parameter). + // If address is warm, then address_access_cost is 100, otherwise it is 2600. See section access sets. + // If value is not 0, then positive_value_cost is 9000. In this case there is also a call stipend that is given to make sure that a basic fallback function can be called. + // If value is not 0 and the address given points to an empty account, then value_to_empty_account_cost is 25000. An account is empty if its balance is 0, its nonce is 0 and it has no code. + + let addr, gasUsed := _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) + + if gt(value, 0) { + if isStatic { + panic() + } + + gasUsed := add(gasUsed, 9000) // positive_value_cost + + if isAddrEmpty(addr) { + gasUsed := add(gasUsed, 25000) // value_to_empty_account_cost + } + } + + evmGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(evmGasLeft, gasToPass) + evmGasLeft := sub(evmGasLeft, gasToPass) + + if gt(value, 0) { + gasToPass := add(gasToPass, 2300) + } + + let success, frameGasLeft := _genericCall( + addr, + gasToPass, + value, + add(argsOffset, MEM_OFFSET()), + argsSize, + add(retOffset, MEM_OFFSET()), + retSize, + isStatic + ) + + newGasLeft := add(evmGasLeft, frameGasLeft) + stackHead := success + } + + function performStaticCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, argsOffset, argsSize, retOffset, retSize + + popStackCheck(oldSp, 6) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + retOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + let addr, gasUsed := _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) + + evmGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(evmGasLeft, gasToPass) + evmGasLeft := sub(evmGasLeft, gasToPass) + + let success, frameGasLeft := _genericCall( + addr, + gasToPass, + 0, + add(MEM_OFFSET(), argsOffset), + argsSize, + add(MEM_OFFSET(), retOffset), + retSize, + true + ) + + newGasLeft := add(evmGasLeft, frameGasLeft) + stackHead := success + } + + + function performDelegateCall(oldSp, evmGasLeft, isStatic, oldStackHead) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, rawArgsOffset, argsSize, rawRetOffset, retSize + + popStackCheck(oldSp, 6) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + rawArgsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + rawRetOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + let addr, gasUsed := _genericPrecallLogic(rawAddr, rawArgsOffset, argsSize, rawRetOffset, retSize) + + newGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(newGasLeft, gasToPass) + + newGasLeft := sub(newGasLeft, gasToPass) + + let success + let frameGasLeft := gasToPass + + let retOffset := add(MEM_OFFSET(), rawRetOffset) + let argsOffset := add(MEM_OFFSET(), rawArgsOffset) + + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + // Not a constructed EVM contract + let precompileCost := getGasForPrecompiles(addr, argsSize) + switch precompileCost + case 0 { + // Not a precompile + _eraseReturndataPointer() + + let isCallToEmptyContract := iszero(addr) // 0x00 is always "empty" + if iszero(isCallToEmptyContract) { + isCallToEmptyContract := iszero(and(shr(224, rawCodeHash), 0xffff)) // is codelen zero? + } + + if isCallToEmptyContract { + success := delegatecall(gas(), addr, argsOffset, argsSize, retOffset, retSize) + _saveReturndataAfterZkEVMCall() + } + + // We forbid delegatecalls to EraVM native contracts + } + default { + // Precompile. Simlate using staticcall, since EraVM behavior differs here + success, frameGasLeft := callPrecompile(addr, precompileCost, gasToPass, 0, argsOffset, argsSize, retOffset, retSize, true) + } + } + default { + // Constructed EVM contract + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := delegatecall(gas(), addr, argsOffset, argsSize, 0, 0) + + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + + newGasLeft := add(newGasLeft, frameGasLeft) + stackHead := success + } + + function _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) -> addr, gasUsed { + addr := and(rawAddr, 0xffffffffffffffffffffffffffffffffffffffff) + + checkMemIsAccessible(argsOffset, argsSize) + checkMemIsAccessible(retOffset, retSize) + + gasUsed := 100 // warm address access cost + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + gasUsed := 2600 // cold address access cost + } + + // memory_expansion_cost + gasUsed := add(gasUsed, expandMemory2(retOffset, retSize, argsOffset, argsSize)) + } + + function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + // zkEVM native call + let precompileCost := getGasForPrecompiles(addr, argsSize) + switch precompileCost + case 0 { + // just smart contract + success, frameGasLeft := callZkVmNative(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic, rawCodeHash) + } + default { + // precompile + success, frameGasLeft := callPrecompile(addr, precompileCost, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) + } + } + default { + switch insufficientBalance(value) + case 0 { + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + default { + frameGasLeft := gasToPass + _eraseReturndataPointer() + } + } + } + + function callPrecompile(addr, precompileCost, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { + switch lt(gasToPass, precompileCost) + case 0 { + let zkVmGasToPass := gas() // pass all remaining gas, precompiles should not call any contracts + + switch isStatic + case 0 { + success := rawCall(zkVmGasToPass, addr, value, argsOffset, argsSize, retOffset, retSize) + } + default { + success := rawStaticcall(zkVmGasToPass, addr, argsOffset, argsSize, retOffset, retSize) + } + + _saveReturndataAfterZkEVMCall() + + if success { + frameGasLeft := sub(gasToPass, precompileCost) + } + // else consume all provided gas + } + default { + // consume all provided gas + _eraseReturndataPointer() + } + } + + // Call native ZkVm contract from EVM context + function callZkVmNative(addr, evmGasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic, rawCodeHash) -> success, frameGasLeft { + let zkEvmGasToPass := mul(evmGasToPass, GAS_DIVISOR()) // convert EVM gas -> ZkVM gas + + let additionalStipend := 6000 // should cover first access to empty account + switch value + case 0 { + if gt(addr, 0) { // zero address is always "empty" + if and(shr(224, rawCodeHash), 0xffff) { // if codelen is not zero + additionalStipend := 0 + } + } + } + default { + additionalStipend := 27000 // Stipend for MsgValueSimulator. Covered by positive_value_cost + } + + zkEvmGasToPass := add(zkEvmGasToPass, additionalStipend) + + if gt(zkEvmGasToPass, UINT32_MAX()) { // just in case + zkEvmGasToPass := UINT32_MAX() + } + + let zkEvmGasBefore := gas() + switch isStatic + case 0 { + success := call(zkEvmGasToPass, addr, value, argsOffset, argsSize, retOffset, retSize) + } + default { + success := staticcall(zkEvmGasToPass, addr, argsOffset, argsSize, retOffset, retSize) + } + let zkEvmGasUsed := sub(zkEvmGasBefore, gas()) + + _saveReturndataAfterZkEVMCall() + + if gt(zkEvmGasUsed, zkEvmGasBefore) { // overflow case + zkEvmGasUsed := 0 // should never happen + } + + switch gt(zkEvmGasUsed, additionalStipend) + case 0 { + zkEvmGasUsed := 0 + } + default { + zkEvmGasUsed := sub(zkEvmGasUsed, additionalStipend) + } + + zkEvmGasToPass := sub(zkEvmGasToPass, additionalStipend) + + // refund gas + if gt(zkEvmGasToPass, zkEvmGasUsed) { + frameGasLeft := div(sub(zkEvmGasToPass, zkEvmGasUsed), GAS_DIVISOR()) + } + } + + function capGasForCall(evmGasLeft, oldGasToPass) -> gasToPass { + let maxGasToPass := sub(evmGasLeft, shr(6, evmGasLeft)) // evmGasLeft >> 6 == evmGasLeft/64 + gasToPass := oldGasToPass + if gt(oldGasToPass, maxGasToPass) { + gasToPass := maxGasToPass + } + } + + // The gas cost mentioned here is purely the cost of the contract, + // and does not consider the cost of the call itself nor the instructions + // to put the parameters in memory. + function getGasForPrecompiles(addr, argsSize) -> gasToCharge { + switch addr + case 0x01 { // ecRecover + gasToCharge := 3000 + } + case 0x02 { // SHA2-256 + let dataWordSize := shr(5, add(argsSize, 31)) // (argsSize+31)/32 + gasToCharge := add(60, mul(12, dataWordSize)) + } + case 0x03 { // RIPEMD-160 + // We do not support RIPEMD-160 + gasToCharge := 0 + } + case 0x04 { // identity + let dataWordSize := shr(5, add(argsSize, 31)) // (argsSize+31)/32 + gasToCharge := add(15, mul(3, dataWordSize)) + } + case 0x05 { // modexp + // We do not support modexp + gasToCharge := 0 + } + // ecAdd ecMul ecPairing EIP below + // https://eips.ethereum.org/EIPS/eip-1108 + case 0x06 { // ecAdd + // The gas cost is fixed at 150. However, if the input + // does not allow to compute a valid result, all the gas sent is consumed. + gasToCharge := 150 + } + case 0x07 { // ecMul + // The gas cost is fixed at 6000. However, if the input + // does not allow to compute a valid result, all the gas sent is consumed. + gasToCharge := 6000 + } + // 34,000 * k + 45,000 gas, where k is the number of pairings being computed. + // The input must always be a multiple of 6 32-byte values. + case 0x08 { // ecPairing + let k := div(argsSize, 0xC0) // 0xC0 == 6*32 + gasToCharge := add(45000, mul(k, 34000)) + } + case 0x09 { // blake2f + // We do not support blake2f + gasToCharge := 0 + } + case 0x0a { // kzg point evaluation + // We do not support kzg point evaluation + gasToCharge := 0 + } + default { + gasToCharge := 0 + } + } + + function _saveReturndataAfterZkEVMCall() { + loadReturndataIntoActivePtr() + mstore(LAST_RETURNDATA_SIZE_OFFSET(), returndatasize()) + } + + function _saveReturndataAfterEVMCall(_outputOffset, _outputLen) -> _gasLeft { + let rtsz := returndatasize() + loadReturndataIntoActivePtr() + + // if (rtsz > 31) + switch gt(rtsz, 31) + case 0 { + // Unexpected return data. + // Most likely out-of-ergs or unexpected error in the emulator or system contracts + abortEvmEnvironment() + } + default { + returndatacopy(0, 0, 32) + _gasLeft := mload(0) + + // We copy as much returndata as possible without going over the + // returndata size. + switch lt(sub(rtsz, 32), _outputLen) + case 0 { returndatacopy(_outputOffset, 32, _outputLen) } + default { returndatacopy(_outputOffset, 32, sub(rtsz, 32)) } + + mstore(LAST_RETURNDATA_SIZE_OFFSET(), sub(rtsz, 32)) + + // Skip the returnData + ptrAddIntoActive(32) + } + } + + function _eraseReturndataPointer() { + let activePtrSize := getActivePtrDataSize() + ptrShrinkIntoActive(and(activePtrSize, 0xFFFFFFFF))// uint32(activePtrSize) + mstore(LAST_RETURNDATA_SIZE_OFFSET(), 0) + } + + //////////////////////////////////////////////////////////////// + // CREATE FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function performCreate(oldEvmGasLeft, oldSp, oldStackHead) -> evmGasLeft, sp, stackHead { + let value, offset, size + + popStackCheck(oldSp, 3) + value, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + offset, sp, size := popStackItemWithoutCheck(sp, stackHead) + + evmGasLeft, stackHead := $llvm_NoInline_llvm$_genericCreate(offset, size, value, oldEvmGasLeft, false, 0) + } + + function performCreate2(oldEvmGasLeft, oldSp, oldStackHead) -> evmGasLeft, sp, stackHead { + let value, offset, size, salt + + popStackCheck(oldSp, 4) + value, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, salt := popStackItemWithoutCheck(sp, stackHead) + + evmGasLeft, stackHead := $llvm_NoInline_llvm$_genericCreate(offset, size, value, oldEvmGasLeft, true, salt) + } + + function $llvm_NoInline_llvm$_genericCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) -> evmGasLeft, addr { + checkMemIsAccessible(offset, size) + + // EIP-3860 + if gt(size, MAX_POSSIBLE_INIT_BYTECODE_LEN()) { + panic() + } + + // dynamicGas = init_code_cost + memory_expansion_cost + deployment_code_execution_cost + code_deposit_cost + // + hash_cost, if isCreate2 + // minimum_word_size = (size + 31) / 32 + // init_code_cost = 2 * minimum_word_size, EIP-3860 + // code_deposit_cost = 200 * deployed_code_size, (charged inside call) + let minimum_word_size := div(add(size, 31), 32) // rounding up + let dynamicGas := add( + mul(2, minimum_word_size), + expandMemory(offset, size) + ) + if isCreate2 { + // hash_cost = 6 * minimum_word_size + dynamicGas := add(dynamicGas, mul(6, minimum_word_size)) + } + evmGasLeft := chargeGas(evmGasLeftOld, dynamicGas) + + _eraseReturndataPointer() + + let err := insufficientBalance(value) + + if iszero(err) { + offset := add(MEM_OFFSET(), offset) // caller must ensure that it doesn't overflow + evmGasLeft, addr := _executeCreate(offset, size, value, evmGasLeft, isCreate2, salt) + } + } + + function _executeCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) -> evmGasLeft, addr { + let gasForTheCall := capGasForCall(evmGasLeftOld, evmGasLeftOld) // pass 63/64 of remaining gas + + let bytecodeHash + if isCreate2 { + switch size + case 0 { + bytecodeHash := EMPTY_KECCAK() + } + default { + bytecodeHash := keccak256(offset, size) + } + } + + // we want to calculate the address of new contract, and if it is deployable (no collision), + // we need to increment deploy nonce. + + // selector: function precreateEvmAccountFromEmulator(bytes32 salt, bytes32 evmBytecodeHash) + mstore(0, 0xf81dae8600000000000000000000000000000000000000000000000000000000) + mstore(4, salt) + mstore(36, bytecodeHash) + let canBeDeployed := performSystemCallRevertable(DEPLOYER_SYSTEM_CONTRACT(), 68) + + if canBeDeployed { + returndatacopy(0, 0, 32) + addr := mload(0) + + pop($llvm_AlwaysInline_llvm$_warmAddress(addr)) // will stay warm even if constructor reverts + // so even if constructor reverts, nonce stays incremented and addr stays warm + + // check for code collision + canBeDeployed := 0 + if iszero(getRawCodeHash(addr)) { + // check for nonce collision + if iszero(getRawNonce(addr)) { + canBeDeployed := 1 + } + } + } + + if iszero(canBeDeployed) { + // Nonce overflow, EVM not allowed or collision. + // This is *internal* panic, consuming all passed gas. + // Note: we should not consume all gas if nonce overflowed, but this should not happen in reality anyway + evmGasLeft := chargeGas(evmGasLeftOld, gasForTheCall) + addr := 0 + } + + + if canBeDeployed { + // verification of the correctness of the deployed bytecode and payment of gas for its storage will occur in the frame of the new contract + pushEvmFrame(gasForTheCall, false) + + // move needed memory slots to the scratch space + mstore(mul(10, 32), mload(sub(offset, 0x80)) + mstore(mul(11, 32), mload(sub(offset, 0x60)) + mstore(mul(12, 32), mload(sub(offset, 0x40)) + mstore(mul(13, 32), mload(sub(offset, 0x20)) + + // selector: function createEvmFromEmulator(address newAddress, bytes calldata _initCode) + mstore(sub(offset, 0x80), 0xe43cec64) + mstore(sub(offset, 0x60), addr) + mstore(sub(offset, 0x40), 0x40) // Where the arg starts (third word) + mstore(sub(offset, 0x20), size) // Length of the init code + + let result := performSystemCallForCreate(value, sub(offset, 0x64), add(size, 0x64)) + + // move memory slots back + mstore(sub(offset, 0x80), mload(mul(10, 32)) + mstore(sub(offset, 0x60), mload(mul(11, 32)) + mstore(sub(offset, 0x40), mload(mul(12, 32)) + mstore(sub(offset, 0x20), mload(mul(13, 32)) + + let gasLeft + switch result + case 0 { + addr := 0 + gasLeft := _saveReturndataAfterEVMCall(0, 0) + resetEvmFrame() + } + default { + gasLeft, addr := _saveConstructorReturnGas() + } + + let gasUsed := sub(gasForTheCall, gasLeft) + evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) + } + } + + function performSystemCallForCreate(value, bytecodeStart, bytecodeLen) -> success { + // system call, not constructor call (ContractDeployer will call constructor) + let farCallAbi := build_farcall_abi(1, gas(), bytecodeStart, bytecodeLen) + + switch iszero(value) + case 0 { + success := verbatim_6i_1o("system_call", MSG_VALUE_SYSTEM_CONTRACT(), farCallAbi, value, DEPLOYER_SYSTEM_CONTRACT(), 1, 0) + } + default { + success := verbatim_6i_1o("system_call", DEPLOYER_SYSTEM_CONTRACT(), farCallAbi, 0, 0, 0, 0) + } + } + + function _saveConstructorReturnGas() -> gasLeft, addr { + loadReturndataIntoActivePtr() + + if lt(returndatasize(), 64) { + // unexpected return data after constructor succeeded, should never happen. + abortEvmEnvironment() + } + + // ContractDeployer returns (uint256 gasLeft, address createdContract) + returndatacopy(0, 0, 64) + gasLeft := mload(0) + addr := mload(32) + + _eraseReturndataPointer() + } + + //////////////////////////////////////////////////////////////// + // EXTCODECOPY FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function $llvm_AlwaysInline_llvm$_copyRest(dest, val, len) { + let rest_bits := shl(3, len) + let upper_bits := sub(256, rest_bits) + let val_mask := shl(upper_bits, MAX_UINT()) + let val_masked := and(val, val_mask) + let dst_val := mload(dest) + let dst_mask := shr(rest_bits, MAX_UINT()) + let dst_masked := and(dst_val, dst_mask) + mstore(dest, or(val_masked, dst_masked)) + } + + function $llvm_AlwaysInline_llvm$_memcpy(dest, src, len) { + let dest_addr := dest + let src_addr := src + let dest_end := add(dest, and(len, sub(0, 32))) + for { } lt(dest_addr, dest_end) {} { + mstore(dest_addr, mload(src_addr)) + dest_addr := add(dest_addr, 32) + src_addr := add(src_addr, 32) + } + + let rest_len := and(len, 31) + if rest_len { + $llvm_AlwaysInline_llvm$_copyRest(dest_addr, mload(src_addr), rest_len) + } + } + + function $llvm_AlwaysInline_llvm$_memsetToZero(dest,len) { + let dest_end := add(dest, and(len, sub(0, 32))) + for {let i := dest} lt(i, dest_end) { i := add(i, 32) } { + mstore(i, 0) + } + + let rest_len := and(len, 31) + if rest_len { + $llvm_AlwaysInline_llvm$_copyRest(dest_end, 0, rest_len) + } + } + + //////////////////////////////////////////////////////////////// + // LOGS FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function _genericLog(sp, stackHead, evmGasLeft, topicCount, isStatic) -> newEvmGasLeft, offset, size, newSp, newStackHead { + newEvmGasLeft := chargeGas(evmGasLeft, 375) + + if isStatic { + panic() + } + + let rawOffset + popStackCheck(sp, add(2, topicCount)) + rawOffset, newSp, newStackHead := popStackItemWithoutCheck(sp, stackHead) + size, newSp, newStackHead := popStackItemWithoutCheck(newSp, newStackHead) + + checkMemIsAccessible(rawOffset, size) + + // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost + let dynamicGas := add(shl(3, size), expandMemory(rawOffset, size)) + dynamicGas := add(dynamicGas, mul(375, topicCount)) + + newEvmGasLeft := chargeGas(newEvmGasLeft, dynamicGas) + + if size { + offset := add(rawOffset, MEM_OFFSET()) + } + } + + function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := 0 + } + + function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + $llvm_AlwaysInline_llvm$_memsetToZero(dstOffset, truncatedLen) + } + + function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + res := 0 + } + + function simulate( + isCallerEVM, + evmGasLeft, + isStatic, + ) -> returnOffset, returnLen, retGasLeft { + + returnOffset := MEM_OFFSET() + returnLen := 0 + + // stack pointer - index to first stack element; empty stack = -1 + let sp := sub(STACK_OFFSET(), 32) + // instruction pointer - index to next instruction. Not called pc because it's an + // actual yul/evm instruction. + let ip := BYTECODE_OFFSET() + let stackHead + + let bytecodeEndOffset := add(BYTECODE_OFFSET(), mload(BYTECODE_LEN_OFFSET())) + + for { } true { } { + let opcode := readIP(ip, bytecodeEndOffset) + + switch opcode + case 0x00 { // OP_STOP + break + } + case 0x01 { // OP_ADD + evmGasLeft := chargeGas(evmGasLeft, 3) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := add(a, stackHead) + + ip := add(ip, 1) + } + case 0x02 { // OP_MUL + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := mul(a, stackHead) + ip := add(ip, 1) + } + case 0x03 { // OP_SUB + evmGasLeft := chargeGas(evmGasLeft, 3) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := sub(a, stackHead) + + ip := add(ip, 1) + } + case 0x04 { // OP_DIV + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := div(a, stackHead) + + ip := add(ip, 1) + } + case 0x05 { // OP_SDIV + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := sdiv(a, stackHead) + + ip := add(ip, 1) + } + case 0x06 { // OP_MOD + evmGasLeft := chargeGas(evmGasLeft, 5) + + let a + popStackCheck(sp, 2) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := mod(a, stackHead) + + ip := add(ip, 1) + } + case 0x07 { // OP_SMOD + evmGasLeft := chargeGas(evmGasLeft, 5) + + let a + popStackCheck(sp, 2) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := smod(a, stackHead) + + ip := add(ip, 1) + } + case 0x08 { // OP_ADDMOD + evmGasLeft := chargeGas(evmGasLeft, 8) + + let a, b, N + + popStackCheck(sp, 3) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, N := popStackItemWithoutCheck(sp, stackHead) + stackHead := addmod(a, b, N) + + ip := add(ip, 1) + } + case 0x09 { // OP_MULMOD + evmGasLeft := chargeGas(evmGasLeft, 8) + + let a, b, N + + popStackCheck(sp, 3) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, N := popStackItemWithoutCheck(sp, stackHead) + + stackHead := mulmod(a, b, N) + ip := add(ip, 1) + } + case 0x0A { // OP_EXP + evmGasLeft := chargeGas(evmGasLeft, 10) + + let a, exponent + + popStackCheck(sp, 2) + a, sp, exponent := popStackItemWithoutCheck(sp, stackHead) + + let to_charge := 0 + let exponentCopy := exponent + for {} gt(exponentCopy, 0) {} { // while exponent > 0 + to_charge := add(to_charge, 50) + exponentCopy := shr(8, exponentCopy) + } + evmGasLeft := chargeGas(evmGasLeft, to_charge) + + stackHead := exp(a, exponent) + + ip := add(ip, 1) + } + case 0x0B { // OP_SIGNEXTEND + evmGasLeft := chargeGas(evmGasLeft, 5) + + let b, x + + popStackCheck(sp, 2) + b, sp, x := popStackItemWithoutCheck(sp, stackHead) + stackHead := signextend(b, x) + + ip := add(ip, 1) + } + case 0x10 { // OP_LT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := lt(a, b) + + ip := add(ip, 1) + } + case 0x11 { // OP_GT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead:= gt(a, b) + + ip := add(ip, 1) + } + case 0x12 { // OP_SLT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := slt(a, b) + + ip := add(ip, 1) + } + case 0x13 { // OP_SGT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := sgt(a, b) + + ip := add(ip, 1) + } + case 0x14 { // OP_EQ + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := eq(a, b) + + ip := add(ip, 1) + } + case 0x15 { // OP_ISZERO + evmGasLeft := chargeGas(evmGasLeft, 3) + + stackHead := iszero(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x16 { // OP_AND + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := and(a,b) + + ip := add(ip, 1) + } + case 0x17 { // OP_OR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := or(a,b) + + ip := add(ip, 1) + } + case 0x18 { // OP_XOR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := xor(a, b) + + ip := add(ip, 1) + } + case 0x19 { // OP_NOT + evmGasLeft := chargeGas(evmGasLeft, 3) + + stackHead := not(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x1A { // OP_BYTE + evmGasLeft := chargeGas(evmGasLeft, 3) + + let i, x + popStackCheck(sp, 2) + i, sp, x := popStackItemWithoutCheck(sp, stackHead) + stackHead := byte(i, x) + + ip := add(ip, 1) + } + case 0x1B { // OP_SHL + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := shl(shift, value) + + ip := add(ip, 1) + } + case 0x1C { // OP_SHR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := shr(shift, value) + + ip := add(ip, 1) + } + case 0x1D { // OP_SAR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := sar(shift, value) + + ip := add(ip, 1) + } + case 0x20 { // OP_KECCAK256 + evmGasLeft := chargeGas(evmGasLeft, 30) + + let rawOffset, size + + popStackCheck(sp, 2) + rawOffset, sp, size := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(rawOffset, size) + + // When an offset is first accessed (either read or write), memory may trigger + // an expansion, which costs gas. + // dynamicGas = 6 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(6, shr(5, add(size, 31))), expandMemory(rawOffset, size)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + let offset + if size { + // use 0 as offset if size is 0 + offset := add(MEM_OFFSET(), rawOffset) + } + + stackHead := keccak256(offset, size) + + ip := add(ip, 1) + } + case 0x30 { // OP_ADDRESS + evmGasLeft := chargeGas(evmGasLeft, 2) + sp, stackHead := pushStackItem(sp, address(), stackHead) + ip := add(ip, 1) + } + case 0x31 { // OP_BALANCE + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + stackHead := balance(addr) + + ip := add(ip, 1) + } + case 0x32 { // OP_ORIGIN + evmGasLeft := chargeGas(evmGasLeft, 2) + let _origin := mload(ORIGIN_CACHE_OFFSET()) + if iszero(_origin) { + _origin := cached(ORIGIN_CACHE_OFFSET(), origin()) + } + sp, stackHead := pushStackItem(sp, _origin, stackHead) + ip := add(ip, 1) + } + case 0x33 { // OP_CALLER + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, caller(), stackHead) + ip := add(ip, 1) + } + case 0x34 { // OP_CALLVALUE + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, callvalue(), stackHead) + ip := add(ip, 1) + } + case 0x35 { // OP_CALLDATALOAD + evmGasLeft := chargeGas(evmGasLeft, 3) + + let calldataOffset := accessStackHead(sp, stackHead) + + stackHead := $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) + + ip := add(ip, 1) + } + case 0x36 { // OP_CALLDATASIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, $llvm_AlwaysInline_llvm$_calldatasize(), stackHead) + ip := add(ip, 1) + } + case 0x37 { // OP_CALLDATACOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + // EraVM will revert if offset + length overflows uint32 + if gt(sourceOffset, UINT32_MAX()) { + sourceOffset := UINT32_MAX() + } + + // Check bytecode out-of-bounds access + let truncatedLen := len + if gt(add(sourceOffset, len), UINT32_MAX()) { + truncatedLen := sub(UINT32_MAX(), sourceOffset) // truncate + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds + } + + if truncatedLen { + $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) + } + + ip := add(ip, 1) + + } + case 0x38 { // OP_CODESIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let bytecodeLen := mload(BYTECODE_LEN_OFFSET()) + sp, stackHead := pushStackItem(sp, bytecodeLen, stackHead) + ip := add(ip, 1) + } + case 0x39 { // OP_CODECOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + if gt(sourceOffset, MAX_UINT64()) { + sourceOffset := MAX_UINT64() + } + + sourceOffset := add(sourceOffset, BYTECODE_OFFSET()) + + if gt(sourceOffset, bytecodeEndOffset) { + sourceOffset := bytecodeEndOffset + } + + // Check bytecode out-of-bounds access + let truncatedLen := len + if gt(add(sourceOffset, len), bytecodeEndOffset) { + truncatedLen := sub(bytecodeEndOffset, sourceOffset) // truncate + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds + } + + if truncatedLen { + $llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, truncatedLen) + } + + ip := add(ip, 1) + } + case 0x3A { // OP_GASPRICE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _gasprice := mload(GASPRICE_CACHE_OFFSET()) + if iszero(_gasprice) { + _gasprice := cached(GASPRICE_CACHE_OFFSET(), gasprice()) + } + sp, stackHead := pushStackItem(sp, _gasprice, stackHead) + ip := add(ip, 1) + } + case 0x3B { // OP_EXTCODESIZE + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + let rawCodeHash := getRawCodeHash(addr) + switch shr(248, rawCodeHash) + case 1 { + stackHead := extcodesize(addr) + } + case 2 { + stackHead := and(shr(224, rawCodeHash), 0xffff) + } + default { + stackHead := 0 + } + + ip := add(ip, 1) + } + case 0x3C { // OP_EXTCODECOPY + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr, dstOffset, srcOffset, len + popStackCheck(sp, 4) + addr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + srcOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + address_access_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add( + mul(3, shr(5, add(len, 31))), + expandMemory(dstOffset, len) + ) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + dynamicGas := add(dynamicGas, 2500) + } + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + if gt(srcOffset, MAX_UINT64()) { + srcOffset := MAX_UINT64() + } + + if gt(len, 0) { + // Gets the code from the addr + let copiedLen := fetchDeployedCode(addr, dstOffset, srcOffset, len) + + if lt(copiedLen, len) { + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, copiedLen), sub(len, copiedLen)) + } + } + + ip := add(ip, 1) + } + case 0x3D { // OP_RETURNDATASIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let rdz := mload(LAST_RETURNDATA_SIZE_OFFSET()) + sp, stackHead := pushStackItem(sp, rdz, stackHead) + ip := add(ip, 1) + } + case 0x3E { // OP_RETURNDATACOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // minimum_word_size = (size + 31) / 32 + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + checkOverflow(sourceOffset, len) + + // Check returndata out-of-bounds error + if gt(add(sourceOffset, len), mload(LAST_RETURNDATA_SIZE_OFFSET())) { + panic() + } + + copyActivePtrData(add(MEM_OFFSET(), dstOffset), sourceOffset, len) + ip := add(ip, 1) + } + case 0x3F { // OP_EXTCODEHASH + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + let codeLen := and(shr(224, rawCodeHash), 0xffff) + + if codeLen { + if lt(addr, 0x100) { + // precompiles and 0x00 + codeLen := 0 + } + } + + switch codeLen + case 0 { + stackHead := EMPTY_KECCAK() + + if iszero(getRawNonce(addr)) { + if iszero(balance(addr)) { + stackHead := 0 + } + } + } + default { + // zkVM contract + stackHead := rawCodeHash + } + } + default { + // Get precalculated keccak of EVM code + stackHead := getEvmExtcodehash(addr) + } + + ip := add(ip, 1) + } + case 0x40 { // OP_BLOCKHASH + evmGasLeft := chargeGas(evmGasLeft, 20) + + stackHead := blockhash(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x41 { // OP_COINBASE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _coinbase := mload(COINBASE_CACHE_OFFSET()) + if iszero(_coinbase) { + _coinbase := cached(COINBASE_CACHE_OFFSET(), coinbase()) + } + sp, stackHead := pushStackItem(sp, _coinbase, stackHead) + ip := add(ip, 1) + } + case 0x42 { // OP_TIMESTAMP + evmGasLeft := chargeGas(evmGasLeft, 2) + let _blocktimestamp := mload(BLOCKTIMESTAMP_CACHE_OFFSET()) + if iszero(_blocktimestamp) { + _blocktimestamp := cached(BLOCKTIMESTAMP_CACHE_OFFSET(), timestamp()) + } + sp, stackHead := pushStackItem(sp, _blocktimestamp, stackHead) + ip := add(ip, 1) + } + case 0x43 { // OP_NUMBER + evmGasLeft := chargeGas(evmGasLeft, 2) + let _blocknumber := mload(BLOCKNUMBER_CACHE_OFFSET()) + if iszero(_blocknumber) { + _blocknumber := cached(BLOCKNUMBER_CACHE_OFFSET(), number()) + } + sp, stackHead := pushStackItem(sp, _blocknumber, stackHead) + ip := add(ip, 1) + } + case 0x44 { // OP_PREVRANDAO + evmGasLeft := chargeGas(evmGasLeft, 2) + let _prevrandao := mload(PREVRANDAO_CACHE_OFFSET()) + if iszero(_prevrandao) { + _prevrandao := cached(PREVRANDAO_CACHE_OFFSET(), prevrandao()) + } + sp, stackHead := pushStackItem(sp, _prevrandao, stackHead) + ip := add(ip, 1) + } + case 0x45 { // OP_GASLIMIT + evmGasLeft := chargeGas(evmGasLeft, 2) + let _gasLimit := mload(GASLIMIT_CACHE_OFFSET()) + if iszero(_gasLimit) { + _gasLimit := cached(GASLIMIT_CACHE_OFFSET(), gaslimit()) + } + sp, stackHead := pushStackItem(sp, _gasLimit, stackHead) + ip := add(ip, 1) + } + case 0x46 { // OP_CHAINID + evmGasLeft := chargeGas(evmGasLeft, 2) + let _chainId := mload(CHAINID_CACHE_OFFSET()) + if iszero(_chainId) { + _chainId := cached(CHAINID_CACHE_OFFSET(), chainid()) + } + sp, stackHead := pushStackItem(sp, _chainId, stackHead) + ip := add(ip, 1) + } + case 0x47 { // OP_SELFBALANCE + evmGasLeft := chargeGas(evmGasLeft, 5) + sp, stackHead := pushStackItem(sp, selfbalance(), stackHead) + ip := add(ip, 1) + } + case 0x48 { // OP_BASEFEE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _baseFee := mload(BASEFEE_CACHE_OFFSET()) + if iszero(_baseFee) { + _baseFee := cached(BASEFEE_CACHE_OFFSET(), basefee()) + } + sp, stackHead := pushStackItem(sp, _baseFee, stackHead) + ip := add(ip, 1) + } + case 0x50 { // OP_POP + evmGasLeft := chargeGas(evmGasLeft, 2) + + let _y + + _y, sp, stackHead := popStackItem(sp, stackHead) + ip := add(ip, 1) + } + case 0x51 { // OP_MLOAD + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset := accessStackHead(sp, stackHead) + + checkMemIsAccessible(offset, 32) + let expansionGas := expandMemory(offset, 32) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + stackHead := mload(add(MEM_OFFSET(), offset)) + + ip := add(ip, 1) + } + case 0x52 { // OP_MSTORE + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset, value + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, 32) + let expansionGas := expandMemory(offset, 32) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + mstore(add(MEM_OFFSET(), offset), value) + ip := add(ip, 1) + } + case 0x53 { // OP_MSTORE8 + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset, value + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, 1) + let expansionGas := expandMemory(offset, 1) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + mstore8(add(MEM_OFFSET(), offset), value) + ip := add(ip, 1) + } + case 0x54 { // OP_SLOAD + evmGasLeft := chargeGas(evmGasLeft, 100) + + let key := accessStackHead(sp, stackHead) + let wasWarm := isSlotWarm(key) + + if iszero(wasWarm) { + evmGasLeft := chargeGas(evmGasLeft, 2000) + } + + let value := sload(key) + + if iszero(wasWarm) { + let _wasW, _orgV := warmSlot(key, value) + } + + stackHead := value + ip := add(ip, 1) + } + case 0x55 { // OP_SSTORE + if isStatic { + panic() + } + + if lt(evmGasLeft, 2301) { // if <= 2300 + panic() + } + + let key, value + + popStackCheck(sp, 2) + key, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + ip := add(ip, 1) + + let dynamicGas := 100 + // Here it is okay to read before we charge since we known anyway that + // the context has enough funds to compensate at least for the read. + let currentValue := sload(key) + let wasWarm, originalValue := warmSlot(key, currentValue) + + if iszero(wasWarm) { + dynamicGas := add(dynamicGas, 2100) + } + + if eq(value, currentValue) { // no-op + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + continue + } + + if eq(originalValue, currentValue) { + switch originalValue + case 0 { + dynamicGas := add(dynamicGas, 19900) + } + default { + dynamicGas := add(dynamicGas, 2800) + } + } + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + sstore(key, value) + } + // NOTE: We don't currently do full jumpdest validation + // (i.e. validating a jumpdest isn't in PUSH data) + case 0x56 { // OP_JUMP + evmGasLeft := chargeGas(evmGasLeft, 9) // charge for OP_JUMP (8) and OP_JUMPDEST (1) immediately + + let counter + counter, sp, stackHead := popStackItem(sp, stackHead) + + // Counter certainly can't be bigger than uint64. + if gt(counter, MAX_UINT64()) { + panic() + } + + ip := add(BYTECODE_OFFSET(), counter) + + // Check next opcode is JUMPDEST + let nextOpcode := readIP(ip, bytecodeEndOffset) + if iszero(eq(nextOpcode, 0x5B)) { + panic() + } + + // execute JUMPDEST immediately + ip := add(ip, 1) + } + case 0x57 { // OP_JUMPI + evmGasLeft := chargeGas(evmGasLeft, 10) + + let counter, b + + popStackCheck(sp, 2) + counter, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + if iszero(b) { + ip := add(ip, 1) + continue + } + + // Counter certainly can't be bigger than uint64. + if gt(counter, MAX_UINT64()) { + panic() + } + + ip := add(BYTECODE_OFFSET(), counter) + + // Check next opcode is JUMPDEST + let nextOpcode := readIP(ip, bytecodeEndOffset) + if iszero(eq(nextOpcode, 0x5B)) { + panic() + } + + // execute JUMPDEST immediately + evmGasLeft := chargeGas(evmGasLeft, 1) + ip := add(ip, 1) + } + case 0x58 { // OP_PC + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, sub(ip, BYTECODE_OFFSET()), stackHead) + + ip := add(ip, 1) + } + case 0x59 { // OP_MSIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let size + + size := mload(MEM_LEN_OFFSET()) + size := shl(5, size) + sp, stackHead := pushStackItem(sp, size, stackHead) + ip := add(ip, 1) + } + case 0x5A { // OP_GAS + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, evmGasLeft, stackHead) + ip := add(ip, 1) + } + case 0x5B { // OP_JUMPDEST + evmGasLeft := chargeGas(evmGasLeft, 1) + ip := add(ip, 1) + } + case 0x5C { // OP_TLOAD + evmGasLeft := chargeGas(evmGasLeft, 100) + + stackHead := tload(accessStackHead(sp, stackHead)) + ip := add(ip, 1) + } + case 0x5D { // OP_TSTORE + evmGasLeft := chargeGas(evmGasLeft, 100) + + if isStatic { + panic() + } + + let key, value + popStackCheck(sp, 2) + key, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + tstore(key, value) + ip := add(ip, 1) + } + case 0x5E { // OP_MCOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let destOffset, offset, size + popStackCheck(sp, 3) + destOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, size) + checkMemIsAccessible(destOffset, size) + + // dynamic_gas = 3 * words_copied + memory_expansion_cost + let dynamicGas := expandMemory2(offset, size, destOffset, size) + let wordsCopied := div(add(size, 31), 32) // div rounding up + dynamicGas := add(dynamicGas, mul(3, wordsCopied)) + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + mcopy(add(destOffset, MEM_OFFSET()), add(offset, MEM_OFFSET()), size) + ip := add(ip, 1) + } + case 0x5F { // OP_PUSH0 + evmGasLeft := chargeGas(evmGasLeft, 2) + + let value := 0 + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 1) + } + case 0x60 { // OP_PUSH1 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 1) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 1) + } + case 0x61 { // OP_PUSH2 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 2) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 2) + } + case 0x62 { // OP_PUSH3 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 3) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 3) + } + case 0x63 { // OP_PUSH4 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 4) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 4) + } + case 0x64 { // OP_PUSH5 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 5) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 5) + } + case 0x65 { // OP_PUSH6 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 6) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 6) + } + case 0x66 { // OP_PUSH7 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 7) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 7) + } + case 0x67 { // OP_PUSH8 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 8) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 8) + } + case 0x68 { // OP_PUSH9 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 9) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 9) + } + case 0x69 { // OP_PUSH10 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 10) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 10) + } + case 0x6A { // OP_PUSH11 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 11) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 11) + } + case 0x6B { // OP_PUSH12 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 12) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 12) + } + case 0x6C { // OP_PUSH13 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 13) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 13) + } + case 0x6D { // OP_PUSH14 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 14) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 14) + } + case 0x6E { // OP_PUSH15 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 15) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 15) + } + case 0x6F { // OP_PUSH16 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 16) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 16) + } + case 0x70 { // OP_PUSH17 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 17) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 17) + } + case 0x71 { // OP_PUSH18 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 18) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 18) + } + case 0x72 { // OP_PUSH19 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 19) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 19) + } + case 0x73 { // OP_PUSH20 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 20) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 20) + } + case 0x74 { // OP_PUSH21 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 21) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 21) + } + case 0x75 { // OP_PUSH22 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 22) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 22) + } + case 0x76 { // OP_PUSH23 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 23) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 23) + } + case 0x77 { // OP_PUSH24 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 24) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 24) + } + case 0x78 { // OP_PUSH25 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 25) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 25) + } + case 0x79 { // OP_PUSH26 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 26) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 26) + } + case 0x7A { // OP_PUSH27 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 27) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 27) + } + case 0x7B { // OP_PUSH28 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 28) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 28) + } + case 0x7C { // OP_PUSH29 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 29) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 29) + } + case 0x7D { // OP_PUSH30 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 30) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 30) + } + case 0x7E { // OP_PUSH31 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 31) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 31) + } + case 0x7F { // OP_PUSH32 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 32) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 32) + } + case 0x80 { // OP_DUP1 + evmGasLeft := chargeGas(evmGasLeft, 3) + sp, stackHead := pushStackItem(sp, accessStackHead(sp, stackHead), stackHead) + ip := add(ip, 1) + } + case 0x81 { // OP_DUP2 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 2, stackHead) + ip := add(ip, 1) + } + case 0x82 { // OP_DUP3 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 3, stackHead) + ip := add(ip, 1) + } + case 0x83 { // OP_DUP4 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 4, stackHead) + ip := add(ip, 1) + } + case 0x84 { // OP_DUP5 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 5, stackHead) + ip := add(ip, 1) + } + case 0x85 { // OP_DUP6 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 6, stackHead) + ip := add(ip, 1) + } + case 0x86 { // OP_DUP7 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 7, stackHead) + ip := add(ip, 1) + } + case 0x87 { // OP_DUP8 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 8, stackHead) + ip := add(ip, 1) + } + case 0x88 { // OP_DUP9 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 9, stackHead) + ip := add(ip, 1) + } + case 0x89 { // OP_DUP10 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 10, stackHead) + ip := add(ip, 1) + } + case 0x8A { // OP_DUP11 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 11, stackHead) + ip := add(ip, 1) + } + case 0x8B { // OP_DUP12 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 12, stackHead) + ip := add(ip, 1) + } + case 0x8C { // OP_DUP13 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 13, stackHead) + ip := add(ip, 1) + } + case 0x8D { // OP_DUP14 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 14, stackHead) + ip := add(ip, 1) + } + case 0x8E { // OP_DUP15 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 15, stackHead) + ip := add(ip, 1) + } + case 0x8F { // OP_DUP16 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 16, stackHead) + ip := add(ip, 1) + } + case 0x90 { // OP_SWAP1 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 1, stackHead) + ip := add(ip, 1) + } + case 0x91 { // OP_SWAP2 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 2, stackHead) + ip := add(ip, 1) + } + case 0x92 { // OP_SWAP3 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 3, stackHead) + ip := add(ip, 1) + } + case 0x93 { // OP_SWAP4 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 4, stackHead) + ip := add(ip, 1) + } + case 0x94 { // OP_SWAP5 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 5, stackHead) + ip := add(ip, 1) + } + case 0x95 { // OP_SWAP6 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 6, stackHead) + ip := add(ip, 1) + } + case 0x96 { // OP_SWAP7 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 7, stackHead) + ip := add(ip, 1) + } + case 0x97 { // OP_SWAP8 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 8, stackHead) + ip := add(ip, 1) + } + case 0x98 { // OP_SWAP9 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 9, stackHead) + ip := add(ip, 1) + } + case 0x99 { // OP_SWAP10 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 10, stackHead) + ip := add(ip, 1) + } + case 0x9A { // OP_SWAP11 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 11, stackHead) + ip := add(ip, 1) + } + case 0x9B { // OP_SWAP12 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 12, stackHead) + ip := add(ip, 1) + } + case 0x9C { // OP_SWAP13 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 13, stackHead) + ip := add(ip, 1) + } + case 0x9D { // OP_SWAP14 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 14, stackHead) + ip := add(ip, 1) + } + case 0x9E { // OP_SWAP15 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 15, stackHead) + ip := add(ip, 1) + } + case 0x9F { // OP_SWAP16 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 16, stackHead) + ip := add(ip, 1) + } + case 0xA0 { // OP_LOG0 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 0, isStatic) + log0(offset, size) + ip := add(ip, 1) + } + case 0xA1 { // OP_LOG1 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 1, isStatic) + { + let topic1 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log1(offset, size, topic1) + } + ip := add(ip, 1) + } + case 0xA2 { // OP_LOG2 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 2, isStatic) + + { + let topic1, topic2 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log2(offset, size, topic1, topic2) + } + ip := add(ip, 1) + } + case 0xA3 { // OP_LOG3 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 3, isStatic) + + { + let topic1, topic2, topic3 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log3(offset, size, topic1, topic2, topic3) + } + ip := add(ip, 1) + } + case 0xA4 { // OP_LOG4 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 4, isStatic) + + { + let topic1, topic2, topic3, topic4 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic4, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log4(offset, size, topic1, topic2, topic3, topic4) + } + ip := add(ip, 1) + } + case 0xF0 { // OP_CREATE + evmGasLeft := chargeGas(evmGasLeft, 32000) + + if isStatic { + panic() + } + + evmGasLeft, sp, stackHead := performCreate(evmGasLeft, sp, stackHead) + ip := add(ip, 1) + } + case 0xF1 { // OP_CALL + // A function was implemented in order to avoid stack depth errors. + evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead, isStatic) + ip := add(ip, 1) + } + case 0xF3 { // OP_RETURN + let offset, size + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + if size { + checkMemIsAccessible(offset, size) + + evmGasLeft := chargeGas(evmGasLeft, expandMemory(offset, size)) + + returnLen := size + + // Don't check overflow here since previous checks are enough to ensure this is safe + returnOffset := add(MEM_OFFSET(), offset) + } + + break + } + case 0xF4 { // OP_DELEGATECALL + evmGasLeft, sp, stackHead := performDelegateCall(sp, evmGasLeft, isStatic, stackHead) + ip := add(ip, 1) + } + case 0xF5 { // OP_CREATE2 + evmGasLeft := chargeGas(evmGasLeft, 32000) + + if isStatic { + panic() + } + + evmGasLeft, sp, stackHead := performCreate2(evmGasLeft, sp, stackHead) + ip := add(ip, 1) + } + case 0xFA { // OP_STATICCALL + evmGasLeft, sp, stackHead := performStaticCall(sp, evmGasLeft, stackHead) + ip := add(ip, 1) + } + case 0xFD { // OP_REVERT + let offset,size + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + switch iszero(size) + case 0 { + checkMemIsAccessible(offset, size) + evmGasLeft := chargeGas(evmGasLeft, expandMemory(offset, size)) + + // Don't check overflow here since previous checks are enough to ensure this is safe + offset := add(offset, MEM_OFFSET()) + } + default { + offset := MEM_OFFSET() + } + + + if eq(isCallerEVM, 1) { + offset := sub(offset, 32) + size := add(size, 32) + + // include gas + mstore(offset, evmGasLeft) + } + + revert(offset, size) + } + case 0xFE { // OP_INVALID + evmGasLeft := 0 + revertWithGas(evmGasLeft) + } + // We explicitly add unused opcodes to optimize the jump table by compiler. + case 0x0C { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x0D { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x0E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x0F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x1E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x1F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x21 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x22 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x23 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x24 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x25 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x26 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x27 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x28 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x29 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2A { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2B { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2C { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2D { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x49 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4A { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4B { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4C { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4D { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xED { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xFB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xFC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xFF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + default { + $llvm_NoInline_llvm$_panic() + } + } + + + retGasLeft := evmGasLeft + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + pop($llvm_AlwaysInline_llvm$_warmAddress(address())) + + let evmGasLeft, isStatic, isCallerEVM := consumeEvmFrame() + + if isStatic { + abortEvmEnvironment() // should never happen + } + + getConstructorBytecode() + + if iszero(isCallerEVM) { + evmGasLeft := getEvmGasFromContext() + } + + let offset, len, gasToReturn := simulate(isCallerEVM, evmGasLeft, false) + + gasToReturn := validateBytecodeAndChargeGas(offset, len, gasToReturn) + + let blobLen := padBytecode(offset, len) + + mstore(add(offset, blobLen), len) + mstore(add(offset, add(32, blobLen)), gasToReturn) + + verbatim_2i_0o("return_deployed", offset, add(blobLen, 64)) + } + object "EvmEmulator_deployed" { + code { + function MAX_POSSIBLE_ACTIVE_BYTECODE() -> max { + max := MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() + } + + function getDeployedBytecode() { + let codeLen := fetchDeployedCode( + getCodeAddress(), + BYTECODE_OFFSET(), // destination offset + 0, // source offset + MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() + ) + + mstore(EMPTY_CODE_OFFSET(), 0) + mstore(BYTECODE_LEN_OFFSET(), codeLen) + } + + //////////////////////////////////////////////////////////////// + // CONSTANTS + //////////////////////////////////////////////////////////////// + + function ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008002 + } + + function NONCE_HOLDER_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008003 + } + + function DEPLOYER_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008006 + } + + function CODE_ORACLE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008012 + } + + function EVM_GAS_MANAGER_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008013 + } + + function MSG_VALUE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008009 + } + + function ORIGIN_CACHE_OFFSET() -> offset { + offset := mul(23, 32) + } + + function GASPRICE_CACHE_OFFSET() -> offset { + offset := mul(24, 32) + } + + function COINBASE_CACHE_OFFSET() -> offset { + offset := mul(25, 32) + } + + function BLOCKTIMESTAMP_CACHE_OFFSET() -> offset { + offset := mul(26, 32) + } + + function BLOCKNUMBER_CACHE_OFFSET() -> offset { + offset := mul(27, 32) + } + + function PREVRANDAO_CACHE_OFFSET() -> offset { + offset := mul(28, 32) + } + + function GASLIMIT_CACHE_OFFSET() -> offset { + offset := mul(29, 32) + } + + function CHAINID_CACHE_OFFSET() -> offset { + offset := mul(30, 32) + } + + function BASEFEE_CACHE_OFFSET() -> offset { + offset := mul(31, 32) + } + + function LAST_RETURNDATA_SIZE_OFFSET() -> offset { + offset := add(BASEFEE_CACHE_OFFSET(), 32) + } + + function STACK_OFFSET() -> offset { + offset := add(LAST_RETURNDATA_SIZE_OFFSET(), 64) + } + + function MAX_STACK_SLOT_OFFSET() -> offset { + offset := add(STACK_OFFSET(), mul(1023, 32)) + } + + function BYTECODE_LEN_OFFSET() -> offset { + offset := add(MAX_STACK_SLOT_OFFSET(), 32) + } + + function BYTECODE_OFFSET() -> offset { + offset := add(BYTECODE_LEN_OFFSET(), 32) + } + + // reserved empty slot to simplify PUSH N opcodes + function EMPTY_CODE_OFFSET() -> offset { + offset := add(BYTECODE_OFFSET(), MAX_POSSIBLE_ACTIVE_BYTECODE()) + } + + function MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() -> max { + max := 24576 // EIP-170 + } + + function MAX_POSSIBLE_INIT_BYTECODE_LEN() -> max { + max := mul(2, MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN()) // EIP-3860 + } + + function MEM_LEN_OFFSET() -> offset { + offset := add(EMPTY_CODE_OFFSET(), 32) + } + + function MEM_OFFSET() -> offset { + offset := add(MEM_LEN_OFFSET(), 32) + } + + // Used to simplify gas calculations for memory expansion. + // The cost to increase the memory to 12 MB is close to 277M EVM gas + function MAX_POSSIBLE_MEM_LEN() -> max { + max := 0xC00000 // 12MB + } + + function MAX_UINT() -> max_uint { + max_uint := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + } + + function MAX_UINT64() -> max { + max := sub(shl(64, 1), 1) + } + + // Each evm gas is 5 zkEVM one + function GAS_DIVISOR() -> gas_div { gas_div := 5 } + + // We need to pass some gas for MsgValueSimulator internal logic to decommit emulator etc + function MSG_VALUE_SIMULATOR_STIPEND_GAS() -> gas_stipend { + gas_stipend := 35000 // 27000 + a little bit more + } + + function OVERHEAD() -> overhead { overhead := 2000 } + + function UINT32_MAX() -> ret { ret := 4294967295 } // 2^32 - 1 + + function EMPTY_KECCAK() -> value { // keccak("") + value := 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 + } + + + //////////////////////////////////////////////////////////////// + // GENERAL FUNCTIONS + //////////////////////////////////////////////////////////////// + + // abort the whole EVM execution environment, including parent frames + function abortEvmEnvironment() { + revert(0, 0) + } + + function $llvm_NoInline_llvm$_panic() { // revert consuming all EVM gas + mstore(0, 0) + revert(0, 32) + } + + function revertWithGas(evmGasLeft) { + mstore(0, evmGasLeft) + revert(0, 32) + } + + function panic() { // revert consuming all EVM gas + mstore(0, 0) + revert(0, 32) + } + + function cached(cacheIndex, value) -> _value { + _value := value + mstore(cacheIndex, _value) + } + + function chargeGas(prevGas, toCharge) -> gasRemaining { + if lt(prevGas, toCharge) { + panic() + } + + gasRemaining := sub(prevGas, toCharge) + } + + function getEvmGasFromContext() -> evmGas { + // Caller must pass at least OVERHEAD() ergs + let _gas := gas() + if gt(_gas, OVERHEAD()) { + evmGas := div(sub(_gas, OVERHEAD()), GAS_DIVISOR()) + } + } + + // This function can overflow, it is the job of the caller to ensure that it does not. + // The argument to this function is the offset into the memory region IN BYTES. + function expandMemory(offset, size) -> gasCost { + // memory expansion costs 0 if size is 0 + if size { + let oldSizeInWords := mload(MEM_LEN_OFFSET()) + + // div rounding up + let newSizeInWords := div(add(add(offset, size), 31), 32) + + // memory_size_word = (memory_byte_size + 31) / 32 + // memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word) + // memory_expansion_cost = new_memory_cost - last_memory_cost + if gt(newSizeInWords, oldSizeInWords) { + let linearPart := mul(3, sub(newSizeInWords, oldSizeInWords)) + let quadraticPart := sub( + div( + mul(newSizeInWords, newSizeInWords), + 512 + ), + div( + mul(oldSizeInWords, oldSizeInWords), + 512 + ) + ) + + gasCost := add(linearPart, quadraticPart) + + mstore(MEM_LEN_OFFSET(), newSizeInWords) + } + } + } + + function expandMemory2(retOffset, retSize, argsOffset, argsSize) -> maxExpand { + switch lt(add(retOffset, retSize), add(argsOffset, argsSize)) + case 0 { + maxExpand := expandMemory(retOffset, retSize) + } + default { + maxExpand := expandMemory(argsOffset, argsSize) + } + } + + function checkMemIsAccessible(relativeOffset, size) { + if size { + checkOverflow(relativeOffset, size) + + if gt(add(relativeOffset, size), MAX_POSSIBLE_MEM_LEN()) { + panic() + } + } + } + + function checkOverflow(data1, data2) { + if lt(add(data1, data2), data2) { + panic() + } + } + + function insufficientBalance(value) -> res { + if value { + res := gt(value, selfbalance()) + } + } + + // It is the responsibility of the caller to ensure that ip is correct + function readIP(ip, bytecodeEndOffset) -> opcode { + if lt(ip, bytecodeEndOffset) { + opcode := and(mload(sub(ip, 31)), 0xff) + } + // STOP else + } + + // It is the responsibility of the caller to ensure that start and length is correct + function readBytes(start, length) -> value { + value := shr(mul(8, sub(32, length)), mload(start)) + // will be padded by zeroes if out of bounds (we have reserved EMPTY_CODE_OFFSET() slot) + } + + function getCodeAddress() -> addr { + addr := verbatim_0i_1o("code_source") + } + + function loadReturndataIntoActivePtr() { + verbatim_0i_0o("return_data_ptr_to_active") + } + + function loadCalldataIntoActivePtr() { + verbatim_0i_0o("calldata_ptr_to_active") + } + + function getActivePtrDataSize() -> size { + size := verbatim_0i_1o("active_ptr_data_size") + } + + function copyActivePtrData(_dest, _source, _size) { + verbatim_3i_0o("active_ptr_data_copy", _dest, _source, _size) + } + + function ptrAddIntoActive(_dest) { + verbatim_1i_0o("active_ptr_add_assign", _dest) + } + + function ptrShrinkIntoActive(_dest) { + verbatim_1i_0o("active_ptr_shrink_assign", _dest) + } + + function getIsStaticFromCallFlags() -> isStatic { + isStatic := verbatim_0i_1o("get_global::call_flags") + isStatic := iszero(iszero(and(isStatic, 0x04))) + } + + function fetchFromSystemContract(to, argSize) -> res { + let success := staticcall(gas(), to, 0, argSize, 0, 0) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + + returndatacopy(0, 0, 32) + res := mload(0) + } + + function isAddrEmpty(addr) -> isEmpty { + // We treat constructing EraVM contracts as non-existing + if iszero(extcodesize(addr)) { // YUL doesn't have short-circuit evaluation + if iszero(balance(addr)) { + if iszero(getRawNonce(addr)) { + isEmpty := 1 + } + } + } + } + + // returns minNonce + 2^128 * deployment nonce. + function getRawNonce(addr) -> nonce { + // selector for function getRawNonce(address addr) + mstore(0, 0x5AA9B6B500000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + nonce := fetchFromSystemContract(NONCE_HOLDER_SYSTEM_CONTRACT(), 36) + } + + function getRawCodeHash(addr) -> hash { + mstore(0, 0x4DE2E46800000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + hash := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) + } + + function getEvmExtcodehash(addr) -> evmCodeHash { + mstore(0, 0x54A3314700000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + evmCodeHash := fetchFromSystemContract(DEPLOYER_SYSTEM_CONTRACT(), 36) + } + + function isEvmContract(addr) -> isEVM { + // function isAccountEVM(address addr) external view returns (bool); + mstore(0, 0x8C04047700000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + isEVM := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) + } + + function isHashOfConstructedEvmContract(rawCodeHash) -> isConstructedEVM { + let version := shr(248, rawCodeHash) + let isConstructedFlag := xor(shr(240, rawCodeHash), 1) + isConstructedEVM := and(eq(version, 2), isConstructedFlag) + } + + // Basically performs an extcodecopy, while returning the length of the copied bytecode. + function fetchDeployedCode(addr, dstOffset, srcOffset, len) -> copiedLen { + let rawCodeHash := getRawCodeHash(addr) + mstore(0, rawCodeHash) + + let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) + // it fails if we don't have any code deployed at this address + if success { + // The length of the bytecode is encoded in versioned bytecode hash + let codeLen := and(shr(224, rawCodeHash), 0xffff) + + if eq(shr(248, rawCodeHash), 1) { + // For native zkVM contracts length encoded in words, not bytes + codeLen := shl(5, codeLen) // * 32 + } + + if gt(len, codeLen) { + len := codeLen + } + + let _returndatasize := returndatasize() + if gt(srcOffset, _returndatasize) { + srcOffset := _returndatasize + } + + if gt(add(len, srcOffset), _returndatasize) { + len := sub(_returndatasize, srcOffset) + } + + if len { + returndatacopy(dstOffset, srcOffset, len) + } + + copiedLen := len + } + } + + function getMax(a, b) -> max { + max := b + if gt(a, b) { + max := a + } + } + + function build_farcall_abi(isSystemCall, gas, dataStart, dataLength) -> farCallAbi { + farCallAbi := shl(248, isSystemCall) + // dataOffset is 0 + farCallAbi := or(farCallAbi, shl(64, dataStart)) + farCallAbi := or(farCallAbi, shl(96, dataLength)) + farCallAbi := or(farCallAbi, shl(192, gas)) + // shardId is 0 + // forwardingMode is 0 + } + + function performSystemCall(to, dataLength) { + let success := performSystemCallRevertable(to, dataLength) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + } + + function performSystemCallRevertable(to, dataLength) -> success { + // system call, dataStart is 0 + let farCallAbi := build_farcall_abi(1, gas(), 0, dataLength) + success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) + } + + function rawCall(gas, to, value, dataStart, dataLength, outputOffset, outputLen) -> success { + switch iszero(value) + case 0 { + // system call to MsgValueSimulator, but call to "to" will be non-system + let farCallAbi := build_farcall_abi(1, gas, dataStart, dataLength) + success := verbatim_6i_1o("system_call", MSG_VALUE_SYSTEM_CONTRACT(), farCallAbi, value, to, 0, 0) + if outputLen { + if success { + let rtdz := returndatasize() + switch lt(rtdz, outputLen) + case 0 { returndatacopy(outputOffset, 0, outputLen) } + default { returndatacopy(outputOffset, 0, rtdz) } + } + } + } + default { + // not a system call + let farCallAbi := build_farcall_abi(0, gas, dataStart, dataLength) + success := verbatim_4i_1o("raw_call", to, farCallAbi, outputOffset, outputLen) + } + } + + function rawStaticcall(gas, to, dataStart, dataLength, outputOffset, outputLen) -> success { + // not a system call + let farCallAbi := build_farcall_abi(0, gas, dataStart, dataLength) + success := verbatim_4i_1o("raw_static_call", to, farCallAbi, outputOffset, outputLen) + } + + //////////////////////////////////////////////////////////////// + // STACK OPERATIONS + //////////////////////////////////////////////////////////////// + + function dupStackItem(sp, evmGas, position, oldStackHead) -> newSp, evmGasLeft, stackHead { + evmGasLeft := chargeGas(evmGas, 3) + + if iszero(lt(sp, MAX_STACK_SLOT_OFFSET())) { + panic() + } + + let tempSp := sub(sp, mul(0x20, sub(position, 1))) + + if lt(tempSp, STACK_OFFSET()) { + panic() + } + + mstore(sp, oldStackHead) + stackHead := mload(tempSp) + newSp := add(sp, 0x20) + } + + function swapStackItem(sp, evmGas, position, oldStackHead) -> evmGasLeft, stackHead { + evmGasLeft := chargeGas(evmGas, 3) + let tempSp := sub(sp, mul(0x20, position)) + + if lt(tempSp, STACK_OFFSET()) { + panic() + } + + stackHead := mload(tempSp) + mstore(tempSp, oldStackHead) + } + + function popStackItem(sp, oldStackHead) -> a, newSp, stackHead { + // We can not return any error here, because it would break compatibility + if lt(sp, STACK_OFFSET()) { + panic() + } + + a := oldStackHead + newSp := sub(sp, 0x20) + stackHead := mload(newSp) + } + + function pushStackItem(sp, item, oldStackHead) -> newSp, stackHead { + if iszero(lt(sp, MAX_STACK_SLOT_OFFSET())) { + panic() + } + + mstore(sp, oldStackHead) + stackHead := item + newSp := add(sp, 0x20) + } + + function popStackItemWithoutCheck(sp, oldStackHead) -> a, newSp, stackHead { + a := oldStackHead + newSp := sub(sp, 0x20) + stackHead := mload(newSp) + } + + function pushStackItemWithoutCheck(sp, item, oldStackHead) -> newSp, stackHead { + mstore(sp, oldStackHead) + stackHead := item + newSp := add(sp, 0x20) + } + + function popStackCheck(sp, numInputs) { + if lt(sub(sp, mul(0x20, sub(numInputs, 1))), STACK_OFFSET()) { + panic() + } + } + + function accessStackHead(sp, stackHead) -> value { + if lt(sp, STACK_OFFSET()) { + panic() + } + + value := stackHead + } + + //////////////////////////////////////////////////////////////// + // EVM GAS MANAGER FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function $llvm_AlwaysInline_llvm$_warmAddress(addr) -> isWarm { + // function warmAccount(address account) + // non-standard selector 0x00 + // addr is packed in the same word with selector + mstore(0, and(addr, 0xffffffffffffffffffffffffffffffffffffffff)) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 32) + + if returndatasize() { + isWarm := true + } + } + + function isSlotWarm(key) -> isWarm { + // non-standard selector 0x01 + mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) + mstore(1, key) + // should be call since we use TSTORE in gas manager + let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 33, 0, 0) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + + if returndatasize() { + isWarm := true + } + } + + function warmSlot(key, currentValue) -> isWarm, originalValue { + // non-standard selector 0x02 + mstore(0, 0x0200000000000000000000000000000000000000000000000000000000000000) + mstore(1, key) + mstore(33, currentValue) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 65) + + originalValue := currentValue + if returndatasize() { + isWarm := true + returndatacopy(0, 0, 32) + originalValue := mload(0) + } + } + + function pushEvmFrame(passGas, isStatic) { + // function pushEVMFrame + // non-standard selector 0x03 + mstore(0, or(0x0300000000000000000000000000000000000000000000000000000000000000, isStatic)) + mstore(32, passGas) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 64) + } + + function consumeEvmFrame() -> passGas, isStatic, callerEVM { + // function consumeEvmFrame() external returns (uint256 passGas, uint256 auxDataRes) + // non-standard selector 0x04 + mstore(0, 0x0400000000000000000000000000000000000000000000000000000000000000) + mstore(1, caller()) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 33) + + let _returndatasize := returndatasize() + if _returndatasize { + callerEVM := true + + returndatacopy(0, 0, 32) + passGas := mload(0) + + isStatic := gt(_returndatasize, 32) + } + } + + function resetEvmFrame() { + // function resetEvmFrame() + // non-standard selector 0x05 + mstore(0, 0x0500000000000000000000000000000000000000000000000000000000000000) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 1) + } + + //////////////////////////////////////////////////////////////// + // CALLS FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function performCall(oldSp, evmGasLeft, oldStackHead, isStatic) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, value, argsOffset, argsSize, retOffset, retSize + + popStackCheck(oldSp, 7) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + retOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + // static_gas = 0 + // dynamic_gas = memory_expansion_cost + code_execution_cost + address_access_cost + positive_value_cost + value_to_empty_account_cost + // code_execution_cost is the cost of the called code execution (limited by the gas parameter). + // If address is warm, then address_access_cost is 100, otherwise it is 2600. See section access sets. + // If value is not 0, then positive_value_cost is 9000. In this case there is also a call stipend that is given to make sure that a basic fallback function can be called. + // If value is not 0 and the address given points to an empty account, then value_to_empty_account_cost is 25000. An account is empty if its balance is 0, its nonce is 0 and it has no code. + + let addr, gasUsed := _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) + + if gt(value, 0) { + if isStatic { + panic() + } + + gasUsed := add(gasUsed, 9000) // positive_value_cost + + if isAddrEmpty(addr) { + gasUsed := add(gasUsed, 25000) // value_to_empty_account_cost + } + } + + evmGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(evmGasLeft, gasToPass) + evmGasLeft := sub(evmGasLeft, gasToPass) + + if gt(value, 0) { + gasToPass := add(gasToPass, 2300) + } + + let success, frameGasLeft := _genericCall( + addr, + gasToPass, + value, + add(argsOffset, MEM_OFFSET()), + argsSize, + add(retOffset, MEM_OFFSET()), + retSize, + isStatic + ) + + newGasLeft := add(evmGasLeft, frameGasLeft) + stackHead := success + } + + function performStaticCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, argsOffset, argsSize, retOffset, retSize + + popStackCheck(oldSp, 6) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + retOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + let addr, gasUsed := _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) + + evmGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(evmGasLeft, gasToPass) + evmGasLeft := sub(evmGasLeft, gasToPass) + + let success, frameGasLeft := _genericCall( + addr, + gasToPass, + 0, + add(MEM_OFFSET(), argsOffset), + argsSize, + add(MEM_OFFSET(), retOffset), + retSize, + true + ) + + newGasLeft := add(evmGasLeft, frameGasLeft) + stackHead := success + } + + + function performDelegateCall(oldSp, evmGasLeft, isStatic, oldStackHead) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, rawArgsOffset, argsSize, rawRetOffset, retSize + + popStackCheck(oldSp, 6) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + rawArgsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + rawRetOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + let addr, gasUsed := _genericPrecallLogic(rawAddr, rawArgsOffset, argsSize, rawRetOffset, retSize) + + newGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(newGasLeft, gasToPass) + + newGasLeft := sub(newGasLeft, gasToPass) + + let success + let frameGasLeft := gasToPass + + let retOffset := add(MEM_OFFSET(), rawRetOffset) + let argsOffset := add(MEM_OFFSET(), rawArgsOffset) + + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + // Not a constructed EVM contract + let precompileCost := getGasForPrecompiles(addr, argsSize) + switch precompileCost + case 0 { + // Not a precompile + _eraseReturndataPointer() + + let isCallToEmptyContract := iszero(addr) // 0x00 is always "empty" + if iszero(isCallToEmptyContract) { + isCallToEmptyContract := iszero(and(shr(224, rawCodeHash), 0xffff)) // is codelen zero? + } + + if isCallToEmptyContract { + success := delegatecall(gas(), addr, argsOffset, argsSize, retOffset, retSize) + _saveReturndataAfterZkEVMCall() + } + + // We forbid delegatecalls to EraVM native contracts + } + default { + // Precompile. Simlate using staticcall, since EraVM behavior differs here + success, frameGasLeft := callPrecompile(addr, precompileCost, gasToPass, 0, argsOffset, argsSize, retOffset, retSize, true) + } + } + default { + // Constructed EVM contract + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := delegatecall(gas(), addr, argsOffset, argsSize, 0, 0) + + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + + newGasLeft := add(newGasLeft, frameGasLeft) + stackHead := success + } + + function _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) -> addr, gasUsed { + addr := and(rawAddr, 0xffffffffffffffffffffffffffffffffffffffff) + + checkMemIsAccessible(argsOffset, argsSize) + checkMemIsAccessible(retOffset, retSize) + + gasUsed := 100 // warm address access cost + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + gasUsed := 2600 // cold address access cost + } + + // memory_expansion_cost + gasUsed := add(gasUsed, expandMemory2(retOffset, retSize, argsOffset, argsSize)) + } + + function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + // zkEVM native call + let precompileCost := getGasForPrecompiles(addr, argsSize) + switch precompileCost + case 0 { + // just smart contract + success, frameGasLeft := callZkVmNative(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic, rawCodeHash) + } + default { + // precompile + success, frameGasLeft := callPrecompile(addr, precompileCost, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) + } + } + default { + switch insufficientBalance(value) + case 0 { + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + default { + frameGasLeft := gasToPass + _eraseReturndataPointer() + } + } + } + + function callPrecompile(addr, precompileCost, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { + switch lt(gasToPass, precompileCost) + case 0 { + let zkVmGasToPass := gas() // pass all remaining gas, precompiles should not call any contracts + + switch isStatic + case 0 { + success := rawCall(zkVmGasToPass, addr, value, argsOffset, argsSize, retOffset, retSize) + } + default { + success := rawStaticcall(zkVmGasToPass, addr, argsOffset, argsSize, retOffset, retSize) + } + + _saveReturndataAfterZkEVMCall() + + if success { + frameGasLeft := sub(gasToPass, precompileCost) + } + // else consume all provided gas + } + default { + // consume all provided gas + _eraseReturndataPointer() + } + } + + // Call native ZkVm contract from EVM context + function callZkVmNative(addr, evmGasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic, rawCodeHash) -> success, frameGasLeft { + let zkEvmGasToPass := mul(evmGasToPass, GAS_DIVISOR()) // convert EVM gas -> ZkVM gas + + let additionalStipend := 6000 // should cover first access to empty account + switch value + case 0 { + if gt(addr, 0) { // zero address is always "empty" + if and(shr(224, rawCodeHash), 0xffff) { // if codelen is not zero + additionalStipend := 0 + } + } + } + default { + additionalStipend := 27000 // Stipend for MsgValueSimulator. Covered by positive_value_cost + } + + zkEvmGasToPass := add(zkEvmGasToPass, additionalStipend) + + if gt(zkEvmGasToPass, UINT32_MAX()) { // just in case + zkEvmGasToPass := UINT32_MAX() + } + + let zkEvmGasBefore := gas() + switch isStatic + case 0 { + success := call(zkEvmGasToPass, addr, value, argsOffset, argsSize, retOffset, retSize) + } + default { + success := staticcall(zkEvmGasToPass, addr, argsOffset, argsSize, retOffset, retSize) + } + let zkEvmGasUsed := sub(zkEvmGasBefore, gas()) + + _saveReturndataAfterZkEVMCall() + + if gt(zkEvmGasUsed, zkEvmGasBefore) { // overflow case + zkEvmGasUsed := 0 // should never happen + } + + switch gt(zkEvmGasUsed, additionalStipend) + case 0 { + zkEvmGasUsed := 0 + } + default { + zkEvmGasUsed := sub(zkEvmGasUsed, additionalStipend) + } + + zkEvmGasToPass := sub(zkEvmGasToPass, additionalStipend) + + // refund gas + if gt(zkEvmGasToPass, zkEvmGasUsed) { + frameGasLeft := div(sub(zkEvmGasToPass, zkEvmGasUsed), GAS_DIVISOR()) + } + } + + function capGasForCall(evmGasLeft, oldGasToPass) -> gasToPass { + let maxGasToPass := sub(evmGasLeft, shr(6, evmGasLeft)) // evmGasLeft >> 6 == evmGasLeft/64 + gasToPass := oldGasToPass + if gt(oldGasToPass, maxGasToPass) { + gasToPass := maxGasToPass + } + } + + // The gas cost mentioned here is purely the cost of the contract, + // and does not consider the cost of the call itself nor the instructions + // to put the parameters in memory. + function getGasForPrecompiles(addr, argsSize) -> gasToCharge { + switch addr + case 0x01 { // ecRecover + gasToCharge := 3000 + } + case 0x02 { // SHA2-256 + let dataWordSize := shr(5, add(argsSize, 31)) // (argsSize+31)/32 + gasToCharge := add(60, mul(12, dataWordSize)) + } + case 0x03 { // RIPEMD-160 + // We do not support RIPEMD-160 + gasToCharge := 0 + } + case 0x04 { // identity + let dataWordSize := shr(5, add(argsSize, 31)) // (argsSize+31)/32 + gasToCharge := add(15, mul(3, dataWordSize)) + } + case 0x05 { // modexp + // We do not support modexp + gasToCharge := 0 + } + // ecAdd ecMul ecPairing EIP below + // https://eips.ethereum.org/EIPS/eip-1108 + case 0x06 { // ecAdd + // The gas cost is fixed at 150. However, if the input + // does not allow to compute a valid result, all the gas sent is consumed. + gasToCharge := 150 + } + case 0x07 { // ecMul + // The gas cost is fixed at 6000. However, if the input + // does not allow to compute a valid result, all the gas sent is consumed. + gasToCharge := 6000 + } + // 34,000 * k + 45,000 gas, where k is the number of pairings being computed. + // The input must always be a multiple of 6 32-byte values. + case 0x08 { // ecPairing + let k := div(argsSize, 0xC0) // 0xC0 == 6*32 + gasToCharge := add(45000, mul(k, 34000)) + } + case 0x09 { // blake2f + // We do not support blake2f + gasToCharge := 0 + } + case 0x0a { // kzg point evaluation + // We do not support kzg point evaluation + gasToCharge := 0 + } + default { + gasToCharge := 0 + } + } + + function _saveReturndataAfterZkEVMCall() { + loadReturndataIntoActivePtr() + mstore(LAST_RETURNDATA_SIZE_OFFSET(), returndatasize()) + } + + function _saveReturndataAfterEVMCall(_outputOffset, _outputLen) -> _gasLeft { + let rtsz := returndatasize() + loadReturndataIntoActivePtr() + + // if (rtsz > 31) + switch gt(rtsz, 31) + case 0 { + // Unexpected return data. + // Most likely out-of-ergs or unexpected error in the emulator or system contracts + abortEvmEnvironment() + } + default { + returndatacopy(0, 0, 32) + _gasLeft := mload(0) + + // We copy as much returndata as possible without going over the + // returndata size. + switch lt(sub(rtsz, 32), _outputLen) + case 0 { returndatacopy(_outputOffset, 32, _outputLen) } + default { returndatacopy(_outputOffset, 32, sub(rtsz, 32)) } + + mstore(LAST_RETURNDATA_SIZE_OFFSET(), sub(rtsz, 32)) + + // Skip the returnData + ptrAddIntoActive(32) + } + } + + function _eraseReturndataPointer() { + let activePtrSize := getActivePtrDataSize() + ptrShrinkIntoActive(and(activePtrSize, 0xFFFFFFFF))// uint32(activePtrSize) + mstore(LAST_RETURNDATA_SIZE_OFFSET(), 0) + } + + //////////////////////////////////////////////////////////////// + // CREATE FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function performCreate(oldEvmGasLeft, oldSp, oldStackHead) -> evmGasLeft, sp, stackHead { + let value, offset, size + + popStackCheck(oldSp, 3) + value, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + offset, sp, size := popStackItemWithoutCheck(sp, stackHead) + + evmGasLeft, stackHead := $llvm_NoInline_llvm$_genericCreate(offset, size, value, oldEvmGasLeft, false, 0) + } + + function performCreate2(oldEvmGasLeft, oldSp, oldStackHead) -> evmGasLeft, sp, stackHead { + let value, offset, size, salt + + popStackCheck(oldSp, 4) + value, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, salt := popStackItemWithoutCheck(sp, stackHead) + + evmGasLeft, stackHead := $llvm_NoInline_llvm$_genericCreate(offset, size, value, oldEvmGasLeft, true, salt) + } + + function $llvm_NoInline_llvm$_genericCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) -> evmGasLeft, addr { + checkMemIsAccessible(offset, size) + + // EIP-3860 + if gt(size, MAX_POSSIBLE_INIT_BYTECODE_LEN()) { + panic() + } + + // dynamicGas = init_code_cost + memory_expansion_cost + deployment_code_execution_cost + code_deposit_cost + // + hash_cost, if isCreate2 + // minimum_word_size = (size + 31) / 32 + // init_code_cost = 2 * minimum_word_size, EIP-3860 + // code_deposit_cost = 200 * deployed_code_size, (charged inside call) + let minimum_word_size := div(add(size, 31), 32) // rounding up + let dynamicGas := add( + mul(2, minimum_word_size), + expandMemory(offset, size) + ) + if isCreate2 { + // hash_cost = 6 * minimum_word_size + dynamicGas := add(dynamicGas, mul(6, minimum_word_size)) + } + evmGasLeft := chargeGas(evmGasLeftOld, dynamicGas) + + _eraseReturndataPointer() + + let err := insufficientBalance(value) + + if iszero(err) { + offset := add(MEM_OFFSET(), offset) // caller must ensure that it doesn't overflow + evmGasLeft, addr := _executeCreate(offset, size, value, evmGasLeft, isCreate2, salt) + } + } + + function _executeCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) -> evmGasLeft, addr { + let gasForTheCall := capGasForCall(evmGasLeftOld, evmGasLeftOld) // pass 63/64 of remaining gas + + let bytecodeHash + if isCreate2 { + switch size + case 0 { + bytecodeHash := EMPTY_KECCAK() + } + default { + bytecodeHash := keccak256(offset, size) + } + } + + // we want to calculate the address of new contract, and if it is deployable (no collision), + // we need to increment deploy nonce. + + // selector: function precreateEvmAccountFromEmulator(bytes32 salt, bytes32 evmBytecodeHash) + mstore(0, 0xf81dae8600000000000000000000000000000000000000000000000000000000) + mstore(4, salt) + mstore(36, bytecodeHash) + let canBeDeployed := performSystemCallRevertable(DEPLOYER_SYSTEM_CONTRACT(), 68) + + if canBeDeployed { + returndatacopy(0, 0, 32) + addr := mload(0) + + pop($llvm_AlwaysInline_llvm$_warmAddress(addr)) // will stay warm even if constructor reverts + // so even if constructor reverts, nonce stays incremented and addr stays warm + + // check for code collision + canBeDeployed := 0 + if iszero(getRawCodeHash(addr)) { + // check for nonce collision + if iszero(getRawNonce(addr)) { + canBeDeployed := 1 + } + } + } + + if iszero(canBeDeployed) { + // Nonce overflow, EVM not allowed or collision. + // This is *internal* panic, consuming all passed gas. + // Note: we should not consume all gas if nonce overflowed, but this should not happen in reality anyway + evmGasLeft := chargeGas(evmGasLeftOld, gasForTheCall) + addr := 0 + } + + + if canBeDeployed { + // verification of the correctness of the deployed bytecode and payment of gas for its storage will occur in the frame of the new contract + pushEvmFrame(gasForTheCall, false) + + // move needed memory slots to the scratch space + mstore(mul(10, 32), mload(sub(offset, 0x80)) + mstore(mul(11, 32), mload(sub(offset, 0x60)) + mstore(mul(12, 32), mload(sub(offset, 0x40)) + mstore(mul(13, 32), mload(sub(offset, 0x20)) + + // selector: function createEvmFromEmulator(address newAddress, bytes calldata _initCode) + mstore(sub(offset, 0x80), 0xe43cec64) + mstore(sub(offset, 0x60), addr) + mstore(sub(offset, 0x40), 0x40) // Where the arg starts (third word) + mstore(sub(offset, 0x20), size) // Length of the init code + + let result := performSystemCallForCreate(value, sub(offset, 0x64), add(size, 0x64)) + + // move memory slots back + mstore(sub(offset, 0x80), mload(mul(10, 32)) + mstore(sub(offset, 0x60), mload(mul(11, 32)) + mstore(sub(offset, 0x40), mload(mul(12, 32)) + mstore(sub(offset, 0x20), mload(mul(13, 32)) + + let gasLeft + switch result + case 0 { + addr := 0 + gasLeft := _saveReturndataAfterEVMCall(0, 0) + resetEvmFrame() + } + default { + gasLeft, addr := _saveConstructorReturnGas() + } + + let gasUsed := sub(gasForTheCall, gasLeft) + evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) + } + } + + function performSystemCallForCreate(value, bytecodeStart, bytecodeLen) -> success { + // system call, not constructor call (ContractDeployer will call constructor) + let farCallAbi := build_farcall_abi(1, gas(), bytecodeStart, bytecodeLen) + + switch iszero(value) + case 0 { + success := verbatim_6i_1o("system_call", MSG_VALUE_SYSTEM_CONTRACT(), farCallAbi, value, DEPLOYER_SYSTEM_CONTRACT(), 1, 0) + } + default { + success := verbatim_6i_1o("system_call", DEPLOYER_SYSTEM_CONTRACT(), farCallAbi, 0, 0, 0, 0) + } + } + + function _saveConstructorReturnGas() -> gasLeft, addr { + loadReturndataIntoActivePtr() + + if lt(returndatasize(), 64) { + // unexpected return data after constructor succeeded, should never happen. + abortEvmEnvironment() + } + + // ContractDeployer returns (uint256 gasLeft, address createdContract) + returndatacopy(0, 0, 64) + gasLeft := mload(0) + addr := mload(32) + + _eraseReturndataPointer() + } + + //////////////////////////////////////////////////////////////// + // EXTCODECOPY FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function $llvm_AlwaysInline_llvm$_copyRest(dest, val, len) { + let rest_bits := shl(3, len) + let upper_bits := sub(256, rest_bits) + let val_mask := shl(upper_bits, MAX_UINT()) + let val_masked := and(val, val_mask) + let dst_val := mload(dest) + let dst_mask := shr(rest_bits, MAX_UINT()) + let dst_masked := and(dst_val, dst_mask) + mstore(dest, or(val_masked, dst_masked)) + } + + function $llvm_AlwaysInline_llvm$_memcpy(dest, src, len) { + let dest_addr := dest + let src_addr := src + let dest_end := add(dest, and(len, sub(0, 32))) + for { } lt(dest_addr, dest_end) {} { + mstore(dest_addr, mload(src_addr)) + dest_addr := add(dest_addr, 32) + src_addr := add(src_addr, 32) + } + + let rest_len := and(len, 31) + if rest_len { + $llvm_AlwaysInline_llvm$_copyRest(dest_addr, mload(src_addr), rest_len) + } + } + + function $llvm_AlwaysInline_llvm$_memsetToZero(dest,len) { + let dest_end := add(dest, and(len, sub(0, 32))) + for {let i := dest} lt(i, dest_end) { i := add(i, 32) } { + mstore(i, 0) + } + + let rest_len := and(len, 31) + if rest_len { + $llvm_AlwaysInline_llvm$_copyRest(dest_end, 0, rest_len) + } + } + + //////////////////////////////////////////////////////////////// + // LOGS FUNCTIONALITY + //////////////////////////////////////////////////////////////// + + function _genericLog(sp, stackHead, evmGasLeft, topicCount, isStatic) -> newEvmGasLeft, offset, size, newSp, newStackHead { + newEvmGasLeft := chargeGas(evmGasLeft, 375) + + if isStatic { + panic() + } + + let rawOffset + popStackCheck(sp, add(2, topicCount)) + rawOffset, newSp, newStackHead := popStackItemWithoutCheck(sp, stackHead) + size, newSp, newStackHead := popStackItemWithoutCheck(newSp, newStackHead) + + checkMemIsAccessible(rawOffset, size) + + // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost + let dynamicGas := add(shl(3, size), expandMemory(rawOffset, size)) + dynamicGas := add(dynamicGas, mul(375, topicCount)) + + newEvmGasLeft := chargeGas(newEvmGasLeft, dynamicGas) + + if size { + offset := add(rawOffset, MEM_OFFSET()) + } + } + + function $llvm_NoInline_llvm$_simulate( + isCallerEVM, + evmGasLeft, + isStatic, + ) -> returnOffset, returnLen { + + returnOffset := MEM_OFFSET() + returnLen := 0 + + // stack pointer - index to first stack element; empty stack = -1 + let sp := sub(STACK_OFFSET(), 32) + // instruction pointer - index to next instruction. Not called pc because it's an + // actual yul/evm instruction. + let ip := BYTECODE_OFFSET() + let stackHead + + let bytecodeEndOffset := add(BYTECODE_OFFSET(), mload(BYTECODE_LEN_OFFSET())) + + for { } true { } { + let opcode := readIP(ip, bytecodeEndOffset) + + switch opcode + case 0x00 { // OP_STOP + break + } + case 0x01 { // OP_ADD + evmGasLeft := chargeGas(evmGasLeft, 3) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := add(a, stackHead) + + ip := add(ip, 1) + } + case 0x02 { // OP_MUL + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := mul(a, stackHead) + ip := add(ip, 1) + } + case 0x03 { // OP_SUB + evmGasLeft := chargeGas(evmGasLeft, 3) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := sub(a, stackHead) + + ip := add(ip, 1) + } + case 0x04 { // OP_DIV + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := div(a, stackHead) + + ip := add(ip, 1) + } + case 0x05 { // OP_SDIV + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := sdiv(a, stackHead) + + ip := add(ip, 1) + } + case 0x06 { // OP_MOD + evmGasLeft := chargeGas(evmGasLeft, 5) + + let a + popStackCheck(sp, 2) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := mod(a, stackHead) + + ip := add(ip, 1) + } + case 0x07 { // OP_SMOD + evmGasLeft := chargeGas(evmGasLeft, 5) + + let a + popStackCheck(sp, 2) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := smod(a, stackHead) + + ip := add(ip, 1) + } + case 0x08 { // OP_ADDMOD + evmGasLeft := chargeGas(evmGasLeft, 8) + + let a, b, N + + popStackCheck(sp, 3) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, N := popStackItemWithoutCheck(sp, stackHead) + stackHead := addmod(a, b, N) + + ip := add(ip, 1) + } + case 0x09 { // OP_MULMOD + evmGasLeft := chargeGas(evmGasLeft, 8) + + let a, b, N + + popStackCheck(sp, 3) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, N := popStackItemWithoutCheck(sp, stackHead) + + stackHead := mulmod(a, b, N) + ip := add(ip, 1) + } + case 0x0A { // OP_EXP + evmGasLeft := chargeGas(evmGasLeft, 10) + + let a, exponent + + popStackCheck(sp, 2) + a, sp, exponent := popStackItemWithoutCheck(sp, stackHead) + + let to_charge := 0 + let exponentCopy := exponent + for {} gt(exponentCopy, 0) {} { // while exponent > 0 + to_charge := add(to_charge, 50) + exponentCopy := shr(8, exponentCopy) + } + evmGasLeft := chargeGas(evmGasLeft, to_charge) + + stackHead := exp(a, exponent) + + ip := add(ip, 1) + } + case 0x0B { // OP_SIGNEXTEND + evmGasLeft := chargeGas(evmGasLeft, 5) + + let b, x + + popStackCheck(sp, 2) + b, sp, x := popStackItemWithoutCheck(sp, stackHead) + stackHead := signextend(b, x) + + ip := add(ip, 1) + } + case 0x10 { // OP_LT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := lt(a, b) + + ip := add(ip, 1) + } + case 0x11 { // OP_GT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead:= gt(a, b) + + ip := add(ip, 1) + } + case 0x12 { // OP_SLT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := slt(a, b) + + ip := add(ip, 1) + } + case 0x13 { // OP_SGT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := sgt(a, b) + + ip := add(ip, 1) + } + case 0x14 { // OP_EQ + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := eq(a, b) + + ip := add(ip, 1) + } + case 0x15 { // OP_ISZERO + evmGasLeft := chargeGas(evmGasLeft, 3) + + stackHead := iszero(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x16 { // OP_AND + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := and(a,b) + + ip := add(ip, 1) + } + case 0x17 { // OP_OR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := or(a,b) + + ip := add(ip, 1) + } + case 0x18 { // OP_XOR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := xor(a, b) + + ip := add(ip, 1) + } + case 0x19 { // OP_NOT + evmGasLeft := chargeGas(evmGasLeft, 3) + + stackHead := not(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x1A { // OP_BYTE + evmGasLeft := chargeGas(evmGasLeft, 3) + + let i, x + popStackCheck(sp, 2) + i, sp, x := popStackItemWithoutCheck(sp, stackHead) + stackHead := byte(i, x) + + ip := add(ip, 1) + } + case 0x1B { // OP_SHL + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := shl(shift, value) + + ip := add(ip, 1) + } + case 0x1C { // OP_SHR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := shr(shift, value) + + ip := add(ip, 1) + } + case 0x1D { // OP_SAR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := sar(shift, value) + + ip := add(ip, 1) + } + case 0x20 { // OP_KECCAK256 + evmGasLeft := chargeGas(evmGasLeft, 30) + + let rawOffset, size + + popStackCheck(sp, 2) + rawOffset, sp, size := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(rawOffset, size) + + // When an offset is first accessed (either read or write), memory may trigger + // an expansion, which costs gas. + // dynamicGas = 6 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(6, shr(5, add(size, 31))), expandMemory(rawOffset, size)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + let offset + if size { + // use 0 as offset if size is 0 + offset := add(MEM_OFFSET(), rawOffset) + } + + stackHead := keccak256(offset, size) + + ip := add(ip, 1) + } + case 0x30 { // OP_ADDRESS + evmGasLeft := chargeGas(evmGasLeft, 2) + sp, stackHead := pushStackItem(sp, address(), stackHead) + ip := add(ip, 1) + } + case 0x31 { // OP_BALANCE + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + stackHead := balance(addr) + + ip := add(ip, 1) + } + case 0x32 { // OP_ORIGIN + evmGasLeft := chargeGas(evmGasLeft, 2) + let _origin := mload(ORIGIN_CACHE_OFFSET()) + if iszero(_origin) { + _origin := cached(ORIGIN_CACHE_OFFSET(), origin()) + } + sp, stackHead := pushStackItem(sp, _origin, stackHead) + ip := add(ip, 1) + } + case 0x33 { // OP_CALLER + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, caller(), stackHead) + ip := add(ip, 1) + } + case 0x34 { // OP_CALLVALUE + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, callvalue(), stackHead) + ip := add(ip, 1) + } + case 0x35 { // OP_CALLDATALOAD + evmGasLeft := chargeGas(evmGasLeft, 3) + + let calldataOffset := accessStackHead(sp, stackHead) + + stackHead := $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) + + ip := add(ip, 1) + } + case 0x36 { // OP_CALLDATASIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, $llvm_AlwaysInline_llvm$_calldatasize(), stackHead) + ip := add(ip, 1) + } + case 0x37 { // OP_CALLDATACOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + // EraVM will revert if offset + length overflows uint32 + if gt(sourceOffset, UINT32_MAX()) { + sourceOffset := UINT32_MAX() + } + + // Check bytecode out-of-bounds access + let truncatedLen := len + if gt(add(sourceOffset, len), UINT32_MAX()) { + truncatedLen := sub(UINT32_MAX(), sourceOffset) // truncate + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds + } + + if truncatedLen { + $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) + } + + ip := add(ip, 1) + + } + case 0x38 { // OP_CODESIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let bytecodeLen := mload(BYTECODE_LEN_OFFSET()) + sp, stackHead := pushStackItem(sp, bytecodeLen, stackHead) + ip := add(ip, 1) + } + case 0x39 { // OP_CODECOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + if gt(sourceOffset, MAX_UINT64()) { + sourceOffset := MAX_UINT64() + } + + sourceOffset := add(sourceOffset, BYTECODE_OFFSET()) + + if gt(sourceOffset, bytecodeEndOffset) { + sourceOffset := bytecodeEndOffset + } + + // Check bytecode out-of-bounds access + let truncatedLen := len + if gt(add(sourceOffset, len), bytecodeEndOffset) { + truncatedLen := sub(bytecodeEndOffset, sourceOffset) // truncate + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds + } + + if truncatedLen { + $llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, truncatedLen) + } + + ip := add(ip, 1) + } + case 0x3A { // OP_GASPRICE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _gasprice := mload(GASPRICE_CACHE_OFFSET()) + if iszero(_gasprice) { + _gasprice := cached(GASPRICE_CACHE_OFFSET(), gasprice()) + } + sp, stackHead := pushStackItem(sp, _gasprice, stackHead) + ip := add(ip, 1) + } + case 0x3B { // OP_EXTCODESIZE + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + let rawCodeHash := getRawCodeHash(addr) + switch shr(248, rawCodeHash) + case 1 { + stackHead := extcodesize(addr) + } + case 2 { + stackHead := and(shr(224, rawCodeHash), 0xffff) + } + default { + stackHead := 0 + } + + ip := add(ip, 1) + } + case 0x3C { // OP_EXTCODECOPY + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr, dstOffset, srcOffset, len + popStackCheck(sp, 4) + addr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + srcOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + address_access_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add( + mul(3, shr(5, add(len, 31))), + expandMemory(dstOffset, len) + ) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + dynamicGas := add(dynamicGas, 2500) + } + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + if gt(srcOffset, MAX_UINT64()) { + srcOffset := MAX_UINT64() + } + + if gt(len, 0) { + // Gets the code from the addr + let copiedLen := fetchDeployedCode(addr, dstOffset, srcOffset, len) + + if lt(copiedLen, len) { + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, copiedLen), sub(len, copiedLen)) + } + } + + ip := add(ip, 1) + } + case 0x3D { // OP_RETURNDATASIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let rdz := mload(LAST_RETURNDATA_SIZE_OFFSET()) + sp, stackHead := pushStackItem(sp, rdz, stackHead) + ip := add(ip, 1) + } + case 0x3E { // OP_RETURNDATACOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // minimum_word_size = (size + 31) / 32 + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + checkOverflow(sourceOffset, len) + + // Check returndata out-of-bounds error + if gt(add(sourceOffset, len), mload(LAST_RETURNDATA_SIZE_OFFSET())) { + panic() + } + + copyActivePtrData(add(MEM_OFFSET(), dstOffset), sourceOffset, len) + ip := add(ip, 1) + } + case 0x3F { // OP_EXTCODEHASH + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + let codeLen := and(shr(224, rawCodeHash), 0xffff) + + if codeLen { + if lt(addr, 0x100) { + // precompiles and 0x00 + codeLen := 0 + } + } + + switch codeLen + case 0 { + stackHead := EMPTY_KECCAK() + + if iszero(getRawNonce(addr)) { + if iszero(balance(addr)) { + stackHead := 0 + } + } + } + default { + // zkVM contract + stackHead := rawCodeHash + } + } + default { + // Get precalculated keccak of EVM code + stackHead := getEvmExtcodehash(addr) + } + + ip := add(ip, 1) + } + case 0x40 { // OP_BLOCKHASH + evmGasLeft := chargeGas(evmGasLeft, 20) + + stackHead := blockhash(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x41 { // OP_COINBASE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _coinbase := mload(COINBASE_CACHE_OFFSET()) + if iszero(_coinbase) { + _coinbase := cached(COINBASE_CACHE_OFFSET(), coinbase()) + } + sp, stackHead := pushStackItem(sp, _coinbase, stackHead) + ip := add(ip, 1) + } + case 0x42 { // OP_TIMESTAMP + evmGasLeft := chargeGas(evmGasLeft, 2) + let _blocktimestamp := mload(BLOCKTIMESTAMP_CACHE_OFFSET()) + if iszero(_blocktimestamp) { + _blocktimestamp := cached(BLOCKTIMESTAMP_CACHE_OFFSET(), timestamp()) + } + sp, stackHead := pushStackItem(sp, _blocktimestamp, stackHead) + ip := add(ip, 1) + } + case 0x43 { // OP_NUMBER + evmGasLeft := chargeGas(evmGasLeft, 2) + let _blocknumber := mload(BLOCKNUMBER_CACHE_OFFSET()) + if iszero(_blocknumber) { + _blocknumber := cached(BLOCKNUMBER_CACHE_OFFSET(), number()) + } + sp, stackHead := pushStackItem(sp, _blocknumber, stackHead) + ip := add(ip, 1) + } + case 0x44 { // OP_PREVRANDAO + evmGasLeft := chargeGas(evmGasLeft, 2) + let _prevrandao := mload(PREVRANDAO_CACHE_OFFSET()) + if iszero(_prevrandao) { + _prevrandao := cached(PREVRANDAO_CACHE_OFFSET(), prevrandao()) + } + sp, stackHead := pushStackItem(sp, _prevrandao, stackHead) + ip := add(ip, 1) + } + case 0x45 { // OP_GASLIMIT + evmGasLeft := chargeGas(evmGasLeft, 2) + let _gasLimit := mload(GASLIMIT_CACHE_OFFSET()) + if iszero(_gasLimit) { + _gasLimit := cached(GASLIMIT_CACHE_OFFSET(), gaslimit()) + } + sp, stackHead := pushStackItem(sp, _gasLimit, stackHead) + ip := add(ip, 1) + } + case 0x46 { // OP_CHAINID + evmGasLeft := chargeGas(evmGasLeft, 2) + let _chainId := mload(CHAINID_CACHE_OFFSET()) + if iszero(_chainId) { + _chainId := cached(CHAINID_CACHE_OFFSET(), chainid()) + } + sp, stackHead := pushStackItem(sp, _chainId, stackHead) + ip := add(ip, 1) + } + case 0x47 { // OP_SELFBALANCE + evmGasLeft := chargeGas(evmGasLeft, 5) + sp, stackHead := pushStackItem(sp, selfbalance(), stackHead) + ip := add(ip, 1) + } + case 0x48 { // OP_BASEFEE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _baseFee := mload(BASEFEE_CACHE_OFFSET()) + if iszero(_baseFee) { + _baseFee := cached(BASEFEE_CACHE_OFFSET(), basefee()) + } + sp, stackHead := pushStackItem(sp, _baseFee, stackHead) + ip := add(ip, 1) + } + case 0x50 { // OP_POP + evmGasLeft := chargeGas(evmGasLeft, 2) + + let _y + + _y, sp, stackHead := popStackItem(sp, stackHead) + ip := add(ip, 1) + } + case 0x51 { // OP_MLOAD + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset := accessStackHead(sp, stackHead) + + checkMemIsAccessible(offset, 32) + let expansionGas := expandMemory(offset, 32) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + stackHead := mload(add(MEM_OFFSET(), offset)) + + ip := add(ip, 1) + } + case 0x52 { // OP_MSTORE + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset, value + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, 32) + let expansionGas := expandMemory(offset, 32) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + mstore(add(MEM_OFFSET(), offset), value) + ip := add(ip, 1) + } + case 0x53 { // OP_MSTORE8 + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset, value + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, 1) + let expansionGas := expandMemory(offset, 1) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + mstore8(add(MEM_OFFSET(), offset), value) + ip := add(ip, 1) + } + case 0x54 { // OP_SLOAD + evmGasLeft := chargeGas(evmGasLeft, 100) + + let key := accessStackHead(sp, stackHead) + let wasWarm := isSlotWarm(key) + + if iszero(wasWarm) { + evmGasLeft := chargeGas(evmGasLeft, 2000) + } + + let value := sload(key) + + if iszero(wasWarm) { + let _wasW, _orgV := warmSlot(key, value) + } + + stackHead := value + ip := add(ip, 1) + } + case 0x55 { // OP_SSTORE + if isStatic { + panic() + } + + if lt(evmGasLeft, 2301) { // if <= 2300 + panic() + } + + let key, value + + popStackCheck(sp, 2) + key, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + ip := add(ip, 1) + + let dynamicGas := 100 + // Here it is okay to read before we charge since we known anyway that + // the context has enough funds to compensate at least for the read. + let currentValue := sload(key) + let wasWarm, originalValue := warmSlot(key, currentValue) + + if iszero(wasWarm) { + dynamicGas := add(dynamicGas, 2100) + } + + if eq(value, currentValue) { // no-op + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + continue + } + + if eq(originalValue, currentValue) { + switch originalValue + case 0 { + dynamicGas := add(dynamicGas, 19900) + } + default { + dynamicGas := add(dynamicGas, 2800) + } + } + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + sstore(key, value) + } + // NOTE: We don't currently do full jumpdest validation + // (i.e. validating a jumpdest isn't in PUSH data) + case 0x56 { // OP_JUMP + evmGasLeft := chargeGas(evmGasLeft, 9) // charge for OP_JUMP (8) and OP_JUMPDEST (1) immediately + + let counter + counter, sp, stackHead := popStackItem(sp, stackHead) + + // Counter certainly can't be bigger than uint64. + if gt(counter, MAX_UINT64()) { + panic() + } + + ip := add(BYTECODE_OFFSET(), counter) + + // Check next opcode is JUMPDEST + let nextOpcode := readIP(ip, bytecodeEndOffset) + if iszero(eq(nextOpcode, 0x5B)) { + panic() + } + + // execute JUMPDEST immediately + ip := add(ip, 1) + } + case 0x57 { // OP_JUMPI + evmGasLeft := chargeGas(evmGasLeft, 10) + + let counter, b + + popStackCheck(sp, 2) + counter, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + if iszero(b) { + ip := add(ip, 1) + continue + } + + // Counter certainly can't be bigger than uint64. + if gt(counter, MAX_UINT64()) { + panic() + } + + ip := add(BYTECODE_OFFSET(), counter) + + // Check next opcode is JUMPDEST + let nextOpcode := readIP(ip, bytecodeEndOffset) + if iszero(eq(nextOpcode, 0x5B)) { + panic() + } + + // execute JUMPDEST immediately + evmGasLeft := chargeGas(evmGasLeft, 1) + ip := add(ip, 1) + } + case 0x58 { // OP_PC + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, sub(ip, BYTECODE_OFFSET()), stackHead) + + ip := add(ip, 1) + } + case 0x59 { // OP_MSIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let size + + size := mload(MEM_LEN_OFFSET()) + size := shl(5, size) + sp, stackHead := pushStackItem(sp, size, stackHead) + ip := add(ip, 1) + } + case 0x5A { // OP_GAS + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, evmGasLeft, stackHead) + ip := add(ip, 1) + } + case 0x5B { // OP_JUMPDEST + evmGasLeft := chargeGas(evmGasLeft, 1) + ip := add(ip, 1) + } + case 0x5C { // OP_TLOAD + evmGasLeft := chargeGas(evmGasLeft, 100) + + stackHead := tload(accessStackHead(sp, stackHead)) + ip := add(ip, 1) + } + case 0x5D { // OP_TSTORE + evmGasLeft := chargeGas(evmGasLeft, 100) + + if isStatic { + panic() + } + + let key, value + popStackCheck(sp, 2) + key, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + tstore(key, value) + ip := add(ip, 1) + } + case 0x5E { // OP_MCOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let destOffset, offset, size + popStackCheck(sp, 3) + destOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, size) + checkMemIsAccessible(destOffset, size) + + // dynamic_gas = 3 * words_copied + memory_expansion_cost + let dynamicGas := expandMemory2(offset, size, destOffset, size) + let wordsCopied := div(add(size, 31), 32) // div rounding up + dynamicGas := add(dynamicGas, mul(3, wordsCopied)) + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + mcopy(add(destOffset, MEM_OFFSET()), add(offset, MEM_OFFSET()), size) + ip := add(ip, 1) + } + case 0x5F { // OP_PUSH0 + evmGasLeft := chargeGas(evmGasLeft, 2) + + let value := 0 + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 1) + } + case 0x60 { // OP_PUSH1 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 1) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 1) + } + case 0x61 { // OP_PUSH2 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 2) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 2) + } + case 0x62 { // OP_PUSH3 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 3) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 3) + } + case 0x63 { // OP_PUSH4 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 4) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 4) + } + case 0x64 { // OP_PUSH5 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 5) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 5) + } + case 0x65 { // OP_PUSH6 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 6) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 6) + } + case 0x66 { // OP_PUSH7 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 7) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 7) + } + case 0x67 { // OP_PUSH8 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 8) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 8) + } + case 0x68 { // OP_PUSH9 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 9) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 9) + } + case 0x69 { // OP_PUSH10 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 10) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 10) + } + case 0x6A { // OP_PUSH11 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 11) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 11) + } + case 0x6B { // OP_PUSH12 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 12) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 12) + } + case 0x6C { // OP_PUSH13 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 13) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 13) + } + case 0x6D { // OP_PUSH14 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 14) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 14) + } + case 0x6E { // OP_PUSH15 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 15) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 15) + } + case 0x6F { // OP_PUSH16 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 16) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 16) + } + case 0x70 { // OP_PUSH17 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 17) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 17) + } + case 0x71 { // OP_PUSH18 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 18) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 18) + } + case 0x72 { // OP_PUSH19 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 19) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 19) + } + case 0x73 { // OP_PUSH20 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 20) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 20) + } + case 0x74 { // OP_PUSH21 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 21) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 21) + } + case 0x75 { // OP_PUSH22 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 22) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 22) + } + case 0x76 { // OP_PUSH23 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 23) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 23) + } + case 0x77 { // OP_PUSH24 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 24) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 24) + } + case 0x78 { // OP_PUSH25 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 25) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 25) + } + case 0x79 { // OP_PUSH26 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 26) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 26) + } + case 0x7A { // OP_PUSH27 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 27) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 27) + } + case 0x7B { // OP_PUSH28 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 28) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 28) + } + case 0x7C { // OP_PUSH29 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 29) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 29) + } + case 0x7D { // OP_PUSH30 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 30) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 30) + } + case 0x7E { // OP_PUSH31 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 31) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 31) + } + case 0x7F { // OP_PUSH32 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 32) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 32) + } + case 0x80 { // OP_DUP1 + evmGasLeft := chargeGas(evmGasLeft, 3) + sp, stackHead := pushStackItem(sp, accessStackHead(sp, stackHead), stackHead) + ip := add(ip, 1) + } + case 0x81 { // OP_DUP2 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 2, stackHead) + ip := add(ip, 1) + } + case 0x82 { // OP_DUP3 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 3, stackHead) + ip := add(ip, 1) + } + case 0x83 { // OP_DUP4 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 4, stackHead) + ip := add(ip, 1) + } + case 0x84 { // OP_DUP5 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 5, stackHead) + ip := add(ip, 1) + } + case 0x85 { // OP_DUP6 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 6, stackHead) + ip := add(ip, 1) + } + case 0x86 { // OP_DUP7 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 7, stackHead) + ip := add(ip, 1) + } + case 0x87 { // OP_DUP8 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 8, stackHead) + ip := add(ip, 1) + } + case 0x88 { // OP_DUP9 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 9, stackHead) + ip := add(ip, 1) + } + case 0x89 { // OP_DUP10 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 10, stackHead) + ip := add(ip, 1) + } + case 0x8A { // OP_DUP11 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 11, stackHead) + ip := add(ip, 1) + } + case 0x8B { // OP_DUP12 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 12, stackHead) + ip := add(ip, 1) + } + case 0x8C { // OP_DUP13 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 13, stackHead) + ip := add(ip, 1) + } + case 0x8D { // OP_DUP14 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 14, stackHead) + ip := add(ip, 1) + } + case 0x8E { // OP_DUP15 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 15, stackHead) + ip := add(ip, 1) + } + case 0x8F { // OP_DUP16 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 16, stackHead) + ip := add(ip, 1) + } + case 0x90 { // OP_SWAP1 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 1, stackHead) + ip := add(ip, 1) + } + case 0x91 { // OP_SWAP2 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 2, stackHead) + ip := add(ip, 1) + } + case 0x92 { // OP_SWAP3 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 3, stackHead) + ip := add(ip, 1) + } + case 0x93 { // OP_SWAP4 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 4, stackHead) + ip := add(ip, 1) + } + case 0x94 { // OP_SWAP5 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 5, stackHead) + ip := add(ip, 1) + } + case 0x95 { // OP_SWAP6 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 6, stackHead) + ip := add(ip, 1) + } + case 0x96 { // OP_SWAP7 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 7, stackHead) + ip := add(ip, 1) + } + case 0x97 { // OP_SWAP8 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 8, stackHead) + ip := add(ip, 1) + } + case 0x98 { // OP_SWAP9 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 9, stackHead) + ip := add(ip, 1) + } + case 0x99 { // OP_SWAP10 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 10, stackHead) + ip := add(ip, 1) + } + case 0x9A { // OP_SWAP11 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 11, stackHead) + ip := add(ip, 1) + } + case 0x9B { // OP_SWAP12 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 12, stackHead) + ip := add(ip, 1) + } + case 0x9C { // OP_SWAP13 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 13, stackHead) + ip := add(ip, 1) + } + case 0x9D { // OP_SWAP14 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 14, stackHead) + ip := add(ip, 1) + } + case 0x9E { // OP_SWAP15 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 15, stackHead) + ip := add(ip, 1) + } + case 0x9F { // OP_SWAP16 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 16, stackHead) + ip := add(ip, 1) + } + case 0xA0 { // OP_LOG0 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 0, isStatic) + log0(offset, size) + ip := add(ip, 1) + } + case 0xA1 { // OP_LOG1 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 1, isStatic) + { + let topic1 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log1(offset, size, topic1) + } + ip := add(ip, 1) + } + case 0xA2 { // OP_LOG2 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 2, isStatic) + + { + let topic1, topic2 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log2(offset, size, topic1, topic2) + } + ip := add(ip, 1) + } + case 0xA3 { // OP_LOG3 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 3, isStatic) + + { + let topic1, topic2, topic3 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log3(offset, size, topic1, topic2, topic3) + } + ip := add(ip, 1) + } + case 0xA4 { // OP_LOG4 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 4, isStatic) + + { + let topic1, topic2, topic3, topic4 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic4, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log4(offset, size, topic1, topic2, topic3, topic4) + } + ip := add(ip, 1) + } + case 0xF0 { // OP_CREATE + evmGasLeft := chargeGas(evmGasLeft, 32000) + + if isStatic { + panic() + } + + evmGasLeft, sp, stackHead := performCreate(evmGasLeft, sp, stackHead) + ip := add(ip, 1) + } + case 0xF1 { // OP_CALL + // A function was implemented in order to avoid stack depth errors. + evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead, isStatic) + ip := add(ip, 1) + } + case 0xF3 { // OP_RETURN + let offset, size + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + if size { + checkMemIsAccessible(offset, size) + + evmGasLeft := chargeGas(evmGasLeft, expandMemory(offset, size)) + + returnLen := size + + // Don't check overflow here since previous checks are enough to ensure this is safe + returnOffset := add(MEM_OFFSET(), offset) + } + + break + } + case 0xF4 { // OP_DELEGATECALL + evmGasLeft, sp, stackHead := performDelegateCall(sp, evmGasLeft, isStatic, stackHead) + ip := add(ip, 1) + } + case 0xF5 { // OP_CREATE2 + evmGasLeft := chargeGas(evmGasLeft, 32000) + + if isStatic { + panic() + } + + evmGasLeft, sp, stackHead := performCreate2(evmGasLeft, sp, stackHead) + ip := add(ip, 1) + } + case 0xFA { // OP_STATICCALL + evmGasLeft, sp, stackHead := performStaticCall(sp, evmGasLeft, stackHead) + ip := add(ip, 1) + } + case 0xFD { // OP_REVERT + let offset,size + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + switch iszero(size) + case 0 { + checkMemIsAccessible(offset, size) + evmGasLeft := chargeGas(evmGasLeft, expandMemory(offset, size)) + + // Don't check overflow here since previous checks are enough to ensure this is safe + offset := add(offset, MEM_OFFSET()) + } + default { + offset := MEM_OFFSET() + } + + + if eq(isCallerEVM, 1) { + offset := sub(offset, 32) + size := add(size, 32) + + // include gas + mstore(offset, evmGasLeft) + } + + revert(offset, size) + } + case 0xFE { // OP_INVALID + evmGasLeft := 0 + revertWithGas(evmGasLeft) + } + // We explicitly add unused opcodes to optimize the jump table by compiler. + case 0x0C { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x0D { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x0E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x0F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x1E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x1F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x21 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x22 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x23 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x24 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x25 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x26 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x27 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x28 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x29 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2A { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2B { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2C { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2D { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x2F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x49 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4A { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4B { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4C { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4D { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4E { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0x4F { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xA9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xAF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xB9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xBF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xC9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xCF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xD9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDD { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xDF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE0 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE1 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE3 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE4 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE5 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xE9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEA { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xED { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEE { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xEF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF2 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF6 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF7 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF8 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xF9 { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xFB { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xFC { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + case 0xFF { // Unused opcode + $llvm_NoInline_llvm$_panic() + } + default { + $llvm_NoInline_llvm$_panic() + } + } + + + function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := calldatasize() + } + + function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + calldatacopy(dstOffset, sourceOffset, truncatedLen) + } + + function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + // EraVM will revert if offset + length overflows uint32 + if lt(calldataOffset, UINT32_MAX()) { + res := calldataload(calldataOffset) + } + } + + if eq(isCallerEVM, 1) { + // Includes gas + returnOffset := sub(returnOffset, 32) + checkOverflow(returnLen, 32) + returnLen := add(returnLen, 32) + + mstore(returnOffset, evmGasLeft) + } + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + let evmGasLeft, isStatic, isCallerEVM := consumeEvmFrame() + + if iszero(isCallerEVM) { + evmGasLeft := getEvmGasFromContext() + isStatic := getIsStaticFromCallFlags() + } + + // First, copy the contract's bytecode to be executed into the `BYTECODE_OFFSET` + // segment of memory. + getDeployedBytecode() + + let returnOffset, returnLen := $llvm_NoInline_llvm$_simulate(isCallerEVM, evmGasLeft, isStatic) + return(returnOffset, returnLen) + } + } +} diff --git a/system-contracts/contracts/EvmEmulator.yul.llvm.options b/system-contracts/contracts/EvmEmulator.yul.llvm.options new file mode 100644 index 000000000..704e0a70e --- /dev/null +++ b/system-contracts/contracts/EvmEmulator.yul.llvm.options @@ -0,0 +1 @@ +'-eravm-jump-table-density-threshold=10 -tail-dup-size=6 -eravm-enable-split-loop-phi-live-ranges -tail-merge-only-bbs-without-succ -tail-dup-fallthrough-bbs' \ No newline at end of file diff --git a/system-contracts/contracts/EvmGasManager.yul b/system-contracts/contracts/EvmGasManager.yul new file mode 100644 index 000000000..bf274eae0 --- /dev/null +++ b/system-contracts/contracts/EvmGasManager.yul @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: MIT + +object "EvmGasManager" { + code { + return(0, 0) + } + object "EvmGasManager_deployed" { + code { + function ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008002 + } + + function IS_ACCOUNT_EVM_PREFIX() -> prefix { + prefix := shl(255, 1) + } + + function IS_ACCOUNT_WARM_PREFIX() -> prefix { + prefix := shl(254, 1) + } + + function IS_SLOT_WARM_PREFIX() -> prefix { + prefix := shl(253, 1) + } + + function PRECOMPILES_END() -> value { + value := 0x0a // As in Cancun + } + + function EVM_GAS_SLOT() -> value { + value := 4 + } + + function EVM_AUX_DATA_SLOT() -> value { + value := 5 + } + + function EVM_ACTIVE_FRAME_FLAG() -> value { + value := 2 + } + + function EVM_STATIC_FLAG() -> value { + value := 1 + } + + function ADDRESS_MASK() -> mask { + mask := sub(shl(160, 1), 1) + } + + function MAX_88_BIT_VALUE() -> value { + value := sub(shl(88, 1), 1) + } + + function $llvm_AlwaysInline_llvm$__getRawSenderCodeHash() -> hash { + mstore(0, 0x4DE2E46800000000000000000000000000000000000000000000000000000000) + mstore(4, caller()) + + let success := staticcall(gas(), ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 0, 36, 0, 0) + + if iszero(success) { + // This error should never happen + revert(0, 0) + } + + returndatacopy(0, 0, 32) + hash := mload(0) + } + + /// @dev Checks that the call is done by the EVM emulator in system mode. + function $llvm_AlwaysInline_llvm$_onlyEvmSystemCall() { + let callFlags := verbatim_0i_1o("get_global::call_flags") + let notSystemCall := iszero(and(callFlags, 2)) + + if notSystemCall { + // error CallerMustBeEvmContract() + mstore(0, 0xBE4BF9E400000000000000000000000000000000000000000000000000000000) + revert(0, 32) + } + + // SELFDESTRUCT is not supported, so it is ok to cache here + let transientSlot := or(IS_ACCOUNT_EVM_PREFIX(), caller()) + let isEVM := tload(transientSlot) + if iszero(isEVM) { + let versionedCodeHash := $llvm_AlwaysInline_llvm$__getRawSenderCodeHash() + isEVM := eq(shr(248, versionedCodeHash), 2) + + if iszero(isEVM) { + // error CallerMustBeEvmContract() + mstore(0, 0xBE4BF9E400000000000000000000000000000000000000000000000000000000) + revert(0, 32) + } + + // we will not cache contract if it is being constructed + let isContractConstructed := iszero(and(0xFF, shr(240, versionedCodeHash))) + if isContractConstructed { + tstore(transientSlot, 1) + } + } + } + + function warmAccount(account) { + let transientSlot := or(IS_ACCOUNT_WARM_PREFIX(), account) + tstore(transientSlot, 1) + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + let _calldata0Slot := calldataload(0) + + // Please note that we do not use the standard solidity calldata encoding here. + // This allows us to optimize the contract and reduce overhead. + // We use 1 byte as selector, arguments can be packed, the size of the returned data may vary. + let functionSelector := shr(248, _calldata0Slot) + switch functionSelector + case 0 { // function warmAccount(address account) + // Warm account, if needed. If it is already warm, will return 32 bytes of unspecified data. + // Account address should be packed in one 32-bytes word with selector. + $llvm_AlwaysInline_llvm$_onlyEvmSystemCall() + + let account := and(ADDRESS_MASK(), _calldata0Slot) + + let wasWarm := true + + // precompiles are always warm + if or(iszero(account), gt(account, PRECOMPILES_END())) { + let transientSlot := or(IS_ACCOUNT_WARM_PREFIX(), account) + wasWarm := tload(transientSlot) + + if iszero(wasWarm) { + tstore(transientSlot, 1) + } + } + + if wasWarm { + return(0x0, 0x20) + } + return(0x0, 0x0) + } + case 1 { // function isSlotWarm(uint256 _slot) + // If specified slot in the caller storage is warm, will return 32 bytes of unspecified data. + let _slot := calldataload(1) // load _slot + let transientSlot + switch gt(_slot, MAX_88_BIT_VALUE()) + case 1 { + mstore(0, _slot) + mstore(32, or(IS_SLOT_WARM_PREFIX(), caller())) // prefixed caller address + transientSlot := keccak256(0, 64) + } + case 0 { + transientSlot := or(shl(160, _slot), caller()) + } + + if tload(transientSlot) { + return(0x0, 0x20) + } + return(0x0, 0x0) + } + case 2 { // function warmSlot(uint256 _slot, uint256 currentValue) + // Warm slot in caller storage, if needed. Will return original value of the slot if it is already warm. + $llvm_AlwaysInline_llvm$_onlyEvmSystemCall() + + let _slot := calldataload(1) // load _slot + let transientSlot + switch gt(_slot, MAX_88_BIT_VALUE()) + case 1 { + mstore(0, _slot) + mstore(32, or(IS_SLOT_WARM_PREFIX(), caller())) // prefixed caller address + transientSlot := keccak256(0, 64) + } + case 0 { + transientSlot := or(shl(160, _slot), caller()) + } + + let isWarm := tload(transientSlot) + + if isWarm { + let originalValue := tload(add(transientSlot, 1)) + mstore(0x0, originalValue) + return(0x0, 0x20) + } + + let currentValue := calldataload(33) + tstore(transientSlot, 1) + tstore(add(transientSlot, 1), currentValue) + return(0x0, 0x0) + } + case 3 { // function pushEVMFrame(bool isStatic, uint256 passGas) + // Save EVM frame context data + // This method is used by EvmEmulator to save new frame context data for external call. + // isStatic flag should be packed in one 32-bytes word with selector. + $llvm_AlwaysInline_llvm$_onlyEvmSystemCall() + let isStatic := and(_calldata0Slot, 1) + let passGas := calldataload(32) + tstore(EVM_GAS_SLOT(), passGas) + tstore(EVM_AUX_DATA_SLOT(), or(isStatic, EVM_ACTIVE_FRAME_FLAG())) // mark frame as active + return(0x0, 0x0) + } + case 4 { // function consumeEvmFrame() + // This method is used by EvmEmulator to get context data. + // If the frame is active, 32 bytes of unspecified data will be returned. + // If the frame is active and is static, 64 bytes of unspecified data will be returned. + $llvm_AlwaysInline_llvm$_onlyEvmSystemCall() + + let auxData := tload(EVM_AUX_DATA_SLOT()) + + let isFrameActive := and(auxData, EVM_ACTIVE_FRAME_FLAG()) + if isFrameActive { + tstore(EVM_AUX_DATA_SLOT(), 0) // mark as consumed + + let passGas := tload(EVM_GAS_SLOT()) + mstore(0x0, passGas) + + let isStatic := and(auxData, EVM_STATIC_FLAG()) + if isStatic { + return(0x0, 0x40) + } + return(0x0, 0x20) + } + + // We do not have active frame. This means that the EVM contract was called from the EraVM contract. + // mark caller and txorigin as warm + let _msgsender := calldataload(1) + let _origin := origin() + warmAccount(_msgsender) + if iszero(eq(_msgsender, _origin)) { + warmAccount(_origin) + } + // We should mark the EVM contract as warm too. + warmAccount(caller()) + warmAccount(coinbase()) // and the coinbase too + return(0x0, 0x0) + } + case 5 { // function resetEVMFrame() + // Reset EVM frame context data + // This method is used by EvmEmulator to clean frame data after failed EVM call. + $llvm_AlwaysInline_llvm$_onlyEvmSystemCall() + + tstore(EVM_AUX_DATA_SLOT(), 0) // mark as consumed (clean it) + } + default { + revert(0, 0) + } + } + } +} diff --git a/system-contracts/contracts/KnownCodesStorage.sol b/system-contracts/contracts/KnownCodesStorage.sol index 31fa04734..463105a64 100644 --- a/system-contracts/contracts/KnownCodesStorage.sol +++ b/system-contracts/contracts/KnownCodesStorage.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.24; import {IKnownCodesStorage} from "./interfaces/IKnownCodesStorage.sol"; import {SystemContractBase} from "./abstract/SystemContractBase.sol"; import {Utils} from "./libraries/Utils.sol"; -import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT} from "./Constants.sol"; +import {COMPRESSOR_CONTRACT, L1_MESSENGER_CONTRACT, DEPLOYER_SYSTEM_CONTRACT} from "./Constants.sol"; import {Unauthorized, MalformedBytecode, BytecodeError} from "./SystemContractErrors.sol"; /** @@ -84,4 +84,30 @@ contract KnownCodesStorage is IKnownCodesStorage, SystemContractBase { revert MalformedBytecode(BytecodeError.NumberOfWords); } } + + /// @notice The method used by ContractDeployer to publish EVM bytecode + /// @dev Bytecode should be padded by EraVM rules + /// @param paddedBytecode The length of EVM bytecode in bytes + /// @param paddedBytecode The bytecode to be published + function publishEVMBytecode( + uint256 evmBytecodeLen, + bytes calldata paddedBytecode + ) external payable onlyCallFrom(address(DEPLOYER_SYSTEM_CONTRACT)) returns (bytes32) { + bytes32 vesionedBytecodeHash = Utils.hashEVMBytecode(evmBytecodeLen, paddedBytecode); + + if (getMarker(vesionedBytecodeHash) == 0) { + L1_MESSENGER_CONTRACT.sendToL1(paddedBytecode); + + assembly { + sstore(vesionedBytecodeHash, 1) + } + + emit MarkedAsKnown(vesionedBytecodeHash, false); + } + + assembly { + mstore(0x0, vesionedBytecodeHash) + return(0x0, 0x20) + } + } } diff --git a/system-contracts/contracts/L2BaseToken.sol b/system-contracts/contracts/L2BaseToken.sol index 9f826a80b..d7a047a8f 100644 --- a/system-contracts/contracts/L2BaseToken.sol +++ b/system-contracts/contracts/L2BaseToken.sol @@ -127,22 +127,4 @@ contract L2BaseToken is IBaseToken, SystemContractBase { // solhint-disable-next-line func-named-parameters return abi.encodePacked(IMailbox.finalizeEthWithdrawal.selector, _to, _amount, _sender, _additionalData); } - - /// @dev This method has not been stabilized and might be - /// removed later on. - function name() external pure override returns (string memory) { - return "Ether"; - } - - /// @dev This method has not been stabilized and might be - /// removed later on. - function symbol() external pure override returns (string memory) { - return "ETH"; - } - - /// @dev This method has not been stabilized and might be - /// removed later on. - function decimals() external pure override returns (uint8) { - return 18; - } } diff --git a/system-contracts/contracts/SystemContext.sol b/system-contracts/contracts/SystemContext.sol index 4763b4153..2ce75419d 100644 --- a/system-contracts/contracts/SystemContext.sol +++ b/system-contracts/contracts/SystemContext.sol @@ -42,6 +42,7 @@ contract SystemContext is ISystemContext, ISystemContextDeprecated, SystemContra /// @notice The `block.coinbase` in the current transaction. /// @dev For the support of coinbase, we will use the bootloader formal address for now + /// @dev (!) EVM emulator doesn't expect this value to change address public coinbase = BOOTLOADER_FORMAL_ADDRESS; /// @notice Formal `block.difficulty` parameter. diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol index b5dfc8276..2ba8eed26 100644 --- a/system-contracts/contracts/SystemContractErrors.sol +++ b/system-contracts/contracts/SystemContractErrors.sol @@ -6,6 +6,8 @@ pragma solidity ^0.8.20; error AddressHasNoCode(address); // 0xefce78c7 error CallerMustBeBootloader(); +// 0xbe4bf9e4 +error CallerMustBeEvmContract(); // 0xb7549616 error CallerMustBeForceDeployer(); // 0x9eedbd2b @@ -32,6 +34,8 @@ error EmptyVirtualBlocks(); error EncodedAndRealBytecodeChunkNotEqual(uint64 expected, uint64 provided); // 0x2bfbfc11 error EncodedLengthNotFourTimesSmallerThanOriginal(); +// 0xb9e6e31f +error EVMEmulationNotSupported(); // 0xe95a1fbe error FailedToChargeGas(); // 0x1f70c58f @@ -138,5 +142,7 @@ enum BytecodeError { NumberOfWords, Length, WordsMustBeOdd, - DictionaryLength + DictionaryLength, + EvmBytecodeLength, + EvmBytecodeLengthTooBig } diff --git a/system-contracts/contracts/abstract/SystemContractBase.sol b/system-contracts/contracts/abstract/SystemContractBase.sol index 89966a576..abc5b8006 100644 --- a/system-contracts/contracts/abstract/SystemContractBase.sol +++ b/system-contracts/contracts/abstract/SystemContractBase.sol @@ -4,7 +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"; +import {SystemCallFlagRequired, Unauthorized, CallerMustBeSystemContract, CallerMustBeBootloader, CallerMustBeForceDeployer, CallerMustBeEvmContract} from "../SystemContractErrors.sol"; /** * @author Matter Labs @@ -60,4 +60,13 @@ abstract contract SystemContractBase { } _; } + + /// @notice Modifier that makes sure that the method + /// can only be called from the EVM emulator using system call (unaccessible from EVM environment) + modifier onlySystemCallFromEvmEmulator() { + if (!SystemContractHelper.isSystemCallFromEvmEmulator()) { + revert CallerMustBeEvmContract(); + } + _; + } } diff --git a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol index 5183e77f6..7bd24cc75 100644 --- a/system-contracts/contracts/interfaces/IAccountCodeStorage.sol +++ b/system-contracts/contracts/interfaces/IAccountCodeStorage.sol @@ -14,4 +14,6 @@ interface IAccountCodeStorage { function getCodeHash(uint256 _input) external view returns (bytes32 codeHash); function getCodeSize(uint256 _input) external view returns (uint256 codeSize); + + function isAccountEVM(address _addr) external view returns (bool); } diff --git a/system-contracts/contracts/interfaces/IBaseToken.sol b/system-contracts/contracts/interfaces/IBaseToken.sol index fc32c7b83..2bd15be51 100644 --- a/system-contracts/contracts/interfaces/IBaseToken.sol +++ b/system-contracts/contracts/interfaces/IBaseToken.sol @@ -9,12 +9,6 @@ interface IBaseToken { function totalSupply() external view returns (uint256); - function name() external pure returns (string memory); - - function symbol() external pure returns (string memory); - - function decimals() external pure returns (uint8); - function mint(address _account, uint256 _amount) external; function withdraw(address _l1Receiver) external payable; diff --git a/system-contracts/contracts/interfaces/IContractDeployer.sol b/system-contracts/contracts/interfaces/IContractDeployer.sol index 6e0bac3dc..fd0d8dec1 100644 --- a/system-contracts/contracts/interfaces/IContractDeployer.sol +++ b/system-contracts/contracts/interfaces/IContractDeployer.sol @@ -25,6 +25,14 @@ interface IContractDeployer { Arbitrary } + /// @notice Defines what types of bytecode are allowed to be deployed on this chain + /// - `EraVm` means that only native contracts can be deployed + /// - `EraVmAndEVM` means that native contracts and EVM contracts can be deployed + enum AllowedBytecodeTypes { + EraVm, + EraVmAndEVM + } + struct AccountInfo { AccountAbstractionVersion supportedAAVersion; AccountNonceOrdering nonceOrdering; @@ -40,6 +48,11 @@ interface IContractDeployer { event AccountVersionUpdated(address indexed accountAddress, AccountAbstractionVersion aaVersion); + event AllowedBytecodeTypesModeUpdated(AllowedBytecodeTypes mode); + + /// @notice Returns what types of bytecode are allowed to be deployed on this chain + function allowedBytecodeTypesToDeploy() external view returns (AllowedBytecodeTypes mode); + function getNewAddressCreate2( address _sender, bytes32 _bytecodeHash, @@ -88,4 +101,18 @@ interface IContractDeployer { /// @notice Can be called by an account to update its nonce ordering function updateNonceOrdering(AccountNonceOrdering _nonceOrdering) external; + + function createEVM(bytes calldata _initCode) external payable returns (uint256 evmGasUsed, address newAddress); + + function create2EVM( + bytes32 _salt, + bytes calldata _initCode + ) external payable returns (uint256 evmGasUsed, address newAddress); + + /// @notice Returns keccak of EVM bytecode at address if it is an EVM contract. Returns bytes32(0) if it isn't a EVM contract. + function evmCodeHash(address) external view returns (bytes32); + + /// @notice Changes what types of bytecodes are allowed to be deployed on the chain. + /// @param newAllowedBytecodeTypes The new allowed bytecode types mode. + function setAllowedBytecodeTypesToDeploy(AllowedBytecodeTypes newAllowedBytecodeTypes) external; } diff --git a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol index 551cfb0d8..fc019be93 100644 --- a/system-contracts/contracts/interfaces/IKnownCodesStorage.sol +++ b/system-contracts/contracts/interfaces/IKnownCodesStorage.sol @@ -16,4 +16,6 @@ interface IKnownCodesStorage { function markBytecodeAsPublished(bytes32 _bytecodeHash) external; function getMarker(bytes32 _hash) external view returns (uint256); + + function publishEVMBytecode(uint256 evmBytecodeLen, bytes calldata bytecode) external payable returns (bytes32); } diff --git a/system-contracts/contracts/libraries/SystemContractHelper.sol b/system-contracts/contracts/libraries/SystemContractHelper.sol index e8469e308..e76d25057 100644 --- a/system-contracts/contracts/libraries/SystemContractHelper.sol +++ b/system-contracts/contracts/libraries/SystemContractHelper.sol @@ -2,7 +2,7 @@ // We use a floating point pragma here so it can be used within other projects that interact with the ZKsync ecosystem without using our exact pragma version. pragma solidity ^0.8.20; -import {MAX_SYSTEM_CONTRACT_ADDRESS} from "../Constants.sol"; +import {MAX_SYSTEM_CONTRACT_ADDRESS, ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT} 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"; @@ -345,6 +345,13 @@ library SystemContractHelper { return uint160(_address) <= uint160(MAX_SYSTEM_CONTRACT_ADDRESS); } + /// @notice Returns whether the current call is a system call from EVM emulator. + /// @return `true` or `false` based on whether the current call is a system call from EVM emulator. + function isSystemCallFromEvmEmulator() internal view returns (bool) { + if (!isSystemCall()) return false; + return ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.isAccountEVM(msg.sender); + } + /// @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. diff --git a/system-contracts/contracts/libraries/TransactionHelper.sol b/system-contracts/contracts/libraries/TransactionHelper.sol index 467eb57f9..9eccfd93e 100644 --- a/system-contracts/contracts/libraries/TransactionHelper.sol +++ b/system-contracts/contracts/libraries/TransactionHelper.sol @@ -20,6 +20,8 @@ uint8 constant LEGACY_TX_TYPE = 0x0; uint8 constant EIP_2930_TX_TYPE = 0x01; /// @dev The type id of EIP1559 transactions. uint8 constant EIP_1559_TX_TYPE = 0x02; +/// @dev The type id of L1 to L2 transactions. +uint8 constant L1_TO_L2_TX_TYPE = 0xFF; /// @notice Structure used to represent a ZKsync transaction. struct Transaction { @@ -163,7 +165,10 @@ library TransactionHelper { encodedGasParam = bytes.concat(encodedGasPrice, encodedGasLimit); } - bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + // "to" field is empty if it is EVM deploy tx + bytes memory encodedTo = _transaction.reserved[1] == 1 + ? bytes(hex"80") + : RLPEncoder.encodeAddress(address(uint160(_transaction.to))); bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); // Encode only the length of the transaction data, and not the data itself, // so as not to copy to memory a potentially huge transaction data twice. @@ -232,7 +237,10 @@ library TransactionHelper { bytes memory encodedNonce = RLPEncoder.encodeUint256(_transaction.nonce); bytes memory encodedGasPrice = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); - bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + // "to" field is empty if it is EVM deploy tx + bytes memory encodedTo = _transaction.reserved[1] == 1 + ? bytes(hex"80") + : RLPEncoder.encodeAddress(address(uint160(_transaction.to))); bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); // solhint-disable-next-line func-named-parameters encodedFixedLengthParams = bytes.concat( @@ -305,7 +313,10 @@ library TransactionHelper { bytes memory encodedMaxPriorityFeePerGas = RLPEncoder.encodeUint256(_transaction.maxPriorityFeePerGas); bytes memory encodedMaxFeePerGas = RLPEncoder.encodeUint256(_transaction.maxFeePerGas); bytes memory encodedGasLimit = RLPEncoder.encodeUint256(_transaction.gasLimit); - bytes memory encodedTo = RLPEncoder.encodeAddress(address(uint160(_transaction.to))); + // "to" field is empty if it is EVM deploy tx + bytes memory encodedTo = _transaction.reserved[1] == 1 + ? bytes(hex"80") + : RLPEncoder.encodeAddress(address(uint160(_transaction.to))); bytes memory encodedValue = RLPEncoder.encodeUint256(_transaction.value); // solhint-disable-next-line func-named-parameters encodedFixedLengthParams = bytes.concat( diff --git a/system-contracts/contracts/libraries/Utils.sol b/system-contracts/contracts/libraries/Utils.sol index fc23de94b..94a615da0 100644 --- a/system-contracts/contracts/libraries/Utils.sol +++ b/system-contracts/contracts/libraries/Utils.sol @@ -3,7 +3,9 @@ pragma solidity ^0.8.20; import {EfficientCall} from "./EfficientCall.sol"; +import {RLPEncoder} from "./RLPEncoder.sol"; import {MalformedBytecode, BytecodeError, Overflow} from "../SystemContractErrors.sol"; +import {ERA_VM_BYTECODE_FLAG, EVM_BYTECODE_FLAG} from "../Constants.sol"; /** * @author Matter Labs @@ -43,15 +45,36 @@ library Utils { return uint24(_x); } - /// @return codeLength The bytecode length in bytes - function bytecodeLenInBytes(bytes32 _bytecodeHash) internal pure returns (uint256 codeLength) { - codeLength = bytecodeLenInWords(_bytecodeHash) << 5; // _bytecodeHash * 32 + /// @return If this bytecode hash for EVM contract or not + function isCodeHashEVM(bytes32 _bytecodeHash) internal pure returns (bool) { + return (uint8(_bytecodeHash[0]) == EVM_BYTECODE_FLAG); + } + + /// @return codeLengthInBytes The bytecode length in bytes + function bytecodeLenInBytes(bytes32 _bytecodeHash) internal pure returns (uint256 codeLengthInBytes) { + unchecked { + uint256 decodedCodeLength = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3])); + if (isCodeHashEVM(_bytecodeHash)) { + // length is encoded in bytes + codeLengthInBytes = decodedCodeLength; + } else { + // length is encoded in words + codeLengthInBytes = decodedCodeLength << 5; // * 32 + } + } } /// @return codeLengthInWords The bytecode length in machine words function bytecodeLenInWords(bytes32 _bytecodeHash) internal pure returns (uint256 codeLengthInWords) { unchecked { - codeLengthInWords = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3])); + uint256 decodedCodeLength = uint256(uint8(_bytecodeHash[2])) * 256 + uint256(uint8(_bytecodeHash[3])); + if (isCodeHashEVM(_bytecodeHash)) { + // length is encoded in bytes + codeLengthInWords = (decodedCodeLength + 31) / 32; // rounded up + } else { + // length is encoded in words + codeLengthInWords = decodedCodeLength; + } } } @@ -106,8 +129,82 @@ library Utils { EfficientCall.sha(_bytecode) & 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; // Setting the version of the hash - hashedBytecode = (hashedBytecode | bytes32(uint256(1 << 248))); + hashedBytecode = (hashedBytecode | bytes32(uint256(ERA_VM_BYTECODE_FLAG) << 248)); // Setting the length hashedBytecode = hashedBytecode | bytes32(lengthInWords << 224); } + + // the real max supported number is 2^16, but we'll stick to evm convention + uint256 internal constant MAX_EVM_BYTECODE_LENGTH = (2 ** 16) - 1; + + /// @notice Validate the bytecode format and calculate its hash. + /// @param _evmBytecodeLen The length of original EVM bytecode in bytes + /// @param _paddedBytecode The padded EVM bytecode to hash. + /// @return hashedEVMBytecode The 32-byte hash of the EVM bytecode. + /// Note: The function reverts the execution if the bytecode has non expected format: + /// - Bytecode bytes length is not a multiple of 32 + /// - Bytecode bytes length is greater than 2^16 - 1 bytes + /// - Bytecode words length is not odd + function hashEVMBytecode( + uint256 _evmBytecodeLen, + bytes calldata _paddedBytecode + ) internal view returns (bytes32 hashedEVMBytecode) { + // Note that the length of the bytecode must be provided in 32-byte words. + if (_paddedBytecode.length % 32 != 0) { + revert MalformedBytecode(BytecodeError.Length); + } + + if (_evmBytecodeLen > _paddedBytecode.length) { + revert MalformedBytecode(BytecodeError.EvmBytecodeLength); + } + + if (_evmBytecodeLen > MAX_EVM_BYTECODE_LENGTH) { + revert MalformedBytecode(BytecodeError.EvmBytecodeLengthTooBig); + } + + uint256 lengthInWords = _paddedBytecode.length / 32; + // bytecode length in words must be odd + if (lengthInWords % 2 == 0) { + revert MalformedBytecode(BytecodeError.WordsMustBeOdd); + } + + hashedEVMBytecode = + EfficientCall.sha(_paddedBytecode) & + 0x00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF; + + // Setting the version of the hash + hashedEVMBytecode = (hashedEVMBytecode | bytes32(uint256(EVM_BYTECODE_FLAG) << 248)); + hashedEVMBytecode = hashedEVMBytecode | bytes32(_evmBytecodeLen << 224); + } + + /// @notice Calculates the address of a deployed contract via create2 on the EVM + /// @param _sender The account that deploys the contract. + /// @param _salt The create2 salt. + /// @param _bytecodeHash The hash of the init code of the new contract. + /// @return newAddress The derived address of the account. + function getNewAddressCreate2EVM( + address _sender, + bytes32 _salt, + bytes32 _bytecodeHash + ) internal pure returns (address newAddress) { + bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), _sender, _salt, _bytecodeHash)); + + newAddress = address(uint160(uint256(hash))); + } + + /// @notice Calculates the address of a deployed contract via create + /// @param _sender The account that deploys the contract. + /// @param _senderNonce The deploy nonce of the sender's account. + function getNewAddressCreateEVM(address _sender, uint256 _senderNonce) internal pure returns (address newAddress) { + bytes memory addressEncoded = RLPEncoder.encodeAddress(_sender); + bytes memory nonceEncoded = RLPEncoder.encodeUint256(_senderNonce); + + uint256 listLength = addressEncoded.length + nonceEncoded.length; + bytes memory listLengthEncoded = RLPEncoder.encodeListLen(uint64(listLength)); + + bytes memory digest = bytes.concat(listLengthEncoded, addressEncoded, nonceEncoded); + + bytes32 hash = keccak256(digest); + newAddress = address(uint160(uint256(hash))); + } } diff --git a/system-contracts/contracts/precompiles/CodeOracle.yul b/system-contracts/contracts/precompiles/CodeOracle.yul index 63b386788..87145d3be 100644 --- a/system-contracts/contracts/precompiles/CodeOracle.yul +++ b/system-contracts/contracts/precompiles/CodeOracle.yul @@ -29,7 +29,7 @@ object "CodeOracle" { //////////////////////////////////////////////////////////////// // HELPER FUNCTIONS //////////////////////////////////////////////////////////////// - + /// @notice The function that returns whether a certain versioned hash is marked as `known` /// @param versionedHash The versioned hash to check /// @return Whether the versioned hash is known @@ -90,7 +90,7 @@ object "CodeOracle" { // Decommitment failed revert(0,0) } - + // The "real" result of the `decommit` operation is a pointer to the memory page where the data was unpacked. // We do not know whether the data was unpacked into the memory of this contract or not. // @@ -111,6 +111,19 @@ object "CodeOracle" { return(0, lenInBytes) } + function paddedBytecodeLen(len) -> blobLen { + blobLen := len + + if iszero(eq(mod(blobLen, 32), 0)) { + blobLen := add(blobLen, sub(32, mod(blobLen, 32))) + } + + // Now it is divisible by 32, but we must make sure that the number of 32 byte words is odd + if iszero(eq(mod(blobLen, 64), 32)) { + blobLen := add(blobLen, 32) + } + } + //////////////////////////////////////////////////////////////// // FALLBACK //////////////////////////////////////////////////////////////// @@ -123,15 +136,21 @@ object "CodeOracle" { } let version := shr(248, versionedCodeHash) - // Currently, only a single version of the code hash is supported: + // Currently, two versions of the code hash is supported: // 1. The standard zkEVM bytecode. It has the following format: // - hash[0] -- version (0x01) // - hash[1] -- whether the contract is being constructed // - hash[2..3] -- big endian length of the bytecode in 32-byte words. This number must be odd. // - hash[4..31] -- the last 28 bytes of the sha256 hash. + // 2. EVM bytecode. It has the following format: + // - hash[0] -- version (0x02) + // - hash[1] -- whether the contract is being constructed + // - hash[2..3] -- big endian length of the bytecode in bytes. This number can be arbitrary. + // - hash[4..31] -- the last 28 bytes of the sha256 hash. // - // Note, that in theory it can represent just some random blob of bytes, while - // in practice it only represents only the corresponding bytecodes. + // Note, that in theory both values can represent just some random blob of bytes, while + // in practice they only represent only the corresponding bytecodes. + switch version case 1 { @@ -140,6 +159,12 @@ object "CodeOracle" { let lengthInWords := and(shr(224, versionedCodeHash), 0xffff) decommit(versionedCodeHash, lengthInWords) } + case 2 { + let lengthInBytes := and(shr(224, versionedCodeHash), 0xffff) + let paddedLengthInBytes := paddedBytecodeLen(lengthInBytes) + + decommit(versionedCodeHash, div(paddedLengthInBytes, 32)) + } default { // Unsupported revert(0,0) diff --git a/system-contracts/contracts/precompiles/Identity.yul b/system-contracts/contracts/precompiles/Identity.yul new file mode 100644 index 000000000..2e35975f3 --- /dev/null +++ b/system-contracts/contracts/precompiles/Identity.yul @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT + +/** + * @author Matter Labs + * @custom:security-contact security@matterlabs.dev + * @notice The contract used to support legacy MCOPY operations + * @dev It simply returns the calldata. + */ + object "Identity" { + code { + return(0, 0) + } + object "Identity_deployed" { + code { + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + let size := calldatasize() + calldatacopy(0, 0, size) + return(0, size) + } + } +} diff --git a/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm b/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm index b95b2a08b..30ed1d9f8 100644 --- a/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm +++ b/system-contracts/contracts/test-contracts/ExtraAbiCaller.zasm @@ -4,14 +4,14 @@ __entry: .func_begin0: sub.s! 0, r2, r0 - jump.eq @.RUNTIME_CODE + jump.eq @RUNTIME_CODE ; deployment code add 32, r0, r1 - st.1 r0, r1 - st.1 r1, r0 - add @CPI0_1[0], r0, r1 - ret.ok.to_label r1, @DEFAULT_FAR_RETURN -.RUNTIME_CODE: + stm.h r0, r1 + stm.h r1, r0 + add code[@CPI0_1], r0, r1 + retl r1, @DEFAULT_FAR_RETURN +RUNTIME_CODE: ; ABI: ; 0-32 address(in the lowest 20 bytes) ; 32-64 msg.value @@ -19,29 +19,31 @@ __entry: ; 384+ calldata ; ; load address into r2 - ld.inc r1, r2, r1 + ldpi r1, r2, r1 ; set msg.value - ld.inc r1, r3, r1 - context.set_context_u128 r3 + ldpi r1, r3, r1 + stvl r3 ; load extra abi data into r3-r12 - ld.inc r1, r3, r1 - ld.inc r1, r4, r1 - ld.inc r1, r5, r1 - ld.inc r1, r6, r1 - ld.inc r1, r7, r1 - ld.inc r1, r8, r1 - ld.inc r1, r9, r1 - ld.inc r1, r10, r1 - ld.inc r1, r11, r1 - ld.inc r1, r12, r1 - ptr.pack.s @CPI0_0[0], r1, r1 - far_call r1, r2, @.CALL_REVERT - ptr.pack.s @CPI0_2[0], r1, r1 - ret.ok r1 + ldpi r1, r3, r1 + ldpi r1, r4, r1 + ldpi r1, r5, r1 + ldpi r1, r6, r1 + ldpi r1, r7, r1 + ldpi r1, r8, r1 + ldpi r1, r9, r1 + ldpi r1, r10, r1 + ldpi r1, r11, r1 + ldpi r1, r12, r1 + pack.s code[@CPI0_0], r1, r1 + callf r1, r2, @.CALL_REVERT + pack.s code[@CPI0_2], r1, r1 + ret r1 .CALL_REVERT: - ptr.pack.s @CPI0_2[0], r1, r1 - ret.revert r1 + pack.s code[@CPI0_2], r1, r1 + rev r1 .func_end0: +DEFAULT_FAR_RETURN: + retl @DEFAULT_FAR_RETURN .note.GNU-stack .rodata ; far call abi: @@ -57,4 +59,4 @@ CPI0_1: .cell 5070602400912917605986812821504 ; 01 00000000 0000000000000000 00000000000000000000000000000000 CPI0_2: - .cell 26959946667150639794667015087019630673637144422540572481103610249216 + .cell 26959946667150639794667015087019630673637144422540572481103610249216 \ No newline at end of file diff --git a/system-contracts/evm-emulator/EvmEmulator.template.yul b/system-contracts/evm-emulator/EvmEmulator.template.yul new file mode 100644 index 000000000..22d188075 --- /dev/null +++ b/system-contracts/evm-emulator/EvmEmulator.template.yul @@ -0,0 +1,170 @@ +object "EvmEmulator" { + code { + function MAX_POSSIBLE_ACTIVE_BYTECODE() -> max { + max := MAX_POSSIBLE_INIT_BYTECODE_LEN() + } + + /// @dev This function is used to get the initCode. + /// @dev It assumes that the initCode has been passed via the calldata and so we use the pointer + /// to obtain the bytecode. + function getConstructorBytecode() { + loadCalldataIntoActivePtr() + + let size := getActivePtrDataSize() + + if gt(size, MAX_POSSIBLE_INIT_BYTECODE_LEN()) { + panic() + } + + mstore(BYTECODE_LEN_OFFSET(), size) + mstore(EMPTY_CODE_OFFSET(), 0) + copyActivePtrData(BYTECODE_OFFSET(), 0, size) + } + + function padBytecode(offset, len) -> blobLen { + let trueLastByte := add(offset, len) + + // clearing out additional bytes + mstore(trueLastByte, 0) + mstore(add(trueLastByte, 32), 0) + + blobLen := len + + if iszero(eq(mod(blobLen, 32), 0)) { + blobLen := add(blobLen, sub(32, mod(blobLen, 32))) + } + + // Now it is divisible by 32, but we must make sure that the number of 32 byte words is odd + if iszero(eq(mod(blobLen, 64), 32)) { + blobLen := add(blobLen, 32) + } + } + + function validateBytecodeAndChargeGas(offset, deployedCodeLen, gasToReturn) -> returnGas { + if deployedCodeLen { + // EIP-3860 + if gt(deployedCodeLen, MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN()) { + panic() + } + + // EIP-3541 + let firstByte := shr(248, mload(offset)) + if eq(firstByte, 0xEF) { + panic() + } + } + + let gasForCode := mul(deployedCodeLen, 200) + returnGas := chargeGas(gasToReturn, gasForCode) + } + + + + + + function simulate( + isCallerEVM, + evmGasLeft, + isStatic, + ) -> returnOffset, returnLen, retGasLeft { + + returnOffset := MEM_OFFSET() + returnLen := 0 + + + + retGasLeft := evmGasLeft + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + pop($llvm_AlwaysInline_llvm$_warmAddress(address())) + + let evmGasLeft, isStatic, isCallerEVM := consumeEvmFrame() + + if isStatic { + abortEvmEnvironment() // should never happen + } + + getConstructorBytecode() + + if iszero(isCallerEVM) { + evmGasLeft := getEvmGasFromContext() + } + + let offset, len, gasToReturn := simulate(isCallerEVM, evmGasLeft, false) + + gasToReturn := validateBytecodeAndChargeGas(offset, len, gasToReturn) + + let blobLen := padBytecode(offset, len) + + mstore(add(offset, blobLen), len) + mstore(add(offset, add(32, blobLen)), gasToReturn) + + verbatim_2i_0o("return_deployed", offset, add(blobLen, 64)) + } + object "EvmEmulator_deployed" { + code { + function MAX_POSSIBLE_ACTIVE_BYTECODE() -> max { + max := MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() + } + + function getDeployedBytecode() { + let codeLen := fetchDeployedCode( + getCodeAddress(), + BYTECODE_OFFSET(), // destination offset + 0, // source offset + MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() + ) + + mstore(EMPTY_CODE_OFFSET(), 0) + mstore(BYTECODE_LEN_OFFSET(), codeLen) + } + + + + function $llvm_NoInline_llvm$_simulate( + isCallerEVM, + evmGasLeft, + isStatic, + ) -> returnOffset, returnLen { + + returnOffset := MEM_OFFSET() + returnLen := 0 + + + + + + if eq(isCallerEVM, 1) { + // Includes gas + returnOffset := sub(returnOffset, 32) + checkOverflow(returnLen, 32) + returnLen := add(returnLen, 32) + + mstore(returnOffset, evmGasLeft) + } + } + + //////////////////////////////////////////////////////////////// + // FALLBACK + //////////////////////////////////////////////////////////////// + + let evmGasLeft, isStatic, isCallerEVM := consumeEvmFrame() + + if iszero(isCallerEVM) { + evmGasLeft := getEvmGasFromContext() + isStatic := getIsStaticFromCallFlags() + } + + // First, copy the contract's bytecode to be executed into the `BYTECODE_OFFSET` + // segment of memory. + getDeployedBytecode() + + let returnOffset, returnLen := $llvm_NoInline_llvm$_simulate(isCallerEVM, evmGasLeft, isStatic) + return(returnOffset, returnLen) + } + } +} diff --git a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul new file mode 100644 index 000000000..61feb9235 --- /dev/null +++ b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul @@ -0,0 +1,1250 @@ +//////////////////////////////////////////////////////////////// +// CONSTANTS +//////////////////////////////////////////////////////////////// + +function ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008002 +} + +function NONCE_HOLDER_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008003 +} + +function DEPLOYER_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008006 +} + +function CODE_ORACLE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008012 +} + +function EVM_GAS_MANAGER_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008013 +} + +function MSG_VALUE_SYSTEM_CONTRACT() -> addr { + addr := 0x0000000000000000000000000000000000008009 +} + +function ORIGIN_CACHE_OFFSET() -> offset { + offset := mul(23, 32) +} + +function GASPRICE_CACHE_OFFSET() -> offset { + offset := mul(24, 32) +} + +function COINBASE_CACHE_OFFSET() -> offset { + offset := mul(25, 32) +} + +function BLOCKTIMESTAMP_CACHE_OFFSET() -> offset { + offset := mul(26, 32) +} + +function BLOCKNUMBER_CACHE_OFFSET() -> offset { + offset := mul(27, 32) +} + +function PREVRANDAO_CACHE_OFFSET() -> offset { + offset := mul(28, 32) +} + +function GASLIMIT_CACHE_OFFSET() -> offset { + offset := mul(29, 32) +} + +function CHAINID_CACHE_OFFSET() -> offset { + offset := mul(30, 32) +} + +function BASEFEE_CACHE_OFFSET() -> offset { + offset := mul(31, 32) +} + +function LAST_RETURNDATA_SIZE_OFFSET() -> offset { + offset := add(BASEFEE_CACHE_OFFSET(), 32) +} + +function STACK_OFFSET() -> offset { + offset := add(LAST_RETURNDATA_SIZE_OFFSET(), 64) +} + +function MAX_STACK_SLOT_OFFSET() -> offset { + offset := add(STACK_OFFSET(), mul(1023, 32)) +} + +function BYTECODE_LEN_OFFSET() -> offset { + offset := add(MAX_STACK_SLOT_OFFSET(), 32) +} + +function BYTECODE_OFFSET() -> offset { + offset := add(BYTECODE_LEN_OFFSET(), 32) +} + +// reserved empty slot to simplify PUSH N opcodes +function EMPTY_CODE_OFFSET() -> offset { + offset := add(BYTECODE_OFFSET(), MAX_POSSIBLE_ACTIVE_BYTECODE()) +} + +function MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN() -> max { + max := 24576 // EIP-170 +} + +function MAX_POSSIBLE_INIT_BYTECODE_LEN() -> max { + max := mul(2, MAX_POSSIBLE_DEPLOYED_BYTECODE_LEN()) // EIP-3860 +} + +function MEM_LEN_OFFSET() -> offset { + offset := add(EMPTY_CODE_OFFSET(), 32) +} + +function MEM_OFFSET() -> offset { + offset := add(MEM_LEN_OFFSET(), 32) +} + +// Used to simplify gas calculations for memory expansion. +// The cost to increase the memory to 12 MB is close to 277M EVM gas +function MAX_POSSIBLE_MEM_LEN() -> max { + max := 0xC00000 // 12MB +} + +function MAX_UINT() -> max_uint { + max_uint := 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +} + +function MAX_UINT64() -> max { + max := sub(shl(64, 1), 1) +} + +// Each evm gas is 5 zkEVM one +function GAS_DIVISOR() -> gas_div { gas_div := 5 } + +// We need to pass some gas for MsgValueSimulator internal logic to decommit emulator etc +function MSG_VALUE_SIMULATOR_STIPEND_GAS() -> gas_stipend { + gas_stipend := 35000 // 27000 + a little bit more +} + +function OVERHEAD() -> overhead { overhead := 2000 } + +function UINT32_MAX() -> ret { ret := 4294967295 } // 2^32 - 1 + +function EMPTY_KECCAK() -> value { // keccak("") + value := 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 +} + + +//////////////////////////////////////////////////////////////// +// GENERAL FUNCTIONS +//////////////////////////////////////////////////////////////// + +// abort the whole EVM execution environment, including parent frames +function abortEvmEnvironment() { + revert(0, 0) +} + +function $llvm_NoInline_llvm$_panic() { // revert consuming all EVM gas + mstore(0, 0) + revert(0, 32) +} + +function revertWithGas(evmGasLeft) { + mstore(0, evmGasLeft) + revert(0, 32) +} + +function panic() { // revert consuming all EVM gas + mstore(0, 0) + revert(0, 32) +} + +function cached(cacheIndex, value) -> _value { + _value := value + mstore(cacheIndex, _value) +} + +function chargeGas(prevGas, toCharge) -> gasRemaining { + if lt(prevGas, toCharge) { + panic() + } + + gasRemaining := sub(prevGas, toCharge) +} + +function getEvmGasFromContext() -> evmGas { + // Caller must pass at least OVERHEAD() ergs + let _gas := gas() + if gt(_gas, OVERHEAD()) { + evmGas := div(sub(_gas, OVERHEAD()), GAS_DIVISOR()) + } +} + +// This function can overflow, it is the job of the caller to ensure that it does not. +// The argument to this function is the offset into the memory region IN BYTES. +function expandMemory(offset, size) -> gasCost { + // memory expansion costs 0 if size is 0 + if size { + let oldSizeInWords := mload(MEM_LEN_OFFSET()) + + // div rounding up + let newSizeInWords := div(add(add(offset, size), 31), 32) + + // memory_size_word = (memory_byte_size + 31) / 32 + // memory_cost = (memory_size_word ** 2) / 512 + (3 * memory_size_word) + // memory_expansion_cost = new_memory_cost - last_memory_cost + if gt(newSizeInWords, oldSizeInWords) { + let linearPart := mul(3, sub(newSizeInWords, oldSizeInWords)) + let quadraticPart := sub( + div( + mul(newSizeInWords, newSizeInWords), + 512 + ), + div( + mul(oldSizeInWords, oldSizeInWords), + 512 + ) + ) + + gasCost := add(linearPart, quadraticPart) + + mstore(MEM_LEN_OFFSET(), newSizeInWords) + } + } +} + +function expandMemory2(retOffset, retSize, argsOffset, argsSize) -> maxExpand { + switch lt(add(retOffset, retSize), add(argsOffset, argsSize)) + case 0 { + maxExpand := expandMemory(retOffset, retSize) + } + default { + maxExpand := expandMemory(argsOffset, argsSize) + } +} + +function checkMemIsAccessible(relativeOffset, size) { + if size { + checkOverflow(relativeOffset, size) + + if gt(add(relativeOffset, size), MAX_POSSIBLE_MEM_LEN()) { + panic() + } + } +} + +function checkOverflow(data1, data2) { + if lt(add(data1, data2), data2) { + panic() + } +} + +function insufficientBalance(value) -> res { + if value { + res := gt(value, selfbalance()) + } +} + +// It is the responsibility of the caller to ensure that ip is correct +function readIP(ip, bytecodeEndOffset) -> opcode { + if lt(ip, bytecodeEndOffset) { + opcode := and(mload(sub(ip, 31)), 0xff) + } + // STOP else +} + +// It is the responsibility of the caller to ensure that start and length is correct +function readBytes(start, length) -> value { + value := shr(mul(8, sub(32, length)), mload(start)) + // will be padded by zeroes if out of bounds (we have reserved EMPTY_CODE_OFFSET() slot) +} + +function getCodeAddress() -> addr { + addr := verbatim_0i_1o("code_source") +} + +function loadReturndataIntoActivePtr() { + verbatim_0i_0o("return_data_ptr_to_active") +} + +function loadCalldataIntoActivePtr() { + verbatim_0i_0o("calldata_ptr_to_active") +} + +function getActivePtrDataSize() -> size { + size := verbatim_0i_1o("active_ptr_data_size") +} + +function copyActivePtrData(_dest, _source, _size) { + verbatim_3i_0o("active_ptr_data_copy", _dest, _source, _size) +} + +function ptrAddIntoActive(_dest) { + verbatim_1i_0o("active_ptr_add_assign", _dest) +} + +function ptrShrinkIntoActive(_dest) { + verbatim_1i_0o("active_ptr_shrink_assign", _dest) +} + +function getIsStaticFromCallFlags() -> isStatic { + isStatic := verbatim_0i_1o("get_global::call_flags") + isStatic := iszero(iszero(and(isStatic, 0x04))) +} + +function fetchFromSystemContract(to, argSize) -> res { + let success := staticcall(gas(), to, 0, argSize, 0, 0) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + + returndatacopy(0, 0, 32) + res := mload(0) +} + +function isAddrEmpty(addr) -> isEmpty { + // We treat constructing EraVM contracts as non-existing + if iszero(extcodesize(addr)) { // YUL doesn't have short-circuit evaluation + if iszero(balance(addr)) { + if iszero(getRawNonce(addr)) { + isEmpty := 1 + } + } + } +} + +// returns minNonce + 2^128 * deployment nonce. +function getRawNonce(addr) -> nonce { + // selector for function getRawNonce(address addr) + mstore(0, 0x5AA9B6B500000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + nonce := fetchFromSystemContract(NONCE_HOLDER_SYSTEM_CONTRACT(), 36) +} + +function getRawCodeHash(addr) -> hash { + mstore(0, 0x4DE2E46800000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + hash := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) +} + +function getEvmExtcodehash(addr) -> evmCodeHash { + mstore(0, 0x54A3314700000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + evmCodeHash := fetchFromSystemContract(DEPLOYER_SYSTEM_CONTRACT(), 36) +} + +function isEvmContract(addr) -> isEVM { + // function isAccountEVM(address addr) external view returns (bool); + mstore(0, 0x8C04047700000000000000000000000000000000000000000000000000000000) + mstore(4, addr) + isEVM := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) +} + +function isHashOfConstructedEvmContract(rawCodeHash) -> isConstructedEVM { + let version := shr(248, rawCodeHash) + let isConstructedFlag := xor(shr(240, rawCodeHash), 1) + isConstructedEVM := and(eq(version, 2), isConstructedFlag) +} + +// Basically performs an extcodecopy, while returning the length of the copied bytecode. +function fetchDeployedCode(addr, dstOffset, srcOffset, len) -> copiedLen { + let rawCodeHash := getRawCodeHash(addr) + mstore(0, rawCodeHash) + + let success := staticcall(gas(), CODE_ORACLE_SYSTEM_CONTRACT(), 0, 32, 0, 0) + // it fails if we don't have any code deployed at this address + if success { + // The length of the bytecode is encoded in versioned bytecode hash + let codeLen := and(shr(224, rawCodeHash), 0xffff) + + if eq(shr(248, rawCodeHash), 1) { + // For native zkVM contracts length encoded in words, not bytes + codeLen := shl(5, codeLen) // * 32 + } + + if gt(len, codeLen) { + len := codeLen + } + + let _returndatasize := returndatasize() + if gt(srcOffset, _returndatasize) { + srcOffset := _returndatasize + } + + if gt(add(len, srcOffset), _returndatasize) { + len := sub(_returndatasize, srcOffset) + } + + if len { + returndatacopy(dstOffset, srcOffset, len) + } + + copiedLen := len + } +} + +function getMax(a, b) -> max { + max := b + if gt(a, b) { + max := a + } +} + +function build_farcall_abi(isSystemCall, gas, dataStart, dataLength) -> farCallAbi { + farCallAbi := shl(248, isSystemCall) + // dataOffset is 0 + farCallAbi := or(farCallAbi, shl(64, dataStart)) + farCallAbi := or(farCallAbi, shl(96, dataLength)) + farCallAbi := or(farCallAbi, shl(192, gas)) + // shardId is 0 + // forwardingMode is 0 +} + +function performSystemCall(to, dataLength) { + let success := performSystemCallRevertable(to, dataLength) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } +} + +function performSystemCallRevertable(to, dataLength) -> success { + // system call, dataStart is 0 + let farCallAbi := build_farcall_abi(1, gas(), 0, dataLength) + success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) +} + +function rawCall(gas, to, value, dataStart, dataLength, outputOffset, outputLen) -> success { + switch iszero(value) + case 0 { + // system call to MsgValueSimulator, but call to "to" will be non-system + let farCallAbi := build_farcall_abi(1, gas, dataStart, dataLength) + success := verbatim_6i_1o("system_call", MSG_VALUE_SYSTEM_CONTRACT(), farCallAbi, value, to, 0, 0) + if outputLen { + if success { + let rtdz := returndatasize() + switch lt(rtdz, outputLen) + case 0 { returndatacopy(outputOffset, 0, outputLen) } + default { returndatacopy(outputOffset, 0, rtdz) } + } + } + } + default { + // not a system call + let farCallAbi := build_farcall_abi(0, gas, dataStart, dataLength) + success := verbatim_4i_1o("raw_call", to, farCallAbi, outputOffset, outputLen) + } +} + +function rawStaticcall(gas, to, dataStart, dataLength, outputOffset, outputLen) -> success { + // not a system call + let farCallAbi := build_farcall_abi(0, gas, dataStart, dataLength) + success := verbatim_4i_1o("raw_static_call", to, farCallAbi, outputOffset, outputLen) +} + +//////////////////////////////////////////////////////////////// +// STACK OPERATIONS +//////////////////////////////////////////////////////////////// + +function dupStackItem(sp, evmGas, position, oldStackHead) -> newSp, evmGasLeft, stackHead { + evmGasLeft := chargeGas(evmGas, 3) + + if iszero(lt(sp, MAX_STACK_SLOT_OFFSET())) { + panic() + } + + let tempSp := sub(sp, mul(0x20, sub(position, 1))) + + if lt(tempSp, STACK_OFFSET()) { + panic() + } + + mstore(sp, oldStackHead) + stackHead := mload(tempSp) + newSp := add(sp, 0x20) +} + +function swapStackItem(sp, evmGas, position, oldStackHead) -> evmGasLeft, stackHead { + evmGasLeft := chargeGas(evmGas, 3) + let tempSp := sub(sp, mul(0x20, position)) + + if lt(tempSp, STACK_OFFSET()) { + panic() + } + + stackHead := mload(tempSp) + mstore(tempSp, oldStackHead) +} + +function popStackItem(sp, oldStackHead) -> a, newSp, stackHead { + // We can not return any error here, because it would break compatibility + if lt(sp, STACK_OFFSET()) { + panic() + } + + a := oldStackHead + newSp := sub(sp, 0x20) + stackHead := mload(newSp) +} + +function pushStackItem(sp, item, oldStackHead) -> newSp, stackHead { + if iszero(lt(sp, MAX_STACK_SLOT_OFFSET())) { + panic() + } + + mstore(sp, oldStackHead) + stackHead := item + newSp := add(sp, 0x20) +} + +function popStackItemWithoutCheck(sp, oldStackHead) -> a, newSp, stackHead { + a := oldStackHead + newSp := sub(sp, 0x20) + stackHead := mload(newSp) +} + +function pushStackItemWithoutCheck(sp, item, oldStackHead) -> newSp, stackHead { + mstore(sp, oldStackHead) + stackHead := item + newSp := add(sp, 0x20) +} + +function popStackCheck(sp, numInputs) { + if lt(sub(sp, mul(0x20, sub(numInputs, 1))), STACK_OFFSET()) { + panic() + } +} + +function accessStackHead(sp, stackHead) -> value { + if lt(sp, STACK_OFFSET()) { + panic() + } + + value := stackHead +} + +//////////////////////////////////////////////////////////////// +// EVM GAS MANAGER FUNCTIONALITY +//////////////////////////////////////////////////////////////// + +function $llvm_AlwaysInline_llvm$_warmAddress(addr) -> isWarm { + // function warmAccount(address account) + // non-standard selector 0x00 + // addr is packed in the same word with selector + mstore(0, and(addr, 0xffffffffffffffffffffffffffffffffffffffff)) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 32) + + if returndatasize() { + isWarm := true + } +} + +function isSlotWarm(key) -> isWarm { + // non-standard selector 0x01 + mstore(0, 0x0100000000000000000000000000000000000000000000000000000000000000) + mstore(1, key) + // should be call since we use TSTORE in gas manager + let success := call(gas(), EVM_GAS_MANAGER_CONTRACT(), 0, 0, 33, 0, 0) + + if iszero(success) { + // This error should never happen + abortEvmEnvironment() + } + + if returndatasize() { + isWarm := true + } +} + +function warmSlot(key, currentValue) -> isWarm, originalValue { + // non-standard selector 0x02 + mstore(0, 0x0200000000000000000000000000000000000000000000000000000000000000) + mstore(1, key) + mstore(33, currentValue) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 65) + + originalValue := currentValue + if returndatasize() { + isWarm := true + returndatacopy(0, 0, 32) + originalValue := mload(0) + } +} + +function pushEvmFrame(passGas, isStatic) { + // function pushEVMFrame + // non-standard selector 0x03 + mstore(0, or(0x0300000000000000000000000000000000000000000000000000000000000000, isStatic)) + mstore(32, passGas) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 64) +} + +function consumeEvmFrame() -> passGas, isStatic, callerEVM { + // function consumeEvmFrame() external returns (uint256 passGas, uint256 auxDataRes) + // non-standard selector 0x04 + mstore(0, 0x0400000000000000000000000000000000000000000000000000000000000000) + mstore(1, caller()) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 33) + + let _returndatasize := returndatasize() + if _returndatasize { + callerEVM := true + + returndatacopy(0, 0, 32) + passGas := mload(0) + + isStatic := gt(_returndatasize, 32) + } +} + +function resetEvmFrame() { + // function resetEvmFrame() + // non-standard selector 0x05 + mstore(0, 0x0500000000000000000000000000000000000000000000000000000000000000) + + performSystemCall(EVM_GAS_MANAGER_CONTRACT(), 1) +} + +//////////////////////////////////////////////////////////////// +// CALLS FUNCTIONALITY +//////////////////////////////////////////////////////////////// + +function performCall(oldSp, evmGasLeft, oldStackHead, isStatic) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, value, argsOffset, argsSize, retOffset, retSize + + popStackCheck(oldSp, 7) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + retOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + // static_gas = 0 + // dynamic_gas = memory_expansion_cost + code_execution_cost + address_access_cost + positive_value_cost + value_to_empty_account_cost + // code_execution_cost is the cost of the called code execution (limited by the gas parameter). + // If address is warm, then address_access_cost is 100, otherwise it is 2600. See section access sets. + // If value is not 0, then positive_value_cost is 9000. In this case there is also a call stipend that is given to make sure that a basic fallback function can be called. + // If value is not 0 and the address given points to an empty account, then value_to_empty_account_cost is 25000. An account is empty if its balance is 0, its nonce is 0 and it has no code. + + let addr, gasUsed := _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) + + if gt(value, 0) { + if isStatic { + panic() + } + + gasUsed := add(gasUsed, 9000) // positive_value_cost + + if isAddrEmpty(addr) { + gasUsed := add(gasUsed, 25000) // value_to_empty_account_cost + } + } + + evmGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(evmGasLeft, gasToPass) + evmGasLeft := sub(evmGasLeft, gasToPass) + + if gt(value, 0) { + gasToPass := add(gasToPass, 2300) + } + + let success, frameGasLeft := _genericCall( + addr, + gasToPass, + value, + add(argsOffset, MEM_OFFSET()), + argsSize, + add(retOffset, MEM_OFFSET()), + retSize, + isStatic + ) + + newGasLeft := add(evmGasLeft, frameGasLeft) + stackHead := success +} + +function performStaticCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, argsOffset, argsSize, retOffset, retSize + + popStackCheck(oldSp, 6) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + retOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + let addr, gasUsed := _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) + + evmGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(evmGasLeft, gasToPass) + evmGasLeft := sub(evmGasLeft, gasToPass) + + let success, frameGasLeft := _genericCall( + addr, + gasToPass, + 0, + add(MEM_OFFSET(), argsOffset), + argsSize, + add(MEM_OFFSET(), retOffset), + retSize, + true + ) + + newGasLeft := add(evmGasLeft, frameGasLeft) + stackHead := success +} + + +function performDelegateCall(oldSp, evmGasLeft, isStatic, oldStackHead) -> newGasLeft, sp, stackHead { + let gasToPass, rawAddr, rawArgsOffset, argsSize, rawRetOffset, retSize + + popStackCheck(oldSp, 6) + gasToPass, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + rawAddr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + rawArgsOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + argsSize, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + rawRetOffset, sp, retSize := popStackItemWithoutCheck(sp, stackHead) + + let addr, gasUsed := _genericPrecallLogic(rawAddr, rawArgsOffset, argsSize, rawRetOffset, retSize) + + newGasLeft := chargeGas(evmGasLeft, gasUsed) + gasToPass := capGasForCall(newGasLeft, gasToPass) + + newGasLeft := sub(newGasLeft, gasToPass) + + let success + let frameGasLeft := gasToPass + + let retOffset := add(MEM_OFFSET(), rawRetOffset) + let argsOffset := add(MEM_OFFSET(), rawArgsOffset) + + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + // Not a constructed EVM contract + let precompileCost := getGasForPrecompiles(addr, argsSize) + switch precompileCost + case 0 { + // Not a precompile + _eraseReturndataPointer() + + let isCallToEmptyContract := iszero(addr) // 0x00 is always "empty" + if iszero(isCallToEmptyContract) { + isCallToEmptyContract := iszero(and(shr(224, rawCodeHash), 0xffff)) // is codelen zero? + } + + if isCallToEmptyContract { + success := delegatecall(gas(), addr, argsOffset, argsSize, retOffset, retSize) + _saveReturndataAfterZkEVMCall() + } + + // We forbid delegatecalls to EraVM native contracts + } + default { + // Precompile. Simlate using staticcall, since EraVM behavior differs here + success, frameGasLeft := callPrecompile(addr, precompileCost, gasToPass, 0, argsOffset, argsSize, retOffset, retSize, true) + } + } + default { + // Constructed EVM contract + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := delegatecall(gas(), addr, argsOffset, argsSize, 0, 0) + + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + + newGasLeft := add(newGasLeft, frameGasLeft) + stackHead := success +} + +function _genericPrecallLogic(rawAddr, argsOffset, argsSize, retOffset, retSize) -> addr, gasUsed { + addr := and(rawAddr, 0xffffffffffffffffffffffffffffffffffffffff) + + checkMemIsAccessible(argsOffset, argsSize) + checkMemIsAccessible(retOffset, retSize) + + gasUsed := 100 // warm address access cost + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + gasUsed := 2600 // cold address access cost + } + + // memory_expansion_cost + gasUsed := add(gasUsed, expandMemory2(retOffset, retSize, argsOffset, argsSize)) +} + +function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + // zkEVM native call + let precompileCost := getGasForPrecompiles(addr, argsSize) + switch precompileCost + case 0 { + // just smart contract + success, frameGasLeft := callZkVmNative(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic, rawCodeHash) + } + default { + // precompile + success, frameGasLeft := callPrecompile(addr, precompileCost, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) + } + } + default { + switch insufficientBalance(value) + case 0 { + pushEvmFrame(gasToPass, isStatic) + // pass all remaining native gas + success := call(gas(), addr, value, argsOffset, argsSize, 0, 0) + frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) + if iszero(success) { + resetEvmFrame() + } + } + default { + frameGasLeft := gasToPass + _eraseReturndataPointer() + } + } +} + +function callPrecompile(addr, precompileCost, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { + switch lt(gasToPass, precompileCost) + case 0 { + let zkVmGasToPass := gas() // pass all remaining gas, precompiles should not call any contracts + + switch isStatic + case 0 { + success := rawCall(zkVmGasToPass, addr, value, argsOffset, argsSize, retOffset, retSize) + } + default { + success := rawStaticcall(zkVmGasToPass, addr, argsOffset, argsSize, retOffset, retSize) + } + + _saveReturndataAfterZkEVMCall() + + if success { + frameGasLeft := sub(gasToPass, precompileCost) + } + // else consume all provided gas + } + default { + // consume all provided gas + _eraseReturndataPointer() + } +} + +// Call native ZkVm contract from EVM context +function callZkVmNative(addr, evmGasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic, rawCodeHash) -> success, frameGasLeft { + let zkEvmGasToPass := mul(evmGasToPass, GAS_DIVISOR()) // convert EVM gas -> ZkVM gas + + let additionalStipend := 6000 // should cover first access to empty account + switch value + case 0 { + if gt(addr, 0) { // zero address is always "empty" + if and(shr(224, rawCodeHash), 0xffff) { // if codelen is not zero + additionalStipend := 0 + } + } + } + default { + additionalStipend := 27000 // Stipend for MsgValueSimulator. Covered by positive_value_cost + } + + zkEvmGasToPass := add(zkEvmGasToPass, additionalStipend) + + if gt(zkEvmGasToPass, UINT32_MAX()) { // just in case + zkEvmGasToPass := UINT32_MAX() + } + + let zkEvmGasBefore := gas() + switch isStatic + case 0 { + success := call(zkEvmGasToPass, addr, value, argsOffset, argsSize, retOffset, retSize) + } + default { + success := staticcall(zkEvmGasToPass, addr, argsOffset, argsSize, retOffset, retSize) + } + let zkEvmGasUsed := sub(zkEvmGasBefore, gas()) + + _saveReturndataAfterZkEVMCall() + + if gt(zkEvmGasUsed, zkEvmGasBefore) { // overflow case + zkEvmGasUsed := 0 // should never happen + } + + switch gt(zkEvmGasUsed, additionalStipend) + case 0 { + zkEvmGasUsed := 0 + } + default { + zkEvmGasUsed := sub(zkEvmGasUsed, additionalStipend) + } + + zkEvmGasToPass := sub(zkEvmGasToPass, additionalStipend) + + // refund gas + if gt(zkEvmGasToPass, zkEvmGasUsed) { + frameGasLeft := div(sub(zkEvmGasToPass, zkEvmGasUsed), GAS_DIVISOR()) + } +} + +function capGasForCall(evmGasLeft, oldGasToPass) -> gasToPass { + let maxGasToPass := sub(evmGasLeft, shr(6, evmGasLeft)) // evmGasLeft >> 6 == evmGasLeft/64 + gasToPass := oldGasToPass + if gt(oldGasToPass, maxGasToPass) { + gasToPass := maxGasToPass + } +} + +// The gas cost mentioned here is purely the cost of the contract, +// and does not consider the cost of the call itself nor the instructions +// to put the parameters in memory. +function getGasForPrecompiles(addr, argsSize) -> gasToCharge { + switch addr + case 0x01 { // ecRecover + gasToCharge := 3000 + } + case 0x02 { // SHA2-256 + let dataWordSize := shr(5, add(argsSize, 31)) // (argsSize+31)/32 + gasToCharge := add(60, mul(12, dataWordSize)) + } + case 0x03 { // RIPEMD-160 + // We do not support RIPEMD-160 + gasToCharge := 0 + } + case 0x04 { // identity + let dataWordSize := shr(5, add(argsSize, 31)) // (argsSize+31)/32 + gasToCharge := add(15, mul(3, dataWordSize)) + } + case 0x05 { // modexp + // We do not support modexp + gasToCharge := 0 + } + // ecAdd ecMul ecPairing EIP below + // https://eips.ethereum.org/EIPS/eip-1108 + case 0x06 { // ecAdd + // The gas cost is fixed at 150. However, if the input + // does not allow to compute a valid result, all the gas sent is consumed. + gasToCharge := 150 + } + case 0x07 { // ecMul + // The gas cost is fixed at 6000. However, if the input + // does not allow to compute a valid result, all the gas sent is consumed. + gasToCharge := 6000 + } + // 34,000 * k + 45,000 gas, where k is the number of pairings being computed. + // The input must always be a multiple of 6 32-byte values. + case 0x08 { // ecPairing + let k := div(argsSize, 0xC0) // 0xC0 == 6*32 + gasToCharge := add(45000, mul(k, 34000)) + } + case 0x09 { // blake2f + // We do not support blake2f + gasToCharge := 0 + } + case 0x0a { // kzg point evaluation + // We do not support kzg point evaluation + gasToCharge := 0 + } + default { + gasToCharge := 0 + } +} + +function _saveReturndataAfterZkEVMCall() { + loadReturndataIntoActivePtr() + mstore(LAST_RETURNDATA_SIZE_OFFSET(), returndatasize()) +} + +function _saveReturndataAfterEVMCall(_outputOffset, _outputLen) -> _gasLeft { + let rtsz := returndatasize() + loadReturndataIntoActivePtr() + + // if (rtsz > 31) + switch gt(rtsz, 31) + case 0 { + // Unexpected return data. + // Most likely out-of-ergs or unexpected error in the emulator or system contracts + abortEvmEnvironment() + } + default { + returndatacopy(0, 0, 32) + _gasLeft := mload(0) + + // We copy as much returndata as possible without going over the + // returndata size. + switch lt(sub(rtsz, 32), _outputLen) + case 0 { returndatacopy(_outputOffset, 32, _outputLen) } + default { returndatacopy(_outputOffset, 32, sub(rtsz, 32)) } + + mstore(LAST_RETURNDATA_SIZE_OFFSET(), sub(rtsz, 32)) + + // Skip the returnData + ptrAddIntoActive(32) + } +} + +function _eraseReturndataPointer() { + let activePtrSize := getActivePtrDataSize() + ptrShrinkIntoActive(and(activePtrSize, 0xFFFFFFFF))// uint32(activePtrSize) + mstore(LAST_RETURNDATA_SIZE_OFFSET(), 0) +} + +//////////////////////////////////////////////////////////////// +// CREATE FUNCTIONALITY +//////////////////////////////////////////////////////////////// + +function performCreate(oldEvmGasLeft, oldSp, oldStackHead) -> evmGasLeft, sp, stackHead { + let value, offset, size + + popStackCheck(oldSp, 3) + value, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + offset, sp, size := popStackItemWithoutCheck(sp, stackHead) + + evmGasLeft, stackHead := $llvm_NoInline_llvm$_genericCreate(offset, size, value, oldEvmGasLeft, false, 0) +} + +function performCreate2(oldEvmGasLeft, oldSp, oldStackHead) -> evmGasLeft, sp, stackHead { + let value, offset, size, salt + + popStackCheck(oldSp, 4) + value, sp, stackHead := popStackItemWithoutCheck(oldSp, oldStackHead) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, salt := popStackItemWithoutCheck(sp, stackHead) + + evmGasLeft, stackHead := $llvm_NoInline_llvm$_genericCreate(offset, size, value, oldEvmGasLeft, true, salt) +} + +function $llvm_NoInline_llvm$_genericCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) -> evmGasLeft, addr { + checkMemIsAccessible(offset, size) + + // EIP-3860 + if gt(size, MAX_POSSIBLE_INIT_BYTECODE_LEN()) { + panic() + } + + // dynamicGas = init_code_cost + memory_expansion_cost + deployment_code_execution_cost + code_deposit_cost + // + hash_cost, if isCreate2 + // minimum_word_size = (size + 31) / 32 + // init_code_cost = 2 * minimum_word_size, EIP-3860 + // code_deposit_cost = 200 * deployed_code_size, (charged inside call) + let minimum_word_size := div(add(size, 31), 32) // rounding up + let dynamicGas := add( + mul(2, minimum_word_size), + expandMemory(offset, size) + ) + if isCreate2 { + // hash_cost = 6 * minimum_word_size + dynamicGas := add(dynamicGas, mul(6, minimum_word_size)) + } + evmGasLeft := chargeGas(evmGasLeftOld, dynamicGas) + + _eraseReturndataPointer() + + let err := insufficientBalance(value) + + if iszero(err) { + offset := add(MEM_OFFSET(), offset) // caller must ensure that it doesn't overflow + evmGasLeft, addr := _executeCreate(offset, size, value, evmGasLeft, isCreate2, salt) + } +} + +function _executeCreate(offset, size, value, evmGasLeftOld, isCreate2, salt) -> evmGasLeft, addr { + let gasForTheCall := capGasForCall(evmGasLeftOld, evmGasLeftOld) // pass 63/64 of remaining gas + + let bytecodeHash + if isCreate2 { + switch size + case 0 { + bytecodeHash := EMPTY_KECCAK() + } + default { + bytecodeHash := keccak256(offset, size) + } + } + + // we want to calculate the address of new contract, and if it is deployable (no collision), + // we need to increment deploy nonce. + + // selector: function precreateEvmAccountFromEmulator(bytes32 salt, bytes32 evmBytecodeHash) + mstore(0, 0xf81dae8600000000000000000000000000000000000000000000000000000000) + mstore(4, salt) + mstore(36, bytecodeHash) + let canBeDeployed := performSystemCallRevertable(DEPLOYER_SYSTEM_CONTRACT(), 68) + + if canBeDeployed { + returndatacopy(0, 0, 32) + addr := mload(0) + + pop($llvm_AlwaysInline_llvm$_warmAddress(addr)) // will stay warm even if constructor reverts + // so even if constructor reverts, nonce stays incremented and addr stays warm + + // check for code collision + canBeDeployed := 0 + if iszero(getRawCodeHash(addr)) { + // check for nonce collision + if iszero(getRawNonce(addr)) { + canBeDeployed := 1 + } + } + } + + if iszero(canBeDeployed) { + // Nonce overflow, EVM not allowed or collision. + // This is *internal* panic, consuming all passed gas. + // Note: we should not consume all gas if nonce overflowed, but this should not happen in reality anyway + evmGasLeft := chargeGas(evmGasLeftOld, gasForTheCall) + addr := 0 + } + + + if canBeDeployed { + // verification of the correctness of the deployed bytecode and payment of gas for its storage will occur in the frame of the new contract + pushEvmFrame(gasForTheCall, false) + + // move needed memory slots to the scratch space + mstore(mul(10, 32), mload(sub(offset, 0x80)) + mstore(mul(11, 32), mload(sub(offset, 0x60)) + mstore(mul(12, 32), mload(sub(offset, 0x40)) + mstore(mul(13, 32), mload(sub(offset, 0x20)) + + // selector: function createEvmFromEmulator(address newAddress, bytes calldata _initCode) + mstore(sub(offset, 0x80), 0xe43cec64) + mstore(sub(offset, 0x60), addr) + mstore(sub(offset, 0x40), 0x40) // Where the arg starts (third word) + mstore(sub(offset, 0x20), size) // Length of the init code + + let result := performSystemCallForCreate(value, sub(offset, 0x64), add(size, 0x64)) + + // move memory slots back + mstore(sub(offset, 0x80), mload(mul(10, 32)) + mstore(sub(offset, 0x60), mload(mul(11, 32)) + mstore(sub(offset, 0x40), mload(mul(12, 32)) + mstore(sub(offset, 0x20), mload(mul(13, 32)) + + let gasLeft + switch result + case 0 { + addr := 0 + gasLeft := _saveReturndataAfterEVMCall(0, 0) + resetEvmFrame() + } + default { + gasLeft, addr := _saveConstructorReturnGas() + } + + let gasUsed := sub(gasForTheCall, gasLeft) + evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) + } +} + +function performSystemCallForCreate(value, bytecodeStart, bytecodeLen) -> success { + // system call, not constructor call (ContractDeployer will call constructor) + let farCallAbi := build_farcall_abi(1, gas(), bytecodeStart, bytecodeLen) + + switch iszero(value) + case 0 { + success := verbatim_6i_1o("system_call", MSG_VALUE_SYSTEM_CONTRACT(), farCallAbi, value, DEPLOYER_SYSTEM_CONTRACT(), 1, 0) + } + default { + success := verbatim_6i_1o("system_call", DEPLOYER_SYSTEM_CONTRACT(), farCallAbi, 0, 0, 0, 0) + } +} + +function _saveConstructorReturnGas() -> gasLeft, addr { + loadReturndataIntoActivePtr() + + if lt(returndatasize(), 64) { + // unexpected return data after constructor succeeded, should never happen. + abortEvmEnvironment() + } + + // ContractDeployer returns (uint256 gasLeft, address createdContract) + returndatacopy(0, 0, 64) + gasLeft := mload(0) + addr := mload(32) + + _eraseReturndataPointer() +} + +//////////////////////////////////////////////////////////////// +// EXTCODECOPY FUNCTIONALITY +//////////////////////////////////////////////////////////////// + +function $llvm_AlwaysInline_llvm$_copyRest(dest, val, len) { + let rest_bits := shl(3, len) + let upper_bits := sub(256, rest_bits) + let val_mask := shl(upper_bits, MAX_UINT()) + let val_masked := and(val, val_mask) + let dst_val := mload(dest) + let dst_mask := shr(rest_bits, MAX_UINT()) + let dst_masked := and(dst_val, dst_mask) + mstore(dest, or(val_masked, dst_masked)) +} + +function $llvm_AlwaysInline_llvm$_memcpy(dest, src, len) { + let dest_addr := dest + let src_addr := src + let dest_end := add(dest, and(len, sub(0, 32))) + for { } lt(dest_addr, dest_end) {} { + mstore(dest_addr, mload(src_addr)) + dest_addr := add(dest_addr, 32) + src_addr := add(src_addr, 32) + } + + let rest_len := and(len, 31) + if rest_len { + $llvm_AlwaysInline_llvm$_copyRest(dest_addr, mload(src_addr), rest_len) + } +} + +function $llvm_AlwaysInline_llvm$_memsetToZero(dest,len) { + let dest_end := add(dest, and(len, sub(0, 32))) + for {let i := dest} lt(i, dest_end) { i := add(i, 32) } { + mstore(i, 0) + } + + let rest_len := and(len, 31) + if rest_len { + $llvm_AlwaysInline_llvm$_copyRest(dest_end, 0, rest_len) + } +} + +//////////////////////////////////////////////////////////////// +// LOGS FUNCTIONALITY +//////////////////////////////////////////////////////////////// + +function _genericLog(sp, stackHead, evmGasLeft, topicCount, isStatic) -> newEvmGasLeft, offset, size, newSp, newStackHead { + newEvmGasLeft := chargeGas(evmGasLeft, 375) + + if isStatic { + panic() + } + + let rawOffset + popStackCheck(sp, add(2, topicCount)) + rawOffset, newSp, newStackHead := popStackItemWithoutCheck(sp, stackHead) + size, newSp, newStackHead := popStackItemWithoutCheck(newSp, newStackHead) + + checkMemIsAccessible(rawOffset, size) + + // dynamicGas = 375 * topic_count + 8 * size + memory_expansion_cost + let dynamicGas := add(shl(3, size), expandMemory(rawOffset, size)) + dynamicGas := add(dynamicGas, mul(375, topicCount)) + + newEvmGasLeft := chargeGas(newEvmGasLeft, dynamicGas) + + if size { + offset := add(rawOffset, MEM_OFFSET()) + } +} \ No newline at end of file diff --git a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul new file mode 100644 index 000000000..d5056dd19 --- /dev/null +++ b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul @@ -0,0 +1,1490 @@ +// stack pointer - index to first stack element; empty stack = -1 +let sp := sub(STACK_OFFSET(), 32) +// instruction pointer - index to next instruction. Not called pc because it's an +// actual yul/evm instruction. +let ip := BYTECODE_OFFSET() +let stackHead + +let bytecodeEndOffset := add(BYTECODE_OFFSET(), mload(BYTECODE_LEN_OFFSET())) + +for { } true { } { + let opcode := readIP(ip, bytecodeEndOffset) + + switch opcode + case 0x00 { // OP_STOP + break + } + case 0x01 { // OP_ADD + evmGasLeft := chargeGas(evmGasLeft, 3) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := add(a, stackHead) + + ip := add(ip, 1) + } + case 0x02 { // OP_MUL + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := mul(a, stackHead) + ip := add(ip, 1) + } + case 0x03 { // OP_SUB + evmGasLeft := chargeGas(evmGasLeft, 3) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := sub(a, stackHead) + + ip := add(ip, 1) + } + case 0x04 { // OP_DIV + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := div(a, stackHead) + + ip := add(ip, 1) + } + case 0x05 { // OP_SDIV + evmGasLeft := chargeGas(evmGasLeft, 5) + + popStackCheck(sp, 2) + let a + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := sdiv(a, stackHead) + + ip := add(ip, 1) + } + case 0x06 { // OP_MOD + evmGasLeft := chargeGas(evmGasLeft, 5) + + let a + popStackCheck(sp, 2) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := mod(a, stackHead) + + ip := add(ip, 1) + } + case 0x07 { // OP_SMOD + evmGasLeft := chargeGas(evmGasLeft, 5) + + let a + popStackCheck(sp, 2) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + stackHead := smod(a, stackHead) + + ip := add(ip, 1) + } + case 0x08 { // OP_ADDMOD + evmGasLeft := chargeGas(evmGasLeft, 8) + + let a, b, N + + popStackCheck(sp, 3) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, N := popStackItemWithoutCheck(sp, stackHead) + stackHead := addmod(a, b, N) + + ip := add(ip, 1) + } + case 0x09 { // OP_MULMOD + evmGasLeft := chargeGas(evmGasLeft, 8) + + let a, b, N + + popStackCheck(sp, 3) + a, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, N := popStackItemWithoutCheck(sp, stackHead) + + stackHead := mulmod(a, b, N) + ip := add(ip, 1) + } + case 0x0A { // OP_EXP + evmGasLeft := chargeGas(evmGasLeft, 10) + + let a, exponent + + popStackCheck(sp, 2) + a, sp, exponent := popStackItemWithoutCheck(sp, stackHead) + + let to_charge := 0 + let exponentCopy := exponent + for {} gt(exponentCopy, 0) {} { // while exponent > 0 + to_charge := add(to_charge, 50) + exponentCopy := shr(8, exponentCopy) + } + evmGasLeft := chargeGas(evmGasLeft, to_charge) + + stackHead := exp(a, exponent) + + ip := add(ip, 1) + } + case 0x0B { // OP_SIGNEXTEND + evmGasLeft := chargeGas(evmGasLeft, 5) + + let b, x + + popStackCheck(sp, 2) + b, sp, x := popStackItemWithoutCheck(sp, stackHead) + stackHead := signextend(b, x) + + ip := add(ip, 1) + } + case 0x10 { // OP_LT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := lt(a, b) + + ip := add(ip, 1) + } + case 0x11 { // OP_GT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead:= gt(a, b) + + ip := add(ip, 1) + } + case 0x12 { // OP_SLT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := slt(a, b) + + ip := add(ip, 1) + } + case 0x13 { // OP_SGT + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := sgt(a, b) + + ip := add(ip, 1) + } + case 0x14 { // OP_EQ + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := eq(a, b) + + ip := add(ip, 1) + } + case 0x15 { // OP_ISZERO + evmGasLeft := chargeGas(evmGasLeft, 3) + + stackHead := iszero(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x16 { // OP_AND + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := and(a,b) + + ip := add(ip, 1) + } + case 0x17 { // OP_OR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := or(a,b) + + ip := add(ip, 1) + } + case 0x18 { // OP_XOR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let a, b + popStackCheck(sp, 2) + a, sp, b := popStackItemWithoutCheck(sp, stackHead) + stackHead := xor(a, b) + + ip := add(ip, 1) + } + case 0x19 { // OP_NOT + evmGasLeft := chargeGas(evmGasLeft, 3) + + stackHead := not(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x1A { // OP_BYTE + evmGasLeft := chargeGas(evmGasLeft, 3) + + let i, x + popStackCheck(sp, 2) + i, sp, x := popStackItemWithoutCheck(sp, stackHead) + stackHead := byte(i, x) + + ip := add(ip, 1) + } + case 0x1B { // OP_SHL + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := shl(shift, value) + + ip := add(ip, 1) + } + case 0x1C { // OP_SHR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := shr(shift, value) + + ip := add(ip, 1) + } + case 0x1D { // OP_SAR + evmGasLeft := chargeGas(evmGasLeft, 3) + + let shift, value + popStackCheck(sp, 2) + shift, sp, value := popStackItemWithoutCheck(sp, stackHead) + stackHead := sar(shift, value) + + ip := add(ip, 1) + } + case 0x20 { // OP_KECCAK256 + evmGasLeft := chargeGas(evmGasLeft, 30) + + let rawOffset, size + + popStackCheck(sp, 2) + rawOffset, sp, size := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(rawOffset, size) + + // When an offset is first accessed (either read or write), memory may trigger + // an expansion, which costs gas. + // dynamicGas = 6 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(6, shr(5, add(size, 31))), expandMemory(rawOffset, size)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + let offset + if size { + // use 0 as offset if size is 0 + offset := add(MEM_OFFSET(), rawOffset) + } + + stackHead := keccak256(offset, size) + + ip := add(ip, 1) + } + case 0x30 { // OP_ADDRESS + evmGasLeft := chargeGas(evmGasLeft, 2) + sp, stackHead := pushStackItem(sp, address(), stackHead) + ip := add(ip, 1) + } + case 0x31 { // OP_BALANCE + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + stackHead := balance(addr) + + ip := add(ip, 1) + } + case 0x32 { // OP_ORIGIN + evmGasLeft := chargeGas(evmGasLeft, 2) + let _origin := mload(ORIGIN_CACHE_OFFSET()) + if iszero(_origin) { + _origin := cached(ORIGIN_CACHE_OFFSET(), origin()) + } + sp, stackHead := pushStackItem(sp, _origin, stackHead) + ip := add(ip, 1) + } + case 0x33 { // OP_CALLER + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, caller(), stackHead) + ip := add(ip, 1) + } + case 0x34 { // OP_CALLVALUE + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, callvalue(), stackHead) + ip := add(ip, 1) + } + case 0x35 { // OP_CALLDATALOAD + evmGasLeft := chargeGas(evmGasLeft, 3) + + let calldataOffset := accessStackHead(sp, stackHead) + + stackHead := $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) + + ip := add(ip, 1) + } + case 0x36 { // OP_CALLDATASIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, $llvm_AlwaysInline_llvm$_calldatasize(), stackHead) + ip := add(ip, 1) + } + case 0x37 { // OP_CALLDATACOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + // EraVM will revert if offset + length overflows uint32 + if gt(sourceOffset, UINT32_MAX()) { + sourceOffset := UINT32_MAX() + } + + // Check bytecode out-of-bounds access + let truncatedLen := len + if gt(add(sourceOffset, len), UINT32_MAX()) { + truncatedLen := sub(UINT32_MAX(), sourceOffset) // truncate + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds + } + + if truncatedLen { + $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) + } + + ip := add(ip, 1) + + } + case 0x38 { // OP_CODESIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let bytecodeLen := mload(BYTECODE_LEN_OFFSET()) + sp, stackHead := pushStackItem(sp, bytecodeLen, stackHead) + ip := add(ip, 1) + } + case 0x39 { // OP_CODECOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + if gt(sourceOffset, MAX_UINT64()) { + sourceOffset := MAX_UINT64() + } + + sourceOffset := add(sourceOffset, BYTECODE_OFFSET()) + + if gt(sourceOffset, bytecodeEndOffset) { + sourceOffset := bytecodeEndOffset + } + + // Check bytecode out-of-bounds access + let truncatedLen := len + if gt(add(sourceOffset, len), bytecodeEndOffset) { + truncatedLen := sub(bytecodeEndOffset, sourceOffset) // truncate + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, truncatedLen), sub(len, truncatedLen)) // pad with zeroes any out-of-bounds + } + + if truncatedLen { + $llvm_AlwaysInline_llvm$_memcpy(dstOffset, sourceOffset, truncatedLen) + } + + ip := add(ip, 1) + } + case 0x3A { // OP_GASPRICE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _gasprice := mload(GASPRICE_CACHE_OFFSET()) + if iszero(_gasprice) { + _gasprice := cached(GASPRICE_CACHE_OFFSET(), gasprice()) + } + sp, stackHead := pushStackItem(sp, _gasprice, stackHead) + ip := add(ip, 1) + } + case 0x3B { // OP_EXTCODESIZE + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + let rawCodeHash := getRawCodeHash(addr) + switch shr(248, rawCodeHash) + case 1 { + stackHead := extcodesize(addr) + } + case 2 { + stackHead := and(shr(224, rawCodeHash), 0xffff) + } + default { + stackHead := 0 + } + + ip := add(ip, 1) + } + case 0x3C { // OP_EXTCODECOPY + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr, dstOffset, srcOffset, len + popStackCheck(sp, 4) + addr, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + srcOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + checkMemIsAccessible(dstOffset, len) + + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + address_access_cost + // minimum_word_size = (size + 31) / 32 + let dynamicGas := add( + mul(3, shr(5, add(len, 31))), + expandMemory(dstOffset, len) + ) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + dynamicGas := add(dynamicGas, 2500) + } + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + dstOffset := add(dstOffset, MEM_OFFSET()) + + if gt(srcOffset, MAX_UINT64()) { + srcOffset := MAX_UINT64() + } + + if gt(len, 0) { + // Gets the code from the addr + let copiedLen := fetchDeployedCode(addr, dstOffset, srcOffset, len) + + if lt(copiedLen, len) { + $llvm_AlwaysInline_llvm$_memsetToZero(add(dstOffset, copiedLen), sub(len, copiedLen)) + } + } + + ip := add(ip, 1) + } + case 0x3D { // OP_RETURNDATASIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let rdz := mload(LAST_RETURNDATA_SIZE_OFFSET()) + sp, stackHead := pushStackItem(sp, rdz, stackHead) + ip := add(ip, 1) + } + case 0x3E { // OP_RETURNDATACOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let dstOffset, sourceOffset, len + popStackCheck(sp, 3) + dstOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + sourceOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + len, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(dstOffset, len) + + // minimum_word_size = (size + 31) / 32 + // dynamicGas = 3 * minimum_word_size + memory_expansion_cost + let dynamicGas := add(mul(3, shr(5, add(len, 31))), expandMemory(dstOffset, len)) + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + checkOverflow(sourceOffset, len) + + // Check returndata out-of-bounds error + if gt(add(sourceOffset, len), mload(LAST_RETURNDATA_SIZE_OFFSET())) { + panic() + } + + copyActivePtrData(add(MEM_OFFSET(), dstOffset), sourceOffset, len) + ip := add(ip, 1) + } + case 0x3F { // OP_EXTCODEHASH + evmGasLeft := chargeGas(evmGasLeft, 100) + + let addr := accessStackHead(sp, stackHead) + addr := and(addr, 0xffffffffffffffffffffffffffffffffffffffff) + + if iszero($llvm_AlwaysInline_llvm$_warmAddress(addr)) { + evmGasLeft := chargeGas(evmGasLeft, 2500) + } + + let rawCodeHash := getRawCodeHash(addr) + switch isHashOfConstructedEvmContract(rawCodeHash) + case 0 { + let codeLen := and(shr(224, rawCodeHash), 0xffff) + + if codeLen { + if lt(addr, 0x100) { + // precompiles and 0x00 + codeLen := 0 + } + } + + switch codeLen + case 0 { + stackHead := EMPTY_KECCAK() + + if iszero(getRawNonce(addr)) { + if iszero(balance(addr)) { + stackHead := 0 + } + } + } + default { + // zkVM contract + stackHead := rawCodeHash + } + } + default { + // Get precalculated keccak of EVM code + stackHead := getEvmExtcodehash(addr) + } + + ip := add(ip, 1) + } + case 0x40 { // OP_BLOCKHASH + evmGasLeft := chargeGas(evmGasLeft, 20) + + stackHead := blockhash(accessStackHead(sp, stackHead)) + + ip := add(ip, 1) + } + case 0x41 { // OP_COINBASE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _coinbase := mload(COINBASE_CACHE_OFFSET()) + if iszero(_coinbase) { + _coinbase := cached(COINBASE_CACHE_OFFSET(), coinbase()) + } + sp, stackHead := pushStackItem(sp, _coinbase, stackHead) + ip := add(ip, 1) + } + case 0x42 { // OP_TIMESTAMP + evmGasLeft := chargeGas(evmGasLeft, 2) + let _blocktimestamp := mload(BLOCKTIMESTAMP_CACHE_OFFSET()) + if iszero(_blocktimestamp) { + _blocktimestamp := cached(BLOCKTIMESTAMP_CACHE_OFFSET(), timestamp()) + } + sp, stackHead := pushStackItem(sp, _blocktimestamp, stackHead) + ip := add(ip, 1) + } + case 0x43 { // OP_NUMBER + evmGasLeft := chargeGas(evmGasLeft, 2) + let _blocknumber := mload(BLOCKNUMBER_CACHE_OFFSET()) + if iszero(_blocknumber) { + _blocknumber := cached(BLOCKNUMBER_CACHE_OFFSET(), number()) + } + sp, stackHead := pushStackItem(sp, _blocknumber, stackHead) + ip := add(ip, 1) + } + case 0x44 { // OP_PREVRANDAO + evmGasLeft := chargeGas(evmGasLeft, 2) + let _prevrandao := mload(PREVRANDAO_CACHE_OFFSET()) + if iszero(_prevrandao) { + _prevrandao := cached(PREVRANDAO_CACHE_OFFSET(), prevrandao()) + } + sp, stackHead := pushStackItem(sp, _prevrandao, stackHead) + ip := add(ip, 1) + } + case 0x45 { // OP_GASLIMIT + evmGasLeft := chargeGas(evmGasLeft, 2) + let _gasLimit := mload(GASLIMIT_CACHE_OFFSET()) + if iszero(_gasLimit) { + _gasLimit := cached(GASLIMIT_CACHE_OFFSET(), gaslimit()) + } + sp, stackHead := pushStackItem(sp, _gasLimit, stackHead) + ip := add(ip, 1) + } + case 0x46 { // OP_CHAINID + evmGasLeft := chargeGas(evmGasLeft, 2) + let _chainId := mload(CHAINID_CACHE_OFFSET()) + if iszero(_chainId) { + _chainId := cached(CHAINID_CACHE_OFFSET(), chainid()) + } + sp, stackHead := pushStackItem(sp, _chainId, stackHead) + ip := add(ip, 1) + } + case 0x47 { // OP_SELFBALANCE + evmGasLeft := chargeGas(evmGasLeft, 5) + sp, stackHead := pushStackItem(sp, selfbalance(), stackHead) + ip := add(ip, 1) + } + case 0x48 { // OP_BASEFEE + evmGasLeft := chargeGas(evmGasLeft, 2) + let _baseFee := mload(BASEFEE_CACHE_OFFSET()) + if iszero(_baseFee) { + _baseFee := cached(BASEFEE_CACHE_OFFSET(), basefee()) + } + sp, stackHead := pushStackItem(sp, _baseFee, stackHead) + ip := add(ip, 1) + } + case 0x50 { // OP_POP + evmGasLeft := chargeGas(evmGasLeft, 2) + + let _y + + _y, sp, stackHead := popStackItem(sp, stackHead) + ip := add(ip, 1) + } + case 0x51 { // OP_MLOAD + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset := accessStackHead(sp, stackHead) + + checkMemIsAccessible(offset, 32) + let expansionGas := expandMemory(offset, 32) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + stackHead := mload(add(MEM_OFFSET(), offset)) + + ip := add(ip, 1) + } + case 0x52 { // OP_MSTORE + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset, value + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, 32) + let expansionGas := expandMemory(offset, 32) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + mstore(add(MEM_OFFSET(), offset), value) + ip := add(ip, 1) + } + case 0x53 { // OP_MSTORE8 + evmGasLeft := chargeGas(evmGasLeft, 3) + + let offset, value + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, 1) + let expansionGas := expandMemory(offset, 1) + evmGasLeft := chargeGas(evmGasLeft, expansionGas) + + mstore8(add(MEM_OFFSET(), offset), value) + ip := add(ip, 1) + } + case 0x54 { // OP_SLOAD + evmGasLeft := chargeGas(evmGasLeft, 100) + + let key := accessStackHead(sp, stackHead) + let wasWarm := isSlotWarm(key) + + if iszero(wasWarm) { + evmGasLeft := chargeGas(evmGasLeft, 2000) + } + + let value := sload(key) + + if iszero(wasWarm) { + let _wasW, _orgV := warmSlot(key, value) + } + + stackHead := value + ip := add(ip, 1) + } + case 0x55 { // OP_SSTORE + if isStatic { + panic() + } + + if lt(evmGasLeft, 2301) { // if <= 2300 + panic() + } + + let key, value + + popStackCheck(sp, 2) + key, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + ip := add(ip, 1) + + let dynamicGas := 100 + // Here it is okay to read before we charge since we known anyway that + // the context has enough funds to compensate at least for the read. + let currentValue := sload(key) + let wasWarm, originalValue := warmSlot(key, currentValue) + + if iszero(wasWarm) { + dynamicGas := add(dynamicGas, 2100) + } + + if eq(value, currentValue) { // no-op + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + continue + } + + if eq(originalValue, currentValue) { + switch originalValue + case 0 { + dynamicGas := add(dynamicGas, 19900) + } + default { + dynamicGas := add(dynamicGas, 2800) + } + } + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + sstore(key, value) + } + // NOTE: We don't currently do full jumpdest validation + // (i.e. validating a jumpdest isn't in PUSH data) + case 0x56 { // OP_JUMP + evmGasLeft := chargeGas(evmGasLeft, 9) // charge for OP_JUMP (8) and OP_JUMPDEST (1) immediately + + let counter + counter, sp, stackHead := popStackItem(sp, stackHead) + + // Counter certainly can't be bigger than uint64. + if gt(counter, MAX_UINT64()) { + panic() + } + + ip := add(BYTECODE_OFFSET(), counter) + + // Check next opcode is JUMPDEST + let nextOpcode := readIP(ip, bytecodeEndOffset) + if iszero(eq(nextOpcode, 0x5B)) { + panic() + } + + // execute JUMPDEST immediately + ip := add(ip, 1) + } + case 0x57 { // OP_JUMPI + evmGasLeft := chargeGas(evmGasLeft, 10) + + let counter, b + + popStackCheck(sp, 2) + counter, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + b, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + if iszero(b) { + ip := add(ip, 1) + continue + } + + // Counter certainly can't be bigger than uint64. + if gt(counter, MAX_UINT64()) { + panic() + } + + ip := add(BYTECODE_OFFSET(), counter) + + // Check next opcode is JUMPDEST + let nextOpcode := readIP(ip, bytecodeEndOffset) + if iszero(eq(nextOpcode, 0x5B)) { + panic() + } + + // execute JUMPDEST immediately + evmGasLeft := chargeGas(evmGasLeft, 1) + ip := add(ip, 1) + } + case 0x58 { // OP_PC + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, sub(ip, BYTECODE_OFFSET()), stackHead) + + ip := add(ip, 1) + } + case 0x59 { // OP_MSIZE + evmGasLeft := chargeGas(evmGasLeft, 2) + + let size + + size := mload(MEM_LEN_OFFSET()) + size := shl(5, size) + sp, stackHead := pushStackItem(sp, size, stackHead) + ip := add(ip, 1) + } + case 0x5A { // OP_GAS + evmGasLeft := chargeGas(evmGasLeft, 2) + + sp, stackHead := pushStackItem(sp, evmGasLeft, stackHead) + ip := add(ip, 1) + } + case 0x5B { // OP_JUMPDEST + evmGasLeft := chargeGas(evmGasLeft, 1) + ip := add(ip, 1) + } + case 0x5C { // OP_TLOAD + evmGasLeft := chargeGas(evmGasLeft, 100) + + stackHead := tload(accessStackHead(sp, stackHead)) + ip := add(ip, 1) + } + case 0x5D { // OP_TSTORE + evmGasLeft := chargeGas(evmGasLeft, 100) + + if isStatic { + panic() + } + + let key, value + popStackCheck(sp, 2) + key, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + value, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + tstore(key, value) + ip := add(ip, 1) + } + case 0x5E { // OP_MCOPY + evmGasLeft := chargeGas(evmGasLeft, 3) + + let destOffset, offset, size + popStackCheck(sp, 3) + destOffset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + checkMemIsAccessible(offset, size) + checkMemIsAccessible(destOffset, size) + + // dynamic_gas = 3 * words_copied + memory_expansion_cost + let dynamicGas := expandMemory2(offset, size, destOffset, size) + let wordsCopied := div(add(size, 31), 32) // div rounding up + dynamicGas := add(dynamicGas, mul(3, wordsCopied)) + + evmGasLeft := chargeGas(evmGasLeft, dynamicGas) + + mcopy(add(destOffset, MEM_OFFSET()), add(offset, MEM_OFFSET()), size) + ip := add(ip, 1) + } + case 0x5F { // OP_PUSH0 + evmGasLeft := chargeGas(evmGasLeft, 2) + + let value := 0 + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 1) + } + case 0x60 { // OP_PUSH1 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 1) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 1) + } + case 0x61 { // OP_PUSH2 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 2) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 2) + } + case 0x62 { // OP_PUSH3 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 3) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 3) + } + case 0x63 { // OP_PUSH4 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 4) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 4) + } + case 0x64 { // OP_PUSH5 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 5) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 5) + } + case 0x65 { // OP_PUSH6 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 6) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 6) + } + case 0x66 { // OP_PUSH7 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 7) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 7) + } + case 0x67 { // OP_PUSH8 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 8) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 8) + } + case 0x68 { // OP_PUSH9 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 9) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 9) + } + case 0x69 { // OP_PUSH10 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 10) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 10) + } + case 0x6A { // OP_PUSH11 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 11) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 11) + } + case 0x6B { // OP_PUSH12 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 12) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 12) + } + case 0x6C { // OP_PUSH13 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 13) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 13) + } + case 0x6D { // OP_PUSH14 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 14) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 14) + } + case 0x6E { // OP_PUSH15 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 15) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 15) + } + case 0x6F { // OP_PUSH16 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 16) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 16) + } + case 0x70 { // OP_PUSH17 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 17) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 17) + } + case 0x71 { // OP_PUSH18 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 18) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 18) + } + case 0x72 { // OP_PUSH19 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 19) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 19) + } + case 0x73 { // OP_PUSH20 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 20) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 20) + } + case 0x74 { // OP_PUSH21 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 21) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 21) + } + case 0x75 { // OP_PUSH22 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 22) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 22) + } + case 0x76 { // OP_PUSH23 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 23) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 23) + } + case 0x77 { // OP_PUSH24 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 24) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 24) + } + case 0x78 { // OP_PUSH25 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 25) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 25) + } + case 0x79 { // OP_PUSH26 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 26) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 26) + } + case 0x7A { // OP_PUSH27 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 27) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 27) + } + case 0x7B { // OP_PUSH28 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 28) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 28) + } + case 0x7C { // OP_PUSH29 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 29) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 29) + } + case 0x7D { // OP_PUSH30 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 30) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 30) + } + case 0x7E { // OP_PUSH31 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 31) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 31) + } + case 0x7F { // OP_PUSH32 + evmGasLeft := chargeGas(evmGasLeft, 3) + + ip := add(ip, 1) + let value := readBytes(ip, 32) + + sp, stackHead := pushStackItem(sp, value, stackHead) + ip := add(ip, 32) + } + case 0x80 { // OP_DUP1 + evmGasLeft := chargeGas(evmGasLeft, 3) + sp, stackHead := pushStackItem(sp, accessStackHead(sp, stackHead), stackHead) + ip := add(ip, 1) + } + case 0x81 { // OP_DUP2 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 2, stackHead) + ip := add(ip, 1) + } + case 0x82 { // OP_DUP3 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 3, stackHead) + ip := add(ip, 1) + } + case 0x83 { // OP_DUP4 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 4, stackHead) + ip := add(ip, 1) + } + case 0x84 { // OP_DUP5 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 5, stackHead) + ip := add(ip, 1) + } + case 0x85 { // OP_DUP6 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 6, stackHead) + ip := add(ip, 1) + } + case 0x86 { // OP_DUP7 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 7, stackHead) + ip := add(ip, 1) + } + case 0x87 { // OP_DUP8 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 8, stackHead) + ip := add(ip, 1) + } + case 0x88 { // OP_DUP9 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 9, stackHead) + ip := add(ip, 1) + } + case 0x89 { // OP_DUP10 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 10, stackHead) + ip := add(ip, 1) + } + case 0x8A { // OP_DUP11 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 11, stackHead) + ip := add(ip, 1) + } + case 0x8B { // OP_DUP12 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 12, stackHead) + ip := add(ip, 1) + } + case 0x8C { // OP_DUP13 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 13, stackHead) + ip := add(ip, 1) + } + case 0x8D { // OP_DUP14 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 14, stackHead) + ip := add(ip, 1) + } + case 0x8E { // OP_DUP15 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 15, stackHead) + ip := add(ip, 1) + } + case 0x8F { // OP_DUP16 + sp, evmGasLeft, stackHead := dupStackItem(sp, evmGasLeft, 16, stackHead) + ip := add(ip, 1) + } + case 0x90 { // OP_SWAP1 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 1, stackHead) + ip := add(ip, 1) + } + case 0x91 { // OP_SWAP2 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 2, stackHead) + ip := add(ip, 1) + } + case 0x92 { // OP_SWAP3 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 3, stackHead) + ip := add(ip, 1) + } + case 0x93 { // OP_SWAP4 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 4, stackHead) + ip := add(ip, 1) + } + case 0x94 { // OP_SWAP5 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 5, stackHead) + ip := add(ip, 1) + } + case 0x95 { // OP_SWAP6 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 6, stackHead) + ip := add(ip, 1) + } + case 0x96 { // OP_SWAP7 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 7, stackHead) + ip := add(ip, 1) + } + case 0x97 { // OP_SWAP8 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 8, stackHead) + ip := add(ip, 1) + } + case 0x98 { // OP_SWAP9 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 9, stackHead) + ip := add(ip, 1) + } + case 0x99 { // OP_SWAP10 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 10, stackHead) + ip := add(ip, 1) + } + case 0x9A { // OP_SWAP11 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 11, stackHead) + ip := add(ip, 1) + } + case 0x9B { // OP_SWAP12 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 12, stackHead) + ip := add(ip, 1) + } + case 0x9C { // OP_SWAP13 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 13, stackHead) + ip := add(ip, 1) + } + case 0x9D { // OP_SWAP14 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 14, stackHead) + ip := add(ip, 1) + } + case 0x9E { // OP_SWAP15 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 15, stackHead) + ip := add(ip, 1) + } + case 0x9F { // OP_SWAP16 + evmGasLeft, stackHead := swapStackItem(sp, evmGasLeft, 16, stackHead) + ip := add(ip, 1) + } + case 0xA0 { // OP_LOG0 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 0, isStatic) + log0(offset, size) + ip := add(ip, 1) + } + case 0xA1 { // OP_LOG1 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 1, isStatic) + { + let topic1 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log1(offset, size, topic1) + } + ip := add(ip, 1) + } + case 0xA2 { // OP_LOG2 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 2, isStatic) + + { + let topic1, topic2 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log2(offset, size, topic1, topic2) + } + ip := add(ip, 1) + } + case 0xA3 { // OP_LOG3 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 3, isStatic) + + { + let topic1, topic2, topic3 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log3(offset, size, topic1, topic2, topic3) + } + ip := add(ip, 1) + } + case 0xA4 { // OP_LOG4 + let offset, size + evmGasLeft, offset, size, sp, stackHead := _genericLog(sp, stackHead, evmGasLeft, 4, isStatic) + + { + let topic1, topic2, topic3, topic4 + topic1, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic2, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic3, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + topic4, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + log4(offset, size, topic1, topic2, topic3, topic4) + } + ip := add(ip, 1) + } + case 0xF0 { // OP_CREATE + evmGasLeft := chargeGas(evmGasLeft, 32000) + + if isStatic { + panic() + } + + evmGasLeft, sp, stackHead := performCreate(evmGasLeft, sp, stackHead) + ip := add(ip, 1) + } + case 0xF1 { // OP_CALL + // A function was implemented in order to avoid stack depth errors. + evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead, isStatic) + ip := add(ip, 1) + } + case 0xF3 { // OP_RETURN + let offset, size + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + if size { + checkMemIsAccessible(offset, size) + + evmGasLeft := chargeGas(evmGasLeft, expandMemory(offset, size)) + + returnLen := size + + // Don't check overflow here since previous checks are enough to ensure this is safe + returnOffset := add(MEM_OFFSET(), offset) + } + + break + } + case 0xF4 { // OP_DELEGATECALL + evmGasLeft, sp, stackHead := performDelegateCall(sp, evmGasLeft, isStatic, stackHead) + ip := add(ip, 1) + } + case 0xF5 { // OP_CREATE2 + evmGasLeft := chargeGas(evmGasLeft, 32000) + + if isStatic { + panic() + } + + evmGasLeft, sp, stackHead := performCreate2(evmGasLeft, sp, stackHead) + ip := add(ip, 1) + } + case 0xFA { // OP_STATICCALL + evmGasLeft, sp, stackHead := performStaticCall(sp, evmGasLeft, stackHead) + ip := add(ip, 1) + } + case 0xFD { // OP_REVERT + let offset,size + + popStackCheck(sp, 2) + offset, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + size, sp, stackHead := popStackItemWithoutCheck(sp, stackHead) + + switch iszero(size) + case 0 { + checkMemIsAccessible(offset, size) + evmGasLeft := chargeGas(evmGasLeft, expandMemory(offset, size)) + + // Don't check overflow here since previous checks are enough to ensure this is safe + offset := add(offset, MEM_OFFSET()) + } + default { + offset := MEM_OFFSET() + } + + + if eq(isCallerEVM, 1) { + offset := sub(offset, 32) + size := add(size, 32) + + // include gas + mstore(offset, evmGasLeft) + } + + revert(offset, size) + } + case 0xFE { // OP_INVALID + evmGasLeft := 0 + revertWithGas(evmGasLeft) + } + // We explicitly add unused opcodes to optimize the jump table by compiler. + + default { + $llvm_NoInline_llvm$_panic() + } +} diff --git a/system-contracts/evm-emulator/EvmEmulatorLoopUnusedOpcodes.template.yul b/system-contracts/evm-emulator/EvmEmulatorLoopUnusedOpcodes.template.yul new file mode 100644 index 000000000..a59e4eb58 --- /dev/null +++ b/system-contracts/evm-emulator/EvmEmulatorLoopUnusedOpcodes.template.yul @@ -0,0 +1,333 @@ +case 0x0C { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x0D { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x0E { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x0F { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x1E { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x1F { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x21 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x22 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x23 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x24 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x25 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x26 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x27 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x28 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x29 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x2A { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x2B { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x2C { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x2D { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x2E { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x2F { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x49 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x4A { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x4B { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x4C { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x4D { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x4E { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0x4F { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xA5 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xA6 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xA7 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xA8 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xA9 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xAA { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xAB { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xAC { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xAD { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xAE { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xAF { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB0 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB1 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB2 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB3 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB4 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB5 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB6 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB7 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB8 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xB9 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xBA { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xBB { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xBC { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xBD { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xBE { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xBF { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC0 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC1 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC2 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC3 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC4 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC5 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC6 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC7 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC8 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xC9 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xCA { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xCB { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xCC { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xCD { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xCE { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xCF { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD0 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD1 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD2 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD3 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD4 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD5 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD6 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD7 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD8 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xD9 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xDA { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xDB { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xDC { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xDD { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xDE { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xDF { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE0 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE1 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE2 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE3 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE4 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE5 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE6 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE7 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE8 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xE9 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xEA { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xEB { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xEC { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xED { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xEE { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xEF { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xF2 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xF6 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xF7 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xF8 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xF9 { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xFB { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xFC { // Unused opcode + $llvm_NoInline_llvm$_panic() +} +case 0xFF { // Unused opcode + $llvm_NoInline_llvm$_panic() +} \ No newline at end of file diff --git a/system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul b/system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul new file mode 100644 index 000000000..075f4dfaa --- /dev/null +++ b/system-contracts/evm-emulator/calldata-opcodes/ConstructorScope.template.yul @@ -0,0 +1,11 @@ +function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := 0 +} + +function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + $llvm_AlwaysInline_llvm$_memsetToZero(dstOffset, truncatedLen) +} + +function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + res := 0 +} \ No newline at end of file diff --git a/system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul b/system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul new file mode 100644 index 000000000..51c88e7b5 --- /dev/null +++ b/system-contracts/evm-emulator/calldata-opcodes/RuntimeScope.template.yul @@ -0,0 +1,14 @@ +function $llvm_AlwaysInline_llvm$_calldatasize() -> size { + size := calldatasize() +} + +function $llvm_AlwaysInline_llvm$_calldatacopy(dstOffset, sourceOffset, truncatedLen) { + calldatacopy(dstOffset, sourceOffset, truncatedLen) +} + +function $llvm_AlwaysInline_llvm$_calldataload(calldataOffset) -> res { + // EraVM will revert if offset + length overflows uint32 + if lt(calldataOffset, UINT32_MAX()) { + res := calldataload(calldataOffset) + } +} \ No newline at end of file diff --git a/system-contracts/evm-emulator/drafted/EvmEmulatorModexpGas.template.yul b/system-contracts/evm-emulator/drafted/EvmEmulatorModexpGas.template.yul new file mode 100644 index 000000000..ba018dae1 --- /dev/null +++ b/system-contracts/evm-emulator/drafted/EvmEmulatorModexpGas.template.yul @@ -0,0 +1,85 @@ +/// (!) Note: this code is unused until we have modexp precompile support +/// This is draft, it is necessary to take into account the case when argsSize is less than expected (data is truncated and padded with zeroes) +/// Also we need to check sanity of Bsize, Esize, Msize + +/// @dev credit to https://github.com/PaulRBerg/prb-math/blob/280fc5f77e1b21b9c54013aac51966be33f4a410/src/Common.sol#L323 +function msb(x) -> result { + let factor := shl(7, gt(x, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) // 2^128 + x := shr(factor, x) + result := or(result, factor) + factor := shl(6, gt(x, 0xFFFFFFFFFFFFFFFF)) // 2^64 + x := shr(factor, x) + result := or(result, factor) + factor := shl(5, gt(x, 0xFFFFFFFF)) // 2^32 + x := shr(factor, x) + result := or(result, factor) + factor := shl(4, gt(x, 0xFFFF)) // 2^16 + x := shr(factor, x) + result := or(result, factor) + factor := shl(3, gt(x, 0xFF)) // 2^8 + x := shr(factor, x) + result := or(result, factor) + factor := shl(2, gt(x, 0xF)) // 2^4 + x := shr(factor, x) + result := or(result, factor) + factor := shl(1, gt(x, 0x3)) // 2^2 + x := shr(factor, x) + result := or(result, factor) + factor := gt(x, 0x1) // 2^1 + // No need to shift x any more. + result := or(result, factor) +} + +// modexp gas cost EIP below +// https://eips.ethereum.org/EIPS/eip-2565 +// [0; 31] (32 bytes) Bsize Byte size of B +// [32; 63] (32 bytes) Esize Byte size of E +// [64; 95] (32 bytes) Msize Byte size of M +let Bsize := mload(argsOffset) +let Esize := mload(add(argsOffset, 0x20)) + +let mulComplex +{ + // mult_complexity(Bsize, Msize), EIP-2565 + let words := getMax(Bsize, mload(add(argsOffset, 0x40))) + words := div(add(words, 7), 8) // TODO OVERFLOW CHECKS + mulComplex := mul(words, words) +} + +/* +def calculate_iteration_count(exponent_length, exponent): + iteration_count = 0 + if exponent_length <= 32 and exponent == 0: iteration_count = 0 + elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 + elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) + return max(iteration_count, 1) +*/ +// [96 + Bsize; 96 + Bsize + Esize] E +let iterationCount := 0 +let expOffset := add(add(argsOffset, 0x60), Bsize) +switch gt(Esize, 32) +case 0 { // if exponent_length <= 32 + let exponent := mload(expOffset) // load 32 bytes + exponent := shr(sub(32, Esize), exponent) // shift to the right if Esize not 32 bytes + + // if exponent_length <= 32 and exponent == 0: iteration_count = 0 + // elif exponent_length <= 32: iteration_count = exponent.bit_length() - 1 + if exponent { + iterationCount := msb(exponent) + } +} +default { // elif exponent_length > 32 + // elif exponent_length > 32: iteration_count = (8 * (exponent_length - 32)) + ((exponent & (2**256 - 1)).bit_length() - 1) + + // load last 32 bytes of exponent + let exponentLast256 := mload(add(expOffset, sub(Esize, 32))) + iterationCount := add(mul(8, sub(Esize, 32)), msb(exponentLast256)) +} +if iszero(iterationCount) { + iterationCount := 1 +} + +/* + return max(200, math.floor(multiplication_complexity * iteration_count / 3)) +*/ +gasToCharge := getMax(200, div(mul(mulComplex, iterationCount), 3)) \ No newline at end of file diff --git a/system-contracts/foundry.toml b/system-contracts/foundry.toml index 06485883a..c39d07a00 100644 --- a/system-contracts/foundry.toml +++ b/system-contracts/foundry.toml @@ -3,12 +3,14 @@ src = "contracts-preprocessed" out = "out" libs = ["lib"] cache_path = "cache-forge" -evm_version = "paris" +evm_version = "cancun" +solc_version = "0.8.24" remappings = [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/", ] [profile.default.zksync] -zksolc = "1.5.0" +zksolc = "1.5.7" enable_eravm_extensions = true +suppressed_errors = ["sendtransfer"] diff --git a/system-contracts/hardhat.config.ts b/system-contracts/hardhat.config.ts index 7ad59a41f..a6e5dc44a 100644 --- a/system-contracts/hardhat.config.ts +++ b/system-contracts/hardhat.config.ts @@ -5,28 +5,13 @@ import "@matterlabs/hardhat-zksync-verify"; 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: { + version: "1.5.7", compilerSource: "binary", settings: { - compilerPath: getZksolcUrl(), - isSystem: true, + enableEraVMExtensions: true, + suppressedErrors: ["sendtransfer"], }, }, zkSyncDeploy: { diff --git a/system-contracts/package.json b/system-contracts/package.json index ef53db110..c2bda4785 100644 --- a/system-contracts/package.json +++ b/system-contracts/package.json @@ -5,7 +5,7 @@ "license": "MIT", "dependencies": { "@matterlabs/hardhat-zksync-deploy": "^0.7.0", - "@matterlabs/hardhat-zksync-solc": "^1.1.4", + "@matterlabs/hardhat-zksync-solc": "^1.2.5", "@matterlabs/hardhat-zksync-verify": "^1.4.3", "commander": "^9.4.1", "eslint": "^8.51.0", @@ -50,9 +50,9 @@ ] }, "scripts": { - "build": "yarn build:system-contracts && yarn build:bootloader", + "build": "yarn build:system-contracts && yarn build:bootloader && forge build --zksync", "build:bootloader": "yarn preprocess:bootloader && yarn compile-yul compile-bootloader", - "build:system-contracts": "yarn preprocess:system-contracts && hardhat compile && yarn compile-yul compile-precompiles", + "build:system-contracts": "yarn preprocess:emulator && yarn preprocess:system-contracts && hardhat compile && yarn compile-yul compile-precompiles", "build:test-system-contracts": "yarn preprocess:system-contracts --test-mode && hardhat compile && yarn compile-yul compile-precompiles && yarn compile-zasm", "calculate-hashes:check": "ts-node scripts/calculate-hashes.ts --check-only", "calculate-hashes:fix": "ts-node scripts/calculate-hashes.ts", @@ -63,6 +63,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:emulator": "rm -f ./contracts/EvmEmulator.yul && yarn ts-node scripts/preprocess-emulator.ts", "preprocess:system-contracts": "rm -rf ./contracts-preprocessed && ts-node scripts/preprocess-system-contracts.ts", "verify-on-explorer": "hardhat run scripts/verify-on-explorer.ts", "test": "yarn build:test-system-contracts && hardhat test --network zkSyncTestNode", diff --git a/system-contracts/scripts/calculate-hashes.ts b/system-contracts/scripts/calculate-hashes.ts index 1b9f355a5..7ecb66723 100644 --- a/system-contracts/scripts/calculate-hashes.ts +++ b/system-contracts/scripts/calculate-hashes.ts @@ -55,17 +55,23 @@ const getSolidityContractDetails = (dir: string, contractName: string): Contract }; const getSolidityContractsDetails = (dir: string): ContractDetails[] => { + const absolutePath = makePathAbsolute(dir); + const eligibleFiles = fs + .readdirSync(absolutePath) + .filter((f) => f.endsWith(".sol")) + .map((f) => f.replace(".sol", "")); const bytecodesDir = SOLIDITY_ARTIFACTS_DIR; const dirsEndingWithSol = findDirsEndingWith(bytecodesDir, ".sol"); - const contractNames = dirsEndingWithSol.map((d) => d.replace(".sol", "")); + const contractNames = dirsEndingWithSol.map((d) => d.replace(".sol", "")).filter((c) => eligibleFiles.includes(c)); const solidityContractsDetails = contractNames.map((c) => getSolidityContractDetails(dir, c)); return solidityContractsDetails; }; -const YUL_ARTIFACTS_DIR = "artifacts"; +const YUL_ARTIFACTS_DIR = "zkout"; const getYulContractDetails = (dir: string, contractName: string): ContractDetails => { - const bytecodePath = join(dir, YUL_ARTIFACTS_DIR, contractName + ".yul.zbin"); + const artifactPath = dir !== "bootloader/build" ? dir : "contracts-preprocessed/bootloader"; + const bytecodePath = join(YUL_ARTIFACTS_DIR, contractName + ".yul", artifactPath, contractName + ".yul.json"); const sourceCodePath = join(dir, contractName + ".yul"); return { contractName, @@ -102,7 +108,7 @@ const readBytecode = (details: ContractDetails): string => { const jsonFile = fs.readFileSync(absolutePath, "utf8"); return ethers.utils.hexlify("0x" + JSON.parse(jsonFile).bytecode.object); } else { - return ethers.utils.hexlify(fs.readFileSync(absolutePath)); + return ethers.utils.hexlify(fs.readFileSync(absolutePath).toString(), { allowMissingPrefix: true }); } } catch (err) { const msg = err instanceof Error ? err.message : "Unknown error"; diff --git a/system-contracts/scripts/compile-yul.ts b/system-contracts/scripts/compile-yul.ts index 67b468987..fc023f359 100644 --- a/system-contracts/scripts/compile-yul.ts +++ b/system-contracts/scripts/compile-yul.ts @@ -1,30 +1,35 @@ // hardhat import should be the first import in the file +import { existsSync } from "fs"; import type { CompilerPaths } from "./utils"; -import { - spawn, - compilerLocation, - prepareCompilerPaths, - getSolcLocation, - needsRecompilation, - setCompilationTime, -} from "./utils"; +import { spawn, compilerLocation, prepareCompilerPaths, 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 COMPILER_VERSION = "1.5.7"; +const IS_COMPILER_PRE_RELEASE = false; 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"; +const LLVM_OPTIONS_FILE_EXTENSION = ".llvm.options"; export async function compileYul(paths: CompilerPaths, file: string) { - const solcCompilerPath = await getSolcLocation(); - const zksolcLocation = await compilerLocation(COMPILER_VERSION, IS_COMPILER_PRE_RELEASE); + + const filePath = `${paths.absolutePathSources}/${file}`; + const llvmOptionsFilePath = `${filePath}${LLVM_OPTIONS_FILE_EXTENSION}`; + let llvmOptions = ""; + if (existsSync(llvmOptionsFilePath)) { + const llvmOptionsFileContent = (await fs.promises.readFile(llvmOptionsFilePath)).toString(); + if (!llvmOptionsFileContent.startsWith("'") || !llvmOptionsFileContent.endsWith("'")) { + throw new Error(`Content in ${llvmOptionsFilePath} must start and end with a single quote.`); + } + llvmOptions = `--llvm-options=${llvmOptionsFileContent}`; + } + await spawn( - `${zksolcLocation} ${paths.absolutePathSources}/${file} --solc ${solcCompilerPath} --optimization 3 --system-mode --yul --bin --overwrite -o ${paths.absolutePathArtifacts}` + `${zksolcLocation} ${paths.absolutePathSources}/${file} --optimization 3 ${llvmOptions} --enable-eravm-extensions --yul --bin --overwrite -o ${paths.absolutePathArtifacts}` ); } diff --git a/system-contracts/scripts/compile-zasm.ts b/system-contracts/scripts/compile-zasm.ts index 2e6e828a9..de0f84d4c 100644 --- a/system-contracts/scripts/compile-zasm.ts +++ b/system-contracts/scripts/compile-zasm.ts @@ -3,13 +3,13 @@ import type { CompilerPaths } from "./utils"; import { spawn, compilerLocation, prepareCompilerPaths } from "./utils"; import * as fs from "fs"; -const COMPILER_VERSION = "1.3.18"; -const IS_COMPILER_PRE_RELEASE = true; +const COMPILER_VERSION = "1.5.7"; +const IS_COMPILER_PRE_RELEASE = false; export async function compileZasm(paths: CompilerPaths, file: string) { const zksolcLocation = await compilerLocation(COMPILER_VERSION, IS_COMPILER_PRE_RELEASE); await spawn( - `${zksolcLocation} ${paths.absolutePathSources}/${file} --zkasm --bin --overwrite -o ${paths.absolutePathArtifacts}` + `${zksolcLocation} ${paths.absolutePathSources}/${file} --eravm-assembly --bin --overwrite -o ${paths.absolutePathArtifacts}` ); } diff --git a/system-contracts/scripts/deploy-preimages.ts b/system-contracts/scripts/deploy-preimages.ts index 0029f56a0..5ff77ce76 100644 --- a/system-contracts/scripts/deploy-preimages.ts +++ b/system-contracts/scripts/deploy-preimages.ts @@ -13,7 +13,14 @@ 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"; +import { + checkMarkers, + filterPublishedFactoryDeps, + getBytecodes, + publishFactoryDeps, + readBytecodeUtf8, + readYulBytecode, +} from "./utils"; const testConfigPath = path.join(process.env.ZKSYNC_HOME as string, "etc/test_config/constant"); const ethTestConfig = JSON.parse(fs.readFileSync(`${testConfigPath}/eth.json`, { encoding: "utf-8" })); @@ -23,6 +30,7 @@ const MAX_COMBINED_LENGTH = 125000; const DEFAULT_ACCOUNT_CONTRACT_NAME = "DefaultAccount"; const BOOTLOADER_CONTRACT_NAME = "Bootloader"; +const EVM_EMULATOR_CONTRACT_NAME = "EvmEmulator"; const CONSOLE_COLOR_RESET = "\x1b[0m"; const CONSOLE_COLOR_RED = "\x1b[31m"; @@ -157,6 +165,55 @@ class ZkSyncDeployer { return await zkSync.getL2BootloaderBytecodeHash(); } + // Returns the current evm emulator bytecode on zkSync + async currentEvmEmulatorBytecode(): Promise { + const zkSync = await this.deployer.zkWallet.getMainContract(); + return await zkSync.getL2EvmEmulatorBytecodeHash(); + } + + // If needed, appends the evm emulator bytecode to the upgrade + async checkShouldUpgradeEvmEmulator(evmEmulatorBytecode: string) { + const bytecodeHash = ethers.utils.hexlify(hashBytecode(evmEmulatorBytecode)); + const currentEvmEmulatorBytecode = ethers.utils.hexlify(await this.currentEvmEmulatorBytecode()); + + // If the bytecode is not the same as the one deployed on zkSync, we need to add it to the deployment + if (bytecodeHash.toLowerCase() !== currentEvmEmulatorBytecode) { + this.defaultAccountToUpgrade = { + name: EVM_EMULATOR_CONTRACT_NAME, + bytecodeHashes: [bytecodeHash], + }; + } + } + + // Publishes the bytecode of the evm emulator and appends it to the deployed bytecodes if needed. + async processEvmEmulator() { + const defaultEvmEmulator = (await this.deployer.loadArtifact(EVM_EMULATOR_CONTRACT_NAME)).bytecode; + + await this.publishEvmEmulator(defaultEvmEmulator); + await this.checkShouldUpgradeEvmEmulator(defaultEvmEmulator); + } + + async publishEvmEmulator(defaultEvmEmulatorBytecode: string) { + const [defaultEvmEmulatorBytecodes] = await filterPublishedFactoryDeps( + EVM_EMULATOR_CONTRACT_NAME, + [defaultEvmEmulatorBytecode], + this.deployer + ); + + if (defaultEvmEmulatorBytecodes.length == 0) { + console.log("Default evm emulator is already published, skipping"); + return; + } + + // Publish evm emulator bytecode + await this.publishFactoryDeps([ + { + name: EVM_EMULATOR_CONTRACT_NAME, + bytecodes: defaultEvmEmulatorBytecodes, + }, + ]); + } + async checkShouldUpgradeBootloader(bootloaderCode: string) { const bytecodeHash = ethers.utils.hexlify(hashBytecode(bootloaderCode)); const currentBootloaderBytecode = ethers.utils.hexlify(await this.currentBootloaderBytecode()); @@ -189,7 +246,7 @@ class ZkSyncDeployer { } async processBootloader() { - const bootloaderCode = ethers.utils.hexlify(fs.readFileSync("./bootloader/build/artifacts/proved_batch.yul.zbin")); + const bootloaderCode = readBytecodeUtf8("./bootloader/build/artifacts/proved_batch.yul/proved_batch.yul.zbin"); await this.publishBootloader(bootloaderCode); await this.checkShouldUpgradeBootloader(bootloaderCode); @@ -302,6 +359,7 @@ async function main() { .option("--l2Rpc ") .option("--bootloader") .option("--default-aa") + .option("--evm-emulator") .option("--system-contracts") .option("--file ") .action(async (cmd) => { @@ -340,6 +398,10 @@ async function main() { await zkSyncDeployer.processDefaultAA(); } + if (cmd.evmEmulator) { + await zkSyncDeployer.processEvmEmulator(); + } + if (cmd.systemContracts) { const dependenciesToPublish = await zkSyncDeployer.prepareContractsForPublishing(); await zkSyncDeployer.publishDependencies(dependenciesToPublish); diff --git a/system-contracts/scripts/preprocess-emulator.ts b/system-contracts/scripts/preprocess-emulator.ts new file mode 100644 index 000000000..5f49df926 --- /dev/null +++ b/system-contracts/scripts/preprocess-emulator.ts @@ -0,0 +1,22 @@ +import { writeFileSync, readFileSync } from "fs"; + +/* eslint-disable @typescript-eslint/no-var-requires */ +const preprocess = require("preprocess"); +/* eslint-enable@typescript-eslint/no-var-requires */ + +const OUTPUT_DIR = "contracts"; +const INPUT_DIR = "evm-emulator"; + +async function main() { + process.chdir(`${INPUT_DIR}`); + const emulatorSource = readFileSync("EvmEmulator.template.yul").toString(); + + console.log("Preprocessing Emulator"); + const emulator = preprocess.preprocess(emulatorSource); + + writeFileSync(`../${OUTPUT_DIR}/EvmEmulator.yul`, emulator); + + console.log("Emulator preprocessing done!"); +} + +main(); diff --git a/system-contracts/scripts/preprocess-system-contracts.ts b/system-contracts/scripts/preprocess-system-contracts.ts index 0b3690a9e..4237ed12e 100644 --- a/system-contracts/scripts/preprocess-system-contracts.ts +++ b/system-contracts/scripts/preprocess-system-contracts.ts @@ -1,4 +1,4 @@ -import { existsSync, mkdirSync, writeFileSync } from "fs"; +import { copyFileSync, existsSync, mkdirSync, writeFileSync } from "fs"; import path from "path"; import { renderFile } from "template-file"; import { glob } from "fast-glob"; @@ -8,6 +8,7 @@ import { needsRecompilation, deleteDir, setCompilationTime, isFolderEmpty } from const CONTRACTS_DIR = "contracts"; const OUTPUT_DIR = "contracts-preprocessed"; const TIMESTAMP_FILE = "last_compilation_preprocessing.timestamp"; // File to store the last compilation time +const LLVM_OPTIONS_FILE_EXTENSION = ".llvm.options"; const params = { SYSTEM_CONTRACTS_OFFSET: "0x8000", @@ -44,6 +45,9 @@ async function preprocess(testMode: boolean) { mkdirSync(directory, { recursive: true }); } writeFileSync(fileName, preprocessed); + if (existsSync(contract + LLVM_OPTIONS_FILE_EXTENSION)) { + copyFileSync(contract + LLVM_OPTIONS_FILE_EXTENSION, fileName + LLVM_OPTIONS_FILE_EXTENSION); + } } console.log("System Contracts preprocessing done!"); diff --git a/system-contracts/scripts/utils.ts b/system-contracts/scripts/utils.ts index 4c1060ee2..cfba8345a 100644 --- a/system-contracts/scripts/utils.ts +++ b/system-contracts/scripts/utils.ts @@ -34,14 +34,18 @@ export interface DeployedDependency { export function readYulBytecode(description: YulContractDescription) { const contractName = description.codeName; - const path = `contracts-preprocessed/${description.path}/artifacts/${contractName}.yul.zbin`; - return ethers.utils.hexlify(fs.readFileSync(path)); + const path = `contracts-preprocessed/${description.path}/artifacts/${contractName}.yul/${contractName}.yul.zbin`; + return readBytecodeUtf8(path); } export function readZasmBytecode(description: ZasmContractDescription) { const contractName = description.codeName; - const path = `contracts-preprocessed/${description.path}/artifacts/${contractName}.zasm.zbin`; - return ethers.utils.hexlify(fs.readFileSync(path)); + const path = `contracts-preprocessed/${description.path}/artifacts/${contractName}.zasm/${contractName}.zasm.zbin`; + return readBytecodeUtf8(path); +} + +export function readBytecodeUtf8(path: string) { + return ethers.utils.hexlify(fs.readFileSync(path).toString(), { allowMissingPrefix: true }); } // The struct used to represent the parameters of a forced deployment -- a deployment during upgrade diff --git a/system-contracts/test/AccountCodeStorage.spec.ts b/system-contracts/test/AccountCodeStorage.spec.ts index dca782e01..f1b44a051 100644 --- a/system-contracts/test/AccountCodeStorage.spec.ts +++ b/system-contracts/test/AccountCodeStorage.spec.ts @@ -11,6 +11,7 @@ import { } from "./shared/constants"; import { prepareEnvironment, setResult } from "./shared/mocks"; import { deployContractOnAddress, getWallets } from "./shared/utils"; +import { ZERO_HASH } from "zksync-ethers/build/utils"; describe("AccountCodeStorage tests", function () { let wallet: Wallet; @@ -20,6 +21,7 @@ describe("AccountCodeStorage tests", function () { const CONSTRUCTING_BYTECODE_HASH = "0x0101FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; const CONSTRUCTED_BYTECODE_HASH = "0x0100FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; + const CONSTRUCTED_EVM_BYTECODE_HASH = "0x0200FFFFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEFDEADBEEF"; const RANDOM_ADDRESS = "0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"; before(async () => { @@ -143,6 +145,22 @@ describe("AccountCodeStorage tests", function () { }); }); + describe("isAccountEVM", function () { + it("false", async () => { + expect(await accountCodeStorage.isAccountEVM(RANDOM_ADDRESS)).to.be.eq(false); + }); + + it("true", async () => { + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_EVM_BYTECODE_HASH); + + expect(await accountCodeStorage.isAccountEVM(RANDOM_ADDRESS)).to.be.eq(true); + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + }); + describe("getCodeHash", function () { it("precompile min address", async () => { // Check that the smallest precompile has EMPTY_STRING_KECCAK hash @@ -186,6 +204,18 @@ describe("AccountCodeStorage tests", function () { await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); }); + it("constructed EVM contract", async () => { + await deployContractOnAddress(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, "ContractDeployer", false); + + await accountCodeStorage + .connect(deployerAccount) + .storeAccountConstructedCodeHash(RANDOM_ADDRESS, CONSTRUCTED_EVM_BYTECODE_HASH); + + expect(await accountCodeStorage.getCodeHash(RANDOM_ADDRESS)).to.be.eq(ZERO_HASH); // contract deployer doesn't have this contract hash + + await unsetCodeHash(accountCodeStorage, RANDOM_ADDRESS); + }); + it("zero", async () => { await setResult("NonceHolder", "getRawNonce", [RANDOM_ADDRESS], { failure: false, diff --git a/system-contracts/test/ContractDeployer.spec.ts b/system-contracts/test/ContractDeployer.spec.ts index bcae882c0..df4603710 100644 --- a/system-contracts/test/ContractDeployer.spec.ts +++ b/system-contracts/test/ContractDeployer.spec.ts @@ -43,7 +43,7 @@ describe("ContractDeployer tests", function () { await prepareEnvironment(); wallet = getWallets()[0]; - await deployContractOnAddress(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, "ContractDeployer"); + await deployContractOnAddress(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, "ContractDeployer", false); contractDeployer = ContractDeployerFactory.connect(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, wallet); const contractDeployerSystemCallContract = await deployContract("SystemCaller", [contractDeployer.address]); @@ -66,6 +66,25 @@ describe("ContractDeployer tests", function () { }); }); + describe("setAllowedBytecodeTypesToDeploy", function () { + it("can't change if not forceDeployer", async () => { + const newContractDeployer = await deployContract("ContractDeployer", []); + + expect(newContractDeployer.setAllowedBytecodeTypesToDeploy(1)).to.be.revertedWithCustomError( + newContractDeployer, + "Unauthorized" + ); + }); + + it("successfully updated allowedBytecodeTypesToDeploy", async () => { + const newContractDeployer = await deployContract("ContractDeployer", []); + + expect(await newContractDeployer.allowedBytecodeTypesToDeploy()).to.be.eq(0); + await newContractDeployer.connect(forceDeployer).setAllowedBytecodeTypesToDeploy(1); + expect(await newContractDeployer.allowedBytecodeTypesToDeploy()).to.be.eq(1); + }); + }); + describe("updateAccountVersion", function () { it("non system call failed", async () => { await expect(contractDeployer.updateAccountVersion(AA_VERSION_NONE)).to.be.revertedWithCustomError( diff --git a/system-contracts/test/KnownCodesStorage.spec.ts b/system-contracts/test/KnownCodesStorage.spec.ts index 36a034cb7..5444c519d 100644 --- a/system-contracts/test/KnownCodesStorage.spec.ts +++ b/system-contracts/test/KnownCodesStorage.spec.ts @@ -6,6 +6,7 @@ import { KnownCodesStorageFactory } from "../typechain"; import { TEST_BOOTLOADER_FORMAL_ADDRESS, TEST_COMPRESSOR_CONTRACT_ADDRESS, + TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS, TEST_KNOWN_CODE_STORAGE_CONTRACT_ADDRESS, } from "./shared/constants"; import { encodeCalldata, getMock, prepareEnvironment } from "./shared/mocks"; @@ -84,6 +85,36 @@ describe("KnownCodesStorage tests", function () { }); }); + describe("publishEVMBytecode", function () { + let deployerAccount: ethers.Signer; + + const InvalidBytecode = + "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"; + + beforeEach(async () => { + deployerAccount = await ethers.getImpersonatedSigner(TEST_DEPLOYER_SYSTEM_CONTRACT_ADDRESS); + }); + + it("non-deployer failed to call", async () => { + await expect(knownCodesStorage.publishEVMBytecode(1, "0x00")).to.be.revertedWithCustomError( + knownCodesStorage, + "Unauthorized" + ); + }); + + it("bytecode with even length failed to publish", async () => { + await expect( + knownCodesStorage.connect(deployerAccount).publishEVMBytecode(64, InvalidBytecode) + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); + }); + + it("invalid length bytecode failed to call", async () => { + await expect( + knownCodesStorage.connect(deployerAccount).publishEVMBytecode(1, "0x00") + ).to.be.revertedWithCustomError(knownCodesStorage, "MalformedBytecode"); + }); + }); + describe("markFactoryDeps", function () { it("non-bootloader failed to call", async () => { await expect( diff --git a/system-contracts/test/L2BaseToken.spec.ts b/system-contracts/test/L2BaseToken.spec.ts index d73f0444d..f4d9c5c92 100644 --- a/system-contracts/test/L2BaseToken.spec.ts +++ b/system-contracts/test/L2BaseToken.spec.ts @@ -146,27 +146,6 @@ describe("L2BaseToken tests", () => { }); }); - describe("name", () => { - it("correct name", async () => { - const name = await L2BaseToken.name(); - expect(name).to.equal("Ether"); - }); - }); - - describe("symbol", () => { - it("correct symbol", async () => { - const symbol = await L2BaseToken.symbol(); - expect(symbol).to.equal("ETH"); - }); - }); - - describe("decimals", () => { - it("correct decimals", async () => { - const decimals = await L2BaseToken.decimals(); - expect(decimals).to.equal(18); - }); - }); - describe("withdraw", () => { it("event, balance, totalsupply", async () => { const amountToWithdraw: BigNumber = ethers.utils.parseEther("1.0"); diff --git a/system-contracts/test/precompiles/Identity.spec.ts b/system-contracts/test/precompiles/Identity.spec.ts new file mode 100644 index 000000000..7da2befa0 --- /dev/null +++ b/system-contracts/test/precompiles/Identity.spec.ts @@ -0,0 +1,19 @@ +import { expect } from "chai"; +import type { Contract } from "zksync-ethers"; +import { callFallback, deployContractYul } from "../shared/utils"; + +describe("Identity tests", function () { + let identity: Contract; + + before(async () => { + identity = await deployContractYul("Identity", "precompiles"); + }); + + describe("Ethereum tests", function () { + it("Returns data", async () => { + const data = "0xff00ff00ff00ff00ff"; + const returnData = await callFallback(identity, data); + expect(returnData).to.be.equal(data); + }); + }); +}); diff --git a/system-contracts/test/shared/utils.ts b/system-contracts/test/shared/utils.ts index c382301a1..1e434a0a7 100644 --- a/system-contracts/test/shared/utils.ts +++ b/system-contracts/test/shared/utils.ts @@ -117,9 +117,14 @@ async function deployBytecode(bytecode: string): Promise { ); } -export async function deployContractOnAddress(address: string, name: string) { +export async function deployContractOnAddress( + address: string, + name: string, + callConstructor: boolean = true, + input = "0x" +) { const artifact = await loadArtifact(name); - await setCode(address, artifact.bytecode, true); + await setCode(address, artifact.bytecode, callConstructor, input); } export async function publishBytecode(bytecode: BytesLike) { @@ -139,7 +144,7 @@ export async function getCode(address: string): Promise { } // Force deploy bytecode on the address -export async function setCode(address: string, bytecode: BytesLike, callConstructor: boolean = false) { +export async function setCode(address: string, bytecode: BytesLike, callConstructor: boolean = false, input = "0x") { // TODO: think about factoryDeps with eth_sendTransaction try { // publish bytecode in a separate tx @@ -156,8 +161,9 @@ export async function setCode(address: string, bytecode: BytesLike, callConstruc newAddress: address, callConstructor, value: 0, - input: "0x", + input, }; + await deployerContract.forceDeployOnAddress(deployment, ethers.constants.AddressZero); } diff --git a/yarn.lock b/yarn.lock index 66cd67b1a..47e9a6aab 100644 --- a/yarn.lock +++ b/yarn.lock @@ -772,6 +772,23 @@ sinon-chai "^3.7.0" undici "^5.14.0" +"@matterlabs/hardhat-zksync-solc@^1.2.5": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-solc/-/hardhat-zksync-solc-1.2.5.tgz#fbeeabc3fea0dd232fa3c8cb31bd93c103eba11a" + integrity sha512-iZyznWl1Hoe/Z46hnUe1s2drBZBjJOS/eN+Ql2lIBX9B6NevBl9DYzkKzH5HEIMCLGnX9sWpRAJqUQJWy9UB6w== + dependencies: + "@nomiclabs/hardhat-docker" "^2.0.2" + chai "^4.3.4" + chalk "^4.1.2" + debug "^4.3.5" + dockerode "^4.0.2" + fs-extra "^11.2.0" + proper-lockfile "^4.1.2" + semver "^7.6.2" + sinon "^18.0.0" + sinon-chai "^3.7.0" + undici "^6.18.2" + "@matterlabs/hardhat-zksync-verify@0.6.1": version "0.6.1" resolved "https://registry.yarnpkg.com/@matterlabs/hardhat-zksync-verify/-/hardhat-zksync-verify-0.6.1.tgz#3fd83f4177ac0b138656ed93d4756ec27f1d329d" @@ -1181,7 +1198,7 @@ "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.1" "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.1" -"@nomiclabs/hardhat-docker@^2.0.0": +"@nomiclabs/hardhat-docker@^2.0.0", "@nomiclabs/hardhat-docker@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-docker/-/hardhat-docker-2.0.2.tgz#ae964be17951275a55859ff7358e9e7c77448846" integrity sha512-XgGEpRT3wlA1VslyB57zyAHV+oll8KnV1TjwnxxC1tpAL04/lbdwpdO5KxInVN8irMSepqFpsiSkqlcnvbE7Ng== @@ -1413,20 +1430,27 @@ dependencies: type-detect "4.0.8" -"@sinonjs/commons@^3.0.0": +"@sinonjs/commons@^3.0.0", "@sinonjs/commons@^3.0.1": version "3.0.1" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== dependencies: type-detect "4.0.8" -"@sinonjs/fake-timers@^11.2.2": +"@sinonjs/fake-timers@11.2.2", "@sinonjs/fake-timers@^11.2.2": version "11.2.2" resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz#50063cc3574f4a27bd8453180a04171c85cc9699" integrity sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw== dependencies: "@sinonjs/commons" "^3.0.0" +"@sinonjs/fake-timers@^13.0.1": + version "13.0.2" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-13.0.2.tgz#3ffe88abb062067a580fdfba706ad00435a0f2a6" + integrity sha512-4Bb+oqXZTSTZ1q27Izly9lv8B9dlV61CROxPiVtywwzv5SnytJqhvYe6FclHYuXml4cd1VHPo1zd5PmTeJozvA== + dependencies: + "@sinonjs/commons" "^3.0.1" + "@sinonjs/samsam@^8.0.0": version "8.0.0" resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-8.0.0.tgz#0d488c91efb3fa1442e26abea81759dfc8b5ac60" @@ -1441,6 +1465,11 @@ resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== +"@sinonjs/text-encoding@^0.7.3": + version "0.7.3" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz#282046f03e886e352b2d5f5da5eb755e01457f3f" + integrity sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA== + "@solidity-parser/parser@^0.14.0": version "0.14.5" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" @@ -2549,6 +2578,19 @@ chai@^4.3.10, chai@^4.3.6, chai@^4.3.7: pathval "^1.1.1" type-detect "^4.0.8" +chai@^4.3.4: + version "4.5.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.5.0.tgz#707e49923afdd9b13a8b0b47d33d732d13812fd8" + integrity sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.3" + deep-eql "^4.1.3" + get-func-name "^2.0.2" + loupe "^2.3.6" + pathval "^1.1.1" + type-detect "^4.1.0" + chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" @@ -2961,6 +3003,13 @@ debug@^3.1.0, debug@^3.2.6, debug@^3.2.7: dependencies: ms "^2.1.1" +debug@^4.3.5: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + decamelize@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" @@ -3041,7 +3090,7 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== -diff@^5.1.0: +diff@^5.1.0, diff@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-5.2.0.tgz#26ded047cd1179b78b9537d5ef725503ce1ae531" integrity sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A== @@ -4004,7 +4053,7 @@ fs-extra@^0.30.0: path-is-absolute "^1.0.0" rimraf "^2.2.8" -fs-extra@^11.1.1: +fs-extra@^11.1.1, fs-extra@^11.2.0: version "11.2.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== @@ -5774,7 +5823,7 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@2.1.3, ms@^2.1.1: +ms@2.1.3, ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5815,6 +5864,17 @@ nise@^5.1.5: just-extend "^6.2.0" path-to-regexp "^6.2.1" +nise@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/nise/-/nise-6.1.1.tgz#78ea93cc49be122e44cb7c8fdf597b0e8778b64a" + integrity sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g== + dependencies: + "@sinonjs/commons" "^3.0.1" + "@sinonjs/fake-timers" "^13.0.1" + "@sinonjs/text-encoding" "^0.7.3" + just-extend "^6.2.0" + path-to-regexp "^8.1.0" + node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" @@ -6102,6 +6162,11 @@ path-to-regexp@^6.2.1: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.2.2.tgz#324377a83e5049cbecadc5554d6a63a9a4866b36" integrity sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw== +path-to-regexp@^8.1.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz#73990cc29e57a3ff2a0d914095156df5db79e8b4" + integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ== + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -6696,6 +6761,11 @@ semver@^7.3.7: resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.1.tgz#60bfe090bf907a25aa8119a72b9f90ef7ca281b2" integrity sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA== +semver@^7.6.2: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + serialize-javascript@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" @@ -6809,6 +6879,18 @@ sinon@^17.0.1: nise "^5.1.5" supports-color "^7.2.0" +sinon@^18.0.0: + version "18.0.1" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-18.0.1.tgz#464334cdfea2cddc5eda9a4ea7e2e3f0c7a91c5e" + integrity sha512-a2N2TDY1uGviajJ6r4D1CyRAkzE9NNVlYOV1wX5xQDuAk0ONgzgRl0EjCQuRCPxOwp13ghsMwt9Gdldujs39qw== + dependencies: + "@sinonjs/commons" "^3.0.1" + "@sinonjs/fake-timers" "11.2.2" + "@sinonjs/samsam" "^8.0.0" + diff "^5.2.0" + nise "^6.0.0" + supports-color "^7" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -7159,7 +7241,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^7.1.0, supports-color@^7.2.0: +supports-color@^7, supports-color@^7.1.0, supports-color@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -7485,6 +7567,11 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.8: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== +type-detect@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.1.0.tgz#deb2453e8f08dcae7ae98c626b13dddb0155906c" + integrity sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw== + type-fest@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" @@ -7635,6 +7722,11 @@ undici@^5.14.0: dependencies: "@fastify/busboy" "^2.0.0" +undici@^6.18.2: + version "6.19.8" + resolved "https://registry.yarnpkg.com/undici/-/undici-6.19.8.tgz#002d7c8a28f8cc3a44ff33c3d4be4d85e15d40e1" + integrity sha512-U8uCCl2x9TK3WANvmBavymRzxbfFYG+tAu+fgx3zxQy3qdagQqBLwJVrdyO1TBfUXvfKveMKJZhpvUYoOjM+4g== + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"