Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions src/compiler/evm_frontend/evm_imported.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -796,9 +796,7 @@ const uint8_t *evmHandleCreateInternal(zen::runtime::EVMInstance *Instance,
if (GasUsed != 0) {
Instance->chargeGas(GasUsed);
}
if (Result.gas_refund > 0) {
Instance->addGasRefund(Result.gas_refund);
}
Instance->addGasRefund(Result.gas_refund);

std::vector<uint8_t> ReturnData(Result.output_data,
Result.output_data + Result.output_size);
Expand Down Expand Up @@ -963,9 +961,7 @@ static uint64_t evmHandleCallInternal(zen::runtime::EVMInstance *Instance,
Instance->chargeGas(GasUsed);
}

if (Result.gas_refund > 0) {
Instance->addGasRefund(Result.gas_refund);
}
Instance->addGasRefund(Result.gas_refund);

// Copy return data to memory if output area is specified.
// Per EVM semantics, bytes beyond returned data length remain unchanged.
Expand Down Expand Up @@ -1004,6 +1000,7 @@ uint64_t evmHandleCallCode(zen::runtime::EVMInstance *Instance, uint64_t Gas,

void evmHandleInvalid(zen::runtime::EVMInstance *Instance) {
// Immediately terminate the execution and return the invalid code (4)
Instance->restoreGasRefundSnapshot();
Instance->setReturnData({});
evmc::Result ExeResult(
EVMC_INVALID_INSTRUCTION, 0, Instance ? Instance->getGasRefund() : 0,
Expand All @@ -1015,6 +1012,7 @@ void evmHandleInvalid(zen::runtime::EVMInstance *Instance) {

void evmHandleUndefined(zen::runtime::EVMInstance *Instance) {
// Immediately terminate the execution and return the undefined code
Instance->restoreGasRefundSnapshot();
Instance->setReturnData({});
evmc::Result ExeResult(
EVMC_UNDEFINED_INSTRUCTION, 0, Instance ? Instance->getGasRefund() : 0,
Expand Down Expand Up @@ -1053,6 +1051,7 @@ void evmSetRevert(zen::runtime::EVMInstance *Instance, uint64_t Offset,
ReturnData =
std::vector<uint8_t>(MemoryBase + Offset, MemoryBase + Offset + Size);
}
Instance->restoreGasRefundSnapshot();
Instance->setReturnData(std::move(ReturnData));
const int64_t GasLeft =
Instance ? static_cast<int64_t>(Instance->getGas()) : 0;
Expand Down
8 changes: 8 additions & 0 deletions src/runtime/evm_instance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ void EVMInstance::pushMessage(evmc_message *Msg) {
initMemoryFrame(Memory, MemoryBase, MemorySize);
MessageStack.push_back(Msg);
CurrentMessage = Msg;
GasRefundStack.push_back(GasRefund);
Gas = Msg ? Msg->gas : 0;
}

Expand All @@ -79,6 +80,9 @@ void EVMInstance::popMessage() {
MessageStack.pop_back();
}
CurrentMessage = MessageStack.empty() ? nullptr : MessageStack.back();
if (!GasRefundStack.empty()) {
GasRefundStack.pop_back();
}
if (!MemoryStack.empty()) {
Memory = std::move(MemoryStack.back().Data);
MemorySize = MemoryStack.back().Size;
Expand Down Expand Up @@ -111,6 +115,10 @@ void EVMInstance::setExecutionError(const Error &NewErr, uint32_t IgnoredDepth,
common::evm_traphandler::EVMTrapState TS) {
ZEN_ASSERT(NewErr.getPhase() == common::ErrorPhase::Execution);
setError(NewErr);
if (NewErr.getCode() != ErrorCode::NoError &&
NewErr.getCode() != ErrorCode::InstanceExit) {
restoreGasRefundSnapshot();
}
if (NewErr.getCode() == ErrorCode::GasLimitExceeded) {
setGas(0); // gas left
}
Expand Down
6 changes: 6 additions & 0 deletions src/runtime/evm_instance.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ class EVMInstance final : public RuntimeObject<EVMInstance> {
void addGasRefund(uint64_t Amount) { GasRefund += Amount; }
void setGasRefund(uint64_t Amount) { GasRefund = Amount; }
uint64_t getGasRefund() const { return GasRefund; }
void restoreGasRefundSnapshot() {
if (!GasRefundStack.empty()) {
GasRefund = GasRefundStack.back();
}
}
void setRevision(evmc_revision NewRev) { Rev = NewRev; }

// ==================== Memory Methods ====================
Expand Down Expand Up @@ -299,6 +304,7 @@ class EVMInstance final : public RuntimeObject<EVMInstance> {
// Message stack for call hierarchy tracking
evmc_message *CurrentMessage = nullptr;
std::vector<evmc_message *> MessageStack;
std::vector<uint64_t> GasRefundStack;
evmc_revision Rev = zen::evm::DEFAULT_REVISION;

// Instance-level cache storage (shared across all messages in execution)
Expand Down
Loading