1pub use self::Instruction::*;
20
21macro_rules! enum_with_from_u8 {
22 (
23 $( #[$enum_attr:meta] )*
24 pub enum $name:ident {
25 $( $( #[$variant_attr:meta] )* $variant:ident = $discriminator:expr ),+,
26 }
27 ) => {
28 $( #[$enum_attr] )*
29 pub enum $name {
30 $( $( #[$variant_attr] )* $variant = $discriminator ),+,
31 }
32
33 impl $name {
34 #[doc = "Convert from u8 to the given enum"]
35 pub fn from_u8(value: u8) -> Option<Self> {
36 match value {
37 $( $discriminator => Some($variant) ),+,
38 _ => None,
39 }
40 }
41 }
42 };
43}
44
45enum_with_from_u8! {
46 #[doc = "Virtual machine bytecode instruction."]
47 #[repr(u8)]
48 #[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Copy, Debug, Hash)]
49 pub enum Instruction {
50 #[doc = "halts execution"]
51 STOP = 0x00,
52 #[doc = "addition operation"]
53 ADD = 0x01,
54 #[doc = "mulitplication operation"]
55 MUL = 0x02,
56 #[doc = "subtraction operation"]
57 SUB = 0x03,
58 #[doc = "integer division operation"]
59 DIV = 0x04,
60 #[doc = "signed integer division operation"]
61 SDIV = 0x05,
62 #[doc = "modulo remainder operation"]
63 MOD = 0x06,
64 #[doc = "signed modulo remainder operation"]
65 SMOD = 0x07,
66 #[doc = "unsigned modular addition"]
67 ADDMOD = 0x08,
68 #[doc = "unsigned modular multiplication"]
69 MULMOD = 0x09,
70 #[doc = "exponential operation"]
71 EXP = 0x0a,
72 #[doc = "extend length of signed integer"]
73 SIGNEXTEND = 0x0b,
74
75 #[doc = "less-than comparision"]
76 LT = 0x10,
77 #[doc = "greater-than comparision"]
78 GT = 0x11,
79 #[doc = "signed less-than comparision"]
80 SLT = 0x12,
81 #[doc = "signed greater-than comparision"]
82 SGT = 0x13,
83 #[doc = "equality comparision"]
84 EQ = 0x14,
85 #[doc = "simple not operator"]
86 ISZERO = 0x15,
87 #[doc = "bitwise AND operation"]
88 AND = 0x16,
89 #[doc = "bitwise OR operation"]
90 OR = 0x17,
91 #[doc = "bitwise XOR operation"]
92 XOR = 0x18,
93 #[doc = "bitwise NOT opertation"]
94 NOT = 0x19,
95 #[doc = "retrieve single byte from word"]
96 BYTE = 0x1a,
97 #[doc = "shift left operation"]
98 SHL = 0x1b,
99 #[doc = "logical shift right operation"]
100 SHR = 0x1c,
101 #[doc = "arithmetic shift right operation"]
102 SAR = 0x1d,
103
104 #[doc = "compute SHA3-256 hash"]
105 SHA3 = 0x20,
106
107 #[doc = "get address of currently executing account"]
108 ADDRESS = 0x30,
109 #[doc = "get balance of the given account"]
110 BALANCE = 0x31,
111 #[doc = "get execution origination address"]
112 ORIGIN = 0x32,
113 #[doc = "get caller address"]
114 CALLER = 0x33,
115 #[doc = "get deposited value by the instruction/transaction responsible for this execution"]
116 CALLVALUE = 0x34,
117 #[doc = "get input data of current environment"]
118 CALLDATALOAD = 0x35,
119 #[doc = "get size of input data in current environment"]
120 CALLDATASIZE = 0x36,
121 #[doc = "copy input data in current environment to memory"]
122 CALLDATACOPY = 0x37,
123 #[doc = "get size of code running in current environment"]
124 CODESIZE = 0x38,
125 #[doc = "copy code running in current environment to memory"]
126 CODECOPY = 0x39,
127 #[doc = "get price of gas in current environment"]
128 GASPRICE = 0x3a,
129 #[doc = "get external code size (from another contract)"]
130 EXTCODESIZE = 0x3b,
131 #[doc = "copy external code (from another contract)"]
132 EXTCODECOPY = 0x3c,
133 #[doc = "get the size of the return data buffer for the last call"]
134 RETURNDATASIZE = 0x3d,
135 #[doc = "copy return data buffer to memory"]
136 RETURNDATACOPY = 0x3e,
137 #[doc = "return the keccak256 hash of contract code"]
138 EXTCODEHASH = 0x3f,
139
140 #[doc = "get hash of most recent complete block"]
141 BLOCKHASH = 0x40,
142 #[doc = "get the block's coinbase address"]
143 COINBASE = 0x41,
144 #[doc = "get the block's timestamp"]
145 TIMESTAMP = 0x42,
146 #[doc = "get the block's number"]
147 NUMBER = 0x43,
148 #[doc = "get the block's difficulty"]
149 DIFFICULTY = 0x44,
150 #[doc = "get the block's gas limit"]
151 GASLIMIT = 0x45,
152 #[doc = "get chain ID"]
153 CHAINID = 0x46,
154 #[doc = "get balance of own account"]
155 SELFBALANCE = 0x47,
156
157 #[doc = "remove item from stack"]
158 POP = 0x50,
159 #[doc = "load word from memory"]
160 MLOAD = 0x51,
161 #[doc = "save word to memory"]
162 MSTORE = 0x52,
163 #[doc = "save byte to memory"]
164 MSTORE8 = 0x53,
165 #[doc = "load word from storage"]
166 SLOAD = 0x54,
167 #[doc = "save word to storage"]
168 SSTORE = 0x55,
169 #[doc = "alter the program counter"]
170 JUMP = 0x56,
171 #[doc = "conditionally alter the program counter"]
172 JUMPI = 0x57,
173 #[doc = "get the program counter"]
174 PC = 0x58,
175 #[doc = "get the size of active memory"]
176 MSIZE = 0x59,
177 #[doc = "get the amount of available gas"]
178 GAS = 0x5a,
179 #[doc = "set a potential jump destination"]
180 JUMPDEST = 0x5b,
181
182 #[doc = "place 1 byte item on stack"]
183 PUSH1 = 0x60,
184 #[doc = "place 2 byte item on stack"]
185 PUSH2 = 0x61,
186 #[doc = "place 3 byte item on stack"]
187 PUSH3 = 0x62,
188 #[doc = "place 4 byte item on stack"]
189 PUSH4 = 0x63,
190 #[doc = "place 5 byte item on stack"]
191 PUSH5 = 0x64,
192 #[doc = "place 6 byte item on stack"]
193 PUSH6 = 0x65,
194 #[doc = "place 7 byte item on stack"]
195 PUSH7 = 0x66,
196 #[doc = "place 8 byte item on stack"]
197 PUSH8 = 0x67,
198 #[doc = "place 9 byte item on stack"]
199 PUSH9 = 0x68,
200 #[doc = "place 10 byte item on stack"]
201 PUSH10 = 0x69,
202 #[doc = "place 11 byte item on stack"]
203 PUSH11 = 0x6a,
204 #[doc = "place 12 byte item on stack"]
205 PUSH12 = 0x6b,
206 #[doc = "place 13 byte item on stack"]
207 PUSH13 = 0x6c,
208 #[doc = "place 14 byte item on stack"]
209 PUSH14 = 0x6d,
210 #[doc = "place 15 byte item on stack"]
211 PUSH15 = 0x6e,
212 #[doc = "place 16 byte item on stack"]
213 PUSH16 = 0x6f,
214 #[doc = "place 17 byte item on stack"]
215 PUSH17 = 0x70,
216 #[doc = "place 18 byte item on stack"]
217 PUSH18 = 0x71,
218 #[doc = "place 19 byte item on stack"]
219 PUSH19 = 0x72,
220 #[doc = "place 20 byte item on stack"]
221 PUSH20 = 0x73,
222 #[doc = "place 21 byte item on stack"]
223 PUSH21 = 0x74,
224 #[doc = "place 22 byte item on stack"]
225 PUSH22 = 0x75,
226 #[doc = "place 23 byte item on stack"]
227 PUSH23 = 0x76,
228 #[doc = "place 24 byte item on stack"]
229 PUSH24 = 0x77,
230 #[doc = "place 25 byte item on stack"]
231 PUSH25 = 0x78,
232 #[doc = "place 26 byte item on stack"]
233 PUSH26 = 0x79,
234 #[doc = "place 27 byte item on stack"]
235 PUSH27 = 0x7a,
236 #[doc = "place 28 byte item on stack"]
237 PUSH28 = 0x7b,
238 #[doc = "place 29 byte item on stack"]
239 PUSH29 = 0x7c,
240 #[doc = "place 30 byte item on stack"]
241 PUSH30 = 0x7d,
242 #[doc = "place 31 byte item on stack"]
243 PUSH31 = 0x7e,
244 #[doc = "place 32 byte item on stack"]
245 PUSH32 = 0x7f,
246
247 #[doc = "copies the highest item in the stack to the top of the stack"]
248 DUP1 = 0x80,
249 #[doc = "copies the second highest item in the stack to the top of the stack"]
250 DUP2 = 0x81,
251 #[doc = "copies the third highest item in the stack to the top of the stack"]
252 DUP3 = 0x82,
253 #[doc = "copies the 4th highest item in the stack to the top of the stack"]
254 DUP4 = 0x83,
255 #[doc = "copies the 5th highest item in the stack to the top of the stack"]
256 DUP5 = 0x84,
257 #[doc = "copies the 6th highest item in the stack to the top of the stack"]
258 DUP6 = 0x85,
259 #[doc = "copies the 7th highest item in the stack to the top of the stack"]
260 DUP7 = 0x86,
261 #[doc = "copies the 8th highest item in the stack to the top of the stack"]
262 DUP8 = 0x87,
263 #[doc = "copies the 9th highest item in the stack to the top of the stack"]
264 DUP9 = 0x88,
265 #[doc = "copies the 10th highest item in the stack to the top of the stack"]
266 DUP10 = 0x89,
267 #[doc = "copies the 11th highest item in the stack to the top of the stack"]
268 DUP11 = 0x8a,
269 #[doc = "copies the 12th highest item in the stack to the top of the stack"]
270 DUP12 = 0x8b,
271 #[doc = "copies the 13th highest item in the stack to the top of the stack"]
272 DUP13 = 0x8c,
273 #[doc = "copies the 14th highest item in the stack to the top of the stack"]
274 DUP14 = 0x8d,
275 #[doc = "copies the 15th highest item in the stack to the top of the stack"]
276 DUP15 = 0x8e,
277 #[doc = "copies the 16th highest item in the stack to the top of the stack"]
278 DUP16 = 0x8f,
279
280 #[doc = "swaps the highest and second highest value on the stack"]
281 SWAP1 = 0x90,
282 #[doc = "swaps the highest and third highest value on the stack"]
283 SWAP2 = 0x91,
284 #[doc = "swaps the highest and 4th highest value on the stack"]
285 SWAP3 = 0x92,
286 #[doc = "swaps the highest and 5th highest value on the stack"]
287 SWAP4 = 0x93,
288 #[doc = "swaps the highest and 6th highest value on the stack"]
289 SWAP5 = 0x94,
290 #[doc = "swaps the highest and 7th highest value on the stack"]
291 SWAP6 = 0x95,
292 #[doc = "swaps the highest and 8th highest value on the stack"]
293 SWAP7 = 0x96,
294 #[doc = "swaps the highest and 9th highest value on the stack"]
295 SWAP8 = 0x97,
296 #[doc = "swaps the highest and 10th highest value on the stack"]
297 SWAP9 = 0x98,
298 #[doc = "swaps the highest and 11th highest value on the stack"]
299 SWAP10 = 0x99,
300 #[doc = "swaps the highest and 12th highest value on the stack"]
301 SWAP11 = 0x9a,
302 #[doc = "swaps the highest and 13th highest value on the stack"]
303 SWAP12 = 0x9b,
304 #[doc = "swaps the highest and 14th highest value on the stack"]
305 SWAP13 = 0x9c,
306 #[doc = "swaps the highest and 15th highest value on the stack"]
307 SWAP14 = 0x9d,
308 #[doc = "swaps the highest and 16th highest value on the stack"]
309 SWAP15 = 0x9e,
310 #[doc = "swaps the highest and 17th highest value on the stack"]
311 SWAP16 = 0x9f,
312
313 #[doc = "Makes a log entry, no topics."]
314 LOG0 = 0xa0,
315 #[doc = "Makes a log entry, 1 topic."]
316 LOG1 = 0xa1,
317 #[doc = "Makes a log entry, 2 topics."]
318 LOG2 = 0xa2,
319 #[doc = "Makes a log entry, 3 topics."]
320 LOG3 = 0xa3,
321 #[doc = "Makes a log entry, 4 topics."]
322 LOG4 = 0xa4,
323
324 #[doc = "create a new account with associated code"]
325 CREATE = 0xf0,
326 #[doc = "message-call into an account"]
327 CALL = 0xf1,
328 #[doc = "message-call with another account's code only"]
329 CALLCODE = 0xf2,
330 #[doc = "halt execution returning output data"]
331 RETURN = 0xf3,
332 #[doc = "like CALLCODE but keeps caller's value and sender"]
333 DELEGATECALL = 0xf4,
334 #[doc = "create a new account and set creation address to sha3(sender + sha3(init code)) % 2**160"]
335 CREATE2 = 0xf5,
336 #[doc = "stop execution and revert state changes. Return output data."]
337 REVERT = 0xfd,
338 #[doc = "like CALL but it does not take value, nor modify the state"]
339 STATICCALL = 0xfa,
340 #[doc = "halt execution and register account for later deletion"]
341 SUICIDE = 0xff,
342 }
343}
344
345impl Instruction {
346 pub fn is_push(&self) -> bool {
348 *self >= PUSH1 && *self <= PUSH32
349 }
350
351 pub fn push_bytes(&self) -> Option<usize> {
354 if self.is_push() {
355 Some(((*self as u8) - (PUSH1 as u8) + 1) as usize)
356 } else {
357 None
358 }
359 }
360
361 pub fn dup_position(&self) -> Option<usize> {
364 if *self >= DUP1 && *self <= DUP16 {
365 Some(((*self as u8) - (DUP1 as u8)) as usize)
366 } else {
367 None
368 }
369 }
370
371 pub fn swap_position(&self) -> Option<usize> {
374 if *self >= SWAP1 && *self <= SWAP16 {
375 Some(((*self as u8) - (SWAP1 as u8) + 1) as usize)
376 } else {
377 None
378 }
379 }
380
381 pub fn log_topics(&self) -> Option<usize> {
384 if *self >= LOG0 && *self <= LOG4 {
385 Some(((*self as u8) - (LOG0 as u8)) as usize)
386 } else {
387 None
388 }
389 }
390
391 pub fn info(&self) -> &'static InstructionInfo {
393 INSTRUCTIONS[*self as usize].as_ref().expect("A instruction is defined in Instruction enum, but it is not found in InstructionInfo struct; this indicates a logic failure in the code.")
394 }
395}
396
397#[derive(PartialEq, Clone, Copy)]
398pub enum GasPriceTier {
399 Zero,
401 Base,
403 VeryLow,
405 Low,
407 Mid,
409 High,
411 Ext,
413 Special,
415}
416
417impl GasPriceTier {
418 pub fn idx(&self) -> usize {
420 match self {
421 &GasPriceTier::Zero => 0,
422 &GasPriceTier::Base => 1,
423 &GasPriceTier::VeryLow => 2,
424 &GasPriceTier::Low => 3,
425 &GasPriceTier::Mid => 4,
426 &GasPriceTier::High => 5,
427 &GasPriceTier::Ext => 6,
428 &GasPriceTier::Special => 7,
429 }
430 }
431}
432
433#[derive(Copy, Clone)]
435pub struct InstructionInfo {
436 pub name: &'static str,
438 pub args: usize,
440 pub ret: usize,
442 pub tier: GasPriceTier
444}
445
446impl InstructionInfo {
447 pub fn new(name: &'static str, args: usize, ret: usize, tier: GasPriceTier) -> Self {
449 InstructionInfo { name, args, ret, tier }
450 }
451}
452
453lazy_static! {
454 static ref INSTRUCTIONS: [Option<InstructionInfo>; 0x100] = {
456 let mut arr = [None; 0x100];
457 arr[STOP as usize] = Some(InstructionInfo::new("STOP", 0, 0, GasPriceTier::Zero));
458 arr[ADD as usize] = Some(InstructionInfo::new("ADD", 2, 1, GasPriceTier::VeryLow));
459 arr[SUB as usize] = Some(InstructionInfo::new("SUB", 2, 1, GasPriceTier::VeryLow));
460 arr[MUL as usize] = Some(InstructionInfo::new("MUL", 2, 1, GasPriceTier::Low));
461 arr[DIV as usize] = Some(InstructionInfo::new("DIV", 2, 1, GasPriceTier::Low));
462 arr[SDIV as usize] = Some(InstructionInfo::new("SDIV", 2, 1, GasPriceTier::Low));
463 arr[MOD as usize] = Some(InstructionInfo::new("MOD", 2, 1, GasPriceTier::Low));
464 arr[SMOD as usize] = Some(InstructionInfo::new("SMOD", 2, 1, GasPriceTier::Low));
465 arr[EXP as usize] = Some(InstructionInfo::new("EXP", 2, 1, GasPriceTier::Special));
466 arr[NOT as usize] = Some(InstructionInfo::new("NOT", 1, 1, GasPriceTier::VeryLow));
467 arr[LT as usize] = Some(InstructionInfo::new("LT", 2, 1, GasPriceTier::VeryLow));
468 arr[GT as usize] = Some(InstructionInfo::new("GT", 2, 1, GasPriceTier::VeryLow));
469 arr[SLT as usize] = Some(InstructionInfo::new("SLT", 2, 1, GasPriceTier::VeryLow));
470 arr[SGT as usize] = Some(InstructionInfo::new("SGT", 2, 1, GasPriceTier::VeryLow));
471 arr[EQ as usize] = Some(InstructionInfo::new("EQ", 2, 1, GasPriceTier::VeryLow));
472 arr[ISZERO as usize] = Some(InstructionInfo::new("ISZERO", 1, 1, GasPriceTier::VeryLow));
473 arr[AND as usize] = Some(InstructionInfo::new("AND", 2, 1, GasPriceTier::VeryLow));
474 arr[OR as usize] = Some(InstructionInfo::new("OR", 2, 1, GasPriceTier::VeryLow));
475 arr[XOR as usize] = Some(InstructionInfo::new("XOR", 2, 1, GasPriceTier::VeryLow));
476 arr[BYTE as usize] = Some(InstructionInfo::new("BYTE", 2, 1, GasPriceTier::VeryLow));
477 arr[SHL as usize] = Some(InstructionInfo::new("SHL", 2, 1, GasPriceTier::VeryLow));
478 arr[SHR as usize] = Some(InstructionInfo::new("SHR", 2, 1, GasPriceTier::VeryLow));
479 arr[SAR as usize] = Some(InstructionInfo::new("SAR", 2, 1, GasPriceTier::VeryLow));
480 arr[ADDMOD as usize] = Some(InstructionInfo::new("ADDMOD", 3, 1, GasPriceTier::Mid));
481 arr[MULMOD as usize] = Some(InstructionInfo::new("MULMOD", 3, 1, GasPriceTier::Mid));
482 arr[SIGNEXTEND as usize] = Some(InstructionInfo::new("SIGNEXTEND", 2, 1, GasPriceTier::Low));
483 arr[RETURNDATASIZE as usize] = Some(InstructionInfo::new("RETURNDATASIZE", 0, 1, GasPriceTier::Base));
484 arr[RETURNDATACOPY as usize] = Some(InstructionInfo::new("RETURNDATACOPY", 3, 0, GasPriceTier::VeryLow));
485 arr[SHA3 as usize] = Some(InstructionInfo::new("SHA3", 2, 1, GasPriceTier::Special));
486 arr[ADDRESS as usize] = Some(InstructionInfo::new("ADDRESS", 0, 1, GasPriceTier::Base));
487 arr[BALANCE as usize] = Some(InstructionInfo::new("BALANCE", 1, 1, GasPriceTier::Special));
488 arr[ORIGIN as usize] = Some(InstructionInfo::new("ORIGIN", 0, 1, GasPriceTier::Base));
489 arr[CALLER as usize] = Some(InstructionInfo::new("CALLER", 0, 1, GasPriceTier::Base));
490 arr[CALLVALUE as usize] = Some(InstructionInfo::new("CALLVALUE", 0, 1, GasPriceTier::Base));
491 arr[CALLDATALOAD as usize] = Some(InstructionInfo::new("CALLDATALOAD", 1, 1, GasPriceTier::VeryLow));
492 arr[CALLDATASIZE as usize] = Some(InstructionInfo::new("CALLDATASIZE", 0, 1, GasPriceTier::Base));
493 arr[CALLDATACOPY as usize] = Some(InstructionInfo::new("CALLDATACOPY", 3, 0, GasPriceTier::VeryLow));
494 arr[EXTCODEHASH as usize] = Some(InstructionInfo::new("EXTCODEHASH", 1, 1, GasPriceTier::Special));
495 arr[CODESIZE as usize] = Some(InstructionInfo::new("CODESIZE", 0, 1, GasPriceTier::Base));
496 arr[CODECOPY as usize] = Some(InstructionInfo::new("CODECOPY", 3, 0, GasPriceTier::VeryLow));
497 arr[GASPRICE as usize] = Some(InstructionInfo::new("GASPRICE", 0, 1, GasPriceTier::Base));
498 arr[EXTCODESIZE as usize] = Some(InstructionInfo::new("EXTCODESIZE", 1, 1, GasPriceTier::Special));
499 arr[EXTCODECOPY as usize] = Some(InstructionInfo::new("EXTCODECOPY", 4, 0, GasPriceTier::Special));
500 arr[BLOCKHASH as usize] = Some(InstructionInfo::new("BLOCKHASH", 1, 1, GasPriceTier::Ext));
501 arr[COINBASE as usize] = Some(InstructionInfo::new("COINBASE", 0, 1, GasPriceTier::Base));
502 arr[TIMESTAMP as usize] = Some(InstructionInfo::new("TIMESTAMP", 0, 1, GasPriceTier::Base));
503 arr[NUMBER as usize] = Some(InstructionInfo::new("NUMBER", 0, 1, GasPriceTier::Base));
504 arr[DIFFICULTY as usize] = Some(InstructionInfo::new("DIFFICULTY", 0, 1, GasPriceTier::Base));
505 arr[GASLIMIT as usize] = Some(InstructionInfo::new("GASLIMIT", 0, 1, GasPriceTier::Base));
506 arr[CHAINID as usize] = Some(InstructionInfo::new("CHAINID", 0, 1, GasPriceTier::Base));
507 arr[SELFBALANCE as usize] = Some(InstructionInfo::new("SELFBALANCE", 0, 1, GasPriceTier::Low));
508 arr[POP as usize] = Some(InstructionInfo::new("POP", 1, 0, GasPriceTier::Base));
509 arr[MLOAD as usize] = Some(InstructionInfo::new("MLOAD", 1, 1, GasPriceTier::VeryLow));
510 arr[MSTORE as usize] = Some(InstructionInfo::new("MSTORE", 2, 0, GasPriceTier::VeryLow));
511 arr[MSTORE8 as usize] = Some(InstructionInfo::new("MSTORE8", 2, 0, GasPriceTier::VeryLow));
512 arr[SLOAD as usize] = Some(InstructionInfo::new("SLOAD", 1, 1, GasPriceTier::Special));
513 arr[SSTORE as usize] = Some(InstructionInfo::new("SSTORE", 2, 0, GasPriceTier::Special));
514 arr[JUMP as usize] = Some(InstructionInfo::new("JUMP", 1, 0, GasPriceTier::Mid));
515 arr[JUMPI as usize] = Some(InstructionInfo::new("JUMPI", 2, 0, GasPriceTier::High));
516 arr[PC as usize] = Some(InstructionInfo::new("PC", 0, 1, GasPriceTier::Base));
517 arr[MSIZE as usize] = Some(InstructionInfo::new("MSIZE", 0, 1, GasPriceTier::Base));
518 arr[GAS as usize] = Some(InstructionInfo::new("GAS", 0, 1, GasPriceTier::Base));
519 arr[JUMPDEST as usize] = Some(InstructionInfo::new("JUMPDEST", 0, 0, GasPriceTier::Special));
520 arr[PUSH1 as usize] = Some(InstructionInfo::new("PUSH1", 0, 1, GasPriceTier::VeryLow));
521 arr[PUSH2 as usize] = Some(InstructionInfo::new("PUSH2", 0, 1, GasPriceTier::VeryLow));
522 arr[PUSH3 as usize] = Some(InstructionInfo::new("PUSH3", 0, 1, GasPriceTier::VeryLow));
523 arr[PUSH4 as usize] = Some(InstructionInfo::new("PUSH4", 0, 1, GasPriceTier::VeryLow));
524 arr[PUSH5 as usize] = Some(InstructionInfo::new("PUSH5", 0, 1, GasPriceTier::VeryLow));
525 arr[PUSH6 as usize] = Some(InstructionInfo::new("PUSH6", 0, 1, GasPriceTier::VeryLow));
526 arr[PUSH7 as usize] = Some(InstructionInfo::new("PUSH7", 0, 1, GasPriceTier::VeryLow));
527 arr[PUSH8 as usize] = Some(InstructionInfo::new("PUSH8", 0, 1, GasPriceTier::VeryLow));
528 arr[PUSH9 as usize] = Some(InstructionInfo::new("PUSH9", 0, 1, GasPriceTier::VeryLow));
529 arr[PUSH10 as usize] = Some(InstructionInfo::new("PUSH10", 0, 1, GasPriceTier::VeryLow));
530 arr[PUSH11 as usize] = Some(InstructionInfo::new("PUSH11", 0, 1, GasPriceTier::VeryLow));
531 arr[PUSH12 as usize] = Some(InstructionInfo::new("PUSH12", 0, 1, GasPriceTier::VeryLow));
532 arr[PUSH13 as usize] = Some(InstructionInfo::new("PUSH13", 0, 1, GasPriceTier::VeryLow));
533 arr[PUSH14 as usize] = Some(InstructionInfo::new("PUSH14", 0, 1, GasPriceTier::VeryLow));
534 arr[PUSH15 as usize] = Some(InstructionInfo::new("PUSH15", 0, 1, GasPriceTier::VeryLow));
535 arr[PUSH16 as usize] = Some(InstructionInfo::new("PUSH16", 0, 1, GasPriceTier::VeryLow));
536 arr[PUSH17 as usize] = Some(InstructionInfo::new("PUSH17", 0, 1, GasPriceTier::VeryLow));
537 arr[PUSH18 as usize] = Some(InstructionInfo::new("PUSH18", 0, 1, GasPriceTier::VeryLow));
538 arr[PUSH19 as usize] = Some(InstructionInfo::new("PUSH19", 0, 1, GasPriceTier::VeryLow));
539 arr[PUSH20 as usize] = Some(InstructionInfo::new("PUSH20", 0, 1, GasPriceTier::VeryLow));
540 arr[PUSH21 as usize] = Some(InstructionInfo::new("PUSH21", 0, 1, GasPriceTier::VeryLow));
541 arr[PUSH22 as usize] = Some(InstructionInfo::new("PUSH22", 0, 1, GasPriceTier::VeryLow));
542 arr[PUSH23 as usize] = Some(InstructionInfo::new("PUSH23", 0, 1, GasPriceTier::VeryLow));
543 arr[PUSH24 as usize] = Some(InstructionInfo::new("PUSH24", 0, 1, GasPriceTier::VeryLow));
544 arr[PUSH25 as usize] = Some(InstructionInfo::new("PUSH25", 0, 1, GasPriceTier::VeryLow));
545 arr[PUSH26 as usize] = Some(InstructionInfo::new("PUSH26", 0, 1, GasPriceTier::VeryLow));
546 arr[PUSH27 as usize] = Some(InstructionInfo::new("PUSH27", 0, 1, GasPriceTier::VeryLow));
547 arr[PUSH28 as usize] = Some(InstructionInfo::new("PUSH28", 0, 1, GasPriceTier::VeryLow));
548 arr[PUSH29 as usize] = Some(InstructionInfo::new("PUSH29", 0, 1, GasPriceTier::VeryLow));
549 arr[PUSH30 as usize] = Some(InstructionInfo::new("PUSH30", 0, 1, GasPriceTier::VeryLow));
550 arr[PUSH31 as usize] = Some(InstructionInfo::new("PUSH31", 0, 1, GasPriceTier::VeryLow));
551 arr[PUSH32 as usize] = Some(InstructionInfo::new("PUSH32", 0, 1, GasPriceTier::VeryLow));
552 arr[DUP1 as usize] = Some(InstructionInfo::new("DUP1", 1, 2, GasPriceTier::VeryLow));
553 arr[DUP2 as usize] = Some(InstructionInfo::new("DUP2", 2, 3, GasPriceTier::VeryLow));
554 arr[DUP3 as usize] = Some(InstructionInfo::new("DUP3", 3, 4, GasPriceTier::VeryLow));
555 arr[DUP4 as usize] = Some(InstructionInfo::new("DUP4", 4, 5, GasPriceTier::VeryLow));
556 arr[DUP5 as usize] = Some(InstructionInfo::new("DUP5", 5, 6, GasPriceTier::VeryLow));
557 arr[DUP6 as usize] = Some(InstructionInfo::new("DUP6", 6, 7, GasPriceTier::VeryLow));
558 arr[DUP7 as usize] = Some(InstructionInfo::new("DUP7", 7, 8, GasPriceTier::VeryLow));
559 arr[DUP8 as usize] = Some(InstructionInfo::new("DUP8", 8, 9, GasPriceTier::VeryLow));
560 arr[DUP9 as usize] = Some(InstructionInfo::new("DUP9", 9, 10, GasPriceTier::VeryLow));
561 arr[DUP10 as usize] = Some(InstructionInfo::new("DUP10", 10, 11, GasPriceTier::VeryLow));
562 arr[DUP11 as usize] = Some(InstructionInfo::new("DUP11", 11, 12, GasPriceTier::VeryLow));
563 arr[DUP12 as usize] = Some(InstructionInfo::new("DUP12", 12, 13, GasPriceTier::VeryLow));
564 arr[DUP13 as usize] = Some(InstructionInfo::new("DUP13", 13, 14, GasPriceTier::VeryLow));
565 arr[DUP14 as usize] = Some(InstructionInfo::new("DUP14", 14, 15, GasPriceTier::VeryLow));
566 arr[DUP15 as usize] = Some(InstructionInfo::new("DUP15", 15, 16, GasPriceTier::VeryLow));
567 arr[DUP16 as usize] = Some(InstructionInfo::new("DUP16", 16, 17, GasPriceTier::VeryLow));
568 arr[SWAP1 as usize] = Some(InstructionInfo::new("SWAP1", 2, 2, GasPriceTier::VeryLow));
569 arr[SWAP2 as usize] = Some(InstructionInfo::new("SWAP2", 3, 3, GasPriceTier::VeryLow));
570 arr[SWAP3 as usize] = Some(InstructionInfo::new("SWAP3", 4, 4, GasPriceTier::VeryLow));
571 arr[SWAP4 as usize] = Some(InstructionInfo::new("SWAP4", 5, 5, GasPriceTier::VeryLow));
572 arr[SWAP5 as usize] = Some(InstructionInfo::new("SWAP5", 6, 6, GasPriceTier::VeryLow));
573 arr[SWAP6 as usize] = Some(InstructionInfo::new("SWAP6", 7, 7, GasPriceTier::VeryLow));
574 arr[SWAP7 as usize] = Some(InstructionInfo::new("SWAP7", 8, 8, GasPriceTier::VeryLow));
575 arr[SWAP8 as usize] = Some(InstructionInfo::new("SWAP8", 9, 9, GasPriceTier::VeryLow));
576 arr[SWAP9 as usize] = Some(InstructionInfo::new("SWAP9", 10, 10, GasPriceTier::VeryLow));
577 arr[SWAP10 as usize] = Some(InstructionInfo::new("SWAP10", 11, 11, GasPriceTier::VeryLow));
578 arr[SWAP11 as usize] = Some(InstructionInfo::new("SWAP11", 12, 12, GasPriceTier::VeryLow));
579 arr[SWAP12 as usize] = Some(InstructionInfo::new("SWAP12", 13, 13, GasPriceTier::VeryLow));
580 arr[SWAP13 as usize] = Some(InstructionInfo::new("SWAP13", 14, 14, GasPriceTier::VeryLow));
581 arr[SWAP14 as usize] = Some(InstructionInfo::new("SWAP14", 15, 15, GasPriceTier::VeryLow));
582 arr[SWAP15 as usize] = Some(InstructionInfo::new("SWAP15", 16, 16, GasPriceTier::VeryLow));
583 arr[SWAP16 as usize] = Some(InstructionInfo::new("SWAP16", 17, 17, GasPriceTier::VeryLow));
584 arr[LOG0 as usize] = Some(InstructionInfo::new("LOG0", 2, 0, GasPriceTier::Special));
585 arr[LOG1 as usize] = Some(InstructionInfo::new("LOG1", 3, 0, GasPriceTier::Special));
586 arr[LOG2 as usize] = Some(InstructionInfo::new("LOG2", 4, 0, GasPriceTier::Special));
587 arr[LOG3 as usize] = Some(InstructionInfo::new("LOG3", 5, 0, GasPriceTier::Special));
588 arr[LOG4 as usize] = Some(InstructionInfo::new("LOG4", 6, 0, GasPriceTier::Special));
589 arr[CREATE as usize] = Some(InstructionInfo::new("CREATE", 3, 1, GasPriceTier::Special));
590 arr[CALL as usize] = Some(InstructionInfo::new("CALL", 7, 1, GasPriceTier::Special));
591 arr[CALLCODE as usize] = Some(InstructionInfo::new("CALLCODE", 7, 1, GasPriceTier::Special));
592 arr[RETURN as usize] = Some(InstructionInfo::new("RETURN", 2, 0, GasPriceTier::Zero));
593 arr[DELEGATECALL as usize] = Some(InstructionInfo::new("DELEGATECALL", 6, 1, GasPriceTier::Special));
594 arr[STATICCALL as usize] = Some(InstructionInfo::new("STATICCALL", 6, 1, GasPriceTier::Special));
595 arr[SUICIDE as usize] = Some(InstructionInfo::new("SUICIDE", 1, 0, GasPriceTier::Special));
596 arr[CREATE2 as usize] = Some(InstructionInfo::new("CREATE2", 4, 1, GasPriceTier::Special));
597 arr[REVERT as usize] = Some(InstructionInfo::new("REVERT", 2, 0, GasPriceTier::Zero));
598 arr
599 };
600}
601
602pub const MAX_NO_OF_TOPICS: usize = 4;
604
605#[cfg(test)]
606mod tests {
607 use super::*;
608
609 #[test]
610 fn test_is_push() {
611 assert!(PUSH1.is_push());
612 assert!(PUSH32.is_push());
613 assert!(!DUP1.is_push());
614 }
615
616 #[test]
617 fn test_get_push_bytes() {
618 assert_eq!(PUSH1.push_bytes(), Some(1));
619 assert_eq!(PUSH3.push_bytes(), Some(3));
620 assert_eq!(PUSH32.push_bytes(), Some(32));
621 }
622
623 #[test]
624 fn test_get_dup_position() {
625 assert_eq!(DUP1.dup_position(), Some(0));
626 assert_eq!(DUP5.dup_position(), Some(4));
627 assert_eq!(DUP10.dup_position(), Some(9));
628 }
629
630 #[test]
631 fn test_get_swap_position() {
632 assert_eq!(SWAP1.swap_position(), Some(1));
633 assert_eq!(SWAP5.swap_position(), Some(5));
634 assert_eq!(SWAP10.swap_position(), Some(10));
635 }
636
637 #[test]
638 fn test_get_log_topics() {
639 assert_eq!(LOG0.log_topics(), Some(0));
640 assert_eq!(LOG2.log_topics(), Some(2));
641 assert_eq!(LOG4.log_topics(), Some(4));
642 }
643}