From beb95cabeaf3647cd16e13da29f304cc7de8634d Mon Sep 17 00:00:00 2001 From: Vladislav Volosnikov Date: Wed, 27 Nov 2024 17:40:58 +0100 Subject: [PATCH] Fix call in static context --- system-contracts/contracts/EvmEmulator.yul | 32 ++++++++----------- .../EvmEmulatorFunctions.template.yul | 8 +++-- .../evm-emulator/EvmEmulatorLoop.template.yul | 8 +---- 3 files changed, 21 insertions(+), 27 deletions(-) diff --git a/system-contracts/contracts/EvmEmulator.yul b/system-contracts/contracts/EvmEmulator.yul index f9a9c0d75..1d5867521 100644 --- a/system-contracts/contracts/EvmEmulator.yul +++ b/system-contracts/contracts/EvmEmulator.yul @@ -644,7 +644,7 @@ object "EvmEmulator" { // CALLS FUNCTIONALITY //////////////////////////////////////////////////////////////// - function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHead { + function performCall(oldSp, evmGasLeft, oldStackHead, isStatic) -> newGasLeft, sp, stackHead { let gasToPass, addr, value, argsOffset, argsSize, retOffset, retSize popStackCheck(oldSp, 7) @@ -676,6 +676,10 @@ object "EvmEmulator" { gasUsed := add(gasUsed, expandMemory2(retOffset, retSize, argsOffset, argsSize)) if gt(value, 0) { + if isStatic { + panic() + } + gasUsed := add(gasUsed, 9000) // positive_value_cost if isAddrEmpty(addr) { @@ -699,7 +703,7 @@ object "EvmEmulator" { argsSize, add(retOffset, MEM_OFFSET()), retSize, - false + isStatic ) newGasLeft := add(evmGasLeft, frameGasLeft) @@ -2648,13 +2652,7 @@ object "EvmEmulator" { } case 0xF1 { // OP_CALL // A function was implemented in order to avoid stack depth errors. - switch isStatic - case 0 { - evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead) - } - default { - evmGasLeft, sp, stackHead := performStaticCall(sp, evmGasLeft, stackHead) - } + evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead, isStatic) ip := add(ip, 1) } case 0xF3 { // OP_RETURN @@ -3692,7 +3690,7 @@ object "EvmEmulator" { // CALLS FUNCTIONALITY //////////////////////////////////////////////////////////////// - function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHead { + function performCall(oldSp, evmGasLeft, oldStackHead, isStatic) -> newGasLeft, sp, stackHead { let gasToPass, addr, value, argsOffset, argsSize, retOffset, retSize popStackCheck(oldSp, 7) @@ -3724,6 +3722,10 @@ object "EvmEmulator" { gasUsed := add(gasUsed, expandMemory2(retOffset, retSize, argsOffset, argsSize)) if gt(value, 0) { + if isStatic { + panic() + } + gasUsed := add(gasUsed, 9000) // positive_value_cost if isAddrEmpty(addr) { @@ -3747,7 +3749,7 @@ object "EvmEmulator" { argsSize, add(retOffset, MEM_OFFSET()), retSize, - false + isStatic ) newGasLeft := add(evmGasLeft, frameGasLeft) @@ -5696,13 +5698,7 @@ object "EvmEmulator" { } case 0xF1 { // OP_CALL // A function was implemented in order to avoid stack depth errors. - switch isStatic - case 0 { - evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead) - } - default { - evmGasLeft, sp, stackHead := performStaticCall(sp, evmGasLeft, stackHead) - } + evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead, isStatic) ip := add(ip, 1) } case 0xF3 { // OP_RETURN diff --git a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul index 58736a58d..e14068704 100644 --- a/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorFunctions.template.yul @@ -582,7 +582,7 @@ function resetEvmFrame() { // CALLS FUNCTIONALITY //////////////////////////////////////////////////////////////// -function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHead { +function performCall(oldSp, evmGasLeft, oldStackHead, isStatic) -> newGasLeft, sp, stackHead { let gasToPass, addr, value, argsOffset, argsSize, retOffset, retSize popStackCheck(oldSp, 7) @@ -614,6 +614,10 @@ function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHe gasUsed := add(gasUsed, expandMemory2(retOffset, retSize, argsOffset, argsSize)) if gt(value, 0) { + if isStatic { + panic() + } + gasUsed := add(gasUsed, 9000) // positive_value_cost if isAddrEmpty(addr) { @@ -637,7 +641,7 @@ function performCall(oldSp, evmGasLeft, oldStackHead) -> newGasLeft, sp, stackHe argsSize, add(retOffset, MEM_OFFSET()), retSize, - false + isStatic ) newGasLeft := add(evmGasLeft, frameGasLeft) diff --git a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul index 78e1a5315..3b72b1a4c 100644 --- a/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul +++ b/system-contracts/evm-emulator/EvmEmulatorLoop.template.yul @@ -1423,13 +1423,7 @@ for { } true { } { } case 0xF1 { // OP_CALL // A function was implemented in order to avoid stack depth errors. - switch isStatic - case 0 { - evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead) - } - default { - evmGasLeft, sp, stackHead := performStaticCall(sp, evmGasLeft, stackHead) - } + evmGasLeft, sp, stackHead := performCall(sp, evmGasLeft, stackHead, isStatic) ip := add(ip, 1) } case 0xF3 { // OP_RETURN