1use evm_interpreter::runtime::RuntimeConfig;
2
3#[derive(Clone, Debug)]
5#[non_exhaustive]
6pub struct Config {
7 pub runtime: RuntimeConfig,
9 pub eip2_no_empty_contract: bool,
11 pub eip2_create_transaction_increase: bool,
13 pub eip1884_trie_repricing: bool,
15 pub eip2200_sstore_gas_metering: bool,
17 pub eip2200_sstore_revert_under_stipend: bool,
19 pub eip2929_increase_state_access_gas: bool,
21 pub eip3529_decrease_clears_refund: bool,
23 pub eip3541_disallow_executable_format: bool,
25 pub eip150_gas_increase: bool,
27 pub eip150_no_err_on_call_with_more_gas: bool,
31 pub eip150_call_l64_after_gas: bool,
33 pub eip161_create_increase_nonce: bool,
35 pub eip170_create_contract_limit: bool,
37 pub eip3860_max_initcode_size: bool,
39 pub eip7_delegate_call: bool,
41 pub eip1014_create2: bool,
43 pub eip140_revert: bool,
45 pub eip160_exp_increase: bool,
47 pub eip211_return_data: bool,
49 pub eip214_static_call: bool,
51 pub eip145_bitwise_shifting: bool,
53 pub eip1344_chain_id: bool,
55 pub eip1884_self_balance: bool,
57 pub eip1052_ext_code_hash: bool,
59 pub eip3198_base_fee: bool,
61 pub eip3855_push0: bool,
63 pub eip1153_transient_storage: bool,
65 pub eip5656_mcopy: bool,
67 pub eip1559_fee_market: bool,
69 pub eip2028_transaction_calldata_decrease: bool,
71 pub eip198_modexp_precompile: bool,
73 pub eip196_ec_add_mul_precompile: bool,
75 pub eip197_ec_pairing_precompile: bool,
77 pub eip152_blake_2f_precompile: bool,
79 pub eip1108_ec_add_mul_pairing_decrease: bool,
81 pub eip2565_lower_modexp: bool,
83 pub eip2930_access_list: bool,
85 pub eip4844_shard_blob: bool,
87 pub eip7516_blob_base_fee: bool,
89 pub eip7623_calldata_floor: bool,
91}
92
93impl Config {
94 pub const fn frontier() -> Config {
96 Config {
97 runtime: RuntimeConfig::frontier(),
98 eip2_no_empty_contract: false,
99 eip2_create_transaction_increase: false,
100 eip2200_sstore_gas_metering: false,
101 eip2200_sstore_revert_under_stipend: false,
102 eip2929_increase_state_access_gas: false,
103 eip3529_decrease_clears_refund: false,
104 eip3541_disallow_executable_format: false,
105 eip150_no_err_on_call_with_more_gas: false,
106 eip161_create_increase_nonce: false,
107 eip150_call_l64_after_gas: false,
108 eip170_create_contract_limit: false,
109 eip3860_max_initcode_size: false,
110 eip7_delegate_call: false,
111 eip1014_create2: false,
112 eip140_revert: false,
113 eip211_return_data: false,
114 eip145_bitwise_shifting: false,
115 eip1344_chain_id: false,
116 eip1884_self_balance: false,
117 eip1052_ext_code_hash: false,
118 eip3198_base_fee: false,
119 eip3855_push0: false,
120 eip1153_transient_storage: false,
121 eip5656_mcopy: false,
122 eip1559_fee_market: false,
123 eip198_modexp_precompile: false,
124 eip196_ec_add_mul_precompile: false,
125 eip197_ec_pairing_precompile: false,
126 eip152_blake_2f_precompile: false,
127 eip150_gas_increase: false,
128 eip160_exp_increase: false,
129 eip1884_trie_repricing: false,
130 eip214_static_call: false,
131 eip1108_ec_add_mul_pairing_decrease: false,
132 eip2028_transaction_calldata_decrease: false,
133 eip2565_lower_modexp: false,
134 eip2930_access_list: false,
135 eip4844_shard_blob: false,
136 eip7516_blob_base_fee: false,
137 eip7623_calldata_floor: false,
138 }
139 }
140
141 pub const fn homestead() -> Config {
143 let mut config = Self::frontier();
144 config.eip2_no_empty_contract = true;
145 config.eip2_create_transaction_increase = true;
146 config.eip7_delegate_call = true;
147 config
148 }
149
150 pub const fn tangerine_whistle() -> Config {
152 let mut config = Self::homestead();
153 config.eip150_gas_increase = true;
154 config.eip150_no_err_on_call_with_more_gas = true;
155 config.eip150_call_l64_after_gas = true;
156 config
157 }
158
159 pub const fn spurious_dragon() -> Config {
161 let mut config = Self::tangerine_whistle();
162 config.runtime.eip161_empty_check = true;
163 config.eip161_create_increase_nonce = true;
164 config.eip160_exp_increase = true;
165 config.eip170_create_contract_limit = true;
166 config
167 }
168
169 pub const fn byzantium() -> Config {
171 let mut config = Self::spurious_dragon();
172 config.eip140_revert = true;
173 config.eip196_ec_add_mul_precompile = true;
174 config.eip197_ec_pairing_precompile = true;
175 config.eip198_modexp_precompile = true;
176 config.eip211_return_data = true;
177 config.eip214_static_call = true;
178 config
179 }
180
181 pub const fn petersburg() -> Config {
183 let mut config = Self::byzantium();
184 config.eip145_bitwise_shifting = true;
185 config.eip1014_create2 = true;
186 config.eip1052_ext_code_hash = true;
187 config
188 }
189
190 pub const fn istanbul() -> Config {
192 let mut config = Self::petersburg();
193 config.eip152_blake_2f_precompile = true;
194 config.eip1108_ec_add_mul_pairing_decrease = true;
195 config.eip1344_chain_id = true;
196 config.eip1884_trie_repricing = true;
197 config.eip1884_self_balance = true;
198 config.eip2028_transaction_calldata_decrease = true;
199 config.eip2200_sstore_gas_metering = true;
200 config.eip2200_sstore_revert_under_stipend = true;
201 config
202 }
203
204 pub const fn berlin() -> Config {
206 let mut config = Self::istanbul();
207 config.eip2565_lower_modexp = true;
208 config.eip2929_increase_state_access_gas = true;
209 config.eip2930_access_list = true;
210 config
211 }
212
213 pub const fn london() -> Config {
215 let mut config = Self::berlin();
216 config.eip1559_fee_market = true;
217 config.eip3198_base_fee = true;
218 config.eip3529_decrease_clears_refund = true;
219 config.eip3541_disallow_executable_format = true;
220 config
221 }
222
223 pub const fn shanghai() -> Config {
225 let mut config = Self::london();
226 config.runtime.eip3651_warm_coinbase_address = true;
227 config.eip3855_push0 = true;
228 config.eip3860_max_initcode_size = true;
229 config
230 }
231
232 pub const fn cancun() -> Config {
234 let mut config = Self::shanghai();
235 config.eip1153_transient_storage = true;
236 config.eip5656_mcopy = true;
237 config.runtime.eip6780_suicide_only_in_same_tx = true;
238 config.eip4844_shard_blob = true;
239 config.eip7516_blob_base_fee = true;
240 config
241 }
242
243 pub const fn prague() -> Config {
245 let mut config = Self::cancun();
246 config.eip7623_calldata_floor = true;
247 config
248 }
249
250 pub fn gas_ext_code(&self) -> u64 {
252 if self.eip150_gas_increase { 700 } else { 20 }
253 }
254
255 pub fn gas_ext_code_hash(&self) -> u64 {
257 if self.eip1884_trie_repricing {
258 700
259 } else {
260 400
261 }
262 }
263
264 pub fn gas_sstore_set(&self) -> u64 {
266 20000
267 }
268
269 pub fn gas_sstore_reset(&self) -> u64 {
271 if self.eip2929_increase_state_access_gas {
272 2900
273 } else {
274 5000
275 }
276 }
277
278 pub fn refund_sstore_clears(&self) -> i64 {
280 if self.eip3529_decrease_clears_refund {
281 4800
282 } else {
283 15000
284 }
285 }
286
287 pub fn max_refund_quotient(&self) -> u64 {
289 if self.eip3529_decrease_clears_refund {
290 5
291 } else {
292 2
293 }
294 }
295
296 pub fn gas_balance(&self) -> u64 {
298 if self.eip1884_trie_repricing {
299 700
300 } else if self.eip150_gas_increase {
301 400
302 } else {
303 20
304 }
305 }
306
307 pub fn gas_sload(&self) -> u64 {
309 if self.eip2929_increase_state_access_gas {
310 100
311 } else if self.eip2200_sstore_gas_metering {
312 800
313 } else if self.eip150_gas_increase {
314 200
315 } else {
316 50
317 }
318 }
319
320 pub fn gas_sload_cold(&self) -> u64 {
322 if self.eip2929_increase_state_access_gas {
323 2100
324 } else {
325 0
326 }
327 }
328
329 pub fn gas_suicide(&self) -> u64 {
331 if self.eip150_gas_increase { 5000 } else { 0 }
332 }
333
334 pub fn gas_suicide_new_account(&self) -> u64 {
336 if self.eip150_gas_increase { 25000 } else { 0 }
337 }
338
339 pub fn gas_call(&self) -> u64 {
341 if self.eip150_gas_increase { 700 } else { 40 }
342 }
343
344 pub fn gas_expbyte(&self) -> u64 {
346 if self.eip160_exp_increase { 50 } else { 10 }
347 }
348
349 pub fn gas_transaction_create(&self) -> u64 {
351 if self.eip2_create_transaction_increase {
352 53000
353 } else {
354 21000
355 }
356 }
357
358 pub fn gas_transaction_call(&self) -> u64 {
360 21000
361 }
362
363 pub fn gas_transaction_zero_data(&self) -> u64 {
365 4
366 }
367
368 pub fn gas_transaction_non_zero_data(&self) -> u64 {
370 if self.eip2028_transaction_calldata_decrease {
371 16
372 } else {
373 68
374 }
375 }
376
377 pub fn gas_floor_transaction_zero_data(&self) -> u64 {
379 if self.eip7623_calldata_floor { 10 } else { 0 }
380 }
381
382 pub fn gas_floor_transaction_non_zero_data(&self) -> u64 {
384 if self.eip7623_calldata_floor { 40 } else { 0 }
385 }
386
387 pub fn gas_access_list_address(&self) -> u64 {
389 if self.eip2930_access_list { 2400 } else { 0 }
390 }
391
392 pub fn gas_access_list_storage_key(&self) -> u64 {
394 if self.eip2930_access_list { 1900 } else { 0 }
395 }
396
397 pub fn gas_account_access_cold(&self) -> u64 {
399 if self.eip2929_increase_state_access_gas {
400 2600
401 } else {
402 0
403 }
404 }
405
406 pub fn gas_storage_read_warm(&self) -> u64 {
408 if self.eip2929_increase_state_access_gas {
409 100
410 } else {
411 0
412 }
413 }
414
415 pub fn stack_limit(&self) -> usize {
417 1024
418 }
419
420 pub fn memory_limit(&self) -> usize {
422 usize::MAX
423 }
424
425 pub fn call_stack_limit(&self) -> usize {
427 1024
428 }
429
430 pub fn call_stipend(&self) -> u64 {
432 2300
433 }
434
435 pub fn max_initcode_size(&self) -> Option<usize> {
437 if self.eip3860_max_initcode_size {
438 Some(0xc000)
439 } else {
440 None
441 }
442 }
443
444 pub fn create_contract_limit(&self) -> Option<usize> {
446 if self.eip170_create_contract_limit {
447 Some(0x6000)
448 } else {
449 None
450 }
451 }
452}