From 39470aa58742ab60fd12625beb807e4e21f0a0d3 Mon Sep 17 00:00:00 2001 From: Tomas Fabrizio Orsi Date: Fri, 14 Feb 2025 17:24:10 -0300 Subject: [PATCH] fix(levm): add spurious dragon checks (#1957) **Motivation** The EXP instruction's cost changed in Spurious dragon **Description** Add a check for its cost. --- crates/vm/levm/src/execution_handlers.rs | 27 ++++++++++--------- crates/vm/levm/src/gas_cost.rs | 12 +++++++-- .../vm/levm/src/opcode_handlers/arithmetic.rs | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/crates/vm/levm/src/execution_handlers.rs b/crates/vm/levm/src/execution_handlers.rs index d899d2f6d1..8cdc13e5a9 100644 --- a/crates/vm/levm/src/execution_handlers.rs +++ b/crates/vm/levm/src/execution_handlers.rs @@ -9,6 +9,8 @@ use crate::{ vm::{StateBackup, VM}, }; +use ethrex_common::types::Fork; + use bytes::Bytes; impl VM { @@ -189,18 +191,19 @@ impl VM { // If the first byte of code is 0xef // If the code_length > MAX_CODE_SIZE // If current_consumed_gas + code_deposit_cost > gas_limit - let validate_create = if code_length > MAX_CODE_SIZE { - Err(VMError::ContractOutputTooBig) - } else if contract_code.first().unwrap_or(&0) == &INVALID_CONTRACT_PREFIX { - Err(VMError::InvalidContractPrefix) - } else if current_call_frame - .increase_consumed_gas(code_deposit_cost) - .is_err() - { - Err(VMError::OutOfGas(OutOfGasError::MaxGasLimitExceeded)) - } else { - Ok(current_call_frame.to) - }; + let validate_create = + if code_length > MAX_CODE_SIZE && self.env.config.fork >= Fork::SpuriousDragon { + Err(VMError::ContractOutputTooBig) + } else if contract_code.first().unwrap_or(&0) == &INVALID_CONTRACT_PREFIX { + Err(VMError::InvalidContractPrefix) + } else if current_call_frame + .increase_consumed_gas(code_deposit_cost) + .is_err() + { + Err(VMError::OutOfGas(OutOfGasError::MaxGasLimitExceeded)) + } else { + Ok(current_call_frame.to) + }; match validate_create { Ok(new_address) => { diff --git a/crates/vm/levm/src/gas_cost.rs b/crates/vm/levm/src/gas_cost.rs index f25a06f0f0..796fd2f459 100644 --- a/crates/vm/levm/src/gas_cost.rs +++ b/crates/vm/levm/src/gas_cost.rs @@ -21,6 +21,7 @@ pub const SMOD: u64 = 5; pub const ADDMOD: u64 = 8; pub const MULMOD: u64 = 8; pub const EXP_STATIC: u64 = 10; +pub const EXP_DYNAMIC_BASE_PRE_SPURIOUS_DRAGON: u64 = 10; pub const EXP_DYNAMIC_BASE: u64 = 50; pub const SIGNEXTEND: u64 = 5; pub const LT: u64 = 3; @@ -260,7 +261,7 @@ pub const BLS12_381_G2_K_DISCOUNT: [u64; 128] = [ ]; pub const G2_MUL_COST: u64 = 22500; -pub fn exp(exponent: U256) -> Result { +pub fn exp(exponent: U256, fork: Fork) -> Result { let exponent_byte_size = (exponent .bits() .checked_add(7) @@ -271,7 +272,14 @@ pub fn exp(exponent: U256) -> Result { .try_into() .map_err(|_| VMError::VeryLargeNumber)?; - let exponent_byte_size_cost = EXP_DYNAMIC_BASE + // https://eips.ethereum.org/EIPS/eip-160 + let dynamic_base = if fork < Fork::SpuriousDragon { + EXP_DYNAMIC_BASE_PRE_SPURIOUS_DRAGON + } else { + EXP_DYNAMIC_BASE + }; + + let exponent_byte_size_cost = dynamic_base .checked_mul(exponent_byte_size) .ok_or(VMError::OutOfGas(OutOfGasError::GasCostOverflow))?; diff --git a/crates/vm/levm/src/opcode_handlers/arithmetic.rs b/crates/vm/levm/src/opcode_handlers/arithmetic.rs index d437c2081c..496df89264 100644 --- a/crates/vm/levm/src/opcode_handlers/arithmetic.rs +++ b/crates/vm/levm/src/opcode_handlers/arithmetic.rs @@ -221,7 +221,7 @@ impl VM { let base = current_call_frame.stack.pop()?; let exponent = current_call_frame.stack.pop()?; - let gas_cost = gas_cost::exp(exponent)?; + let gas_cost = gas_cost::exp(exponent, self.env.config.fork)?; current_call_frame.increase_consumed_gas(gas_cost)?;