Skip to content

Commit

Permalink
fix(levm): add spurious dragon checks (#1957)
Browse files Browse the repository at this point in the history
**Motivation**

The EXP instruction's cost changed in Spurious dragon

**Description**

Add a check for its cost.
  • Loading branch information
lima-limon-inc authored Feb 14, 2025
1 parent 7afd281 commit 39470aa
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 15 deletions.
27 changes: 15 additions & 12 deletions crates/vm/levm/src/execution_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use crate::{
vm::{StateBackup, VM},
};

use ethrex_common::types::Fork;

use bytes::Bytes;

impl VM {
Expand Down Expand Up @@ -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) => {
Expand Down
12 changes: 10 additions & 2 deletions crates/vm/levm/src/gas_cost.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<u64, VMError> {
pub fn exp(exponent: U256, fork: Fork) -> Result<u64, VMError> {
let exponent_byte_size = (exponent
.bits()
.checked_add(7)
Expand All @@ -271,7 +272,14 @@ pub fn exp(exponent: U256) -> Result<u64, VMError> {
.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))?;

Expand Down
2 changes: 1 addition & 1 deletion crates/vm/levm/src/opcode_handlers/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)?;

Expand Down

0 comments on commit 39470aa

Please sign in to comment.