From 966dc1281d36c95ad285d2ab105752c2916669c5 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 25 Sep 2024 13:12:06 +0200 Subject: [PATCH 1/4] Optimize EvmGasManager --- .../contracts/AccountCodeStorage.sol | 3 +- system-contracts/contracts/EvmGasManager.sol | 90 ++++++++----------- system-contracts/contracts/EvmInterpreter.yul | 90 +++---------------- .../contracts/interfaces/IEvmGasManager.sol | 4 +- .../EvmInterpreterFunctions.template.yul | 45 ++-------- 5 files changed, 59 insertions(+), 173 deletions(-) diff --git a/system-contracts/contracts/AccountCodeStorage.sol b/system-contracts/contracts/AccountCodeStorage.sol index 15ccdd9ce..52879df1f 100644 --- a/system-contracts/contracts/AccountCodeStorage.sol +++ b/system-contracts/contracts/AccountCodeStorage.sol @@ -115,8 +115,7 @@ 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)) { + } else if (Utils.isCodeHashEVM(codeHash)) { codeHash = DEPLOYER_SYSTEM_CONTRACT.evmCodeHash(account); } diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index 398735247..bf9585b24 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.0; -import "./libraries/Utils.sol"; +import {Utils} from "./libraries/Utils.sol"; import {ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT} from "./Constants.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; @@ -12,16 +12,19 @@ import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; // We consider all the contracts (including system ones) as warm. uint160 constant PRECOMPILES_END = 0xffff; -uint256 constant INF_PASS_GAS = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff; - // Transient storage prefixes uint256 constant IS_ACCOUNT_EVM_PREFIX = 1 << 255; uint256 constant IS_ACCOUNT_WARM_PREFIX = 1 << 254; uint256 constant IS_SLOT_WARM_PREFIX = 1 << 253; -uint256 constant EVM_STACK_SLOT = 2; + +uint256 constant EVM_GAS_SLOT = 4; +uint256 constant EVM_AUX_DATA_SLOT = 5; +uint256 constant EVM_ACTIVE_FRAME_FLAG = 1 << 1; contract EvmGasManager { modifier onlySystemEvm() { + require(SystemContractHelper.isSystemCall(), "This method requires system call flag"); + // cache use is safe since we do not support SELFDESTRUCT uint256 transient_slot = IS_ACCOUNT_EVM_PREFIX | uint256(uint160(msg.sender)); bool isEVM; @@ -42,7 +45,6 @@ contract EvmGasManager { } require(isEVM, "only system evm"); - require(SystemContractHelper.isSystemCall(), "This method requires system call flag"); _; } @@ -51,17 +53,17 @@ contract EvmGasManager { */ function warmAccount(address account) external payable onlySystemEvm returns (bool wasWarm) { if (uint160(account) < PRECOMPILES_END) return true; - uint256 transient_slot = IS_ACCOUNT_WARM_PREFIX | uint256(uint160(account)); assembly { wasWarm := tload(transient_slot) - } - if (!wasWarm) { - assembly { + if iszero(wasWarm) { tstore(transient_slot, 1) } + + mstore(0x0, wasWarm) + return(0x0, 0x20) } } @@ -72,10 +74,10 @@ contract EvmGasManager { mstore(0, prefix) mstore(0x20, _slot) transient_slot := keccak256(0, 64) - } - - assembly { isWarm := tload(transient_slot) + + mstore(0x0, isWarm) + return(0x0, 0x20) } } @@ -89,69 +91,55 @@ contract EvmGasManager { mstore(0, prefix) mstore(0x20, _slot) transient_slot := keccak256(0, 64) - } - assembly { isWarm := tload(transient_slot) - } - if (isWarm) { - assembly { - originalValue := tload(add(transient_slot, 1)) - } - } else { - originalValue = _currentValue; - - assembly { + switch isWarm + case 0 { + originalValue := _currentValue tstore(transient_slot, 1) tstore(add(transient_slot, 1), originalValue) } + default { + originalValue := tload(add(transient_slot, 1)) + } + + mstore(0x0, isWarm) + mstore(0x20, originalValue) + return(0x0, 0x40) } } /* - The flow is the following: When conducting call: 1. caller calls to an EVM contract pushEVMFrame with the corresponding gas - 2. callee calls consumeEvmFrame to get the gas and determine if a call is static - 3. calleer calls popEVMFrame to remove the frame + 2. callee calls consumeEvmFrame to get the gas and determine if a call is static, frame is marked as used */ function pushEVMFrame(uint256 passGas, bool isStatic) external onlySystemEvm { assembly { - let stackDepth := add(tload(EVM_STACK_SLOT), 1) - tstore(EVM_STACK_SLOT, stackDepth) - let stackPointer := add(EVM_STACK_SLOT, mul(2, stackDepth)) - tstore(stackPointer, passGas) - tstore(add(stackPointer, 1), isStatic) + tstore(EVM_GAS_SLOT, passGas) + tstore(EVM_AUX_DATA_SLOT, or(isStatic, EVM_ACTIVE_FRAME_FLAG)) } } - function consumeEvmFrame() external onlySystemEvm returns (uint256 passGas, bool isStatic) { - uint256 stackDepth; + function consumeEvmFrame() external onlySystemEvm returns (uint256 passGas, uint256 auxDataRes) { assembly { - stackDepth := tload(EVM_STACK_SLOT) - } - if (stackDepth == 0) return (INF_PASS_GAS, false); + let auxData := tload(EVM_AUX_DATA_SLOT) + let isFrameActive := and(auxData, EVM_ACTIVE_FRAME_FLAG) - assembly { - let stackPointer := add(EVM_STACK_SLOT, mul(2, stackDepth)) - passGas := tload(stackPointer) - isStatic := tload(add(stackPointer, 1)) - tstore(stackPointer, INF_PASS_GAS) // mark as consumed - } - } + if isFrameActive { + passGas := tload(EVM_GAS_SLOT) + auxDataRes := auxData - function popEVMFrame() external onlySystemEvm { - uint256 stackDepth; - assembly { - stackDepth := tload(EVM_STACK_SLOT) - } - require(stackDepth != 0); - assembly { - tstore(EVM_STACK_SLOT, sub(stackDepth, 1)) + tstore(EVM_AUX_DATA_SLOT, 0) // mark as consumed + } + + mstore(0x0, passGas) + mstore(0x20, auxDataRes) + return(0x0, 0x40) } } } diff --git a/system-contracts/contracts/EvmInterpreter.yul b/system-contracts/contracts/EvmInterpreter.yul index b16daad6a..3e35f5d5e 100644 --- a/system-contracts/contracts/EvmInterpreter.yul +++ b/system-contracts/contracts/EvmInterpreter.yul @@ -368,7 +368,7 @@ object "EVMInterpreter" { } function consumeEvmFrame() -> passGas, isStatic, callerEVM { - // function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) + // function consumeEvmFrame() external returns (uint256 passGas, uint256 auxDataRes) mstore(0, 0x04C14E9E00000000000000000000000000000000000000000000000000000000) let farCallAbi := getFarCallABI( @@ -393,11 +393,12 @@ object "EVMInterpreter" { returndatacopy(0,0,64) - passGas := mload(0) - isStatic := mload(32) + let auxData := mload(32) + callerEVM := gt(auxData, 1) - if iszero(eq(passGas, INF_PASS_GAS())) { - callerEVM := true + if callerEVM { + isStatic := and(auxData, 1) + passGas := mload(0) } } @@ -774,33 +775,6 @@ object "EVMInterpreter" { } } - function _popEVMFrame() { - // function popEVMFrame() external - - let farCallAbi := getFarCallABI( - 0, - 0, - 0, - 4, - gas(), - // Only rollup is supported for now - 0, - 0, - 0, - 1 - ) - - let to := EVM_GAS_MANAGER_CONTRACT() - - mstore(0, 0xE467D2F000000000000000000000000000000000000000000000000000000000) - - let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) - if iszero(success) { - // This error should never happen - revert(0, 0) - } - } - // Each evm gas is 5 zkEVM one function GAS_DIVISOR() -> gas_div { gas_div := 5 } function EVM_GAS_STIPEND() -> gas_stipend { gas_stipend := shl(30, 1) } // 1 << 30 @@ -941,7 +915,6 @@ object "EVMInterpreter" { success := staticcall(gasToPass, addr, add(MEM_OFFSET_INNER(), argsOffset), argsSize, 0, 0) frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET_INNER(), retOffset), retSize) - _popEVMFrame() } let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) @@ -998,7 +971,6 @@ object "EVMInterpreter" { _pushEVMFrame(gasToPassNew, isStatic) success := call(EVM_GAS_STIPEND(), addr, value, argsOffset, argsSize, 0, 0) frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) - _popEVMFrame() } } default { @@ -1139,8 +1111,6 @@ object "EVMInterpreter" { let frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET_INNER(), retOffset), retSize) - _popEVMFrame() - let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) switch iszero(precompileCost) case 1 { @@ -1182,7 +1152,6 @@ object "EVMInterpreter" { success := staticcall(EVM_GAS_STIPEND(), _callee, _inputOffset, _inputLen, 0, 0) _gasLeft := _saveReturndataAfterEVMCall(_outputOffset, _outputLen) - _popEVMFrame() } } @@ -1272,8 +1241,6 @@ object "EVMInterpreter" { let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) - _popEVMFrame() - let back // skipping check since we pushed exactly 4 items earlier @@ -3234,7 +3201,7 @@ object "EVMInterpreter" { } function consumeEvmFrame() -> passGas, isStatic, callerEVM { - // function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) + // function consumeEvmFrame() external returns (uint256 passGas, uint256 auxDataRes) mstore(0, 0x04C14E9E00000000000000000000000000000000000000000000000000000000) let farCallAbi := getFarCallABI( @@ -3259,11 +3226,12 @@ object "EVMInterpreter" { returndatacopy(0,0,64) - passGas := mload(0) - isStatic := mload(32) + let auxData := mload(32) + callerEVM := gt(auxData, 1) - if iszero(eq(passGas, INF_PASS_GAS())) { - callerEVM := true + if callerEVM { + isStatic := and(auxData, 1) + passGas := mload(0) } } @@ -3640,33 +3608,6 @@ object "EVMInterpreter" { } } - function _popEVMFrame() { - // function popEVMFrame() external - - let farCallAbi := getFarCallABI( - 0, - 0, - 0, - 4, - gas(), - // Only rollup is supported for now - 0, - 0, - 0, - 1 - ) - - let to := EVM_GAS_MANAGER_CONTRACT() - - mstore(0, 0xE467D2F000000000000000000000000000000000000000000000000000000000) - - let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) - if iszero(success) { - // This error should never happen - revert(0, 0) - } - } - // Each evm gas is 5 zkEVM one function GAS_DIVISOR() -> gas_div { gas_div := 5 } function EVM_GAS_STIPEND() -> gas_stipend { gas_stipend := shl(30, 1) } // 1 << 30 @@ -3807,7 +3748,6 @@ object "EVMInterpreter" { success := staticcall(gasToPass, addr, add(MEM_OFFSET_INNER(), argsOffset), argsSize, 0, 0) frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET_INNER(), retOffset), retSize) - _popEVMFrame() } let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) @@ -3864,7 +3804,6 @@ object "EVMInterpreter" { _pushEVMFrame(gasToPassNew, isStatic) success := call(EVM_GAS_STIPEND(), addr, value, argsOffset, argsSize, 0, 0) frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) - _popEVMFrame() } } default { @@ -4005,8 +3944,6 @@ object "EVMInterpreter" { let frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET_INNER(), retOffset), retSize) - _popEVMFrame() - let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) switch iszero(precompileCost) case 1 { @@ -4048,7 +3985,6 @@ object "EVMInterpreter" { success := staticcall(EVM_GAS_STIPEND(), _callee, _inputOffset, _inputLen, 0, 0) _gasLeft := _saveReturndataAfterEVMCall(_outputOffset, _outputLen) - _popEVMFrame() } } @@ -4138,8 +4074,6 @@ object "EVMInterpreter" { let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) - _popEVMFrame() - let back // skipping check since we pushed exactly 4 items earlier diff --git a/system-contracts/contracts/interfaces/IEvmGasManager.sol b/system-contracts/contracts/interfaces/IEvmGasManager.sol index 63c42ff2f..426deb5bc 100644 --- a/system-contracts/contracts/interfaces/IEvmGasManager.sol +++ b/system-contracts/contracts/interfaces/IEvmGasManager.sol @@ -10,7 +10,5 @@ interface IEvmGasManager { function pushEVMFrame(uint256 _passGas, bool _isStatic) external; - function consumeEvmFrame() external returns (uint256 passGas, bool isStatic); - - function popEVMFrame() external; + function consumeEvmFrame() external returns (uint256 passGas, uint256 auxData); } diff --git a/system-contracts/evm-interpreter/EvmInterpreterFunctions.template.yul b/system-contracts/evm-interpreter/EvmInterpreterFunctions.template.yul index 4d2f6f3aa..1e4ec38f7 100644 --- a/system-contracts/evm-interpreter/EvmInterpreterFunctions.template.yul +++ b/system-contracts/evm-interpreter/EvmInterpreterFunctions.template.yul @@ -286,7 +286,7 @@ function getDeployedBytecode() { } function consumeEvmFrame() -> passGas, isStatic, callerEVM { - // function consumeEvmFrame() external returns (uint256 passGas, bool isStatic) + // function consumeEvmFrame() external returns (uint256 passGas, uint256 auxDataRes) mstore(0, 0x04C14E9E00000000000000000000000000000000000000000000000000000000) let farCallAbi := getFarCallABI( @@ -311,11 +311,12 @@ function consumeEvmFrame() -> passGas, isStatic, callerEVM { returndatacopy(0,0,64) - passGas := mload(0) - isStatic := mload(32) + let auxData := mload(32) + callerEVM := gt(auxData, 1) - if iszero(eq(passGas, INF_PASS_GAS())) { - callerEVM := true + if callerEVM { + isStatic := and(auxData, 1) + passGas := mload(0) } } @@ -692,33 +693,6 @@ function _pushEVMFrame(_passGas, _isStatic) { } } -function _popEVMFrame() { - // function popEVMFrame() external - - let farCallAbi := getFarCallABI( - 0, - 0, - 0, - 4, - gas(), - // Only rollup is supported for now - 0, - 0, - 0, - 1 - ) - - let to := EVM_GAS_MANAGER_CONTRACT() - - mstore(0, 0xE467D2F000000000000000000000000000000000000000000000000000000000) - - let success := verbatim_6i_1o("system_call", to, farCallAbi, 0, 0, 0, 0) - if iszero(success) { - // This error should never happen - revert(0, 0) - } -} - // Each evm gas is 5 zkEVM one function GAS_DIVISOR() -> gas_div { gas_div := 5 } function EVM_GAS_STIPEND() -> gas_stipend { gas_stipend := shl(30, 1) } // 1 << 30 @@ -859,7 +833,6 @@ function performStaticCall(oldSp,evmGasLeft) -> extraCost, sp { success := staticcall(gasToPass, addr, add(MEM_OFFSET_INNER(), argsOffset), argsSize, 0, 0) frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET_INNER(), retOffset), retSize) - _popEVMFrame() } let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) @@ -916,7 +889,6 @@ function _performCall(addr,gasToPass,value,argsOffset,argsSize,retOffset,retSize _pushEVMFrame(gasToPassNew, isStatic) success := call(EVM_GAS_STIPEND(), addr, value, argsOffset, argsSize, 0, 0) frameGasLeft := _saveReturndataAfterEVMCall(retOffset, retSize) - _popEVMFrame() } } default { @@ -1057,8 +1029,6 @@ function delegateCall(oldSp, oldIsStatic, evmGasLeft) -> sp, isStatic, extraCost let frameGasLeft := _saveReturndataAfterEVMCall(add(MEM_OFFSET_INNER(), retOffset), retSize) - _popEVMFrame() - let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) switch iszero(precompileCost) case 1 { @@ -1100,7 +1070,6 @@ function _performStaticCall( success := staticcall(EVM_GAS_STIPEND(), _callee, _inputOffset, _inputLen, 0, 0) _gasLeft := _saveReturndataAfterEVMCall(_outputOffset, _outputLen) - _popEVMFrame() } } @@ -1190,8 +1159,6 @@ function $llvm_NoInline_llvm$_genericCreate(offset, size, sp, value, evmGasLeftO let gasUsed := sub(gasForTheCall, gasLeft) evmGasLeft := chargeGas(evmGasLeftOld, gasUsed) - _popEVMFrame() - let back // skipping check since we pushed exactly 4 items earlier From a0448c990f94c2001a11ed8ba963eb41affa4835 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 25 Sep 2024 14:40:03 +0200 Subject: [PATCH 2/4] Make EvmGasManager methods payable --- system-contracts/contracts/EvmGasManager.sol | 4 ++-- system-contracts/contracts/interfaces/IEvmGasManager.sol | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index bf9585b24..50cab37c7 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -118,14 +118,14 @@ contract EvmGasManager { 2. callee calls consumeEvmFrame to get the gas and determine if a call is static, frame is marked as used */ - function pushEVMFrame(uint256 passGas, bool isStatic) external onlySystemEvm { + function pushEVMFrame(uint256 passGas, bool isStatic) external payable onlySystemEvm { assembly { tstore(EVM_GAS_SLOT, passGas) tstore(EVM_AUX_DATA_SLOT, or(isStatic, EVM_ACTIVE_FRAME_FLAG)) } } - function consumeEvmFrame() external onlySystemEvm returns (uint256 passGas, uint256 auxDataRes) { + function consumeEvmFrame() external payable onlySystemEvm returns (uint256 passGas, uint256 auxDataRes) { assembly { let auxData := tload(EVM_AUX_DATA_SLOT) let isFrameActive := and(auxData, EVM_ACTIVE_FRAME_FLAG) diff --git a/system-contracts/contracts/interfaces/IEvmGasManager.sol b/system-contracts/contracts/interfaces/IEvmGasManager.sol index 426deb5bc..646d7bf24 100644 --- a/system-contracts/contracts/interfaces/IEvmGasManager.sol +++ b/system-contracts/contracts/interfaces/IEvmGasManager.sol @@ -8,7 +8,7 @@ interface IEvmGasManager { function warmSlot(uint256 _slot, uint256 _currentValue) external payable returns (bool, uint256); - function pushEVMFrame(uint256 _passGas, bool _isStatic) external; + function pushEVMFrame(uint256 _passGas, bool _isStatic) external payable; - function consumeEvmFrame() external returns (uint256 passGas, uint256 auxData); + function consumeEvmFrame() external payable returns (uint256 passGas, uint256 auxData); } From ea5a158d5d4348eefb819a1b603a2d6e5086e106 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 25 Sep 2024 16:18:55 +0200 Subject: [PATCH 3/4] Use custom errors and optimize call inside EvmGasManager --- system-contracts/contracts/EvmGasManager.sol | 34 +++++++++++++++---- .../contracts/SystemContractErrors.sol | 2 ++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index 50cab37c7..b98bc9228 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -8,6 +8,7 @@ import {Utils} from "./libraries/Utils.sol"; import {ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT} from "./Constants.sol"; import {SystemContractHelper} from "./libraries/SystemContractHelper.sol"; +import {SystemCallFlagRequired, CallerMustBeEvmContract} from "./SystemContractErrors.sol"; // We consider all the contracts (including system ones) as warm. uint160 constant PRECOMPILES_END = 0xffff; @@ -23,28 +24,47 @@ uint256 constant EVM_ACTIVE_FRAME_FLAG = 1 << 1; contract EvmGasManager { modifier onlySystemEvm() { - require(SystemContractHelper.isSystemCall(), "This method requires system call flag"); + if (!SystemContractHelper.isSystemCall()) { + revert SystemCallFlagRequired(); + } // cache use is safe since we do not support SELFDESTRUCT - uint256 transient_slot = IS_ACCOUNT_EVM_PREFIX | uint256(uint160(msg.sender)); + uint256 _sender = uint256(uint160(msg.sender)); + uint256 transient_slot = IS_ACCOUNT_EVM_PREFIX | _sender; bool isEVM; assembly { isEVM := tload(transient_slot) } if (!isEVM) { - bytes32 bytecodeHash = ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT.getRawCodeHash(msg.sender); - isEVM = Utils.isCodeHashEVM(bytecodeHash); + address to = address(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT); + bytes32 rawCodeHash; + assembly { + // function getRawCodeHash(address _address) public view returns (bytes32 codeHash) + mstore(0, 0x4DE2E46800000000000000000000000000000000000000000000000000000000) + mstore(4, _sender) + + let success := staticcall(gas(), to, 0, 36, 0, 32) + + if iszero(success) { + // This error should never happen + revert(0, 0) + } + + rawCodeHash := mload(0) + } + + isEVM = Utils.isCodeHashEVM(rawCodeHash); if (isEVM) { - if (!Utils.isContractConstructing(bytecodeHash)) { + if (!Utils.isContractConstructing(rawCodeHash)) { assembly { tstore(transient_slot, isEVM) } } + } else { + revert CallerMustBeEvmContract(); } } - - require(isEVM, "only system evm"); _; } diff --git a/system-contracts/contracts/SystemContractErrors.sol b/system-contracts/contracts/SystemContractErrors.sol index b5dfc8276..49dee4655 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 From 0b6175e9954f16ae598a55995e50fa6b3270667d Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 25 Sep 2024 16:19:37 +0200 Subject: [PATCH 4/4] Prettier run --- system-contracts/contracts/EvmGasManager.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system-contracts/contracts/EvmGasManager.sol b/system-contracts/contracts/EvmGasManager.sol index b98bc9228..30bc9f938 100644 --- a/system-contracts/contracts/EvmGasManager.sol +++ b/system-contracts/contracts/EvmGasManager.sol @@ -43,14 +43,14 @@ contract EvmGasManager { // function getRawCodeHash(address _address) public view returns (bytes32 codeHash) mstore(0, 0x4DE2E46800000000000000000000000000000000000000000000000000000000) mstore(4, _sender) - + let success := staticcall(gas(), to, 0, 36, 0, 32) - + if iszero(success) { // This error should never happen revert(0, 0) } - + rawCodeHash := mload(0) }