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}