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) {