From fe6757e80a5d7409fc38fc2a8034d19301464b08 Mon Sep 17 00:00:00 2001 From: cmgCr Date: Wed, 8 Apr 2026 12:57:43 +0000 Subject: [PATCH 1/2] fix(evm): fix ZEN_LOG format string mismatch causing 'argument index out of range' ZEN_LOG_* macros use snprintf (printf-style %s/%d), but several log calls in evm_test_host.hpp and evm_test_helpers.h used fmt-style {} placeholders. snprintf ignores {}, leaving them in the output string. When spdlog then parses the message as a fmt format string, it triggers 'argument index out of range' error. Fixed by replacing all {} with %s in ZEN_LOG_* calls. Also fixed a mixed {%d} format in action/interpreter.cpp. Fixes #450, #452 --- src/action/interpreter.cpp | 2 +- src/tests/evm_test_helpers.h | 6 +++--- src/tests/evm_test_host.hpp | 26 +++++++++++++------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/action/interpreter.cpp b/src/action/interpreter.cpp index dbfa494b4..e4551bb5d 100644 --- a/src/action/interpreter.cpp +++ b/src/action/interpreter.cpp @@ -580,7 +580,7 @@ class BaseInterpreterImpl { break; } default: - ZEN_LOG_ERROR("unimplemented opcode : {%d}", Opcode); + ZEN_LOG_ERROR("unimplemented opcode : 0x%x", Opcode); ZEN_ASSERT_TODO(); break; } diff --git a/src/tests/evm_test_helpers.h b/src/tests/evm_test_helpers.h index 24ab35de2..406a1be41 100644 --- a/src/tests/evm_test_helpers.h +++ b/src/tests/evm_test_helpers.h @@ -146,7 +146,7 @@ inline std::string decimalToHex(const std::string &DecimalStr) { return "0"; } if (TrimmedStr[0] == '-') { - ZEN_LOG_ERROR("Negative values are not supported. Value: {}", + ZEN_LOG_ERROR("Negative values are not supported. Value: %s", DecimalStr.c_str()); return "0"; } @@ -162,11 +162,11 @@ inline std::string decimalToHex(const std::string &DecimalStr) { try { Value = std::stoull(TrimmedStr); } catch (const std::out_of_range &E) { - ZEN_LOG_ERROR("Value exceeds uint64_t range. Value: {}", + ZEN_LOG_ERROR("Value exceeds uint64_t range. Value: %s", DecimalStr.c_str()); return "0"; } catch (const std::invalid_argument &E) { - ZEN_LOG_ERROR("Invalid decimal string (parsing failed). Value: {}", + ZEN_LOG_ERROR("Invalid decimal string (parsing failed). Value: %s", DecimalStr.c_str()); return "0"; } diff --git a/src/tests/evm_test_host.hpp b/src/tests/evm_test_host.hpp index a07155673..16a6f5852 100644 --- a/src/tests/evm_test_host.hpp +++ b/src/tests/evm_test_host.hpp @@ -481,7 +481,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { if (It == accounts.end() || It->second.code.empty()) { // No contract found, return parent result ZEN_LOG_DEBUG( - "No contract found for code address {}, return parent result", + "No contract found for code address %s, return parent result", evmc::hex(evmc::bytes_view(CodeAddr.bytes, 20)).c_str()); if (Msg.kind == EVMC_CALL && !applyCallValueTransfer(Msg)) { return ParentResult; @@ -517,7 +517,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { auto ModRet = RT->loadEVMModule(ModName, ContractCode.data(), ContractCode.size()); if (!ModRet) { - ZEN_LOG_ERROR("Failed to load EVM module: {}", ModName.c_str()); + ZEN_LOG_ERROR("Failed to load EVM module: %s", ModName.c_str()); return ParentResult; } @@ -526,7 +526,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { IsolationPtr Iso(nullptr, IsolationDeleter{RT}); Iso.reset(RT->createManagedIsolation()); if (!Iso) { - ZEN_LOG_ERROR("Failed to create isolation for module: {}", + ZEN_LOG_ERROR("Failed to create isolation for module: %s", ModName.c_str()); return ParentResult; } @@ -534,7 +534,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { // Create EVM instance auto InstRet = Iso->createEVMInstance(*Mod, Msg.gas); if (!InstRet) { - ZEN_LOG_ERROR("Failed to create EVM instance for module: {}", + ZEN_LOG_ERROR("Failed to create EVM instance for module: %s", ModName.c_str()); return ParentResult; } @@ -573,7 +573,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { RT->callEVMMain(*Inst, CallMsg, ExecResult); } } catch (const std::exception &E) { - ZEN_LOG_ERROR("Error in recursive call: {}", E.what()); + ZEN_LOG_ERROR("Error in recursive call: %s", E.what()); restoreHostState(StateSnapshot); return ParentResult; } @@ -599,7 +599,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { } catch (const std::exception &E) { // On error, return parent result - ZEN_LOG_ERROR("Error in recursive call: {}", E.what()); + ZEN_LOG_ERROR("Error in recursive call: %s", E.what()); restoreHostState(StateSnapshot); return ParentResult; } @@ -695,7 +695,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { if (!IsNewAccount) { ensureAccountHasCodeHash(It->second); if (isCreateCollision(It->second)) { - ZEN_LOG_ERROR("Create collision at address {}", + ZEN_LOG_ERROR("Create collision at address %s", evmc::hex(NewAddr).c_str()); auto SenderIt = accounts.find(Msg.sender); if (SenderIt != accounts.end() && @@ -721,7 +721,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { auto ModRet = RT->loadEVMModule(ModName, InitcodePtr, InitcodeSize); if (!ModRet) { restoreHostState(StateSnapshot); - ZEN_LOG_ERROR("Failed to load EVM module: {}", ModName.c_str()); + ZEN_LOG_ERROR("Failed to load EVM module: %s", ModName.c_str()); return evmc::Result{EVMC_FAILURE, Msg.gas, 0, NewAddr}; } EVMModule *Mod = *ModRet; @@ -730,7 +730,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { Iso.reset(RT->createManagedIsolation()); if (!Iso) { restoreHostState(StateSnapshot); - ZEN_LOG_ERROR("Failed to create isolation for module: {}", + ZEN_LOG_ERROR("Failed to create isolation for module: %s", ModName.c_str()); return evmc::Result{EVMC_FAILURE, Msg.gas, 0, NewAddr}; } @@ -738,7 +738,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { auto InstRet = Iso->createEVMInstance(*Mod, Msg.gas); if (!InstRet) { restoreHostState(StateSnapshot); - ZEN_LOG_ERROR("Failed to create EVM instance for module: {}", + ZEN_LOG_ERROR("Failed to create EVM instance for module: %s", ModName.c_str()); return evmc::Result{EVMC_FAILURE, Msg.gas, 0, NewAddr}; } @@ -761,7 +761,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { intx::be::load(SenderAcc.balance); if (SenderBalance < Value) { restoreHostState(StateSnapshot); - ZEN_LOG_ERROR("Insufficient balance for CREATE: have {}, need {}", + ZEN_LOG_ERROR("Insufficient balance for CREATE: have %s, need %s", SenderBalance, Value); return evmc::Result{EVMC_INSUFFICIENT_BALANCE, Msg.gas, 0, NewAddr}; } @@ -799,7 +799,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { } } catch (const std::exception &E) { restoreHostState(StateSnapshot); - ZEN_LOG_ERROR("Error in handleCreate execution: {}", E.what()); + ZEN_LOG_ERROR("Error in handleCreate execution: %s", E.what()); return evmc::Result{EVMC_FAILURE, Msg.gas, 0, evmc::address{}}; } @@ -889,7 +889,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { CreateResult.create_address = NewAddr; return CreateResult; } catch (const std::exception &E) { - ZEN_LOG_ERROR("Error in handleCreate: {}", E.what()); + ZEN_LOG_ERROR("Error in handleCreate: %s", E.what()); restoreHostState(StateSnapshot); return evmc::Result{EVMC_FAILURE, Msg.gas, 0, evmc::address{}}; } From b771a199b7a5b630d38b53a130ee44f71038933a Mon Sep 17 00:00:00 2001 From: cmgCr Date: Thu, 9 Apr 2026 08:13:38 +0000 Subject: [PATCH 2/2] fix(evm): fix remaining ZEN_LOG format string issues --- src/tests/evm_test_helpers.h | 4 ++-- src/tests/evm_test_host.hpp | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/tests/evm_test_helpers.h b/src/tests/evm_test_helpers.h index 406a1be41..0bf3a15bf 100644 --- a/src/tests/evm_test_helpers.h +++ b/src/tests/evm_test_helpers.h @@ -153,7 +153,7 @@ inline std::string decimalToHex(const std::string &DecimalStr) { for (char C : TrimmedStr) { if (!std::isdigit(C)) { ZEN_LOG_ERROR( - "Invalid decimal string (contains non-digit characters). Value: {}", + "Invalid decimal string (contains non-digit characters). Value: %s", DecimalStr.c_str()); return "0"; } @@ -175,7 +175,7 @@ inline std::string decimalToHex(const std::string &DecimalStr) { std::string HexStr = S.str(); if (HexStr.size() > 64) { ZEN_LOG_ERROR( - "Hex value exceeds 64 characters (uint256 max). Length: {}, Value: {}", + "Hex value exceeds 64 characters (uint256 max). Length: %zu, Value: %s", HexStr.size(), HexStr.c_str()); HexStr = HexStr.substr(HexStr.size() - 64); } diff --git a/src/tests/evm_test_host.hpp b/src/tests/evm_test_host.hpp index 16a6f5852..9cf8cc03c 100644 --- a/src/tests/evm_test_host.hpp +++ b/src/tests/evm_test_host.hpp @@ -504,7 +504,7 @@ class ZenMockedEVMHost : public evmc::MockedHost { const auto &ContractCode = It->second.code; if (ContractCode.empty()) { ZEN_LOG_DEBUG( - "Contract code is empty for recipient {}", + "Contract code is empty for recipient %s", evmc::hex(evmc::bytes_view(Msg.recipient.bytes, 20)).c_str()); return ParentResult; } @@ -761,8 +761,10 @@ class ZenMockedEVMHost : public evmc::MockedHost { intx::be::load(SenderAcc.balance); if (SenderBalance < Value) { restoreHostState(StateSnapshot); + const auto SenderBalanceStr = intx::to_string(SenderBalance); + const auto ValueStr = intx::to_string(Value); ZEN_LOG_ERROR("Insufficient balance for CREATE: have %s, need %s", - SenderBalance, Value); + SenderBalanceStr.c_str(), ValueStr.c_str()); return evmc::Result{EVMC_INSUFFICIENT_BALANCE, Msg.gas, 0, NewAddr}; } SenderBalance -= Value;