1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//! Evm types needed for parsing instruction sets as well

// use serde::{Deserialize, Serialize};
// use std::fmt;

pub mod gas_utils;
pub mod memory;
pub mod opcode_ids;
pub mod stack;
pub mod storage;
pub mod transient_storage;

pub use memory::{Memory, MemoryAddress};
pub use opcode_ids::OpcodeId;
pub use stack::{Stack, StackAddress};
pub use storage::Storage;
pub use transient_storage::TransientStorage;

/// According to EIP-3541, disallow new code starting with 0xEF to be deployed.
pub const INVALID_INIT_CODE_FIRST_BYTE: u8 = 0xef;
/// Once per word of the init code when creating a contract.
pub const INIT_CODE_WORD_GAS: u64 = 2;
/// Quotient for max refund of gas used
pub const MAX_REFUND_QUOTIENT_OF_GAS_USED: usize = 5;
/// Gas stipend when CALL or CALLCODE is attached with value.
pub const GAS_STIPEND_CALL_WITH_VALUE: u64 = 2300;

/// This constant ((2^32 - 1) * 32) is the highest number that can be used without overflowing the
/// square operation of gas calculation.
/// <https://github.com/ethereum/go-ethereum/blob/e6b6a8b738069ad0579f6798ee59fde93ed13b43/core/vm/gas_table.go#L38>
pub const MAX_EXPANDED_MEMORY_ADDRESS: u64 = 0x1FFFFFFFE0;

#[cfg(feature = "shanghai")]
mod gas_create {
    // For EIP-3860, there are 2 special gas cost constraints in geth
    // [gasCreate2Eip3860](https://github.com/ethereum/go-ethereum/blob/eb83e7c54021573eaceb14236af3a7a8c64f6027/core/vm/gas_table.go#L321)
    // (similar for CREATE).
    // 1. size <= 49152 (MaxInitCodeSize)
    // 2. gasCost = memoryGasCost + (2 + 6) * ((size + 31) / 32) should not overflow for Uint64.
    // No need to constrain the second condition, since the maximum gas cost
    // cannot overflow for Uint64 (36028809887100925 calculated by
    // `memorySize = 0x1FFFFFFFE0` and `size = 49152`) if the first condition is
    // satisfied.

    /// Maximum init code size to permit in a creation transaction and create instructions.
    pub const MAX_INIT_CODE_SIZE: u64 = 2 * super::MAX_CODE_SIZE;
    /// Once per word of the init code when creating a contract.
    pub const INIT_CODE_WORD_GAS: u64 = 2;
    /// Gas per code word for CREATE.
    pub const CREATE_GAS_PER_CODE_WORD: u64 = INIT_CODE_WORD_GAS;
    /// Gas per code word for CREATE2.
    pub const CREATE2_GAS_PER_CODE_WORD: u64 = INIT_CODE_WORD_GAS + super::GasCost::COPY_SHA3.0;
}
#[cfg(not(feature = "shanghai"))]
mod gas_create {
    /// Maximum init code size (0x1FFFFFFFE0) if not EIP-3860.
    pub use super::MAX_EXPANDED_MEMORY_ADDRESS as MAX_INIT_CODE_SIZE;
    /// Gas per code word for CREATE if not EIP-3860.
    pub const CREATE_GAS_PER_CODE_WORD: u64 = 0;
    /// Gas per code word for CREATE2 if not EIP-3860.
    pub const CREATE2_GAS_PER_CODE_WORD: u64 = super::GasCost::COPY_SHA3;
}
pub use gas_create::*;

/// Defines the gas consumption.
pub struct GasCost;

impl GasCost {
    /// Constant cost for free step
    pub const ZERO: u64 = 0;
    /// Constant cost for jumpdest step, only takes one gas
    pub const ONE: u64 = 1;
    /// Constant cost for quick step
    pub const QUICK: u64 = 2;
    /// Constant cost for fastest step
    pub const FASTEST: u64 = 3;
    /// Constant cost for fast step
    pub const FAST: u64 = 5;
    /// Constant cost for mid step
    pub const MID: u64 = 8;
    /// Constant cost for slow step
    pub const SLOW: u64 = 10;
    /// Constant cost for ext step
    pub const EXT: u64 = 20;
    /// Constant cost for SHA3
    pub const SHA3: u64 = 30;
    /// Constant cost for SELFDESTRUCT
    pub const SELFDESTRUCT: u64 = 5000;
    /// Constant cost for CREATE and CREATE2
    pub const CREATE: u64 = 32000;
    /// Constant cost for copying every word
    pub const COPY: u64 = 3;
    /// Constant cost for copying every word, specifically in the case of SHA3
    /// opcode.
    pub const COPY_SHA3: u64 = 6;
    /// Constant cost for accessing account or storage key
    pub const WARM_ACCESS: u64 = 100;
    /// Constant cost for a cold SLOAD
    pub const COLD_SLOAD: u64 = 2100;
    /// Constant cost for a cold account access
    pub const COLD_ACCOUNT_ACCESS: u64 = 2600;
    /// SSTORE reentrancy sentry
    pub const SSTORE_SENTRY: u64 = 2300;
    /// Constant cost for a storage set
    pub const SSTORE_SET: u64 = 20000;
    /// Constant cost for a storage reset
    pub const SSTORE_RESET: u64 = 2900;
    /// Constant cost for a storage clear. EIP-3529 changed it to 4800 from
    /// 15000.
    pub const SSTORE_CLEARS_SCHEDULE: u64 = 4800;
    /// Constant cost for a non-creation transaction
    pub const TX: u64 = 21000;
    /// Constant cost for a creation transaction
    pub const CREATION_TX: u64 = 53000;
    /// Constant cost for calling with non-zero value
    pub const CALL_WITH_VALUE: u64 = 9000;
    /// Constant cost for turning empty account into non-empty account
    pub const NEW_ACCOUNT: u64 = 25000;
    /// Cost per byte of deploying a new contract
    pub const CODE_DEPOSIT_BYTE_COST: u64 = 200;
    /// Denominator of quadratic part of memory expansion gas cost
    pub const MEMORY_EXPANSION_QUAD_DENOMINATOR: u64 = 512;
    /// Coefficient of linear part of memory expansion gas cost
    pub const MEMORY_EXPANSION_LINEAR_COEFF: u64 = 3;
    /// Constant gas for LOG[0-4] op codes
    pub const LOG: u64 = 375;
    /// Times ceil exponent byte size for the EXP instruction, EIP-158 changed
    /// it from 10 to 50.
    pub const EXP_BYTE_TIMES: u64 = 50;
    /// Base gas cost for precompile call: Elliptic curve recover
    pub const PRECOMPILE_ECRECOVER_BASE: u64 = 3000;
    /// Base gas cost for precompile call: SHA256
    pub const PRECOMPILE_SHA256_BASE: u64 = 60;
    /// Per-word gas cost for SHA256
    pub const PRECOMPILE_SHA256_PER_WORD: u64 = 12;
    /// Base gas cost for precompile call: RIPEMD160
    pub const PRECOMPILE_RIPEMD160_BASE: u64 = 600;
    /// Per-word gas cost for RIPEMD160
    pub const PRECOMPILE_RIPEMD160_PER_WORD: u64 = 120;
    /// Base gas cost for precompile call: Identity
    pub const PRECOMPILE_IDENTITY_BASE: u64 = 15;
    /// Per-word gas cost for Identity
    pub const PRECOMPILE_IDENTITY_PER_WORD: u64 = 3;
    /// Base gas cost for precompile call: BN256 point addition
    pub const PRECOMPILE_BN256ADD: u64 = 150;
    /// Base gas cost for precompile call: BN256 scalar multiplication
    pub const PRECOMPILE_BN256MUL: u64 = 6000;
    /// Base gas cost for precompile call: BN256 pairing op base cost
    pub const PRECOMPILE_BN256PAIRING: u64 = 45000;
    /// Per-pair gas cost for BN256 pairing
    pub const PRECOMPILE_BN256PAIRING_PER_PAIR: u64 = 34000;
    /// Base gas cost for precompile call: MODEXP
    pub const PRECOMPILE_MODEXP: u64 = 200; // eip255
    /// Minimum gas cost for precompile calls: MODEXP
    pub const PRECOMPILE_MODEXP_MIN: u64 = 200;
    /// Base gas cost for precompile call: BLAKE2F
    pub const PRECOMPILE_BLAKE2F: u64 = 0;
}

/// This constant is used to iterate through precompile contract addresses 0x01 to 0x09
pub const PRECOMPILE_COUNT: u64 = 9;