diff --git a/category/execution/CMakeLists.txt b/category/execution/CMakeLists.txt
index 1157e65713..d3acb7c93b 100644
--- a/category/execution/CMakeLists.txt
+++ b/category/execution/CMakeLists.txt
@@ -135,6 +135,8 @@ add_library(
"ethereum/block_reward.hpp"
"ethereum/create_contract_address.cpp"
"ethereum/create_contract_address.hpp"
+ "ethereum/deterministic_factory_contract.cpp"
+ "ethereum/deterministic_factory_contract.hpp"
"ethereum/dispatch_transaction.cpp"
"ethereum/dispatch_transaction.hpp"
"ethereum/evmc_host.cpp"
diff --git a/category/execution/ethereum/deterministic_factory_contract.cpp b/category/execution/ethereum/deterministic_factory_contract.cpp
new file mode 100644
index 0000000000..190f68c711
--- /dev/null
+++ b/category/execution/ethereum/deterministic_factory_contract.cpp
@@ -0,0 +1,55 @@
+// Copyright (C) 2025-26 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+MONAD_ANONYMOUS_NAMESPACE_BEGIN
+
+constexpr auto FACTORY_ADDRESS =
+ 0x4e59b44847b379578588920cA78FbF26c0B4956C_address;
+
+byte_string const FACTORY_CODE =
+ from_hex("0x7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+ "fe03601600081602082378035828234f58015156039578182fd5b808252505050"
+ "6014600cf3")
+ .value();
+
+MONAD_ANONYMOUS_NAMESPACE_END
+
+MONAD_NAMESPACE_BEGIN
+
+// EIP-7997
+template
+void deploy_deterministic_factory_contract(State &state)
+{
+ if constexpr (!traits::eip_7997_active()) {
+ return;
+ }
+
+ if (MONAD_UNLIKELY(!state.account_exists(FACTORY_ADDRESS))) {
+ state.create_contract(FACTORY_ADDRESS);
+ state.set_code(FACTORY_ADDRESS, FACTORY_CODE);
+ state.set_nonce(FACTORY_ADDRESS, 1);
+ }
+}
+
+EXPLICIT_TRAITS(deploy_deterministic_factory_contract);
+
+MONAD_NAMESPACE_END
diff --git a/category/execution/ethereum/deterministic_factory_contract.hpp b/category/execution/ethereum/deterministic_factory_contract.hpp
new file mode 100644
index 0000000000..4ce5b9e07e
--- /dev/null
+++ b/category/execution/ethereum/deterministic_factory_contract.hpp
@@ -0,0 +1,25 @@
+// Copyright (C) 2025-26 Category Labs, Inc.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+#include
+#include
+#include
+
+MONAD_NAMESPACE_BEGIN
+
+template
+void deploy_deterministic_factory_contract(State &);
+
+MONAD_NAMESPACE_END
diff --git a/category/execution/ethereum/execute_block_header.cpp b/category/execution/ethereum/execute_block_header.cpp
index e7c2c108ef..b963c59bfc 100644
--- a/category/execution/ethereum/execute_block_header.cpp
+++ b/category/execution/ethereum/execute_block_header.cpp
@@ -20,6 +20,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -70,6 +71,8 @@ void execute_block_header(
deploy_block_hash_history_contract(state);
set_block_hash_history(state, header);
+ deploy_deterministic_factory_contract(state);
+
if constexpr (traits::evm_rev() >= MONAD_ETH_CANCUN) {
set_beacon_root(state, header);
}
diff --git a/category/vm/evm/traits.hpp b/category/vm/evm/traits.hpp
index 87a01a91d9..e8a660c062 100644
--- a/category/vm/evm/traits.hpp
+++ b/category/vm/evm/traits.hpp
@@ -85,6 +85,7 @@ namespace monad
{ T::eip_7939_active() } -> std::same_as;
{ T::eip_7951_active() } -> std::same_as;
{ T::eip_7981_active() } -> std::same_as;
+ { T::eip_7997_active() } -> std::same_as;
{ T::mip_3_active() } -> std::same_as;
{ T::mip_8_active() } -> std::same_as;
{ T::mip_11_active() } -> std::same_as;
@@ -188,6 +189,11 @@ namespace monad
return Rev >= MONAD_ETH_AMSTERDAM;
}
+ static consteval bool eip_7997_active() noexcept
+ {
+ return Rev >= MONAD_ETH_AMSTERDAM;
+ }
+
static consteval bool mip_3_active() noexcept
{
return false;
@@ -367,6 +373,11 @@ namespace monad
return evm_rev() >= MONAD_ETH_AMSTERDAM;
}
+ static consteval bool eip_7997_active() noexcept
+ {
+ return evm_rev() >= MONAD_ETH_AMSTERDAM;
+ }
+
static consteval bool mip_3_active() noexcept
{
if constexpr (Rev >= MONAD_NINE) {