diff --git a/src/compiler/evm_frontend/evm_imported.cpp b/src/compiler/evm_frontend/evm_imported.cpp index 18759674..cbe4dbde 100644 --- a/src/compiler/evm_frontend/evm_imported.cpp +++ b/src/compiler/evm_frontend/evm_imported.cpp @@ -794,6 +794,7 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance, if (GasUsed != 0) { Instance->chargeGas(GasUsed); } + // Track subcall refund (may be negative) Instance->addGasRefund(Result.gas_refund); std::vector ReturnData(Result.output_data, @@ -956,6 +957,7 @@ static uint64_t evmHandleCallInternal(zen::runtime::EVMInstance *Instance, Instance->chargeGas(GasUsed); } + // Track subcall refund (may be negative) Instance->addGasRefund(Result.gas_refund); // Copy return data to memory if output area is specified. diff --git a/src/evm/interpreter.h b/src/evm/interpreter.h index 9bf562cd..bb6e5d5d 100644 --- a/src/evm/interpreter.h +++ b/src/evm/interpreter.h @@ -30,7 +30,7 @@ struct EVMFrame { evmc_message Msg = {}; evmc::Host *Host = nullptr; evmc_tx_context MTx = {}; - uint64_t GasRefundSnapshot = 0; + int64_t GasRefundSnapshot = 0; size_t Sp = 0; uint64_t Pc = 0; diff --git a/src/evm/opcode_handlers.cpp b/src/evm/opcode_handlers.cpp index 01e1e465..c42baf01 100644 --- a/src/evm/opcode_handlers.cpp +++ b/src/evm/opcode_handlers.cpp @@ -1461,11 +1461,8 @@ void CallHandler::doExecute() { return; } - if (Result.gas_refund > 0) { - // Track subcall refund at Instance level - Context->getInstance()->addGasRefund(Result.gas_refund); - } - + // Track subcall refund at Instance level (may be negative) + Context->getInstance()->addGasRefund(Result.gas_refund); Context->setStatus(EVMC_SUCCESS); } diff --git a/src/runtime/evm_instance.h b/src/runtime/evm_instance.h index fde721bb..4d97e22d 100644 --- a/src/runtime/evm_instance.h +++ b/src/runtime/evm_instance.h @@ -59,9 +59,9 @@ class EVMInstance final : public RuntimeObject { void chargeGas(uint64_t GasCost); void addGas(uint64_t GasAmount); - void addGasRefund(uint64_t Amount) { GasRefund += Amount; } - void setGasRefund(uint64_t Amount) { GasRefund = Amount; } - uint64_t getGasRefund() const { return GasRefund; } + void addGasRefund(int64_t Amount) { GasRefund += Amount; } + void setGasRefund(int64_t Amount) { GasRefund = Amount; } + int64_t getGasRefund() const { return GasRefund; } void restoreGasRefundSnapshot() { if (!GasRefundStack.empty()) { GasRefund = GasRefundStack.back(); @@ -288,7 +288,7 @@ class EVMInstance final : public RuntimeObject { newEVMInstance(Isolation &Iso, const EVMModule &Mod, uint64_t GasLimit = 0); const EVMModule *Mod = nullptr; - uint64_t GasRefund = 0; + int64_t GasRefund = 0; // memory uint8_t *MemoryBase = nullptr; uint64_t MemorySize = 0;