From 2856203f15ae8affa04b684630f696fd48602f33 Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Tue, 19 Nov 2024 16:52:45 +0100 Subject: [PATCH] Fix calls to contract being created --- system-contracts/contracts/EvmEmulator.yul | 18 ++++++++++++++++-- .../EvmEmulatorFunctions.template.yul | 9 ++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul index f9a9c0d75..e6143bcd7 100644 --- a/system-contracts/contracts/EvmEmulator.yul +++ b/system-contracts/contracts/EvmEmulator.yul @@ -393,6 +393,13 @@ object "EvmEmulator" { isEVM := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) } + function isConstructedEvmContract(addr) -> isConstructedEVM { + let rawCodeHash := getRawCodeHash(addr) + 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 codeHash := getRawCodeHash(addr) @@ -802,7 +809,7 @@ object "EvmEmulator" { } function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { - switch isEvmContract(addr) + switch isConstructedEvmContract(addr) case 0 { // zkEVM native call let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) @@ -3441,6 +3448,13 @@ object "EvmEmulator" { isEVM := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) } + function isConstructedEvmContract(addr) -> isConstructedEVM { + let rawCodeHash := getRawCodeHash(addr) + 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 codeHash := getRawCodeHash(addr) @@ -3850,7 +3864,7 @@ object "EvmEmulator" { } function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { - switch isEvmContract(addr) + switch isConstructedEvmContract(addr) case 0 { // zkEVM native call let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize) diff --git a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul index 58736a58d..5e928f341 100644 --- a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul @@ -331,6 +331,13 @@ function isEvmContract(addr) -> isEVM { isEVM := fetchFromSystemContract(ACCOUNT_CODE_STORAGE_SYSTEM_CONTRACT(), 36) } +function isConstructedEvmContract(addr) -> isConstructedEVM { + let rawCodeHash := getRawCodeHash(addr) + 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 codeHash := getRawCodeHash(addr) @@ -740,7 +747,7 @@ function performDelegateCall(oldSp, evmGasLeft, isStatic, oldStackHead) -> newGa } function _genericCall(addr, gasToPass, value, argsOffset, argsSize, retOffset, retSize, isStatic) -> success, frameGasLeft { - switch isEvmContract(addr) + switch isConstructedEvmContract(addr) case 0 { // zkEVM native call let precompileCost := getGasForPrecompiles(addr, argsOffset, argsSize)