1#![allow(
2 clippy::needless_update,
3 unreachable_pub,
4 dead_code,
5 missing_docs,
6 missing_debug_implementations
7)]
8
9use crate::*;
10use revm_bytecode::opcode as op;
11use revm_context_interface as context_interface;
12use revm_interpreter as interpreter;
13use revm_interpreter::{
14 CreateInputs, FrameInput, Gas, InstructionResult, InterpreterAction, InterpreterResult,
15};
16use revm_primitives::{
17 Address, B256, Bytes, KECCAK_EMPTY, Log, LogData, hardfork::SpecId, hex, keccak256,
18};
19use revmc_builtins::gas;
20
21const fn keccak256_cost(len: u64) -> Option<u64> {
23 let words = len.div_ceil(32);
24 match words.checked_mul(gas::KECCAK256WORD) {
25 Some(dyn_cost) => Some(gas::KECCAK256.saturating_add(dyn_cost)),
26 None => None,
27 }
28}
29
30const fn log_cost(n_topics: u8, len: u64) -> Option<u64> {
32 match gas::LOGDATA.checked_mul(len) {
33 Some(dyn_cost) => {
34 Some((gas::LOG + gas::LOGTOPIC * n_topics as u64).saturating_add(dyn_cost))
35 }
36 None => None,
37 }
38}
39
40const fn verylowcopy_cost(len: u64) -> Option<u64> {
42 let words = len.div_ceil(32);
43 match words.checked_mul(gas::COPY) {
44 Some(dyn_cost) => Some(gas::VERYLOW.saturating_add(dyn_cost)),
45 None => None,
46 }
47}
48
49#[macro_use]
50mod macros;
51
52mod meta;
53
54mod fibonacci;
55mod resume;
56mod resume_at_call;
57
58mod runner;
59pub use runner::*;
60
61#[cfg(feature = "llvm")]
62pub fn with_jit_compiler<R>(
63 opt_level: revmc_backend::OptimizationLevel,
64 f: fn(&mut EvmCompiler<revmc_llvm::EvmLlvmBackend>) -> R,
65) -> R {
66 init_tracing();
67 let mut compiler = EvmCompiler::new_llvm(false).unwrap();
68 compiler.set_opt_level(opt_level);
69 compiler.set_profiling_support(false);
70 compiler.set_simple_perf(false);
71 compiler.single_error(false);
72 f(&mut compiler)
73}
74
75const I256_MIN: U256 = U256::from_limbs([
76 0x0000000000000000,
77 0x0000000000000000,
78 0x0000000000000000,
79 0x8000000000000000,
80]);
81
82const I256_MAX: U256 = U256::from_limbs([
83 0xFFFFFFFFFFFFFFFF,
84 0xFFFFFFFFFFFFFFFF,
85 0xFFFFFFFFFFFFFFFF,
86 0x7FFFFFFFFFFFFFFF,
87]);
88
89tests! {
90 ret {
91 empty(@raw {}),
92 no_stop(@raw {
93 bytecode: &[op::PUSH0],
94 expected_stack: &[U256::ZERO],
95 expected_gas: 2,
96 }),
97 stop(@raw {
98 bytecode: &[op::STOP],
99 expected_gas: 0,
100 }),
101 invalid(@raw {
102 bytecode: &[op::INVALID],
103 expected_return: InstructionResult::InvalidFEOpcode,
104 expected_gas: 0,
105 }),
106 unknown(@raw {
107 bytecode: &[0x21],
108 expected_return: InstructionResult::OpcodeNotFound,
109 expected_gas: 0,
110 }),
111 underflow1(@raw {
112 bytecode: &[op::ADD],
113 expected_return: InstructionResult::StackUnderflow,
114 expected_gas: 3,
115 }),
116 underflow2(@raw {
117 bytecode: &[op::PUSH0, op::ADD],
118 expected_return: InstructionResult::StackUnderflow,
119 expected_stack: &[U256::ZERO],
120 expected_gas: 5,
121 }),
122 underflow3(@raw {
123 bytecode: &[op::PUSH0, op::POP, op::ADD],
124 expected_return: InstructionResult::StackUnderflow,
125 expected_gas: 7,
126 }),
127 underflow4(@raw {
128 bytecode: &[op::PUSH0, op::ADD, op::POP],
129 expected_return: InstructionResult::StackUnderflow,
130 expected_stack: &[U256::ZERO],
131 expected_gas: 5,
132 }),
133 overflow_not0(@raw {
134 bytecode: &[op::PUSH0; 1023],
135 expected_return: InstructionResult::Stop,
136 expected_stack: &[0_U256; 1023],
137 expected_gas: 2 * 1023,
138 }),
139 overflow_not1(@raw {
140 bytecode: &[op::PUSH0; 1024],
141 expected_return: InstructionResult::Stop,
142 expected_stack: &[0_U256; 1024],
143 expected_gas: 2 * 1024,
144 }),
145 overflow0(@raw {
146 bytecode: &[op::PUSH0; 1025],
147 expected_return: InstructionResult::StackOverflow,
148 expected_stack: &[0_U256; 1024],
149 expected_gas: 2 * 1025,
150 }),
151 overflow1(@raw {
152 bytecode: &[op::PUSH0; 1026],
153 expected_return: InstructionResult::StackOverflow,
154 expected_stack: &[0_U256; 1024],
155 expected_gas: 2 * 1025,
156 }),
157 }
158
159 spec_id {
160 push0_merge(@raw {
161 bytecode: &[op::PUSH0],
162 spec_id: SpecId::MERGE,
163 expected_return: InstructionResult::NotActivated,
164 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
165 }),
166 push0_shanghai(@raw {
167 bytecode: &[op::PUSH0],
168 spec_id: SpecId::SHANGHAI,
169 expected_stack: &[U256::ZERO],
170 expected_gas: 2,
171 }),
172 push0_cancun(@raw {
173 bytecode: &[op::PUSH0],
174 spec_id: SpecId::CANCUN,
175 expected_stack: &[U256::ZERO],
176 expected_gas: 2,
177 }),
178 clz_cancun(@raw {
179 bytecode: &[op::MSIZE, op::CLZ],
180 spec_id: SpecId::CANCUN,
181 expected_return: InstructionResult::NotActivated,
182 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
183 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
184 }),
185 clz_arrow_glacier(@raw {
186 bytecode: &[op::MSIZE, op::CLZ],
187 spec_id: SpecId::ARROW_GLACIER,
188 expected_return: InstructionResult::NotActivated,
189 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
190 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
191 }),
192
193 dupn_cancun(@raw {
194 bytecode: &[op::PUSH0, op::DUPN, 0x00],
195 spec_id: SpecId::CANCUN,
196 expected_return: InstructionResult::NotActivated,
197 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
198 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
199 }),
200 swapn_cancun(@raw {
201 bytecode: &[op::PUSH0, op::SWAPN, 0x00],
202 spec_id: SpecId::CANCUN,
203 expected_return: InstructionResult::NotActivated,
204 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
205 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
206 }),
207 exchange_cancun(@raw {
208 bytecode: &[op::PUSH0, op::EXCHANGE, 0x01],
209 spec_id: SpecId::CANCUN,
210 expected_return: InstructionResult::NotActivated,
211 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
212 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
213 }),
214 slotnum_cancun(@raw {
215 bytecode: &[op::SLOTNUM],
216 spec_id: SpecId::CANCUN,
217 expected_return: InstructionResult::NotActivated,
218 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
219 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
220 }),
221
222 exp_zero_frontier(@raw {
225 bytecode: &bytecode_binop(op::EXP, 2_U256, 0_U256),
226 spec_id: SpecId::FRONTIER,
227 expected_stack: &[1_U256],
228 expected_gas: 6 + 10,
229 }),
230 exp_one_frontier(@raw {
232 bytecode: &bytecode_binop(op::EXP, 2_U256, 1_U256),
233 spec_id: SpecId::FRONTIER,
234 expected_stack: &[2_U256],
235 expected_gas: 6 + 10 + 10,
236 }),
237 exp_multi_byte_frontier(@raw {
239 bytecode: &bytecode_binop(op::EXP, 2_U256, 256_U256),
240 spec_id: SpecId::FRONTIER,
241 expected_stack: &[0_U256],
242 expected_gas: 6 + 10 + 20,
243 }),
244 exp_zero_istanbul(@raw {
246 bytecode: &bytecode_binop(op::EXP, 2_U256, 0_U256),
247 spec_id: SpecId::ISTANBUL,
248 expected_stack: &[1_U256],
249 expected_gas: 6 + 10,
250 }),
251 exp_one_istanbul(@raw {
252 bytecode: &bytecode_binop(op::EXP, 2_U256, 1_U256),
253 spec_id: SpecId::ISTANBUL,
254 expected_stack: &[2_U256],
255 expected_gas: 6 + 10 + 50,
256 }),
257 exp_multi_byte_istanbul(@raw {
258 bytecode: &bytecode_binop(op::EXP, 2_U256, 256_U256),
259 spec_id: SpecId::ISTANBUL,
260 expected_stack: &[0_U256],
261 expected_gas: 6 + 10 + 100,
262 }),
263 }
264
265 stack {
266 pop(@raw {
267 bytecode: &[op::PUSH1, 1, op::POP],
268 expected_gas: 3 + 2,
269 }),
270 dup(@raw {
271 bytecode: &[op::PUSH1, 1, op::DUP1],
272 expected_stack: &[1_U256, 1_U256],
273 expected_gas: 3 + 3,
274 }),
275
276 swap(@raw {
277 bytecode: &[op::PUSH1, 1, op::PUSH1, 2, op::SWAP1],
278 expected_stack: &[2_U256, 1_U256],
279 expected_gas: 3 + 3 + 3,
280 }),
281 swap2(@raw {
282 bytecode: &[op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::SWAP2],
283 expected_stack: &[3_U256, 2_U256, 1_U256],
284 expected_gas: 3 + 3 + 3 + 3,
285 }),
286 swap3(@raw {
287 bytecode: &[op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::SWAP3],
288 expected_stack: &[4_U256, 2_U256, 3_U256, 1_U256],
289 expected_gas: 3 + 3 + 3 + 3 + 3,
290 }),
291
292 dupn(@raw {
294 bytecode: &{
295 let mut code = [0u8; 21];
296 code[0] = op::PUSH1; code[1] = 1; let mut i = 2;
299 while i < 18 {
300 code[i] = op::PUSH0;
301 i += 1;
302 }
303 code[18] = op::DUPN;
304 code[19] = 0x80; code
306 },
307 spec_id: SpecId::AMSTERDAM,
308 expected_stack: &{
309 let mut s = [U256::ZERO; 18];
310 s[0] = 1_U256; s[17] = 1_U256; s
314 },
315 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
316 }),
317
318 swapn(@raw {
320 bytecode: &{
321 let mut code = [0u8; 23];
322 code[0] = op::PUSH1; code[1] = 1; let mut i = 2;
325 while i < 18 {
326 code[i] = op::PUSH0;
327 i += 1;
328 }
329 code[18] = op::PUSH1; code[19] = 2; code[20] = op::SWAPN;
331 code[21] = 0x80; code
333 },
334 spec_id: SpecId::AMSTERDAM,
335 expected_stack: &{
336 let mut s = [U256::ZERO; 18];
337 s[0] = 2_U256; s[17] = 1_U256; s
341 },
342 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
343 }),
344
345 exchange_basic(@raw {
347 bytecode: &[op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::EXCHANGE, 0x8E],
348 spec_id: SpecId::AMSTERDAM,
349 expected_stack: &[2_U256, 1_U256, 3_U256],
353 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
354 }),
355
356 slotnum(@raw {
358 bytecode: &[op::SLOTNUM],
359 spec_id: SpecId::AMSTERDAM,
360 expected_stack: &[U256::ZERO],
361 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
362 }),
363
364 dupn_underflow(@raw {
366 bytecode: &[op::PUSH0, op::DUPN, 0x80],
367 spec_id: SpecId::AMSTERDAM,
368 expected_return: InstructionResult::StackOverflow,
369 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
370 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
371 }),
372 swapn_underflow(@raw {
374 bytecode: &[op::PUSH0, op::SWAPN, 0x80],
375 spec_id: SpecId::AMSTERDAM,
376 expected_return: InstructionResult::StackUnderflow,
377 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
378 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
379 }),
380 exchange_underflow(@raw {
382 bytecode: &[op::PUSH0, op::PUSH0, op::EXCHANGE, 0x8E],
383 spec_id: SpecId::AMSTERDAM,
384 expected_return: InstructionResult::StackUnderflow,
385 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
386 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
387 }),
388
389 dupn_invalid_imm(@raw {
391 bytecode: &[op::PUSH0, op::DUPN, 0x5B],
392 spec_id: SpecId::AMSTERDAM,
393 expected_return: InstructionResult::InvalidImmediateEncoding,
394 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
395 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
396 }),
397 swapn_invalid_imm(@raw {
398 bytecode: &[op::PUSH0, op::SWAPN, 0x5B],
399 spec_id: SpecId::AMSTERDAM,
400 expected_return: InstructionResult::InvalidImmediateEncoding,
401 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
402 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
403 }),
404 exchange_invalid_imm(@raw {
406 bytecode: &[op::PUSH0, op::PUSH0, op::PUSH0, op::EXCHANGE, 82],
407 spec_id: SpecId::AMSTERDAM,
408 expected_return: InstructionResult::InvalidImmediateEncoding,
409 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
410 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
411 }),
412
413 dupn_truncated_eof(@raw {
416 bytecode: &{
417 let mut code = [0u8; 18];
418 let mut i = 0;
419 while i < 17 {
420 code[i] = op::PUSH0;
421 i += 1;
422 }
423 code[17] = op::DUPN; code
425 },
426 spec_id: SpecId::AMSTERDAM,
427 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
428 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
429 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
430 }),
431 swapn_truncated_eof(@raw {
434 bytecode: &{
435 let mut code = [0u8; 19];
436 let mut i = 0;
437 while i < 18 {
438 code[i] = op::PUSH0;
439 i += 1;
440 }
441 code[18] = op::SWAPN; code
443 },
444 spec_id: SpecId::AMSTERDAM,
445 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
446 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
447 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
448 }),
449
450 jump_into_dupn_immediate(@raw {
453 bytecode: &[
454 op::PUSH1, 4, op::JUMP,
455 op::DUPN, op::JUMPDEST, op::PUSH1, 0x42, op::PUSH0, op::MSTORE,
457 op::PUSH1, 0x20, op::PUSH0, op::RETURN,
458 ],
459 spec_id: SpecId::AMSTERDAM,
460 expected_return: InstructionResult::Return,
461 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
462 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
463 }),
464 jump_into_swapn_immediate(@raw {
466 bytecode: &[
467 op::PUSH1, 4, op::JUMP,
468 op::SWAPN, op::JUMPDEST,
469 op::PUSH1, 0x42, op::PUSH0, op::MSTORE,
470 op::PUSH1, 0x20, op::PUSH0, op::RETURN,
471 ],
472 spec_id: SpecId::AMSTERDAM,
473 expected_return: InstructionResult::Return,
474 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
475 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
476 }),
477 jump_into_exchange_immediate(@raw {
479 bytecode: &[
480 op::PUSH1, 4, op::JUMP,
481 op::EXCHANGE, op::JUMPDEST,
482 op::PUSH1, 0x42, op::PUSH0, op::MSTORE,
483 op::PUSH1, 0x20, op::PUSH0, op::RETURN,
484 ],
485 spec_id: SpecId::AMSTERDAM,
486 expected_return: InstructionResult::Return,
487 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
488 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
489 }),
490
491 push2_truncated_eof(@raw {
494 bytecode: &[op::PUSH2, 0x42],
495 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
496 expected_stack: &[U256::from(0x4200u64)],
497 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
498 }),
499 push3_truncated_eof(@raw {
501 bytecode: &[op::PUSH3, 0xAB, 0xCD],
502 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
503 expected_stack: &[U256::from(0xABCD00u64)],
504 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
505 }),
506 push1_no_imm_eof(@raw {
508 bytecode: &[op::PUSH1],
509 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
510 expected_stack: &[U256::ZERO],
511 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
512 }),
513
514 overflow_analysis_edge_case(@raw {
515 bytecode: &[&[op::JUMPDEST][..], &[op::PUSH0; 1025][..], &[op::JUMPI][..]].concat(),
516 expected_return: InstructionResult::StackOverflow,
517 }),
518 }
519
520 control_flow {
521 basic_jump(@raw {
522 bytecode: &[op::PUSH1, 3, op::JUMP, op::JUMPDEST, op::PUSH1, 69],
523 expected_stack: &[69_U256],
524 expected_gas: 3 + 8 + 1 + 3,
525 }),
526 unmodified_stack_after_push_jump(@raw {
527 bytecode: &[op::PUSH1, 3, op::JUMP, op::JUMPDEST, op::PUSH0, op::ADD],
528 expected_return: InstructionResult::StackUnderflow,
529 expected_stack: &[U256::ZERO],
530 expected_gas: 3 + 8 + 1 + 2 + 3,
531 }),
532 bad_jump(@raw {
533 bytecode: &[op::JUMP],
534 expected_return: InstructionResult::StackUnderflow,
535 expected_gas: 8,
536 }),
537 bad_jumpi1(@raw {
538 bytecode: &[op::JUMPI],
539 expected_return: InstructionResult::StackUnderflow,
540 expected_gas: 10,
541 }),
542 bad_jumpi2(@raw {
543 bytecode: &[op::PUSH0, op::JUMPI],
544 expected_return: InstructionResult::StackUnderflow,
545 expected_stack: &[0_U256],
546 expected_gas: 2 + 10,
547 }),
548 bad_jumpi3(@raw {
549 bytecode: &[op::JUMPDEST, op::PUSH0, op::JUMPI],
550 expected_return: InstructionResult::StackUnderflow,
551 expected_stack: &[0_U256],
552 expected_gas: 1 + 2 + 10,
553 }),
554
555 basic_jumpi1(@raw {
556 bytecode: &[op::JUMPDEST, op::PUSH0, op::PUSH0, op::JUMPI, op::PUSH1, 69],
557 expected_stack: &[69_U256],
558 expected_gas: 1 + 2 + 2 + 10 + 3,
559 }),
560 basic_jumpi1_lazy_invalid_target(@raw {
561 bytecode: &[op::PUSH0, op::PUSH0, op::JUMPI, op::PUSH1, 69],
562 expected_stack: &[69_U256],
563 expected_gas: 2 + 2 + 10 + 3,
564 }),
565 basic_jumpi2(@raw {
566 bytecode: &[op::PUSH1, 1, op::PUSH1, 5, op::JUMPI, op::JUMPDEST, op::PUSH1, 69],
567 expected_stack: &[69_U256],
568 expected_gas: 3 + 3 + 10 + 1 + 3,
569 }),
570 basic_jumpi2_lazy_invalid_target(@raw {
571 bytecode: &[op::PUSH1, 1, op::PUSH0, op::JUMPI, op::PUSH1, 69],
572 expected_return: InstructionResult::InvalidJump,
573 expected_gas: 3 + 2 + 10,
574 }),
575 unmodified_stack_after_push_jumpi(@raw {
576 bytecode: &[op::PUSH1, 1, op::PUSH1, 5, op::JUMPI, op::JUMPDEST, op::PUSH0, op::ADD],
577 expected_return: InstructionResult::StackUnderflow,
578 expected_stack: &[U256::ZERO],
579 expected_gas: 3 + 3 + 10 + 1 + 2 + 3,
580 }),
581
582 basic_loop(@raw {
583 bytecode: &[
584 op::PUSH1, 3, op::JUMPDEST, op::PUSH1, 1, op::SWAP1, op::SUB, op::DUP1, op::PUSH1, 2, op::JUMPI, op::POP, op::PUSH1, 69, ],
595 expected_stack: &[69_U256],
596 expected_gas: 3 + (1 + 3 + 3 + 3 + 3 + 3 + 10) * 3 + 2 + 3,
597 }),
598
599 pc(@raw {
600 bytecode: &[op::PC, op::PC, op::PUSH1, 69, op::PC, op::PUSH0, op::PC],
601 expected_stack: &[0_U256, 1_U256, 69_U256, 4_U256, 0_U256, 6_U256],
602 expected_gas: 2 + 2 + 3 + 2 + 2 + 2,
603 }),
604
605 }
606
607 arith {
608 add1(op::ADD, 0_U256, 0_U256 => 0_U256),
609 add2(op::ADD, 1_U256, 2_U256 => 3_U256),
610 add3(op::ADD, 255_U256, 255_U256 => 510_U256),
611 add4(op::ADD, U256::MAX, 1_U256 => 0_U256),
612 add5(op::ADD, U256::MAX, 2_U256 => 1_U256),
613
614 sub1(op::SUB, 3_U256, 2_U256 => 1_U256),
615 sub2(op::SUB, 1_U256, 2_U256 => -1_U256),
616 sub3(op::SUB, 1_U256, 3_U256 => (-1_U256).wrapping_sub(1_U256)),
617 sub4(op::SUB, 255_U256, 255_U256 => 0_U256),
618
619 mul1(op::MUL, 1_U256, 2_U256 => 2_U256),
620 mul2(op::MUL, 32_U256, 32_U256 => 1024_U256),
621 mul3(op::MUL, U256::MAX, 2_U256 => U256::MAX.wrapping_sub(1_U256)),
622
623 div1(op::DIV, 32_U256, 32_U256 => 1_U256),
624 div2(op::DIV, 1_U256, 2_U256 => 0_U256),
625 div3(op::DIV, 2_U256, 2_U256 => 1_U256),
626 div4(op::DIV, 3_U256, 2_U256 => 1_U256),
627 div5(op::DIV, 4_U256, 2_U256 => 2_U256),
628 div_by_one(op::DIV, 42_U256, 1_U256 => 42_U256),
629 div_pow2_4(op::DIV, 100_U256, 4_U256 => 25_U256),
630 div_pow2_256(op::DIV, 512_U256, 256_U256 => 2_U256),
631 div_zero_dividend(op::DIV, 0_U256, 42_U256 => 0_U256),
632 div_by_zero1(op::DIV, 0_U256, 0_U256 => 0_U256),
633 div_by_zero2(op::DIV, 32_U256, 0_U256 => 0_U256),
634
635 rem1(op::MOD, 32_U256, 32_U256 => 0_U256),
636 rem2(op::MOD, 1_U256, 2_U256 => 1_U256),
637 rem3(op::MOD, 2_U256, 2_U256 => 0_U256),
638 rem4(op::MOD, 3_U256, 2_U256 => 1_U256),
639 rem5(op::MOD, 4_U256, 2_U256 => 0_U256),
640 rem_by_one(op::MOD, 42_U256, 1_U256 => 0_U256),
641 rem_pow2_4(op::MOD, 100_U256, 4_U256 => 0_U256),
642 rem_pow2_256(op::MOD, 513_U256, 256_U256 => 1_U256),
643 rem_zero_dividend(op::MOD, 0_U256, 42_U256 => 0_U256),
644 rem_by_zero1(op::MOD, 0_U256, 0_U256 => 0_U256),
645 rem_by_zero2(op::MOD, 32_U256, 0_U256 => 0_U256),
646
647 sdiv1(op::SDIV, 32_U256, 32_U256 => 1_U256),
648 sdiv2(op::SDIV, 1_U256, 2_U256 => 0_U256),
649 sdiv3(op::SDIV, 2_U256, 2_U256 => 1_U256),
650 sdiv4(op::SDIV, 3_U256, 2_U256 => 1_U256),
651 sdiv5(op::SDIV, 4_U256, 2_U256 => 2_U256),
652 sdiv_by_zero1(op::SDIV, 0_U256, 0_U256 => 0_U256),
653 sdiv_by_zero2(op::SDIV, 32_U256, 0_U256 => 0_U256),
654 sdiv_min_by_1(op::SDIV, I256_MIN, 1_U256 => -I256_MIN),
655 sdiv_min_by_minus_1(op::SDIV, I256_MIN, -1_U256 => I256_MIN),
656 sdiv_max1(op::SDIV, I256_MAX, 1_U256 => I256_MAX),
657 sdiv_max2(op::SDIV, I256_MAX, -1_U256 => -I256_MAX),
658 sdiv_by_int_min(op::SDIV, I256_MIN, I256_MIN => 1_U256),
659 sdiv_nonmin_by_int_min(op::SDIV, 42_U256, I256_MIN => 0_U256),
660 sdiv_zero_dividend(op::SDIV, 0_U256, 42_U256 => 0_U256),
661
662 srem1(op::SMOD, 32_U256, 32_U256 => 0_U256),
663 srem2(op::SMOD, 1_U256, 2_U256 => 1_U256),
664 srem3(op::SMOD, 2_U256, 2_U256 => 0_U256),
665 srem4(op::SMOD, 3_U256, 2_U256 => 1_U256),
666 srem5(op::SMOD, 4_U256, 2_U256 => 0_U256),
667 srem_by_one(op::SMOD, 42_U256, 1_U256 => 0_U256),
668 srem_by_minus_one(op::SMOD, 42_U256, -1_U256 => 0_U256),
669 srem_zero_dividend(op::SMOD, 0_U256, 42_U256 => 0_U256),
670 srem_by_zero1(op::SMOD, 0_U256, 0_U256 => 0_U256),
671 srem_by_zero2(op::SMOD, 32_U256, 0_U256 => 0_U256),
672
673 addmod_mod_zero(op::ADDMOD, 1_U256, 2_U256, 0_U256 => 0_U256),
674 addmod_mod_one(op::ADDMOD, 5_U256, 3_U256, 1_U256 => 0_U256),
675 addmod_both_zero(op::ADDMOD, 0_U256, 0_U256, 42_U256 => 0_U256),
676 addmod1(op::ADDMOD, 1_U256, 2_U256, 3_U256 => 0_U256),
677 addmod2(op::ADDMOD, 1_U256, 2_U256, 4_U256 => 3_U256),
678 addmod3(op::ADDMOD, 1_U256, 2_U256, 2_U256 => 1_U256),
679 addmod4(op::ADDMOD, 32_U256, 32_U256, 69_U256 => 64_U256),
680
681 mulmod_mod_zero(op::MULMOD, 3_U256, 4_U256, 0_U256 => 0_U256),
682 mulmod1(op::MULMOD, 0_U256, 0_U256, 1_U256 => 0_U256),
683 mulmod2(op::MULMOD, 69_U256, 0_U256, 1_U256 => 0_U256),
684 mulmod3(op::MULMOD, 0_U256, 1_U256, 2_U256 => 0_U256),
685 mulmod_a_zero(op::MULMOD, 0_U256, 5_U256, 7_U256 => 0_U256),
686 mulmod_b_zero(op::MULMOD, 5_U256, 0_U256, 7_U256 => 0_U256),
687 mulmod4(op::MULMOD, 69_U256, 1_U256, 2_U256 => 1_U256),
688 mulmod5(op::MULMOD, 69_U256, 1_U256, 30_U256 => 9_U256),
689 mulmod6(op::MULMOD, 69_U256, 2_U256, 100_U256 => 38_U256),
690
691 exp1(op::EXP, 0_U256, 0_U256 => 1_U256; op_gas(10)),
692 exp2(op::EXP, 2_U256, 0_U256 => 1_U256; op_gas(10)),
693 exp3(op::EXP, 2_U256, 1_U256 => 2_U256; op_gas(60)),
694 exp4(op::EXP, 2_U256, 2_U256 => 4_U256; op_gas(60)),
695 exp5(op::EXP, 2_U256, 3_U256 => 8_U256; op_gas(60)),
696 exp6(op::EXP, 2_U256, 4_U256 => 16_U256; op_gas(60)),
697 exp_zero_base_zero_exp(op::EXP, 0_U256, 0_U256 => 1_U256; op_gas(10)),
698 exp_zero_base_nonzero_exp(op::EXP, 0_U256, 5_U256 => 0_U256; op_gas(60)),
699 exp_one_base_large_exp(op::EXP, 1_U256, U256::MAX => 1_U256; op_gas(1610)),
700 exp_minus_one_base_even_exp(op::EXP, -1_U256, 4_U256 => 1_U256; op_gas(60)),
701 exp_minus_one_base_odd_exp(op::EXP, -1_U256, 5_U256 => -1_U256; op_gas(60)),
702 exp_pow4_base_in_range(op::EXP, 4_U256, 63_U256 => 1_U256 << 126; op_gas(60)),
703 exp_pow4_base_overflow(op::EXP, 4_U256, 128_U256 => 0_U256; op_gas(60)),
704 exp_non_pow2_base(op::EXP, 3_U256, 5_U256 => 243_U256; op_gas(60)),
705 exp_overflow(op::EXP, 2_U256, 256_U256 => 0_U256; op_gas(110)),
706 exp_large(op::EXP, 2_U256, 0xFFFF_U256 => 2_U256.pow(0xFFFF_U256); op_gas(110)),
708 exp_max_exponent(op::EXP, 2_U256, U256::MAX => 0_U256; op_gas(1610)),
710
711 signextend1(op::SIGNEXTEND, 0_U256, 0_U256 => 0_U256),
712 signextend2(op::SIGNEXTEND, 1_U256, 0_U256 => 0_U256),
713 signextend3(op::SIGNEXTEND, 0_U256, -1_U256 => -1_U256),
714 signextend4(op::SIGNEXTEND, 1_U256, -1_U256 => -1_U256),
715 signextend5(op::SIGNEXTEND, 0_U256, 0x7f_U256 => 0x7f_U256),
716 signextend6(op::SIGNEXTEND, 0_U256, 0x80_U256 => -0x80_U256),
717 signextend7(op::SIGNEXTEND, 0_U256, 0xff_U256 => U256::MAX),
718 signextend8(op::SIGNEXTEND, 1_U256, 0x7fff_U256 => 0x7fff_U256),
719 signextend8_extra(op::SIGNEXTEND, 1_U256, 0xff7fff_U256 => 0x7fff_U256),
720 signextend9(op::SIGNEXTEND, 1_U256, 0x8000_U256 => -0x8000_U256),
721 signextend9_extra(op::SIGNEXTEND, 1_U256, 0x118000_U256 => -0x8000_U256),
722 signextend10(op::SIGNEXTEND, 1_U256, 0xffff_U256 => U256::MAX),
723 signextend_noop_31(op::SIGNEXTEND, 31_U256, 0x42_U256 => 0x42_U256),
724 signextend_noop_32(op::SIGNEXTEND, 32_U256, 0x42_U256 => 0x42_U256),
725 signextend_noop_max(op::SIGNEXTEND, U256::MAX, 0x42_U256 => 0x42_U256),
726 }
727
728 cmp {
729 lt1(op::LT, 1_U256, 2_U256 => 1_U256),
730 lt2(op::LT, 2_U256, 1_U256 => 0_U256),
731 lt3(op::LT, 1_U256, 1_U256 => 0_U256),
732 lt4(op::LT, -1_U256, 1_U256 => 0_U256),
733
734 gt1(op::GT, 1_U256, 2_U256 => 0_U256),
735 gt2(op::GT, 2_U256, 1_U256 => 1_U256),
736 gt3(op::GT, 1_U256, 1_U256 => 0_U256),
737 gt4(op::GT, -1_U256, 1_U256 => 1_U256),
738
739 slt1(op::SLT, 1_U256, 2_U256 => 1_U256),
740 slt2(op::SLT, 2_U256, 1_U256 => 0_U256),
741 slt3(op::SLT, 1_U256, 1_U256 => 0_U256),
742 slt4(op::SLT, -1_U256, 1_U256 => 1_U256),
743
744 sgt1(op::SGT, 1_U256, 2_U256 => 0_U256),
745 sgt2(op::SGT, 2_U256, 1_U256 => 1_U256),
746 sgt3(op::SGT, 1_U256, 1_U256 => 0_U256),
747 sgt4(op::SGT, -1_U256, 1_U256 => 0_U256),
748
749 eq1(op::EQ, 1_U256, 2_U256 => 0_U256),
750 eq2(op::EQ, 2_U256, 1_U256 => 0_U256),
751 eq3(op::EQ, 1_U256, 1_U256 => 1_U256),
752
753 iszero1(op::ISZERO, 0_U256 => 1_U256),
754 iszero2(op::ISZERO, 1_U256 => 0_U256),
755 iszero3(op::ISZERO, 2_U256 => 0_U256),
756 }
757
758 bitwise {
759 and1(op::AND, 0_U256, 0_U256 => 0_U256),
760 and2(op::AND, 1_U256, 1_U256 => 1_U256),
761 and3(op::AND, 1_U256, 2_U256 => 0_U256),
762 and4(op::AND, 255_U256, 255_U256 => 255_U256),
763
764 or1(op::OR, 0_U256, 0_U256 => 0_U256),
765 or2(op::OR, 1_U256, 2_U256 => 3_U256),
766 or3(op::OR, 1_U256, 3_U256 => 3_U256),
767 or4(op::OR, 2_U256, 2_U256 => 2_U256),
768
769 xor1(op::XOR, 0_U256, 0_U256 => 0_U256),
770 xor2(op::XOR, 1_U256, 2_U256 => 3_U256),
771 xor3(op::XOR, 1_U256, 3_U256 => 2_U256),
772 xor4(op::XOR, 2_U256, 2_U256 => 0_U256),
773
774 not1(op::NOT, 0_U256 => U256::MAX),
775 not2(op::NOT, U256::MAX => 0_U256),
776 not3(op::NOT, 1_U256 => U256::MAX.wrapping_sub(1_U256)),
777
778 byte1(op::BYTE, 0_U256, 0x1122334400000000000000000000000000000000000000000000000000000000_U256 => 0x11_U256),
779 byte2(op::BYTE, 1_U256, 0x1122334400000000000000000000000000000000000000000000000000000000_U256 => 0x22_U256),
780 byte3(op::BYTE, 2_U256, 0x1122334400000000000000000000000000000000000000000000000000000000_U256 => 0x33_U256),
781 byte4(op::BYTE, 3_U256, 0x1122334400000000000000000000000000000000000000000000000000000000_U256 => 0x44_U256),
782 byte5(op::BYTE, 4_U256, 0x1122334400000000000000000000000000000000000000000000000000000000_U256 => 0x00_U256),
783 byte_oob0(op::BYTE, 31_U256, U256::MAX => 0xFF_U256),
784 byte_oob1(op::BYTE, 32_U256, U256::MAX => 0_U256),
785 byte_oob2(op::BYTE, 33_U256, U256::MAX => 0_U256),
786
787 shl1(op::SHL, 0_U256, 1_U256 => 1_U256),
790 shl2(op::SHL, 1_U256, 1_U256 => 2_U256),
791 shl3(op::SHL, 2_U256, 1_U256 => 4_U256),
792 shl4(op::SHL, 255_U256, -1_U256 => -1_U256 << 255),
793 shl5(op::SHL, 256_U256, -1_U256 => 0_U256),
794
795 shr1(op::SHR, 0_U256, 1_U256 => 1_U256),
796 shr2(op::SHR, 1_U256, 2_U256 => 1_U256),
797 shr3(op::SHR, 2_U256, 4_U256 => 1_U256),
798 shr4(op::SHR, 255_U256, -1_U256 => 1_U256),
799 shr5(op::SHR, 256_U256, -1_U256 => 0_U256),
800
801 sar1(op::SAR, 0_U256, 1_U256 => 1_U256),
802 sar2(op::SAR, 1_U256, 2_U256 => 1_U256),
803 sar3(op::SAR, 2_U256, 4_U256 => 1_U256),
804 sar4(op::SAR, 1_U256, -1_U256 => -1_U256),
805 sar5(op::SAR, 2_U256, -1_U256 => -1_U256),
806 sar6(op::SAR, 255_U256, -1_U256 => -1_U256),
807 sar7(op::SAR, 256_U256, -1_U256 => -1_U256),
808 }
809
810 system {
811 gas0(@raw {
812 bytecode: &[op::GAS, op::GAS, op::JUMPDEST, op::GAS],
813 expected_stack: &[DEF_GAS_LIMIT_U256 - 2_U256, DEF_GAS_LIMIT_U256 - 4_U256, DEF_GAS_LIMIT_U256 - 7_U256],
814 expected_gas: 2 + 2 + 1 + 2,
815 }),
816 keccak256_empty1(@raw {
817 bytecode: &[op::PUSH0, op::PUSH0, op::KECCAK256],
818 expected_stack: &[KECCAK_EMPTY.into()],
819 expected_gas: 2 + 2 + gas::KECCAK256,
820 }),
821 keccak256_empty2(@raw {
822 bytecode: &[op::PUSH0, op::PUSH1, 32, op::KECCAK256],
823 expected_stack: &[KECCAK_EMPTY.into()],
824 expected_gas: 2 + 3 + gas::KECCAK256,
825 }),
826 keccak256_empty_dynamic_offset(@raw {
827 bytecode: &[op::PUSH0, op::ADDRESS, op::KECCAK256],
828 expected_stack: &[KECCAK_EMPTY.into()],
829 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
830 }),
831 keccak256_1(@raw {
832 bytecode: &[op::PUSH1, 32, op::PUSH0, op::KECCAK256],
833 expected_stack: &[keccak256([0; 32]).into()],
834 expected_memory: &[0; 32],
835 expected_gas: 3 + 2 + (keccak256_cost(32).unwrap() + 3),
836 }),
837 keccak256_2(@raw {
838 bytecode: &[op::PUSH2, 0x69, 0x42, op::PUSH0, op::MSTORE, op::PUSH1, 0x20, op::PUSH0, op::KECCAK256],
839 expected_stack: &[keccak256(0x6942_U256.to_be_bytes::<32>()).into()],
840 expected_memory: &0x6942_U256.to_be_bytes::<32>(),
841 expected_gas: 3 + 2 + (3 + 3) + 3 + 2 + keccak256_cost(32).unwrap(),
842 }),
843
844 address(@raw {
845 bytecode: &[op::ADDRESS, op::ADDRESS],
846 expected_stack: &[DEF_ADDR.into_word().into(), DEF_ADDR.into_word().into()],
847 expected_gas: 4,
848 }),
849 origin(@raw {
850 bytecode: &[op::ORIGIN, op::ORIGIN],
851 expected_stack: &[def_env().tx.caller.into_word().into(), def_env().tx.caller.into_word().into()],
852 expected_gas: 4,
853 }),
854 caller(@raw {
855 bytecode: &[op::CALLER, op::CALLER],
856 expected_stack: &[DEF_CALLER.into_word().into(), DEF_CALLER.into_word().into()],
857 expected_gas: 4,
858 }),
859 callvalue(@raw {
860 bytecode: &[op::CALLVALUE, op::CALLVALUE],
861 expected_stack: &[DEF_VALUE, DEF_VALUE],
862 expected_gas: 4,
863 }),
864 }
865
866 calldata {
867 calldataload1(@raw {
868 bytecode: &[op::PUSH0, op::CALLDATALOAD],
869 expected_stack: &[U256::from_be_slice(&DEF_CD[..32])],
870 expected_gas: 2 + 3,
871 }),
872 calldataload2(@raw {
873 bytecode: &[op::PUSH1, 63, op::CALLDATALOAD],
874 expected_stack: &[0xaa00000000000000000000000000000000000000000000000000000000000000_U256],
875 expected_gas: 3 + 3,
876 }),
877 calldatasize(@raw {
878 bytecode: &[op::CALLDATASIZE, op::CALLDATASIZE],
879 expected_stack: &[U256::from(DEF_CD.len()), U256::from(DEF_CD.len())],
880 expected_gas: 2 + 2,
881 }),
882 calldatacopy(@raw {
883 bytecode: &[op::PUSH1, 32, op::PUSH0, op::PUSH0, op::CALLDATACOPY],
884 expected_memory: &DEF_CD[..32],
885 expected_gas: 3 + 2 + 2 + (verylowcopy_cost(32).unwrap() + 3),
886 }),
887 }
888
889 code {
890 codesize(@raw {
891 bytecode: &[op::CODESIZE, op::CODESIZE],
892 expected_stack: &[2_U256, 2_U256],
893 expected_gas: 2 + 2,
894 }),
895 codecopy(@raw {
896 bytecode: &[op::PUSH1, 5, op::PUSH0, op::PUSH0, op::CODECOPY],
897 expected_memory: &hex!("60055f5f39000000000000000000000000000000000000000000000000000000"),
898 expected_gas: 3 + 2 + 2 + (verylowcopy_cost(32).unwrap() + memory_gas_cost(1)),
899 }),
900 }
901
902 returndata {
903 returndatasize(@raw {
904 bytecode: &[op::RETURNDATASIZE, op::RETURNDATASIZE],
906 expected_stack: &[0_U256, 0_U256],
907 expected_gas: 2 + 2,
908 }),
909 returndatacopy(@raw {
910 bytecode: &[op::PUSH1, 32, op::PUSH0, op::PUSH0, op::RETURNDATACOPY],
912 expected_return: InstructionResult::OutOfOffset,
913 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
914 }),
915 }
916
917 extcode {
918 extcodesize1(op::EXTCODESIZE, DEF_ADDR.into_word().into() => 0_U256;
919 op_gas(100)),
920 extcodesize2(op::EXTCODESIZE, OTHER_ADDR.into_word().into() => U256::from(def_codemap()[&OTHER_ADDR].len());
921 op_gas(100)),
922 extcodecopy1(@raw {
923 bytecode: &[op::PUSH0, op::PUSH0, op::PUSH0, op::PUSH0, op::EXTCODECOPY],
924 expected_memory: &[],
925 expected_gas: 2 + 2 + 2 + 2 + 100,
926 }),
927 extcodecopy2(@raw {
928 bytecode: &hex!("6040 5f 5f 736969696969696969696969696969696969696969 3c"),
930 expected_memory: &{
931 let mut mem = [0; 64];
932 let code = def_codemap()[&OTHER_ADDR].original_bytes();
933 mem[..code.len()].copy_from_slice(&code);
934 mem
935 },
936 expected_gas: 3 + 2 + 2 + 3 + (100 + 12),
937 }),
938 extcodehash1(op::EXTCODEHASH, DEF_ADDR.into_word().into() => KECCAK_EMPTY.into();
939 op_gas(100)),
940 extcodehash2(op::EXTCODEHASH, OTHER_ADDR.into_word().into() => def_codemap()[&OTHER_ADDR].hash_slow().into();
941 op_gas(100)),
942 }
943
944 env {
945 gas_price(@raw {
946 bytecode: &[op::GASPRICE],
947 expected_stack: &[def_env().effective_gas_price()],
948 expected_gas: 2,
949 }),
950 blockhash0(op::BLOCKHASH, DEF_BN - 0_U256 => 0_U256), blockhash1(op::BLOCKHASH, DEF_BN - 1_U256 => DEF_BN - 1_U256), blockhash2(op::BLOCKHASH, DEF_BN - 255_U256 => DEF_BN - 255_U256), blockhash3(op::BLOCKHASH, DEF_BN - 256_U256 => DEF_BN - 256_U256), blockhash4(op::BLOCKHASH, DEF_BN - 257_U256 => 0_U256), coinbase(@raw {
960 bytecode: &[op::COINBASE, op::COINBASE],
961 expected_stack: &[def_env().block.coinbase.into_word().into(), def_env().block.coinbase.into_word().into()],
962 expected_gas: 4,
963 }),
964 timestamp(@raw {
965 bytecode: &[op::TIMESTAMP, op::TIMESTAMP],
966 expected_stack: &[def_env().block.timestamp, def_env().block.timestamp],
967 expected_gas: 4,
968 }),
969 number(@raw {
970 bytecode: &[op::NUMBER, op::NUMBER],
971 expected_stack: &[def_env().block.number, def_env().block.number],
972 expected_gas: 4,
973 }),
974 difficulty(@raw {
975 bytecode: &[op::DIFFICULTY, op::DIFFICULTY],
976 spec_id: SpecId::GRAY_GLACIER,
977 expected_stack: &[def_env().block.difficulty, def_env().block.difficulty],
978 expected_gas: 4,
979 }),
980 difficulty_prevrandao(@raw {
981 bytecode: &[op::DIFFICULTY, op::DIFFICULTY],
982 spec_id: SpecId::MERGE,
983 expected_stack: &[def_env().block.prevrandao.unwrap().into(), def_env().block.prevrandao.unwrap().into()],
984 expected_gas: 4,
985 }),
986 gaslimit(@raw {
987 bytecode: &[op::GASLIMIT, op::GASLIMIT],
988 expected_stack: &[def_env().block.gas_limit, def_env().block.gas_limit],
989 expected_gas: 4,
990 }),
991 chainid(@raw {
992 bytecode: &[op::CHAINID, op::CHAINID],
993 expected_stack: &[U256::from(def_env().cfg.chain_id), U256::from(def_env().cfg.chain_id)],
994 expected_gas: 4,
995 }),
996 selfbalance(@raw {
997 bytecode: &[op::SELFBALANCE, op::SELFBALANCE],
998 expected_stack: &[0xba_U256, 0xba_U256],
999 expected_gas: 10,
1000 }),
1001 basefee(@raw {
1002 bytecode: &[op::BASEFEE, op::BASEFEE],
1003 expected_stack: &[def_env().block.basefee, def_env().block.basefee],
1004 expected_gas: 4,
1005 }),
1006 blobhash0(@raw {
1007 bytecode: &[op::PUSH0, op::BLOBHASH],
1008 expected_stack: &[def_env().tx.blob_hashes[0].into()],
1009 expected_gas: 2 + 3,
1010 }),
1011 blobhash1(@raw {
1012 bytecode: &[op::PUSH1, 1, op::BLOBHASH],
1013 expected_stack: &[def_env().tx.blob_hashes[1].into()],
1014 expected_gas: 3 + 3,
1015 }),
1016 blobhash2(@raw {
1017 bytecode: &[op::PUSH1, 2, op::BLOBHASH],
1018 expected_stack: &[0_U256],
1019 expected_gas: 3 + 3,
1020 }),
1021 blobbasefee(@raw {
1022 bytecode: &[op::BLOBBASEFEE, op::BLOBBASEFEE],
1023 expected_stack: &[U256::from(def_env().block.get_blob_gasprice().unwrap()), U256::from(def_env().block.get_blob_gasprice().unwrap())],
1024 expected_gas: 4,
1025 }),
1026 }
1027
1028 memory {
1029 mload1(@raw {
1030 bytecode: &[op::PUSH0, op::MLOAD],
1031 expected_stack: &[0_U256],
1032 expected_memory: &[0; 32],
1033 expected_gas: 2 + (3 + memory_gas_cost(1)),
1034 }),
1035 mload2(@raw {
1036 bytecode: &[op::PUSH1, 1, op::MLOAD],
1037 expected_stack: &[0_U256],
1038 expected_memory: &[0; 64],
1039 expected_gas: 3 + (3 + memory_gas_cost(2)),
1040 }),
1041 mload3(@raw {
1042 bytecode: &[op::PUSH1, 32, op::MLOAD],
1043 expected_stack: &[0_U256],
1044 expected_memory: &[0; 64],
1045 expected_gas: 3 + (3 + memory_gas_cost(2)),
1046 }),
1047 mload4(@raw {
1048 bytecode: &[op::PUSH1, 33, op::MLOAD],
1049 expected_stack: &[0_U256],
1050 expected_memory: &[0; 96],
1051 expected_gas: 3 + (3 + memory_gas_cost(3)),
1052 }),
1053 mload_overflow1(@raw {
1054 bytecode: &[op::PUSH8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, op::MLOAD],
1055 expected_return: InstructionResult::MemoryOOG,
1056 expected_stack: &[U256::from(u64::MAX)],
1057 expected_gas: 3 + 3,
1058 }),
1059 mload_overflow2(@raw {
1060 bytecode: &[op::PUSH8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - 1, op::MLOAD],
1061 expected_return: InstructionResult::MemoryOOG,
1062 expected_stack: &[U256::from(u64::MAX - 1)],
1063 expected_gas: 3 + 3,
1064 }),
1065 mload_overflow3(@raw {
1066 bytecode: &[op::PUSH8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - 31, op::MLOAD],
1067 expected_return: InstructionResult::MemoryOOG,
1068 expected_stack: &[U256::from(u64::MAX - 31)],
1069 expected_gas: 3 + 3,
1070 }),
1071 mload_overflow4(@raw {
1072 bytecode: &[op::PUSH8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - 32, op::MLOAD],
1073 expected_return: InstructionResult::MemoryOOG,
1074 expected_stack: &[U256::from(u64::MAX - 32)],
1075 expected_gas: 3 + 3,
1076 }),
1077 mload_overflow5(@raw {
1078 bytecode: &[op::PUSH8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff - 33, op::MLOAD],
1079 expected_return: InstructionResult::MemoryOOG,
1080 expected_stack: &[U256::from(u64::MAX - 33)],
1081 expected_gas: 3 + 3,
1082 }),
1083 mload_overflow6(@raw {
1084 bytecode: &[op::ADDRESS, op::MLOAD],
1085 expected_return: InstructionResult::InvalidOperandOOG,
1086 expected_stack: &[DEF_ADDR.into_word().into()],
1087 expected_gas: 5,
1088 }),
1089 mload_const_offset_too_large(@raw {
1090 bytecode: &{
1091 let mut code = Vec::new();
1092 code.push(op::PUSH9);
1093 code.extend_from_slice(&0x1_0000_0000_0000_0000_U256.to_be_bytes::<32>()[23..]);
1094 code.push(op::MLOAD);
1095 code
1096 },
1097 expected_return: InstructionResult::InvalidOperandOOG,
1098 expected_stack: &[0x1_0000_0000_0000_0000_U256],
1099 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1100 }),
1101 mstore1(@raw {
1102 bytecode: &[op::PUSH0, op::PUSH0, op::MSTORE],
1103 expected_memory: &[0; 32],
1104 expected_gas: 2 + 2 + (3 + memory_gas_cost(1)),
1105 }),
1106 mstore_const_offset_dyn_value(@raw {
1107 bytecode: &bytecode_binop_mixed(op::MSTORE, 0_U256, 0x69_U256, true, false),
1108 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1109 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1110 }),
1111 mstore_dyn_offset_const_value(@raw {
1112 bytecode: &bytecode_binop_mixed(op::MSTORE, 0_U256, 0x69_U256, false, true),
1113 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1114 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1115 }),
1116 mstore_dyn_offset_dyn_value(@raw {
1117 bytecode: &bytecode_binop_mixed(op::MSTORE, 0_U256, 0x69_U256, false, false),
1118 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1119 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1120 }),
1121 mstore8_1(@raw {
1122 bytecode: &[op::PUSH0, op::PUSH0, op::MSTORE8],
1123 expected_memory: &[0; 32],
1124 expected_gas: 2 + 2 + (3 + memory_gas_cost(1)),
1125 }),
1126 mstore8_2(@raw {
1127 bytecode: &[op::PUSH2, 0x69, 0x69, op::PUSH0, op::MSTORE8],
1128 expected_memory: &{
1129 let mut mem = [0; 32];
1130 mem[0] = 0x69;
1131 mem
1132 },
1133 expected_gas: 3 + 2 + (3 + memory_gas_cost(1)),
1134 }),
1135 msize1(@raw {
1136 bytecode: &[op::MSIZE, op::MSIZE],
1137 expected_stack: &[0_U256, 0_U256],
1138 expected_gas: 2 + 2,
1139 }),
1140 msize2(@raw {
1141 bytecode: &[op::MSIZE, op::PUSH0, op::MLOAD, op::POP, op::MSIZE, op::PUSH1, 1, op::MLOAD, op::POP, op::MSIZE],
1142 expected_stack: &[0_U256, 32_U256, 64_U256],
1143 expected_memory: &[0; 64],
1144 expected_gas: 2 + 2 + (3 + memory_gas_cost(1)) + 2 + 2 + 3 + (3 + (memory_gas_cost(2) - memory_gas_cost(1))) + 2 + 2,
1145 }),
1146 mcopy1(@raw {
1147 bytecode: &[op::PUSH1, 32, op::PUSH0, op::PUSH1, 32, op::MCOPY],
1148 expected_memory: &[0; 64],
1149 expected_gas: 3 + 2 + 3 + (verylowcopy_cost(32).unwrap() + memory_gas_cost(2)),
1150 }),
1151 mcopy2(@raw {
1152 bytecode: &[op::PUSH2, 0x42, 0x69, op::PUSH0, op::MSTORE,
1153 op::PUSH1, 2, op::PUSH1, 30, op::PUSH1, 1, op::MCOPY],
1154 expected_memory: &{
1155 let mut mem = [0; 32];
1156 mem[30] = 0x42;
1157 mem[31] = 0x69;
1158 mem[1] = 0x42;
1159 mem[2] = 0x69;
1160 mem
1161 },
1162 expected_gas: 3 + 2 + (3 + memory_gas_cost(1)) +
1163 3 + 3 + 3 + verylowcopy_cost(2).unwrap(),
1164 }),
1165 }
1166
1167 host {
1168 balance(op::BALANCE, 0_U256 => 0_U256; op_gas(100)),
1169 sload1(@raw {
1170 bytecode: &[op::PUSH1, 69, op::SLOAD],
1171 expected_stack: &[42_U256],
1172 expected_gas: 3 + 100,
1173 }),
1174 sload2(@raw {
1175 bytecode: &[op::PUSH1, 70, op::SLOAD],
1176 expected_stack: &[0_U256],
1177 expected_gas: 3 + 100, }),
1179 sload3(@raw {
1180 bytecode: &[op::PUSH1, 0xff, op::SLOAD],
1181 expected_stack: &[0_U256],
1182 expected_gas: 3 + 100, }),
1184 sstore1(@raw {
1185 bytecode: &[op::PUSH1, 200, op::SLOAD, op::PUSH1, 100, op::PUSH1, 200, op::SSTORE, op::PUSH1, 200, op::SLOAD],
1186 expected_stack: &[0_U256, 100_U256],
1187 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1188 assert_host: Some(|host| {
1189 assert_eq!(host.storage.get(&200_U256), Some(&100_U256));
1190 }),
1191 }),
1192 sstore_const_inputs(@raw {
1193 bytecode: &[op::PUSH1, 42, op::PUSH0, op::SSTORE],
1194 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1195 assert_host: Some(|host| {
1196 assert_eq!(host.storage.get(&U256::ZERO), Some(&42_U256));
1197 }),
1198 }),
1199 tstore_const_inputs(@raw {
1200 bytecode: &[op::PUSH1, 42, op::PUSH1, 69, op::TSTORE],
1201 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1202 assert_host: Some(|host| {
1203 assert_eq!(host.transient_storage.get(&69_U256), Some(&42_U256));
1204 }),
1205 }),
1206 sstore_constantinople(@raw {
1207 bytecode: &[op::PC, op::PC, op::SSTORE, op::PC, op::COINBASE],
1208 spec_id: SpecId::CONSTANTINOPLE,
1209 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
1210 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1211 }),
1212 tload(@raw {
1213 bytecode: &[op::PUSH1, 69, op::TLOAD],
1214 expected_stack: &[0_U256],
1215 expected_gas: 3 + 100,
1216 assert_host: Some(|host| {
1217 assert!(host.transient_storage.is_empty());
1218 }),
1219 }),
1220 tstore(@raw {
1221 bytecode: &[op::PUSH1, 69, op::TLOAD, op::PUSH1, 42, op::PUSH1, 69, op::TSTORE, op::PUSH1, 69, op::TLOAD],
1222 expected_stack: &[0_U256, 42_U256],
1223 expected_gas: 3 + 100 + 3 + 3 + 100 + 3 + 100,
1224 assert_host: Some(|host| {
1225 assert_eq!(host.transient_storage.get(&69_U256), Some(&42_U256));
1226 }),
1227 }),
1228 log0(@raw {
1229 bytecode: &[op::PUSH0, op::PUSH0, op::LOG0],
1230 expected_gas: 2 + 2 + log_cost(0, 0).unwrap(),
1231 assert_host: Some(|host| {
1232 assert_eq!(host.logs, [Log {
1233 address: DEF_ADDR,
1234 data: LogData::new(vec![], Bytes::new()).unwrap(),
1235 }]);
1236 }),
1237 }),
1238 log0_data(@raw {
1239 bytecode: &[op::PUSH2, 0x69, 0x42, op::PUSH0, op::MSTORE, op::PUSH1, 32, op::PUSH0, op::LOG0],
1240 expected_memory: &0x6942_U256.to_be_bytes::<32>(),
1241 expected_gas: 3 + 2 + (3 + memory_gas_cost(1)) + 3 + 2 + log_cost(0, 32).unwrap(),
1242 assert_host: Some(|host| {
1243 assert_eq!(host.logs, [Log {
1244 address: DEF_ADDR,
1245 data: LogData::new(vec![], Bytes::copy_from_slice(&0x6942_U256.to_be_bytes::<32>())).unwrap(),
1246 }]);
1247 }),
1248 }),
1249 log1_1(@raw {
1250 bytecode: &[op::PUSH0, op::PUSH0, op::PUSH0, op::LOG1],
1251 expected_gas: 2 + 2 + 2 + log_cost(1, 0).unwrap(),
1252 assert_host: Some(|host| {
1253 assert_eq!(host.logs, [Log {
1254 address: DEF_ADDR,
1255 data: LogData::new(vec![B256::ZERO], Bytes::new()).unwrap(),
1256 }]);
1257 }),
1258 }),
1259 log1_2(@raw {
1260 bytecode: &hex!(
1261 "7f000000000000000000000000ffffffffffffffffffffffffffffffffffffffff"
1262 "7f0000000000000000000000000000000000000000000000000000000000000032" "59"
1264 "a1"
1265 ),
1266 expected_memory: &[0; 64],
1267 expected_gas: 3 + 3 + 2 + (log_cost(1, 50).unwrap() + memory_gas_cost(2)),
1268 assert_host: Some(|host| {
1269 assert_eq!(host.logs, [Log {
1270 address: DEF_ADDR,
1271 data: LogData::new(
1272 vec![0xffffffffffffffffffffffffffffffffffffffff_U256.into()],
1273 Bytes::copy_from_slice(&[0; 50]),
1274 ).unwrap(),
1275 }]);
1276 }),
1277 }),
1278 create(@raw {
1279 bytecode: &[op::PUSH1, 0x69, op::PUSH0, op::MSTORE, op::PUSH1, 32, op::PUSH0, op::PUSH1, 0x42, op::CREATE],
1280 expected_return: InstructionResult::Stop,
1281 expected_stack: &[],
1283 expected_memory: &0x69_U256.to_be_bytes::<32>(),
1284 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1285 expected_next_action: InterpreterAction::NewFrame(FrameInput::Create(Box::new(CreateInputs::new(
1286 DEF_ADDR,
1287 context_interface::CreateScheme::Create,
1288 0x42_U256,
1289 Bytes::copy_from_slice(&0x69_U256.to_be_bytes::<32>()),
1290 66917,
1291 0,
1292 )))),
1293 }),
1294 create2(@raw {
1295 bytecode: &[op::PUSH1, 0x69, op::PUSH0, op::MSTORE, op::PUSH1, 100, op::PUSH1, 32, op::PUSH0, op::PUSH1, 0x42, op::CREATE2],
1296 expected_return: InstructionResult::Stop,
1297 expected_stack: &[],
1299 expected_memory: &0x69_U256.to_be_bytes::<32>(),
1300 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1301 expected_next_action: InterpreterAction::NewFrame(FrameInput::Create(Box::new(CreateInputs::new(
1302 DEF_ADDR,
1303 context_interface::CreateScheme::Create2 { salt: 100_U256 },
1304 0x42_U256,
1305 Bytes::copy_from_slice(&0x69_U256.to_be_bytes::<32>()),
1306 66908,
1307 0,
1308 )))),
1309 }),
1310 call(@raw {
1311 bytecode: &[
1312 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1320 ],
1321 expected_return: InstructionResult::Stop,
1322 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1324 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1325 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1326 }),
1327 callcode(@raw {
1328 bytecode: &[
1329 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALLCODE,
1337 ],
1338 expected_return: InstructionResult::Stop,
1339 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1340 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1341 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1342 }),
1343 delegatecall(@raw {
1344 bytecode: &[
1345 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::DELEGATECALL,
1352 ],
1353 expected_return: InstructionResult::Stop,
1354 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1355 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1356 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1357 }),
1358 staticcall(@raw {
1359 bytecode: &[
1360 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::STATICCALL,
1367 ],
1368 expected_return: InstructionResult::Stop,
1369 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1370 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1371 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1372 }),
1373 ret_empty_dynamic_offset(@raw {
1374 bytecode: &[op::PUSH0, op::ADDRESS, op::RETURN],
1375 expected_return: InstructionResult::Return,
1376 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1377 }),
1378 ret(@raw {
1379 bytecode: &[op::PUSH1, 0x69, op::PUSH0, op::MSTORE, op::PUSH1, 32, op::PUSH0, op::RETURN],
1380 expected_return: InstructionResult::Return,
1381 expected_memory: &0x69_U256.to_be_bytes::<32>(),
1382 expected_gas: 3 + 2 + (3 + memory_gas_cost(1)) + 3 + 2,
1383 expected_next_action: InterpreterAction::Return(
1384 InterpreterResult {
1385 result: InstructionResult::Return,
1386 output: Bytes::copy_from_slice(&0x69_U256.to_be_bytes::<32>()),
1387 gas: {
1388 let mut gas = Gas::new(DEF_GAS_LIMIT);
1389 assert!(gas.record_regular_cost(3 + 2 + (3 + memory_gas_cost(1)) + 3 + 2));
1390 gas
1391 },
1392 }
1393 ),
1394 }),
1395 revert(@raw {
1396 bytecode: &[op::PUSH1, 0x69, op::PUSH0, op::MSTORE, op::PUSH1, 32, op::PUSH0, op::REVERT],
1397 expected_return: InstructionResult::Revert,
1398 expected_memory: &0x69_U256.to_be_bytes::<32>(),
1399 expected_gas: 3 + 2 + (3 + memory_gas_cost(1)) + 3 + 2,
1400 expected_next_action: InterpreterAction::Return(
1401 InterpreterResult {
1402 result: InstructionResult::Revert,
1403 output: Bytes::copy_from_slice(&0x69_U256.to_be_bytes::<32>()),
1404 gas: {
1405 let mut gas = Gas::new(DEF_GAS_LIMIT);
1406 assert!(gas.record_regular_cost(3 + 2 + (3 + memory_gas_cost(1)) + 3 + 2));
1407 gas
1408 },
1409 }
1410 ),
1411 }),
1412 selfdestruct(@raw {
1413 bytecode: &[op::PUSH1, 0x69, op::SELFDESTRUCT, op::INVALID],
1414 expected_return: InstructionResult::SelfDestruct,
1415 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1416 assert_host: Some(|host| {
1417 assert_eq!(host.selfdestructs, [(DEF_ADDR, Address::with_last_byte(0x69))]);
1418 }),
1419 }),
1420 selfdestruct_static_oog(@raw {
1422 bytecode: &[op::PUSH1, 0x01, op::SELFDESTRUCT],
1423 is_static: true,
1424 gas_limit: 4000,
1425 expected_return: InstructionResult::OutOfGas,
1426 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1427 }),
1428 selfdestruct_static_enough_gas(@raw {
1430 bytecode: &[op::PUSH1, 0x01, op::SELFDESTRUCT],
1431 is_static: true,
1432 expected_return: InstructionResult::StateChangeDuringStaticCall,
1433 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1434 }),
1435 }
1436
1437 call_gas {
1440 call_value_cancun(@raw {
1441 bytecode: &[
1442 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1450 ],
1451 spec_id: SpecId::CANCUN,
1452 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1453 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1454 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1455 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1456 }),
1457 call_no_value_cancun(@raw {
1458 bytecode: &[
1459 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH0, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1467 ],
1468 spec_id: SpecId::CANCUN,
1469 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1470 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1471 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1472 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1473 }),
1474 staticcall_cancun(@raw {
1475 bytecode: &[
1476 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::STATICCALL,
1483 ],
1484 spec_id: SpecId::CANCUN,
1485 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1486 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1487 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1488 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1489 }),
1490 delegatecall_cancun(@raw {
1491 bytecode: &[
1492 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::DELEGATECALL,
1499 ],
1500 spec_id: SpecId::CANCUN,
1501 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1502 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1503 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1504 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1505 }),
1506
1507 call_value_petersburg(@raw {
1509 bytecode: &[
1510 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1518 ],
1519 spec_id: SpecId::PETERSBURG,
1520 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1521 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1522 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1523 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1524 }),
1525 call_no_value_petersburg(@raw {
1526 bytecode: &[
1527 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 0, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1535 ],
1536 spec_id: SpecId::PETERSBURG,
1537 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1538 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1539 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1540 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1541 }),
1542 staticcall_petersburg(@raw {
1543 bytecode: &[
1544 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::STATICCALL,
1551 ],
1552 spec_id: SpecId::PETERSBURG,
1553 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1554 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1555 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1556 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1557 }),
1558 call_value_istanbul(@raw {
1559 bytecode: &[
1560 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1568 ],
1569 spec_id: SpecId::ISTANBUL,
1570 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1571 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1572 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1573 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1574 }),
1575 call_no_value_istanbul(@raw {
1576 bytecode: &[
1577 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 0, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1585 ],
1586 spec_id: SpecId::ISTANBUL,
1587 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1588 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1589 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1590 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1591 }),
1592 staticcall_istanbul(@raw {
1593 bytecode: &[
1594 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::STATICCALL,
1601 ],
1602 spec_id: SpecId::ISTANBUL,
1603 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1604 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1605 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1606 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1607 }),
1608 call_value_byzantium(@raw {
1609 bytecode: &[
1610 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1618 ],
1619 spec_id: SpecId::BYZANTIUM,
1620 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1621 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1622 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1623 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1624 }),
1625 call_high_gas_value_istanbul(@raw {
1626 bytecode: &[
1627 op::PUSH1, 32, op::PUSH1, 0, op::PUSH1, 64, op::PUSH1, 0, op::PUSH1, 100, op::PUSH1, 0x69, op::PUSH2, 0xFF, 0xFF, op::CALL,
1635 ],
1636 spec_id: SpecId::ISTANBUL,
1637 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1638 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1639 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1640 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1641 }),
1642 call_value_muir_glacier(@raw {
1644 bytecode: &[
1645 op::PUSH1, 1, op::PUSH1, 2, op::PUSH1, 3, op::PUSH1, 4, op::PUSH1, 5, op::PUSH1, 6, op::PUSH1, 7, op::CALL,
1653 ],
1654 spec_id: SpecId::MUIR_GLACIER,
1655 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1656 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1657 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1658 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1659 }),
1660 call_high_gas_value(@raw {
1661 bytecode: &[
1662 op::PUSH1, 32, op::PUSH0, op::PUSH1, 64, op::PUSH0, op::PUSH1, 100, op::PUSH1, 0x69, op::PUSH2, 0xFF, 0xFF, op::CALL,
1670 ],
1671 spec_id: SpecId::CANCUN,
1672 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1673 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1674 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1675 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1676 }),
1677 call_known_bytecode(@raw {
1678 bytecode: &[
1679 op::PUSH1, 0, op::PUSH1, 0, op::PUSH1, 0, op::PUSH1, 0, op::PUSH1, 0, op::PUSH1, 0x69, op::PUSH1, 7, op::CALL,
1687 ],
1688 spec_id: SpecId::CANCUN,
1689 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1690 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1691 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1692 expected_next_action: ACTION_WHAT_INTERPRETER_SAYS,
1693 assert_ecx: Some(|ecx| {
1694 if let Some(InterpreterAction::NewFrame(FrameInput::Call(call_inputs))) =
1695 ecx.next_action.as_ref()
1696 {
1697 let (code_hash, _) = &call_inputs.known_bytecode;
1698 assert!(
1699 !code_hash.is_zero(),
1700 "CALL must populate known_bytecode via load_account_delegated; \
1701 got zero code hash (old code path that skips delegation resolution)"
1702 );
1703 }
1704 }),
1705 }),
1706 }
1707
1708 i256_lanes {
1712 add_full_width(op::ADD,
1714 0xDEADBEEF_12345678_ABCDEF01_23456789_FEDCBA98_76543210_01234567_89ABCDEF_U256,
1715 0x11111111_22222222_33333333_44444444_55555555_66666666_77777777_88888888_U256
1716 => 0xDEADBEEF_12345678_ABCDEF01_23456789_FEDCBA98_76543210_01234567_89ABCDEF_U256
1717 + 0x11111111_22222222_33333333_44444444_55555555_66666666_77777777_88888888_U256
1718 ),
1719 mul_full_width(op::MUL,
1721 0x00000000_00000000_00000000_00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_U256,
1722 0x00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000002_U256
1723 => 0x00000000_00000000_00000000_00000001_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFE_U256
1724 ),
1725 sub_cross_lane(op::SUB,
1727 0x00000000_00000000_00000000_00000001_00000000_00000000_00000000_00000000_U256,
1728 0x00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001_U256
1729 => 0x00000000_00000000_00000000_00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF_U256
1730 ),
1731 or_all_lanes(op::OR,
1733 0xFF000000_00000000_00FF0000_00000000_0000FF00_00000000_000000FF_00000000_U256,
1734 0x00000000_FF000000_00000000_00FF0000_00000000_0000FF00_00000000_000000FF_U256
1735 => 0xFF000000_FF000000_00FF0000_00FF0000_0000FF00_0000FF00_000000FF_000000FF_U256
1736 ),
1737 shl_cross_lane(op::SHL,
1739 64_U256,
1740 0x00000000_00000000_00000000_00000000_00000000_00000000_00000000_00000001_U256
1741 => 0x00000000_00000000_00000000_00000000_00000000_00000001_00000000_00000000_U256
1742 ),
1743 shr_cross_lane(op::SHR,
1745 64_U256,
1746 0x00000000_00000001_00000000_00000000_00000000_00000000_00000000_00000000_U256
1747 => 0x00000000_00000000_00000000_00000001_00000000_00000000_00000000_00000000_U256
1748 ),
1749 }
1750
1751 codecopy_fix {
1755 codecopy_exact(@raw {
1756 bytecode: &[op::PUSH1, 5, op::PUSH0, op::PUSH0, op::CODECOPY],
1757 expected_memory: &hex!("60055f5f39000000000000000000000000000000000000000000000000000000"),
1758 expected_gas: 3 + 2 + 2 + (verylowcopy_cost(32).unwrap() + memory_gas_cost(1)),
1759 }),
1760 codecopy_offset(@raw {
1761 bytecode: &[op::PUSH1, 3, op::PUSH1, 2, op::PUSH0, op::CODECOPY],
1762 expected_memory: &hex!("60025f0000000000000000000000000000000000000000000000000000000000"),
1763 expected_gas: 3 + 3 + 2 + (verylowcopy_cost(32).unwrap() + memory_gas_cost(1)),
1764 }),
1765 codecopy_beyond(@raw {
1766 bytecode: &[op::PUSH1, 10, op::PUSH0, op::PUSH0, op::CODECOPY],
1767 expected_memory: &hex!("600a5f5f39000000000000000000000000000000000000000000000000000000"),
1768 expected_gas: 3 + 2 + 2 + (verylowcopy_cost(32).unwrap() + memory_gas_cost(1)),
1769 }),
1770 codecopy_longer(@raw {
1771 bytecode: &[
1772 op::PUSH1, 42, op::POP, op::PUSH1, 99, op::POP, op::PUSH1, 12, op::PUSH0, op::PUSH0, op::CODECOPY, ],
1781 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
1782 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1783 }),
1784 codecopy_runtime_ptr(@raw {
1788 bytecode: &[op::PUSH1, 5, op::PUSH0, op::PUSH0, op::CODECOPY],
1789 modify_ecx: Some(|ecx| {
1790 static FAKE_CODE: [u8; 5] = [0xAA, 0xBB, 0xCC, 0xDD, 0xEE];
1791 ecx.bytecode = &FAKE_CODE as *const [u8];
1792 }),
1793 expected_return: InstructionResult::Stop,
1794 expected_memory: &hex!("AABBCCDDEE000000000000000000000000000000000000000000000000000000"),
1795 expected_gas: 3 + 2 + 2 + (verylowcopy_cost(32).unwrap() + memory_gas_cost(1)),
1796 }),
1797 }
1798
1799 dedup {
1800 transitive_redirect_multi_jump(@raw {
1809 bytecode: &asm("
1810 ; entry: dispatch on CALLDATASIZE (nonzero -> path1)
1811 CALLDATASIZE
1812 PUSH %path1
1813 JUMPI
1814 ; not taken: u0 via t0
1815 PUSH %u0
1816 PUSH %t0
1817 JUMP
1818
1819 path1:
1820 JUMPDEST
1821 CALLVALUE
1822 PUSH %path2
1823 JUMPI
1824 ; not taken: u1 via t1 via fn
1825 PUSH %u1
1826 PUSH %t1
1827 PUSH %fn
1828 JUMP
1829
1830 path2:
1831 JUMPDEST
1832 ; u1 via t2 via fn
1833 PUSH %u1
1834 PUSH %t2
1835 PUSH %fn
1836 JUMP
1837
1838 dead0: INVALID
1839 dead1: INVALID
1840 dead2: INVALID
1841
1842 ; three byte-identical trampolines that get deduped (t2->t1->t0)
1843 t0: JUMPDEST JUMP
1844 t1: JUMPDEST JUMP
1845 t2: JUMPDEST JUMP
1846
1847 u0: JUMPDEST STOP
1848 u1: JUMPDEST STOP
1849
1850 fn: JUMPDEST JUMP
1851 "),
1852 spec_id: SpecId::CANCUN,
1853 expected_return: RETURN_WHAT_INTERPRETER_SAYS,
1854 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
1855 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1856 }),
1857
1858 dedup_multi_jump_dispatcher(@raw {
1866 bytecode: &asm("
1867 ; dispatch on first calldata word
1868 PUSH0
1869 CALLDATALOAD
1870 PUSH %d1
1871 JUMPI
1872
1873 ; dispatch on second calldata word
1874 PUSH 0x20
1875 CALLDATALOAD
1876 PUSH %d0
1877 JUMPI
1878
1879 ; neither taken: stop0 via fn1
1880 PUSH %stop0
1881 PUSH %fn1
1882 JUMP
1883
1884 d0:
1885 JUMPDEST
1886 PUSH %stop1
1887 PUSH %fn1
1888 JUMP
1889
1890 d1:
1891 JUMPDEST
1892 PUSH 0x20
1893 CALLDATALOAD
1894 PUSH %d1_taken
1895 JUMPI
1896 ; not taken: stop2 via fn2
1897 PUSH %stop2
1898 PUSH %fn2
1899 JUMP
1900
1901 d1_taken:
1902 JUMPDEST
1903 PUSH %stop3
1904 PUSH %fn2
1905 JUMP
1906
1907 stop0: JUMPDEST STOP
1908 stop1: JUMPDEST STOP
1909 stop2: JUMPDEST STOP
1910 stop3: JUMPDEST STOP
1911
1912 ; two byte-identical dispatchers that get deduped
1913 fn1: JUMPDEST JUMP
1914 fn2: JUMPDEST JUMP
1915 "),
1916 expected_return: InstructionResult::Stop,
1917 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1918 }),
1919 }
1920
1921 regressions {
1922 dedup_leader_propagation(@raw {
1931 bytecode: &asm("
1932 entry:
1933 JUMPDEST
1934 PUSH 0x00 ; cond = 0
1935 PUSH %jumpi2
1936 JUMPI ; not taken
1937 ; canonical fall-through
1938 PUSH %jumpi2
1939 JUMP
1940
1941 jumpi2:
1942 JUMPDEST
1943 PUSH 0x2a ; live-out value DSE must preserve
1944 CALLDATASIZE ; condition (nonzero)
1945 PUSH %dest
1946 JUMPI ; taken
1947 ; duplicate fall-through (same bytes as canonical -> deduped)
1948 PUSH %jumpi2
1949 JUMP
1950
1951 INVALID ; alive after dead deduped block
1952
1953 dest:
1954 JUMPDEST
1955 PUSH 0x00
1956 MSTORE ; mem[0] = 0x2a
1957 PUSH 0x20
1958 PUSH 0x00
1959 RETURN
1960 "),
1961 inspect_stack: Some(false),
1962 expected_return: InstructionResult::Return,
1963 expected_memory: &U256::from(0x2a).to_be_bytes::<32>(),
1964 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
1965 expected_next_action: InterpreterAction::Return(
1966 InterpreterResult {
1967 result: InstructionResult::Return,
1968 output: Bytes::copy_from_slice(&U256::from(0x2a).to_be_bytes::<32>()),
1969 gas: Gas::new(GAS_WHAT_INTERPRETER_SAYS),
1970 }
1971 ),
1972 }),
1973
1974 dedup_jumpdest_leader(@raw {
1979 bytecode: &asm("
1980 entry:
1981 JUMPDEST
1982 PUSH 0x00
1983 CALLDATASIZE
1984 PUSH %alt_entry
1985 JUMPI
1986 ; not-taken -> dup_ret (makes it reachable for analysis)
1987 PUSH %dup_ret
1988 JUMP
1989
1990 canonical_ret:
1991 JUMPDEST
1992 PUSH %dest
1993 JUMP
1994
1995 alt_entry:
1996 JUMPDEST
1997 DUP1
1998 POP
1999 POP
2000 PUSH 0x2a ; <- DSE must NOT kill
2001
2002 dup_ret:
2003 ; byte-identical to canonical_ret -> deduped
2004 JUMPDEST
2005 PUSH %dest
2006 JUMP
2007
2008 INVALID ; alive after dead dup_ret
2009
2010 dest:
2011 JUMPDEST
2012 PUSH 0x00
2013 MSTORE
2014 PUSH 0x20
2015 PUSH 0x00
2016 RETURN
2017 "),
2018 inspect_stack: Some(false),
2019 expected_return: InstructionResult::Return,
2020 expected_memory: &U256::from(0x2a).to_be_bytes::<32>(),
2021 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
2022 expected_next_action: InterpreterAction::Return(
2023 InterpreterResult {
2024 result: InstructionResult::Return,
2025 output: Bytes::copy_from_slice(&U256::from(0x2a).to_be_bytes::<32>()),
2026 gas: Gas::new(GAS_WHAT_INTERPRETER_SAYS),
2027 }
2028 ),
2029 }),
2030
2031 calldatasize_tstore_shanghai(@raw {
2040 bytecode: &[op::CALLDATASIZE, op::TSTORE],
2041 spec_id: SpecId::SHANGHAI,
2042 expected_return: InstructionResult::NotActivated,
2043 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
2044 }),
2045
2046 push0_tload_shanghai(@raw {
2048 bytecode: &[op::PUSH0, op::TLOAD],
2049 spec_id: SpecId::SHANGHAI,
2050 expected_return: InstructionResult::NotActivated,
2051 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
2052 }),
2053
2054 st_solidity_keywords(@raw {
2057 bytecode: &hex!("7c01000000000000000000000000000000000000000000000000000000006000350463380e439681146037578063c040622614604757005b603d6084565b8060005260206000f35b604d6057565b8060005260206000f35b6000605f6084565b600060006101000a81548160ff0219169083021790555060ff60016000540416905090565b6000808160011560cd575b600a82121560a157600190910190608f565b81600a1460ac5760c9565b50600a5b60008160ff16111560c85760019182900391900360b0565b5b60d5565b6000925060ed565b8160001460e05760e8565b6001925060ed565b600092505b50509056"),
2058 spec_id: SpecId::ISTANBUL,
2059 modify_ecx: Some(|ecx| {
2060 ecx.input.call_value = 1_U256;
2061 ecx.input.input = interpreter::CallInput::Bytes(Bytes::from(&hex!("c0406226")));
2062 }),
2063 expected_return: InstructionResult::Return,
2067 expected_stack: STACK_WHAT_INTERPRETER_SAYS,
2068 expected_gas: GAS_WHAT_INTERPRETER_SAYS,
2069 expected_memory: MEMORY_WHAT_INTERPRETER_SAYS,
2070 expected_next_action: InterpreterAction::Return(
2071 InterpreterResult {
2072 result: InstructionResult::Return,
2073 output: Bytes::copy_from_slice(&1_U256.to_be_bytes::<32>()),
2074 gas: Gas::new(GAS_WHAT_INTERPRETER_SAYS),
2075 }
2076 ),
2077 assert_host: Some(|host| {
2078 assert_eq!(host.storage.get(&0_U256), Some(&1_U256));
2079 }),
2080 }),
2081 }
2082}
2083
2084fn bytecode_unop(op: u8, a: U256) -> [u8; 34] {
2085 let mut code = [0; 34];
2086 let mut i = 0;
2087 build_push32!(code[i], a);
2088 code[i] = op;
2089 code
2090}
2091
2092fn bytecode_binop(op: u8, a: U256, b: U256) -> [u8; 67] {
2093 let mut code = [0; 67];
2094 let mut i = 0;
2095 build_push32!(code[i], b);
2096 build_push32!(code[i], a);
2097 code[i] = op;
2098 code
2099}
2100
2101fn bytecode_ternop(op: u8, a: U256, b: U256, c: U256) -> [u8; 100] {
2102 let mut code = [0; 100];
2103 let mut i = 0;
2104 build_push32!(code[i], c);
2105 build_push32!(code[i], b);
2106 build_push32!(code[i], a);
2107 code[i] = op;
2108 code
2109}
2110
2111fn bytecode_unop_opaque(opcode: u8, a: U256) -> Vec<u8> {
2113 let mut code = Vec::with_capacity(64);
2114 code.push(op::PUSH32);
2115 code.extend_from_slice(&a.to_be_bytes::<32>());
2116 code.push(op::PUSH1);
2117 code.push(0x00);
2118 code.push(op::MSTORE);
2119 code.push(op::PUSH1);
2120 code.push(0x00);
2121 code.push(op::MLOAD);
2122 code.push(opcode);
2123 code
2124}
2125
2126fn push_const_or_load(code: &mut Vec<u8>, value: U256, is_const: bool, offset: u8) {
2127 if is_const {
2128 code.push(op::PUSH32);
2129 code.extend_from_slice(&value.to_be_bytes::<32>());
2130 } else {
2131 code.push(op::PUSH1);
2132 code.push(offset);
2133 code.push(op::MLOAD);
2134 }
2135}
2136
2137fn store_dynamic_operands(code: &mut Vec<u8>, operands: &[(U256, bool, u8)]) {
2138 for &(value, is_const, offset) in operands {
2139 if !is_const {
2140 code.push(op::PUSH32);
2141 code.extend_from_slice(&value.to_be_bytes::<32>());
2142 code.push(op::PUSH1);
2143 code.push(offset);
2144 code.push(op::MSTORE);
2145 }
2146 }
2147}
2148
2149fn bytecode_binop_mixed(opcode: u8, a: U256, b: U256, a_const: bool, b_const: bool) -> Vec<u8> {
2150 let mut code = Vec::with_capacity(128);
2151 store_dynamic_operands(&mut code, &[(a, a_const, 0x00), (b, b_const, 0x20)]);
2152 push_const_or_load(&mut code, b, b_const, 0x20);
2153 push_const_or_load(&mut code, a, a_const, 0x00);
2154 code.push(opcode);
2155 code
2156}
2157
2158fn bytecode_ternop_mixed(
2159 opcode: u8,
2160 a: U256,
2161 b: U256,
2162 c: U256,
2163 a_const: bool,
2164 b_const: bool,
2165 c_const: bool,
2166) -> Vec<u8> {
2167 let mut code = Vec::with_capacity(192);
2168 store_dynamic_operands(
2169 &mut code,
2170 &[(a, a_const, 0x00), (b, b_const, 0x20), (c, c_const, 0x40)],
2171 );
2172 push_const_or_load(&mut code, c, c_const, 0x40);
2173 push_const_or_load(&mut code, b, b_const, 0x20);
2174 push_const_or_load(&mut code, a, a_const, 0x00);
2175 code.push(opcode);
2176 code
2177}
2178
2179fn asm(s: &str) -> Vec<u8> {
2180 crate::parse_asm(s).unwrap()
2181}