fuzz/
grammar.rs

1// Copyright 2025 Security Research Labs GmbH
2//
3// SPDX-License-Identifier: Apache-2.0
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// 	http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License./ DEALINGS IN THE SOFTWARE.
15
16#[derive(Clone, Debug, arbitrary::Arbitrary)]
17pub struct FuzzData {
18	pub contract: Vec<Opcode>,
19	pub call_data: Vec<u8>,
20	pub value: u64,
21	pub check_proof_size: bool,
22}
23
24#[derive(Clone, Debug, arbitrary::Arbitrary)]
25pub enum Opcode {
26	STOP,
27	ADD,
28	MUL,
29	SUB,
30	DIV,
31	SDIV,
32	MOD,
33	SMOD,
34	ADDMOD,
35	MULMOD,
36	EXP,
37	SIGNEXTEND,
38	LT,
39	GT,
40	SLT,
41	SGT,
42	EQ,
43	ISZERO,
44	AND,
45	OR,
46	XOR,
47	NOT,
48	BYTE,
49	SHL,
50	SHR,
51	SAR,
52	SHA3,
53	ADDRESS,
54	BALANCE,
55	ORIGIN,
56	CALLER,
57	CALLVALUE,
58	CALLDATALOAD,
59	CALLDATASIZE,
60	CALLDATACOPY,
61	CODESIZE,
62	CODECOPY,
63	GASPRICE,
64	EXTCODESIZE,
65	EXTCODECOPY,
66	RETURNDATASIZE,
67	RETURNDATACOPY,
68	EXTCODEHASH,
69	BLOCKHASH,
70	COINBASE,
71	TIMESTAMP,
72	NUMBER,
73	DIFFICULTY,
74	GASLIMIT,
75	CHAINID,
76	SELFBALANCE,
77	BASEFEE,
78	POP,
79	MLOAD,
80	MSTORE,
81	MSTORE8,
82	SLOAD,
83	SSTORE,
84	JUMP,
85	JUMPI,
86	PC,
87	MSIZE,
88	GAS,
89	JUMPDEST,
90	MCOPY,
91	TLOAD,
92	TSTORE,
93	PUSH0,
94	PUSH1([u8; 1]),
95	PUSH2([u8; 2]),
96	PUSH3([u8; 3]),
97	PUSH4([u8; 4]),
98	PUSH5([u8; 5]),
99	PUSH6([u8; 6]),
100	PUSH7([u8; 7]),
101	PUSH8([u8; 8]),
102	PUSH9([u8; 9]),
103	PUSH10([u8; 10]),
104	PUSH11([u8; 11]),
105	PUSH12([u8; 12]),
106	PUSH13([u8; 13]),
107	PUSH14([u8; 14]),
108	PUSH15([u8; 15]),
109	PUSH16([u8; 16]),
110	PUSH17([u8; 17]),
111	PUSH18([u8; 18]),
112	PUSH19([u8; 19]),
113	PUSH20([u8; 20]),
114	PUSH21([u8; 21]),
115	PUSH22([u8; 22]),
116	PUSH23([u8; 23]),
117	PUSH24([u8; 24]),
118	PUSH25([u8; 25]),
119	PUSH26([u8; 26]),
120	PUSH27([u8; 27]),
121	PUSH28([u8; 28]),
122	PUSH29([u8; 29]),
123	PUSH30([u8; 30]),
124	PUSH31([u8; 31]),
125	PUSH32([u8; 32]),
126	DUP1,
127	DUP2,
128	DUP3,
129	DUP4,
130	DUP5,
131	DUP6,
132	DUP7,
133	DUP8,
134	DUP9,
135	DUP10,
136	DUP11,
137	DUP12,
138	DUP13,
139	DUP14,
140	DUP15,
141	DUP16,
142	SWAP1,
143	SWAP2,
144	SWAP3,
145	SWAP4,
146	SWAP5,
147	SWAP6,
148	SWAP7,
149	SWAP8,
150	SWAP9,
151	SWAP10,
152	SWAP11,
153	SWAP12,
154	SWAP13,
155	SWAP14,
156	SWAP15,
157	SWAP16,
158	LOG0,
159	LOG1,
160	LOG2,
161	LOG3,
162	LOG4,
163	CREATE,
164	CALL,
165	CALLCODE,
166	RETURN,
167	DELEGATECALL,
168	CREATE2,
169	STATICCALL,
170	REVERT,
171	INVALID,
172	SELFDESTRUCT,
173	BLOBBASEFEE,
174	BLOBHASH,
175}
176
177impl Opcode {
178	pub fn to_bytes(&self, output: &mut Vec<u8>) {
179		match self {
180			Opcode::STOP => output.push(0x00),
181			Opcode::ADD => output.push(0x01),
182			Opcode::MUL => output.push(0x02),
183			Opcode::SUB => output.push(0x03),
184			Opcode::DIV => output.push(0x04),
185			Opcode::SDIV => output.push(0x05),
186			Opcode::MOD => output.push(0x06),
187			Opcode::SMOD => output.push(0x07),
188			Opcode::ADDMOD => output.push(0x08),
189			Opcode::MULMOD => output.push(0x09),
190			Opcode::EXP => output.push(0x0A),
191			Opcode::SIGNEXTEND => output.push(0x0B),
192			Opcode::LT => output.push(0x10),
193			Opcode::GT => output.push(0x11),
194			Opcode::SLT => output.push(0x12),
195			Opcode::SGT => output.push(0x13),
196			Opcode::EQ => output.push(0x14),
197			Opcode::ISZERO => output.push(0x15),
198			Opcode::AND => output.push(0x16),
199			Opcode::OR => output.push(0x17),
200			Opcode::XOR => output.push(0x18),
201			Opcode::NOT => output.push(0x19),
202			Opcode::BYTE => output.push(0x1A),
203			Opcode::SHL => output.push(0x1B),
204			Opcode::SHR => output.push(0x1C),
205			Opcode::SAR => output.push(0x1D),
206			Opcode::SHA3 => output.push(0x20),
207			Opcode::ADDRESS => output.push(0x30),
208			Opcode::BALANCE => output.push(0x31),
209			Opcode::ORIGIN => output.push(0x32),
210			Opcode::CALLER => output.push(0x33),
211			Opcode::CALLVALUE => output.push(0x34),
212			Opcode::CALLDATALOAD => output.push(0x35),
213			Opcode::CALLDATASIZE => output.push(0x36),
214			Opcode::CALLDATACOPY => output.push(0x37),
215			Opcode::CODESIZE => output.push(0x38),
216			Opcode::CODECOPY => output.push(0x39),
217			Opcode::GASPRICE => output.push(0x3A),
218			Opcode::EXTCODESIZE => output.push(0x3B),
219			Opcode::EXTCODECOPY => output.push(0x3C),
220			Opcode::RETURNDATASIZE => output.push(0x3D),
221			Opcode::RETURNDATACOPY => output.push(0x3E),
222			Opcode::EXTCODEHASH => output.push(0x3F),
223			Opcode::BLOCKHASH => output.push(0x40),
224			Opcode::COINBASE => output.push(0x41),
225			Opcode::TIMESTAMP => output.push(0x42),
226			Opcode::NUMBER => output.push(0x43),
227			Opcode::DIFFICULTY => output.push(0x44),
228			Opcode::GASLIMIT => output.push(0x45),
229			Opcode::CHAINID => output.push(0x46),
230			Opcode::SELFBALANCE => output.push(0x47),
231			Opcode::BASEFEE => output.push(0x48),
232			Opcode::POP => output.push(0x50),
233			Opcode::MLOAD => output.push(0x51),
234			Opcode::MSTORE => output.push(0x52),
235			Opcode::MSTORE8 => output.push(0x53),
236			Opcode::SLOAD => output.push(0x54),
237			Opcode::SSTORE => output.push(0x55),
238			Opcode::JUMP => output.push(0x56),
239			Opcode::JUMPI => output.push(0x57),
240			Opcode::PC => output.push(0x58),
241			Opcode::MSIZE => output.push(0x59),
242			Opcode::GAS => output.push(0x5A),
243			Opcode::JUMPDEST => output.push(0x5B),
244			Opcode::MCOPY => output.push(0x5C),
245			Opcode::TLOAD => output.push(0x5D),
246			Opcode::TSTORE => output.push(0x5E),
247			// Handle PUSH operations - add both the opcode and the pushed bytes
248			Opcode::PUSH0 => {
249				output.push(0x5F);
250				output.push(0x00);
251			}
252			Opcode::PUSH1(data) => {
253				output.push(0x60);
254				output.extend_from_slice(data);
255			}
256			Opcode::PUSH2(data) => {
257				output.push(0x61);
258				output.extend_from_slice(data.as_slice());
259			}
260			Opcode::PUSH3(data) => {
261				output.push(0x62);
262				output.extend_from_slice(data.as_slice());
263			}
264			Opcode::PUSH4(data) => {
265				output.push(0x63);
266				output.extend_from_slice(data.as_slice());
267			}
268			Opcode::PUSH5(data) => {
269				output.push(0x64);
270				output.extend_from_slice(data.as_slice());
271			}
272			Opcode::PUSH6(data) => {
273				output.push(0x65);
274				output.extend_from_slice(data.as_slice());
275			}
276			Opcode::PUSH7(data) => {
277				output.push(0x66);
278				output.extend_from_slice(data.as_slice());
279			}
280			Opcode::PUSH8(data) => {
281				output.push(0x67);
282				output.extend_from_slice(data.as_slice());
283			}
284			Opcode::PUSH9(data) => {
285				output.push(0x68);
286				output.extend_from_slice(data.as_slice());
287			}
288			Opcode::PUSH10(data) => {
289				output.push(0x69);
290				output.extend_from_slice(data.as_slice());
291			}
292			Opcode::PUSH11(data) => {
293				output.push(0x6A);
294				output.extend_from_slice(data.as_slice());
295			}
296			Opcode::PUSH12(data) => {
297				output.push(0x6B);
298				output.extend_from_slice(data.as_slice());
299			}
300			Opcode::PUSH13(data) => {
301				output.push(0x6C);
302				output.extend_from_slice(data.as_slice());
303			}
304			Opcode::PUSH14(data) => {
305				output.push(0x6D);
306				output.extend_from_slice(data.as_slice());
307			}
308			Opcode::PUSH15(data) => {
309				output.push(0x6E);
310				output.extend_from_slice(data.as_slice());
311			}
312			Opcode::PUSH16(data) => {
313				output.push(0x6F);
314				output.extend_from_slice(data.as_slice());
315			}
316			Opcode::PUSH17(data) => {
317				output.push(0x70);
318				output.extend_from_slice(data.as_slice());
319			}
320			Opcode::PUSH18(data) => {
321				output.push(0x71);
322				output.extend_from_slice(data.as_slice());
323			}
324			Opcode::PUSH19(data) => {
325				output.push(0x72);
326				output.extend_from_slice(data.as_slice());
327			}
328			Opcode::PUSH20(data) => {
329				output.push(0x73);
330				output.extend_from_slice(data.as_slice());
331			}
332			Opcode::PUSH21(data) => {
333				output.push(0x74);
334				output.extend_from_slice(data.as_slice());
335			}
336			Opcode::PUSH22(data) => {
337				output.push(0x75);
338				output.extend_from_slice(data.as_slice());
339			}
340			Opcode::PUSH23(data) => {
341				output.push(0x76);
342				output.extend_from_slice(data.as_slice());
343			}
344			Opcode::PUSH24(data) => {
345				output.push(0x77);
346				output.extend_from_slice(data.as_slice());
347			}
348			Opcode::PUSH25(data) => {
349				output.push(0x78);
350				output.extend_from_slice(data.as_slice());
351			}
352			Opcode::PUSH26(data) => {
353				output.push(0x79);
354				output.extend_from_slice(data.as_slice());
355			}
356			Opcode::PUSH27(data) => {
357				output.push(0x7A);
358				output.extend_from_slice(data.as_slice());
359			}
360			Opcode::PUSH28(data) => {
361				output.push(0x7B);
362				output.extend_from_slice(data.as_slice());
363			}
364			Opcode::PUSH29(data) => {
365				output.push(0x7C);
366				output.extend_from_slice(data.as_slice());
367			}
368			Opcode::PUSH30(data) => {
369				output.push(0x7D);
370				output.extend_from_slice(data.as_slice());
371			}
372			Opcode::PUSH31(data) => {
373				output.push(0x7E);
374				output.extend_from_slice(data.as_slice());
375			}
376			Opcode::PUSH32(data) => {
377				output.push(0x7F);
378				output.extend_from_slice(data.as_slice());
379			}
380
381			// Remaining opcodes
382			Opcode::DUP1 => output.push(0x80),
383			Opcode::DUP2 => output.push(0x81),
384			Opcode::DUP3 => output.push(0x82),
385			Opcode::DUP4 => output.push(0x83),
386			Opcode::DUP5 => output.push(0x84),
387			Opcode::DUP6 => output.push(0x85),
388			Opcode::DUP7 => output.push(0x86),
389			Opcode::DUP8 => output.push(0x87),
390			Opcode::DUP9 => output.push(0x88),
391			Opcode::DUP10 => output.push(0x89),
392			Opcode::DUP11 => output.push(0x8A),
393			Opcode::DUP12 => output.push(0x8B),
394			Opcode::DUP13 => output.push(0x8C),
395			Opcode::DUP14 => output.push(0x8D),
396			Opcode::DUP15 => output.push(0x8E),
397			Opcode::DUP16 => output.push(0x8F),
398			Opcode::SWAP1 => output.push(0x90),
399			Opcode::SWAP2 => output.push(0x91),
400			Opcode::SWAP3 => output.push(0x92),
401			Opcode::SWAP4 => output.push(0x93),
402			Opcode::SWAP5 => output.push(0x94),
403			Opcode::SWAP6 => output.push(0x95),
404			Opcode::SWAP7 => output.push(0x96),
405			Opcode::SWAP8 => output.push(0x97),
406			Opcode::SWAP9 => output.push(0x98),
407			Opcode::SWAP10 => output.push(0x99),
408			Opcode::SWAP11 => output.push(0x9A),
409			Opcode::SWAP12 => output.push(0x9B),
410			Opcode::SWAP13 => output.push(0x9C),
411			Opcode::SWAP14 => output.push(0x9D),
412			Opcode::SWAP15 => output.push(0x9E),
413			Opcode::SWAP16 => output.push(0x9F),
414			Opcode::LOG0 => output.push(0xA0),
415			Opcode::LOG1 => output.push(0xA1),
416			Opcode::LOG2 => output.push(0xA2),
417			Opcode::LOG3 => output.push(0xA3),
418			Opcode::LOG4 => output.push(0xA4),
419			Opcode::CREATE => output.push(0xF0),
420			Opcode::CALL => output.push(0xF1),
421			Opcode::CALLCODE => output.push(0xF2),
422			Opcode::RETURN => output.push(0xF3),
423			Opcode::DELEGATECALL => output.push(0xF4),
424			Opcode::CREATE2 => output.push(0xF5),
425			Opcode::STATICCALL => output.push(0xFA),
426			Opcode::REVERT => output.push(0xFD),
427			Opcode::INVALID => output.push(0xFE),
428			Opcode::SELFDESTRUCT => output.push(0xFF),
429			Opcode::BLOBBASEFEE => output.push(0x4A),
430			Opcode::BLOBHASH => output.push(0x49),
431		}
432	}
433}