aurora_evm/core/
opcode.rs

1use core::fmt::{Display, Formatter};
2
3/// Opcode enum. One-to-one corresponding to an `u8` value.
4#[derive(Clone, Copy, Debug, Eq, PartialEq)]
5#[cfg_attr(
6    feature = "with-codec",
7    derive(scale_codec::Encode, scale_codec::Decode, scale_info::TypeInfo)
8)]
9#[cfg_attr(feature = "with-serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct Opcode(pub u8);
11
12// Core opcodes.
13#[allow(clippy::use_self)]
14impl Opcode {
15    /// `STOP`
16    pub const STOP: Opcode = Opcode(0x00);
17    /// `ADD`
18    pub const ADD: Opcode = Opcode(0x01);
19    /// `MUL`
20    pub const MUL: Opcode = Opcode(0x02);
21    /// `SUB`
22    pub const SUB: Opcode = Opcode(0x03);
23    /// `DIV`
24    pub const DIV: Opcode = Opcode(0x04);
25    /// `SDIV`
26    pub const SDIV: Opcode = Opcode(0x05);
27    /// `MOD`
28    pub const MOD: Opcode = Opcode(0x06);
29    /// `SMOD`
30    pub const SMOD: Opcode = Opcode(0x07);
31    /// `ADDMOD`
32    pub const ADDMOD: Opcode = Opcode(0x08);
33    /// `MULMOD`
34    pub const MULMOD: Opcode = Opcode(0x09);
35    /// `EXP`
36    pub const EXP: Opcode = Opcode(0x0a);
37    /// `SIGNEXTEND`
38    pub const SIGNEXTEND: Opcode = Opcode(0x0b);
39
40    /// `LT`
41    pub const LT: Opcode = Opcode(0x10);
42    /// `GT`
43    pub const GT: Opcode = Opcode(0x11);
44    /// `SLT`
45    pub const SLT: Opcode = Opcode(0x12);
46    /// `SGT`
47    pub const SGT: Opcode = Opcode(0x13);
48    /// `EQ`
49    pub const EQ: Opcode = Opcode(0x14);
50    /// `ISZERO`
51    pub const ISZERO: Opcode = Opcode(0x15);
52    /// `AND`
53    pub const AND: Opcode = Opcode(0x16);
54    /// `OR`
55    pub const OR: Opcode = Opcode(0x17);
56    /// `XOR`
57    pub const XOR: Opcode = Opcode(0x18);
58    /// `NOT`
59    pub const NOT: Opcode = Opcode(0x19);
60    /// `BYTE`
61    pub const BYTE: Opcode = Opcode(0x1a);
62    /// `SHL`
63    pub const SHL: Opcode = Opcode(0x1b);
64    /// `SHR`
65    pub const SHR: Opcode = Opcode(0x1c);
66    /// `SAR`
67    pub const SAR: Opcode = Opcode(0x1d);
68
69    /// `SHA3`
70    pub const SHA3: Opcode = Opcode(0x20);
71
72    /// `ADDRESS`
73    pub const ADDRESS: Opcode = Opcode(0x30);
74    /// `BALANCE`
75    pub const BALANCE: Opcode = Opcode(0x31);
76    /// `ORIGIN`
77    pub const ORIGIN: Opcode = Opcode(0x32);
78    /// `CALLER`
79    pub const CALLER: Opcode = Opcode(0x33);
80    /// `CALLVALUE`
81    pub const CALLVALUE: Opcode = Opcode(0x34);
82    /// `CALLDATALOAD`
83    pub const CALLDATALOAD: Opcode = Opcode(0x35);
84    /// `CALLDATASIZE`
85    pub const CALLDATASIZE: Opcode = Opcode(0x36);
86    /// `CALLDATACOPY`
87    pub const CALLDATACOPY: Opcode = Opcode(0x37);
88    /// `CODESIZE`
89    pub const CODESIZE: Opcode = Opcode(0x38);
90    /// `CODECOPY`
91    pub const CODECOPY: Opcode = Opcode(0x39);
92
93    /// `GASPRICE`
94    pub const GASPRICE: Opcode = Opcode(0x3a);
95    /// `EXTCODESIZE`
96    pub const EXTCODESIZE: Opcode = Opcode(0x3b);
97    /// `EXTCODECOPY`
98    pub const EXTCODECOPY: Opcode = Opcode(0x3c);
99    /// `RETURNDATASIZE`
100    pub const RETURNDATASIZE: Opcode = Opcode(0x3d);
101    /// `RETURNDATACOPY`
102    pub const RETURNDATACOPY: Opcode = Opcode(0x3e);
103    /// `EXTCODEHASH`
104    pub const EXTCODEHASH: Opcode = Opcode(0x3f);
105    /// `BLOCKHASH`
106    pub const BLOCKHASH: Opcode = Opcode(0x40);
107    /// `COINBASE`
108    pub const COINBASE: Opcode = Opcode(0x41);
109    /// `TIMESTAMP`
110    pub const TIMESTAMP: Opcode = Opcode(0x42);
111    /// `NUMBER`
112    pub const NUMBER: Opcode = Opcode(0x43);
113    /// `DIFFICULTY`
114    /// EIP-4399 - Rename `DIFFICULTY` to `PREVRANDAO`
115    pub const PREVRANDAO: Opcode = Opcode(0x44);
116    /// `GASLIMIT`
117    pub const GASLIMIT: Opcode = Opcode(0x45);
118    /// `CHAINID`
119    pub const CHAINID: Opcode = Opcode(0x46);
120    /// `SELFBALANCE`
121    pub const SELFBALANCE: Opcode = Opcode(0x47);
122    /// `BASEFEE`
123    pub const BASEFEE: Opcode = Opcode(0x48);
124    /// `BLOBHASH` - EIP-4844
125    pub const BLOBHASH: Opcode = Opcode(0x49);
126    /// `BLOBBASEFEE` - EIP-7516
127    pub const BLOBBASEFEE: Opcode = Opcode(0x4a);
128
129    /// `POP`
130    pub const POP: Opcode = Opcode(0x50);
131    /// `MLOAD`
132    pub const MLOAD: Opcode = Opcode(0x51);
133    /// `MSTORE`
134    pub const MSTORE: Opcode = Opcode(0x52);
135    /// `MSTORE8`
136    pub const MSTORE8: Opcode = Opcode(0x53);
137    /// `SLOAD`
138    pub const SLOAD: Opcode = Opcode(0x54);
139    /// `SSTORE`
140    pub const SSTORE: Opcode = Opcode(0x55);
141    /// `JUMP`
142    pub const JUMP: Opcode = Opcode(0x56);
143    /// `JUMPI`
144    pub const JUMPI: Opcode = Opcode(0x57);
145    /// `PC`
146    pub const PC: Opcode = Opcode(0x58);
147    /// `MSIZE`
148    pub const MSIZE: Opcode = Opcode(0x59);
149    /// `GAS`
150    pub const GAS: Opcode = Opcode(0x5a);
151    /// `JUMPDEST`
152    pub const JUMPDEST: Opcode = Opcode(0x5b);
153    /// `TLOAD` - EIP-1153
154    pub const TLOAD: Opcode = Opcode(0x5c);
155    /// `TSTORE` - EIP-1153
156    pub const TSTORE: Opcode = Opcode(0x5d);
157    /// `MCOPY` - EIP-5656
158    pub const MCOPY: Opcode = Opcode(0x5e);
159
160    /// `PUSHn`
161    pub const PUSH0: Opcode = Opcode(0x5f);
162    pub const PUSH1: Opcode = Opcode(0x60);
163    pub const PUSH2: Opcode = Opcode(0x61);
164    pub const PUSH3: Opcode = Opcode(0x62);
165    pub const PUSH4: Opcode = Opcode(0x63);
166    pub const PUSH5: Opcode = Opcode(0x64);
167    pub const PUSH6: Opcode = Opcode(0x65);
168    pub const PUSH7: Opcode = Opcode(0x66);
169    pub const PUSH8: Opcode = Opcode(0x67);
170    pub const PUSH9: Opcode = Opcode(0x68);
171    pub const PUSH10: Opcode = Opcode(0x69);
172    pub const PUSH11: Opcode = Opcode(0x6a);
173    pub const PUSH12: Opcode = Opcode(0x6b);
174    pub const PUSH13: Opcode = Opcode(0x6c);
175    pub const PUSH14: Opcode = Opcode(0x6d);
176    pub const PUSH15: Opcode = Opcode(0x6e);
177    pub const PUSH16: Opcode = Opcode(0x6f);
178    pub const PUSH17: Opcode = Opcode(0x70);
179    pub const PUSH18: Opcode = Opcode(0x71);
180    pub const PUSH19: Opcode = Opcode(0x72);
181    pub const PUSH20: Opcode = Opcode(0x73);
182    pub const PUSH21: Opcode = Opcode(0x74);
183    pub const PUSH22: Opcode = Opcode(0x75);
184    pub const PUSH23: Opcode = Opcode(0x76);
185    pub const PUSH24: Opcode = Opcode(0x77);
186    pub const PUSH25: Opcode = Opcode(0x78);
187    pub const PUSH26: Opcode = Opcode(0x79);
188    pub const PUSH27: Opcode = Opcode(0x7a);
189    pub const PUSH28: Opcode = Opcode(0x7b);
190    pub const PUSH29: Opcode = Opcode(0x7c);
191    pub const PUSH30: Opcode = Opcode(0x7d);
192    pub const PUSH31: Opcode = Opcode(0x7e);
193    pub const PUSH32: Opcode = Opcode(0x7f);
194
195    /// `DUPn`
196    pub const DUP1: Opcode = Opcode(0x80);
197    pub const DUP2: Opcode = Opcode(0x81);
198    pub const DUP3: Opcode = Opcode(0x82);
199    pub const DUP4: Opcode = Opcode(0x83);
200    pub const DUP5: Opcode = Opcode(0x84);
201    pub const DUP6: Opcode = Opcode(0x85);
202    pub const DUP7: Opcode = Opcode(0x86);
203    pub const DUP8: Opcode = Opcode(0x87);
204    pub const DUP9: Opcode = Opcode(0x88);
205    pub const DUP10: Opcode = Opcode(0x89);
206    pub const DUP11: Opcode = Opcode(0x8a);
207    pub const DUP12: Opcode = Opcode(0x8b);
208    pub const DUP13: Opcode = Opcode(0x8c);
209    pub const DUP14: Opcode = Opcode(0x8d);
210    pub const DUP15: Opcode = Opcode(0x8e);
211    pub const DUP16: Opcode = Opcode(0x8f);
212
213    /// `SWAPn`
214    pub const SWAP1: Opcode = Opcode(0x90);
215    pub const SWAP2: Opcode = Opcode(0x91);
216    pub const SWAP3: Opcode = Opcode(0x92);
217    pub const SWAP4: Opcode = Opcode(0x93);
218    pub const SWAP5: Opcode = Opcode(0x94);
219    pub const SWAP6: Opcode = Opcode(0x95);
220    pub const SWAP7: Opcode = Opcode(0x96);
221    pub const SWAP8: Opcode = Opcode(0x97);
222    pub const SWAP9: Opcode = Opcode(0x98);
223    pub const SWAP10: Opcode = Opcode(0x99);
224    pub const SWAP11: Opcode = Opcode(0x9a);
225    pub const SWAP12: Opcode = Opcode(0x9b);
226    pub const SWAP13: Opcode = Opcode(0x9c);
227    pub const SWAP14: Opcode = Opcode(0x9d);
228    pub const SWAP15: Opcode = Opcode(0x9e);
229    pub const SWAP16: Opcode = Opcode(0x9f);
230
231    /// `LOGn`
232    pub const LOG0: Opcode = Opcode(0xa0);
233    pub const LOG1: Opcode = Opcode(0xa1);
234    pub const LOG2: Opcode = Opcode(0xa2);
235    pub const LOG3: Opcode = Opcode(0xa3);
236    pub const LOG4: Opcode = Opcode(0xa4);
237
238    pub const DATALOAD: Opcode = Opcode(0xd0);
239    pub const DATALOADN: Opcode = Opcode(0xd1);
240    pub const DATASIZE: Opcode = Opcode(0xd2);
241    pub const DATACOPY: Opcode = Opcode(0xd3);
242
243    /// `RJUMP` relative jump (EIP-4200)
244    pub const RJUMP: Opcode = Opcode(0xe0);
245    /// `RJUMPI` conditional relative jump (EIP-4200)
246    pub const RJUMPI: Opcode = Opcode(0xe1);
247    /// `RJUMPV` relative jump with  via jump table (EIP-4200)
248    pub const RJUMPV: Opcode = Opcode(0xe2);
249
250    /// `CALLF` call a function (EIP-4750)
251    pub const CALLF: Opcode = Opcode(0xe3);
252    /// `RETF` return from a function (EIP-4750)
253    pub const RETF: Opcode = Opcode(0xe4);
254
255    /// `JUMPF`  jumps to a code section without adding a new return stack frame (EIP-6206)
256    pub const JUMPF: Opcode = Opcode(0xe5);
257
258    /// `DUPN` EIP-663
259    pub const DUPN: Opcode = Opcode(0xe6);
260    /// `SWAPN` EIP-663
261    pub const SWAPN: Opcode = Opcode(0xe7);
262    /// `EXCHANGE` EIP-663
263    pub const EXCHANGE: Opcode = Opcode(0xe8);
264
265    /// `EOFCREATE` EIP-7620
266    pub const EOFCREATE: Opcode = Opcode(0xec);
267    /// `RETURNCONTRACT` EIP-7620
268    pub const RETURNCONTRACT: Opcode = Opcode(0xee);
269
270    /// `CREATE`
271    pub const CREATE: Opcode = Opcode(0xf0);
272    /// `CALL`
273    pub const CALL: Opcode = Opcode(0xf1);
274    /// `CALLCODE`
275    pub const CALLCODE: Opcode = Opcode(0xf2);
276    /// `RETURN`
277    pub const RETURN: Opcode = Opcode(0xf3);
278    /// `DELEGATECALL`
279    pub const DELEGATECALL: Opcode = Opcode(0xf4);
280    /// `CREATE2`
281    pub const CREATE2: Opcode = Opcode(0xf5);
282
283    /// `RETURNDATALOAD` - EIP-7069
284    pub const RETURNDATALOAD: Opcode = Opcode(0xf7);
285    /// `EXTCALL` - EIP-7069
286    pub const EXTCALL: Opcode = Opcode(0xf8);
287    /// `EXTDELEGATECALL` - EIP-7069
288    pub const EXTDELEGATECALL: Opcode = Opcode(0xf9);
289    /// `STATICCALL`
290    pub const STATICCALL: Opcode = Opcode(0xfa);
291    /// `EXTSTATICCALL` - EIP-7069
292    pub const EXTSTATICCALL: Opcode = Opcode(0xfb);
293
294    /// `REVERT`
295    pub const REVERT: Opcode = Opcode(0xfd);
296    /// `INVALID`
297    pub const INVALID: Opcode = Opcode(0xfe);
298    /// `SELFDESTRUCT`
299    pub const SELFDESTRUCT: Opcode = Opcode(0xff);
300}
301
302impl Opcode {
303    /// Whether the opcode is a push opcode.
304    #[must_use]
305    pub fn is_push(&self) -> Option<u8> {
306        let value = self.0;
307        if (0x60..=0x7f).contains(&value) {
308            Some(value - 0x60 + 1)
309        } else {
310            None
311        }
312    }
313
314    #[inline]
315    #[must_use]
316    pub const fn as_u8(&self) -> u8 {
317        self.0
318    }
319
320    #[inline]
321    #[must_use]
322    #[allow(clippy::as_conversions)]
323    pub const fn as_usize(&self) -> usize {
324        self.0 as usize
325    }
326}
327
328impl Display for Opcode {
329    #[allow(clippy::too_many_lines)]
330    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
331        let name = match *self {
332            Self::STOP => "STOP",
333            Self::ADD => "ADD",
334            Self::MUL => "MUL",
335            Self::SUB => "SUB",
336            Self::DIV => "DIV",
337            Self::SDIV => "SDIV",
338            Self::MOD => "MOD",
339            Self::SMOD => "SMOD",
340            Self::ADDMOD => "ADDMOD",
341            Self::MULMOD => "MULMOD",
342            Self::EXP => "EXP",
343            Self::SIGNEXTEND => "SIGNEXTEND",
344            Self::LT => "LT",
345            Self::GT => "GT",
346            Self::SLT => "SLT",
347            Self::SGT => "SGT",
348            Self::EQ => "EQ",
349            Self::ISZERO => "ISZERO",
350            Self::AND => "AND",
351            Self::OR => "OR",
352            Self::XOR => "XOR",
353            Self::NOT => "NOT",
354            Self::BYTE => "BYTE",
355            Self::CALLDATALOAD => "CALLDATALOAD",
356            Self::CALLDATASIZE => "CALLDATASIZE",
357            Self::CALLDATACOPY => "CALLDATACOPY",
358            Self::CODESIZE => "CODESIZE",
359            Self::CODECOPY => "CODECOPY",
360            Self::SHL => "SHL",
361            Self::SHR => "SHR",
362            Self::SAR => "SAR",
363            Self::POP => "POP",
364            Self::MLOAD => "MLOAD",
365            Self::MSTORE => "MSTORE",
366            Self::MSTORE8 => "MSTORE8",
367            Self::JUMP => "JUMP",
368            Self::JUMPI => "JUMPI",
369            Self::PC => "PC",
370            Self::MSIZE => "MSIZE",
371            Self::JUMPDEST => "JUMPDEST",
372            Self::TLOAD => "TLOAD",
373            Self::TSTORE => "TSTORE",
374            Self::MCOPY => "MCOPY",
375            Self::PUSH0 => "PUSH0",
376            Self::PUSH1 => "PUSH1",
377            Self::PUSH2 => "PUSH2",
378            Self::PUSH3 => "PUSH3",
379            Self::PUSH4 => "PUSH4",
380            Self::PUSH5 => "PUSH5",
381            Self::PUSH6 => "PUSH6",
382            Self::PUSH7 => "PUSH7",
383            Self::PUSH8 => "PUSH8",
384            Self::PUSH9 => "PUSH9",
385            Self::PUSH10 => "PUSH10",
386            Self::PUSH11 => "PUSH11",
387            Self::PUSH12 => "PUSH12",
388            Self::PUSH13 => "PUSH13",
389            Self::PUSH14 => "PUSH14",
390            Self::PUSH15 => "PUSH15",
391            Self::PUSH16 => "PUSH16",
392            Self::PUSH17 => "PUSH17",
393            Self::PUSH18 => "PUSH18",
394            Self::PUSH19 => "PUSH19",
395            Self::PUSH20 => "PUSH20",
396            Self::PUSH21 => "PUSH21",
397            Self::PUSH22 => "PUSH22",
398            Self::PUSH23 => "PUSH23",
399            Self::PUSH24 => "PUSH24",
400            Self::PUSH25 => "PUSH25",
401            Self::PUSH26 => "PUSH26",
402            Self::PUSH27 => "PUSH27",
403            Self::PUSH28 => "PUSH28",
404            Self::PUSH29 => "PUSH29",
405            Self::PUSH30 => "PUSH30",
406            Self::PUSH31 => "PUSH31",
407            Self::PUSH32 => "PUSH32",
408            Self::DUP1 => "DUP1",
409            Self::DUP2 => "DUP2",
410            Self::DUP3 => "DUP3",
411            Self::DUP4 => "DUP4",
412            Self::DUP5 => "DUP5",
413            Self::DUP6 => "DUP6",
414            Self::DUP7 => "DUP7",
415            Self::DUP8 => "DUP8",
416            Self::DUP9 => "DUP9",
417            Self::DUP10 => "DUP10",
418            Self::DUP11 => "DUP11",
419            Self::DUP12 => "DUP12",
420            Self::DUP13 => "DUP13",
421            Self::DUP14 => "DUP14",
422            Self::DUP15 => "DUP15",
423            Self::DUP16 => "DUP16",
424            Self::SWAP1 => "SWAP1",
425            Self::SWAP2 => "SWAP2",
426            Self::SWAP3 => "SWAP3",
427            Self::SWAP4 => "SWAP4",
428            Self::SWAP5 => "SWAP5",
429            Self::SWAP6 => "SWAP6",
430            Self::SWAP7 => "SWAP7",
431            Self::SWAP8 => "SWAP8",
432            Self::SWAP9 => "SWAP9",
433            Self::SWAP10 => "SWAP10",
434            Self::SWAP11 => "SWAP11",
435            Self::SWAP12 => "SWAP12",
436            Self::SWAP13 => "SWAP13",
437            Self::SWAP14 => "SWAP14",
438            Self::SWAP15 => "SWAP15",
439            Self::SWAP16 => "SWAP16",
440            Self::RETURN => "RETURN",
441            Self::REVERT => "REVERT",
442            Self::INVALID => "INVALID",
443            Self::SHA3 => "SHA3",
444            Self::ADDRESS => "ADDRESS",
445            Self::BALANCE => "BALANCE",
446            Self::SELFBALANCE => "SELFBALANCE",
447            Self::BASEFEE => "BASEFEE",
448            Self::BLOBHASH => "BLOBHASH",
449            Self::BLOBBASEFEE => "BLOBBASEFEE",
450            Self::ORIGIN => "ORIGIN",
451            Self::CALLER => "CALLER",
452            Self::CALLVALUE => "CALLVALUE",
453            Self::GASPRICE => "GASPRICE",
454            Self::EXTCODESIZE => "EXTCODESIZE",
455            Self::EXTCODECOPY => "EXTCODECOPY",
456            Self::EXTCODEHASH => "EXTCODEHASH",
457            Self::RETURNDATASIZE => "RETURNDATASIZE",
458            Self::RETURNDATACOPY => "RETURNDATACOPY",
459            Self::BLOCKHASH => "BLOCKHASH",
460            Self::COINBASE => "COINBASE",
461            Self::TIMESTAMP => "TIMESTAMP",
462            Self::NUMBER => "NUMBER",
463            Self::PREVRANDAO => "PREVRANDAO",
464            Self::GASLIMIT => "GASLIMIT",
465            Self::SLOAD => "SLOAD",
466            Self::SSTORE => "SSTORE",
467            Self::GAS => "GAS",
468            Self::LOG0 => "LOG0",
469            Self::LOG1 => "LOG1",
470            Self::LOG2 => "LOG2",
471            Self::LOG3 => "LOG3",
472            Self::LOG4 => "LOG4",
473            Self::CREATE => "CREATE",
474            Self::CREATE2 => "CREATE2",
475            Self::CALL => "CALL",
476            Self::CALLCODE => "CALLCODE",
477            Self::DELEGATECALL => "DELEGATECALL",
478            Self::STATICCALL => "STATICCALL",
479            Self::SELFDESTRUCT => "SELFDESTRUCT",
480            Self::CHAINID => "CHAINID",
481            Self::EXTSTATICCALL => "EXTSTATICCALL",
482            Self::EXTCALL => "EXTCALL",
483            Self::EXTDELEGATECALL => "EXTDELEGATECALL",
484            Self::RETURNDATALOAD => "RETURNDATALOAD",
485            _ => "UNKNOWN",
486        };
487        write!(f, "{name} [{}]", self.0)
488    }
489}