diff --git a/crates/vm/backends/levm/mod.rs b/crates/vm/backends/levm/mod.rs index 158878d7f0..2ecec009d2 100644 --- a/crates/vm/backends/levm/mod.rs +++ b/crates/vm/backends/levm/mod.rs @@ -4,7 +4,7 @@ mod tracing; use super::BlockExecutionResult; use crate::system_contracts::{ BEACON_ROOTS_ADDRESS, CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS, HISTORY_STORAGE_ADDRESS, - SYSTEM_ADDRESS, WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, + PRAGUE_SYSTEM_CONTRACTS, SYSTEM_ADDRESS, WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS, }; use crate::{EvmError, ExecutionResult}; use bytes::Bytes; @@ -381,6 +381,21 @@ pub fn generic_system_contract_levm( ..Default::default() }; + // This check is not necessary in practice, since contract deployment has succesfully happened in all relevant testnets and mainnet + // However, it's necessary to pass some of the Hive tests related to system contract deployment, which is why we have it + // The error that should be returned for the relevant contracts is indicated in the following: + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7002.md#empty-code-failure + // https://github.com/ethereum/EIPs/blob/master/EIPS/eip-7251.md#empty-code-failure + if PRAGUE_SYSTEM_CONTRACTS + .iter() + .any(|contract| contract.address == contract_address) + && db.get_account_code(contract_address)?.is_empty() + { + return Err(EvmError::SystemContractCallFailed(format!( + "System contract: {contract_address} has no code after deployment" + ))); + }; + let tx = &Transaction::EIP1559Transaction(EIP1559Transaction { to: TxKind::Call(contract_address), value: U256::zero(), diff --git a/crates/vm/system_contracts.rs b/crates/vm/system_contracts.rs index d7be861a31..411d04298a 100644 --- a/crates/vm/system_contracts.rs +++ b/crates/vm/system_contracts.rs @@ -69,3 +69,8 @@ pub fn system_contracts_for_fork(fork: Fork) -> impl Iterator