huff_utils/
evm.rs

1use phf::phf_map;
2use std::fmt;
3use strum_macros::EnumString;
4
5/// All the EVM opcodes as a static array
6/// They are arranged in a particular order such that all the opcodes that have common
7/// prefixes are ordered by decreasing length to avoid mismatch when lexing.
8/// Example : [origin, or] or [push32, ..., push3]
9pub const OPCODES: [&str; 142] = [
10    "lt",
11    "gt",
12    "slt",
13    "sgt",
14    "eq",
15    "iszero",
16    "and",
17    "origin",
18    "or",
19    "xor",
20    "not",
21    "sha3",
22    "address",
23    "balance",
24    "caller",
25    "callvalue",
26    "calldataload",
27    "calldatasize",
28    "calldatacopy",
29    "codesize",
30    "codecopy",
31    "blockhash",
32    "coinbase",
33    "timestamp",
34    "number",
35    "difficulty",
36    "gaslimit",
37    "chainid",
38    "selfbalance",
39    "pop",
40    "mload",
41    "mstore8",
42    "mstore",
43    "sload",
44    "sstore",
45    "jumpdest",
46    "jumpi",
47    "jump",
48    "pc",
49    "msize",
50    "stop",
51    "addmod",
52    "add",
53    "mulmod",
54    "mul",
55    "sub",
56    "div",
57    "sdiv",
58    "mod",
59    "smod",
60    "exp",
61    "signextend",
62    "byte",
63    "shl",
64    "shr",
65    "sar",
66    "gasprice",
67    "extcodesize",
68    "extcodecopy",
69    "returndatasize",
70    "returndatacopy",
71    "extcodehash",
72    "gas",
73    "log0",
74    "log1",
75    "log2",
76    "log3",
77    "log4",
78    "create2",
79    "create",
80    "callcode",
81    "call",
82    "return",
83    "delegatecall",
84    "staticcall",
85    "revert",
86    "invalid",
87    "selfdestruct",
88    "push32",
89    "push31",
90    "push30",
91    "push29",
92    "push28",
93    "push27",
94    "push26",
95    "push25",
96    "push24",
97    "push23",
98    "push22",
99    "push21",
100    "push20",
101    "push19",
102    "push18",
103    "push17",
104    "push16",
105    "push15",
106    "push14",
107    "push13",
108    "push12",
109    "push11",
110    "push10",
111    "push9",
112    "push8",
113    "push7",
114    "push6",
115    "push5",
116    "push4",
117    "push3",
118    "push2",
119    "push1",
120    "swap16",
121    "swap15",
122    "swap14",
123    "swap13",
124    "swap12",
125    "swap11",
126    "swap10",
127    "swap9",
128    "swap8",
129    "swap7",
130    "swap6",
131    "swap5",
132    "swap4",
133    "swap3",
134    "swap2",
135    "swap1",
136    "dup16",
137    "dup15",
138    "dup14",
139    "dup13",
140    "dup12",
141    "dup11",
142    "dup10",
143    "dup9",
144    "dup8",
145    "dup7",
146    "dup6",
147    "dup5",
148    "dup4",
149    "dup3",
150    "dup2",
151    "dup1",
152];
153
154/// Hashmap of all the EVM opcodes
155pub static OPCODES_MAP: phf::Map<&'static str, Opcode> = phf_map! {
156    "lt" => Opcode::Lt,
157    "gt" => Opcode::Gt,
158    "slt" => Opcode::Slt,
159    "sgt" => Opcode::Sgt,
160    "eq" => Opcode::Eq,
161    "iszero" => Opcode::Iszero,
162    "and" => Opcode::And,
163    "or" => Opcode::Or,
164    "xor" => Opcode::Xor,
165    "not" => Opcode::Not,
166    "sha3" => Opcode::Sha3,
167    "address" => Opcode::Address,
168    "balance" => Opcode::Balance,
169    "origin" => Opcode::Origin,
170    "caller" => Opcode::Caller,
171    "callvalue" => Opcode::Callvalue,
172    "calldataload" => Opcode::Calldataload,
173    "calldatasize" => Opcode::Calldatasize,
174    "calldatacopy" => Opcode::Calldatacopy,
175    "codesize" => Opcode::Codesize,
176    "codecopy" => Opcode::Codecopy,
177    "blockhash" => Opcode::Blockhash,
178    "coinbase" => Opcode::Coinbase,
179    "timestamp" => Opcode::Timestamp,
180    "number" => Opcode::Number,
181    "difficulty" => Opcode::Difficulty,
182    "gaslimit" => Opcode::Gaslimit,
183    "chainid" => Opcode::Chainid,
184    "selfbalance" => Opcode::Selfbalance,
185    "pop" => Opcode::Pop,
186    "mload" => Opcode::Mload,
187    "mstore" => Opcode::Mstore,
188    "mstore8" => Opcode::Mstore8,
189    "sload" => Opcode::Sload,
190    "sstore" => Opcode::Sstore,
191    "jump" => Opcode::Jump,
192    "jumpi" => Opcode::Jumpi,
193    "pc" => Opcode::Pc,
194    "msize" => Opcode::Msize,
195    "push1" => Opcode::Push1,
196    "push2" => Opcode::Push2,
197    "push3" => Opcode::Push3,
198    "push4" => Opcode::Push4,
199    "push5" => Opcode::Push5,
200    "push6" => Opcode::Push6,
201    "push7" => Opcode::Push7,
202    "push8" => Opcode::Push8,
203    "push9" => Opcode::Push9,
204    "push10" => Opcode::Push10,
205    "push17" => Opcode::Push17,
206    "push18" => Opcode::Push18,
207    "push19" => Opcode::Push19,
208    "push20" => Opcode::Push20,
209    "push21" => Opcode::Push21,
210    "push22" => Opcode::Push22,
211    "push23" => Opcode::Push23,
212    "push24" => Opcode::Push24,
213    "push25" => Opcode::Push25,
214    "push26" => Opcode::Push26,
215    "dup1" => Opcode::Dup1,
216    "dup2" => Opcode::Dup2,
217    "dup3" => Opcode::Dup3,
218    "dup4" => Opcode::Dup4,
219    "dup5" => Opcode::Dup5,
220    "dup6" => Opcode::Dup6,
221    "dup7" => Opcode::Dup7,
222    "dup8" => Opcode::Dup8,
223    "dup9" => Opcode::Dup9,
224    "dup10" => Opcode::Dup10,
225    "swap1" => Opcode::Swap1,
226    "swap2" => Opcode::Swap2,
227    "swap3" => Opcode::Swap3,
228    "swap4" => Opcode::Swap4,
229    "swap5" => Opcode::Swap5,
230    "swap6" => Opcode::Swap6,
231    "swap7" => Opcode::Swap7,
232    "swap8" => Opcode::Swap8,
233    "swap9" => Opcode::Swap9,
234    "swap10" => Opcode::Swap10,
235    "stop" => Opcode::Stop,
236    "add" => Opcode::Add,
237    "mul" => Opcode::Mul,
238    "sub" => Opcode::Sub,
239    "div" => Opcode::Div,
240    "sdiv" => Opcode::Sdiv,
241    "mod" => Opcode::Mod,
242    "smod" => Opcode::Smod,
243    "addmod" => Opcode::Addmod,
244    "mulmod" => Opcode::Mulmod,
245    "exp" => Opcode::Exp,
246    "signextend" => Opcode::Signextend,
247    "byte" => Opcode::Byte,
248    "shl" => Opcode::Shl,
249    "shr" => Opcode::Shr,
250    "sar" => Opcode::Sar,
251    "gasprice" => Opcode::Gasprice,
252    "extcodesize" => Opcode::Extcodesize,
253    "extcodecopy" => Opcode::Extcodecopy,
254    "returndatasize" => Opcode::Returndatasize,
255    "returndatacopy" => Opcode::Returndatacopy,
256    "extcodehash" => Opcode::Extcodehash,
257    "gas" => Opcode::Gas,
258    "jumpdest" => Opcode::Jumpdest,
259    "push11" => Opcode::Push11,
260    "push12" => Opcode::Push12,
261    "push13" => Opcode::Push13,
262    "push14" => Opcode::Push14,
263    "push15" => Opcode::Push15,
264    "push16" => Opcode::Push16,
265    "push27" => Opcode::Push27,
266    "push28" => Opcode::Push28,
267    "push29" => Opcode::Push29,
268    "push30" => Opcode::Push30,
269    "push31" => Opcode::Push31,
270    "push32" => Opcode::Push32,
271    "dup11" => Opcode::Dup11,
272    "dup12" => Opcode::Dup12,
273    "dup13" => Opcode::Dup13,
274    "dup14" => Opcode::Dup14,
275    "dup15" => Opcode::Dup15,
276    "dup16" => Opcode::Dup16,
277    "swap11" => Opcode::Swap11,
278    "swap12" => Opcode::Swap12,
279    "swap13" => Opcode::Swap13,
280    "swap14" => Opcode::Swap14,
281    "swap15" => Opcode::Swap15,
282    "swap16" => Opcode::Swap16,
283    "log0" => Opcode::Log0,
284    "log1" => Opcode::Log1,
285    "log2" => Opcode::Log2,
286    "log3" => Opcode::Log3,
287    "log4" => Opcode::Log4,
288    "create" => Opcode::Create,
289    "call" => Opcode::Call,
290    "callcode" => Opcode::Callcode,
291    "return" => Opcode::Return,
292    "delegatecall" => Opcode::Delegatecall,
293    "staticcall" => Opcode::Staticcall,
294    "create2" => Opcode::Create2,
295    "revert" => Opcode::Revert,
296    "invalid" => Opcode::Invalid,
297    "selfdestruct" => Opcode::Selfdestruct
298};
299
300/// EVM Opcodes
301/// References <https://evm.codes>
302#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, EnumString)]
303pub enum Opcode {
304    /// Halts execution.
305    #[strum(serialize = "stop")]
306    Stop,
307    /// Addition operation
308    #[strum(serialize = "add")]
309    Add,
310    /// Multiplication Operation
311    #[strum(serialize = "mul")]
312    Mul,
313    /// Subtraction Operation
314    Sub,
315    /// Integer Division Operation
316    Div,
317    /// Signed Integer Division Operation
318    Sdiv,
319    /// Modulo Remainder Operation
320    Mod,
321    /// Signed Modulo Remainder Operation
322    Smod,
323    /// Modulo Addition Operation
324    Addmod,
325    /// Modulo Multiplication Operation
326    Mulmod,
327    /// Exponential Operation
328    Exp,
329    /// Extend Length of Two's Complement Signed Integer
330    Signextend,
331    /// Less-than Comparison
332    Lt,
333    /// Greater-than Comparison
334    Gt,
335    /// Signed Less-than Comparison
336    Slt,
337    /// Signed Greater-than Comparison
338    Sgt,
339    /// Equality Comparison
340    Eq,
341    /// Not Operation
342    Iszero,
343    /// Bitwise AND Operation
344    And,
345    /// Bitwise OR Operation
346    Or,
347    /// Bitwise XOR Operation
348    Xor,
349    /// Bitwise NOT Operation
350    Not,
351    /// Retrieve Single Byte from Word
352    Byte,
353    /// Left Shift Operation
354    Shl,
355    /// Right Shift Operation
356    Shr,
357    /// Arithmetic Shift Right Operation
358    Sar,
359    /// Compute the Keccak-256 hash of a 32-byte word
360    Sha3,
361    /// Address of currently executing account
362    Address,
363    /// Balance of a given account
364    Balance,
365    /// Address of execution origination
366    Origin,
367    /// Address of the caller
368    Caller,
369    /// Value of the call
370    Callvalue,
371    /// Loads Calldata
372    Calldataload,
373    /// Size of the Calldata
374    Calldatasize,
375    /// Copies the Calldata to Memory
376    Calldatacopy,
377    /// Size of the Executing Code
378    Codesize,
379    /// Copies Executing Code to Memory
380    Codecopy,
381    /// Current Price of Gas
382    Gasprice,
383    /// Size of an Account's Code
384    Extcodesize,
385    /// Copies an Account's Code to Memory
386    Extcodecopy,
387    /// Size of Output Data from Previous Call
388    Returndatasize,
389    /// Copies Output Data from Previous Call to Memory
390    Returndatacopy,
391    /// Hash of a Block from the most recent 256 blocks
392    Blockhash,
393    /// The Current Blocks Beneficiary Address
394    Coinbase,
395    /// The Current Blocks Timestamp
396    Timestamp,
397    /// The Current Blocks Number
398    Number,
399    /// The Current Blocks Difficulty
400    Difficulty,
401    /// The Current Blocks Gas Limit
402    Gaslimit,
403    /// The Chain ID
404    Chainid,
405    /// Balance of the Currently Executing Account
406    Selfbalance,
407    /// Base Fee
408    Basefee,
409    /// Removes an Item from the Stack
410    Pop,
411    /// Loads a word from Memory
412    Mload,
413    /// Stores a word in Memory
414    Mstore,
415    /// Stores a byte in Memory
416    Mstore8,
417    /// Load a word from Storage
418    Sload,
419    /// Store a word in Storage
420    Sstore,
421    /// Alter the Program Counter
422    Jump,
423    /// Conditionally Alter the Program Counter
424    Jumpi,
425    /// Value of the Program Counter Before the Current Instruction
426    Pc,
427    /// Size of Active Memory in Bytes
428    Msize,
429    /// Amount of available gas including the cost of the current instruction
430    Gas,
431    /// Marks a valid destination for jumps
432    Jumpdest,
433    /// Places 1 byte item on top of the stack
434    Push1,
435    /// Places 2 byte item on top of the stack
436    Push2,
437    /// Places 3 byte item on top of the stack
438    Push3,
439    /// Places 4 byte item on top of the stack
440    Push4,
441    /// Places 5 byte item on top of the stack
442    Push5,
443    /// Places 6 byte item on top of the stack
444    Push6,
445    /// Places 7 byte item on top of the stack
446    Push7,
447    /// Places 8 byte item on top of the stack
448    Push8,
449    /// Places 9 byte item on top of the stack
450    Push9,
451    /// Places 10 byte item on top of the stack
452    Push10,
453    /// Places 11 byte item on top of the stack
454    Push11,
455    /// Places 12 byte item on top of the stack
456    Push12,
457    /// Places 13 byte item on top of the stack
458    Push13,
459    /// Places 14 byte item on top of the stack
460    Push14,
461    /// Places 15 byte item on top of the stack
462    Push15,
463    /// Places 16 byte item on top of the stack
464    Push16,
465    /// Places 17 byte item on top of the stack
466    Push17,
467    /// Places 18 byte item on top of the stack
468    Push18,
469    /// Places 19 byte item on top of the stack
470    Push19,
471    /// Places 20 byte item on top of the stack
472    Push20,
473    /// Places 21 byte item on top of the stack
474    Push21,
475    /// Places 22 byte item on top of the stack
476    Push22,
477    /// Places 23 byte item on top of the stack
478    Push23,
479    /// Places 24 byte item on top of the stack
480    Push24,
481    /// Places 25 byte item on top of the stack
482    Push25,
483    /// Places 26 byte item on top of the stack
484    Push26,
485    /// Places 27 byte item on top of the stack
486    Push27,
487    /// Places 28 byte item on top of the stack
488    Push28,
489    /// Places 29 byte item on top of the stack
490    Push29,
491    /// Places 30 byte item on top of the stack
492    Push30,
493    /// Places 31 byte item on top of the stack
494    Push31,
495    /// Places 32 byte item on top of the stack
496    Push32,
497    /// Duplicates the first stack item
498    Dup1,
499    /// Duplicates the 2nd stack item
500    Dup2,
501    /// Duplicates the 3rd stack item
502    Dup3,
503    /// Duplicates the 4th stack item
504    Dup4,
505    /// Duplicates the 5th stack item
506    Dup5,
507    /// Duplicates the 6th stack item
508    Dup6,
509    /// Duplicates the 7th stack item
510    Dup7,
511    /// Duplicates the 8th stack item
512    Dup8,
513    /// Duplicates the 9th stack item
514    Dup9,
515    /// Duplicates the 10th stack item
516    Dup10,
517    /// Duplicates the 11th stack item
518    Dup11,
519    /// Duplicates the 12th stack item
520    Dup12,
521    /// Duplicates the 13th stack item
522    Dup13,
523    /// Duplicates the 14th stack item
524    Dup14,
525    /// Duplicates the 15th stack item
526    Dup15,
527    /// Duplicates the 16th stack item
528    Dup16,
529    /// Exchange the top two stack items
530    Swap1,
531    /// Exchange the first and third stack items
532    Swap2,
533    /// Exchange the first and fourth stack items
534    Swap3,
535    /// Exchange the first and fifth stack items
536    Swap4,
537    /// Exchange the first and sixth stack items
538    Swap5,
539    /// Exchange the first and seventh stack items
540    Swap6,
541    /// Exchange the first and eighth stack items
542    Swap7,
543    /// Exchange the first and ninth stack items
544    Swap8,
545    /// Exchange the first and tenth stack items
546    Swap9,
547    /// Exchange the first and eleventh stack items
548    Swap10,
549    /// Exchange the first and twelfth stack items
550    Swap11,
551    /// Exchange the first and thirteenth stack items
552    Swap12,
553    /// Exchange the first and fourteenth stack items
554    Swap13,
555    /// Exchange the first and fifteenth stack items
556    Swap14,
557    /// Exchange the first and sixteenth stack items
558    Swap15,
559    /// Exchange the first and seventeenth stack items
560    Swap16,
561    /// Append Log Record with no Topics
562    Log0,
563    /// Append Log Record with 1 Topic
564    Log1,
565    /// Append Log Record with 2 Topics
566    Log2,
567    /// Append Log Record with 3 Topics
568    Log3,
569    /// Append Log Record with 4 Topics
570    Log4,
571    /// Create a new account with associated code
572    Create,
573    /// Message-call into an account
574    Call,
575    /// Message-call into this account with an alternative accounts code
576    Callcode,
577    /// Halt execution, returning output data
578    Return,
579    /// Message-call into this account with an alternative accounts code, persisting the sender and
580    /// value
581    Delegatecall,
582    /// Create a new account with associated code
583    Create2,
584    /// Static Message-call into an account
585    Staticcall,
586    /// Halt execution, reverting state changes, but returning data and remaining gas
587    Revert,
588    /// Invalid Instruction
589    Invalid,
590    /// Halt Execution and Register Account for later deletion
591    Selfdestruct,
592    /// Get hash of an account’s code
593    Extcodehash,
594}
595
596impl Opcode {
597    /// Translates an Opcode into a string
598    pub fn string(&self) -> String {
599        let opcode_str = match self {
600            Opcode::Stop => "00",
601            Opcode::Add => "01",
602            Opcode::Mul => "02",
603            Opcode::Sub => "03",
604            Opcode::Div => "04",
605            Opcode::Sdiv => "05",
606            Opcode::Mod => "06",
607            Opcode::Smod => "07",
608            Opcode::Addmod => "08",
609            Opcode::Mulmod => "09",
610            Opcode::Exp => "0a",
611            Opcode::Signextend => "0b",
612            Opcode::Lt => "10",
613            Opcode::Gt => "11",
614            Opcode::Slt => "12",
615            Opcode::Sgt => "13",
616            Opcode::Eq => "14",
617            Opcode::Iszero => "15",
618            Opcode::And => "16",
619            Opcode::Or => "17",
620            Opcode::Xor => "18",
621            Opcode::Not => "19",
622            Opcode::Byte => "1a",
623            Opcode::Shl => "1b",
624            Opcode::Shr => "1c",
625            Opcode::Sar => "1d",
626            Opcode::Sha3 => "20",
627            // Opcode::Keccak => "20",
628            Opcode::Address => "30",
629            Opcode::Balance => "31",
630            Opcode::Origin => "32",
631            Opcode::Caller => "33",
632            Opcode::Callvalue => "34",
633            Opcode::Calldataload => "35",
634            Opcode::Calldatasize => "36",
635            Opcode::Calldatacopy => "37",
636            Opcode::Codesize => "38",
637            Opcode::Codecopy => "39",
638            Opcode::Gasprice => "3a",
639            Opcode::Extcodesize => "3b",
640            Opcode::Extcodecopy => "3c",
641            Opcode::Returndatasize => "3d",
642            Opcode::Returndatacopy => "3e",
643            Opcode::Extcodehash => "3f",
644            Opcode::Blockhash => "40",
645            Opcode::Coinbase => "41",
646            Opcode::Timestamp => "42",
647            Opcode::Number => "43",
648            Opcode::Difficulty => "44",
649            Opcode::Gaslimit => "45",
650            Opcode::Chainid => "46",
651            Opcode::Selfbalance => "47",
652            Opcode::Basefee => "48",
653            Opcode::Pop => "50",
654            Opcode::Mload => "51",
655            Opcode::Mstore => "52",
656            Opcode::Mstore8 => "53",
657            Opcode::Sload => "54",
658            Opcode::Sstore => "55",
659            Opcode::Jump => "56",
660            Opcode::Jumpi => "57",
661            Opcode::Pc => "58",
662            Opcode::Msize => "59",
663            Opcode::Gas => "5a",
664            Opcode::Jumpdest => "5b",
665            Opcode::Push1 => "60",
666            Opcode::Push2 => "61",
667            Opcode::Push3 => "62",
668            Opcode::Push4 => "63",
669            Opcode::Push5 => "64",
670            Opcode::Push6 => "65",
671            Opcode::Push7 => "66",
672            Opcode::Push8 => "67",
673            Opcode::Push9 => "68",
674            Opcode::Push10 => "69",
675            Opcode::Push11 => "6a",
676            Opcode::Push12 => "6b",
677            Opcode::Push13 => "6c",
678            Opcode::Push14 => "6d",
679            Opcode::Push15 => "6e",
680            Opcode::Push16 => "6f",
681            Opcode::Push17 => "70",
682            Opcode::Push18 => "71",
683            Opcode::Push19 => "72",
684            Opcode::Push20 => "73",
685            Opcode::Push21 => "74",
686            Opcode::Push22 => "75",
687            Opcode::Push23 => "76",
688            Opcode::Push24 => "77",
689            Opcode::Push25 => "78",
690            Opcode::Push26 => "79",
691            Opcode::Push27 => "7a",
692            Opcode::Push28 => "7b",
693            Opcode::Push29 => "7c",
694            Opcode::Push30 => "7d",
695            Opcode::Push31 => "7e",
696            Opcode::Push32 => "7f",
697            Opcode::Dup1 => "80",
698            Opcode::Dup2 => "81",
699            Opcode::Dup3 => "82",
700            Opcode::Dup4 => "83",
701            Opcode::Dup5 => "84",
702            Opcode::Dup6 => "85",
703            Opcode::Dup7 => "86",
704            Opcode::Dup8 => "87",
705            Opcode::Dup9 => "88",
706            Opcode::Dup10 => "89",
707            Opcode::Dup11 => "8a",
708            Opcode::Dup12 => "8b",
709            Opcode::Dup13 => "8c",
710            Opcode::Dup14 => "8d",
711            Opcode::Dup15 => "8e",
712            Opcode::Dup16 => "8f",
713            Opcode::Swap1 => "90",
714            Opcode::Swap2 => "91",
715            Opcode::Swap3 => "92",
716            Opcode::Swap4 => "93",
717            Opcode::Swap5 => "94",
718            Opcode::Swap6 => "95",
719            Opcode::Swap7 => "96",
720            Opcode::Swap8 => "97",
721            Opcode::Swap9 => "98",
722            Opcode::Swap10 => "99",
723            Opcode::Swap11 => "9a",
724            Opcode::Swap12 => "9b",
725            Opcode::Swap13 => "9c",
726            Opcode::Swap14 => "9d",
727            Opcode::Swap15 => "9e",
728            Opcode::Swap16 => "9f",
729            Opcode::Log0 => "a0",
730            Opcode::Log1 => "a1",
731            Opcode::Log2 => "a2",
732            Opcode::Log3 => "a3",
733            Opcode::Log4 => "a4",
734            Opcode::Create => "f0",
735            Opcode::Call => "f1",
736            Opcode::Callcode => "f2",
737            Opcode::Return => "f3",
738            Opcode::Delegatecall => "f4",
739            Opcode::Create2 => "f5",
740            Opcode::Staticcall => "fa",
741            Opcode::Revert => "fd",
742            Opcode::Invalid => "fe",
743            Opcode::Selfdestruct => "ff",
744        };
745        opcode_str.to_string()
746    }
747}
748
749impl fmt::Display for Opcode {
750    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
751        let opcode_str = self.string();
752        write!(f, "{}", opcode_str)
753    }
754}
755
756impl From<Opcode> for String {
757    fn from(o: Opcode) -> Self {
758        o.string()
759    }
760}