1use crate::Target;
4use phf::{phf_map, phf_set};
5use std::fmt;
6
7#[allow(unused)]
8pub struct YulBuiltinPrototype {
9 pub name: &'static str,
10 pub no_args: u8,
11 pub no_returns: u8,
12 pub doc: &'static str,
13 pub ty: YulBuiltInFunction,
14 pub stops_execution: bool,
15 pub availability: [bool; 3],
16}
17
18impl YulBuiltinPrototype {
19 pub fn is_available(&self, target: &Target) -> bool {
21 match target {
22 Target::EVM => self.availability[0],
23 Target::Polkadot { .. } => self.availability[1],
24 Target::Solana => self.availability[2],
25 Target::Soroban => unimplemented!(),
26 }
27 }
28}
29
30#[derive(Clone, Debug, PartialEq, Eq, Copy)]
32#[repr(u8)]
33pub enum YulBuiltInFunction {
34 Stop = 0,
35 Add = 1,
36 Sub = 2,
37 Mul = 3,
38 Div = 4,
39 SDiv = 5,
40 Mod = 6,
41 SMod = 7,
42 Exp = 8,
43 Not = 9,
44 Lt = 10,
45 Gt = 11,
46 Slt = 12,
47 Sgt = 13,
48 Eq = 14,
49 IsZero = 15,
50 And = 16,
51 Or = 17,
52 Xor = 18,
53 Byte = 19,
54 Shl = 20,
55 Shr = 21,
56 Sar = 22,
57 AddMod = 23,
58 MulMod = 24,
59 SignExtend = 25,
60 Keccak256 = 26,
61 Pc = 27,
62 Pop = 28,
63 MLoad = 29,
64 MStore = 30,
65 MStore8 = 31,
66 SLoad = 32,
67 SStore = 33,
68 MSize = 34,
69 Gas = 35,
70 Address = 36,
71 Balance = 37,
72 SelfBalance = 38,
73 Caller = 39,
74 CallValue = 40,
75 CallDataLoad = 41,
76 CallDataSize = 42,
77 CallDataCopy = 43,
78 CodeSize = 44,
79 CodeCopy = 45,
80 ExtCodeSize = 46,
81 ExtCodeCopy = 47,
82 ReturnDataSize = 48,
83 ReturnDataCopy = 49,
84 ExtCodeHash = 50,
85 Create = 51,
86 Create2 = 52,
87 Call = 53,
88 CallCode = 54,
89 DelegateCall = 55,
90 StaticCall = 56,
91 Return = 57,
92 Revert = 58,
93 SelfDestruct = 59,
94 Invalid = 60,
95 Log0 = 61,
96 Log1 = 62,
97 Log2 = 63,
98 Log3 = 64,
99 Log4 = 65,
100 ChainId = 66,
101 BaseFee = 67,
102 Origin = 68,
103 GasPrice = 69,
104 BlockHash = 70,
105 CoinBase = 71,
106 Timestamp = 72,
107 Number = 73,
108 Difficulty = 74,
109 GasLimit = 75,
110 PrevRandao = 76,
111}
112
113static UNSUPPORTED_BUILTINS: phf::Set<&'static str> = phf_set! {
115 "datasize", "dataoffset", "datacopy", "setimmutable", "loadimmutable",
116 "linkersymbol", "memoryguard"
117};
118
119pub(crate) fn yul_unsupported_builtin(name: &str) -> bool {
121 UNSUPPORTED_BUILTINS.contains(name)
122}
123
124static BUILTIN_YUL_FUNCTIONS: phf::Map<&'static str, YulBuiltInFunction> = phf_map! {
125 "stop" => YulBuiltInFunction::Stop,
126 "add" => YulBuiltInFunction::Add,
127 "sub" => YulBuiltInFunction::Sub,
128 "mul" => YulBuiltInFunction::Mul,
129 "div" => YulBuiltInFunction::Div,
130 "sdiv" => YulBuiltInFunction::SDiv,
131 "mod" => YulBuiltInFunction::Mod,
132 "smod" => YulBuiltInFunction::SMod,
133 "exp" => YulBuiltInFunction::Exp,
134 "not" => YulBuiltInFunction::Not,
135 "lt" => YulBuiltInFunction::Lt,
136 "gt" => YulBuiltInFunction::Gt,
137 "slt" => YulBuiltInFunction::Slt,
138 "sgt" => YulBuiltInFunction::Sgt,
139 "eq" => YulBuiltInFunction::Eq,
140 "iszero" => YulBuiltInFunction::IsZero,
141 "and" => YulBuiltInFunction::And,
142 "or" => YulBuiltInFunction::Or,
143 "xor" => YulBuiltInFunction::Xor,
144 "byte" => YulBuiltInFunction::Byte,
145 "shl" => YulBuiltInFunction::Shl,
146 "shr" => YulBuiltInFunction::Shr,
147 "sar" => YulBuiltInFunction::Sar,
148 "addmod" => YulBuiltInFunction::AddMod,
149 "mulmod" => YulBuiltInFunction::MulMod,
150 "signextend" => YulBuiltInFunction::SignExtend,
151 "keccak256" => YulBuiltInFunction::Keccak256,
152 "pc" => YulBuiltInFunction::Pc,
153 "pop" => YulBuiltInFunction::Pop,
154 "mload" => YulBuiltInFunction::MLoad,
155 "mstore" => YulBuiltInFunction::MStore,
156 "mstore8" => YulBuiltInFunction::MStore8,
157 "sload" => YulBuiltInFunction::SLoad,
158 "sstore" => YulBuiltInFunction::SStore,
159 "msize" => YulBuiltInFunction::MSize,
160 "gas" => YulBuiltInFunction::Gas,
161 "address" => YulBuiltInFunction::Address,
162 "balance" => YulBuiltInFunction::Balance,
163 "selfbalance" => YulBuiltInFunction::SelfBalance,
164 "caller" => YulBuiltInFunction::Caller,
165 "callvalue" => YulBuiltInFunction::CallValue,
166 "calldataload" => YulBuiltInFunction::CallDataLoad,
167 "calldatasize" => YulBuiltInFunction::CallDataSize,
168 "calldatacopy" => YulBuiltInFunction::CallDataCopy,
169 "codesize" => YulBuiltInFunction::CodeSize,
170 "codecopy" => YulBuiltInFunction::CodeCopy,
171 "extcodesize" => YulBuiltInFunction::ExtCodeSize,
172 "extcodecopy" => YulBuiltInFunction::ExtCodeCopy,
173 "returndatasize" => YulBuiltInFunction::ReturnDataSize,
174 "returndatacopy" => YulBuiltInFunction::ReturnDataCopy,
175 "extcodehash" => YulBuiltInFunction::ExtCodeHash,
176 "create" => YulBuiltInFunction::Create,
177 "create2" => YulBuiltInFunction::Create2,
178 "call" => YulBuiltInFunction::Call,
179 "callcode" => YulBuiltInFunction::CallCode,
180 "delegatecall" => YulBuiltInFunction::DelegateCall,
181 "staticcall" => YulBuiltInFunction::StaticCall,
182 "return" => YulBuiltInFunction::Return,
183 "revert" => YulBuiltInFunction::Revert,
184 "selfdestruct" => YulBuiltInFunction::SelfDestruct,
185 "invalid" => YulBuiltInFunction::Invalid,
186 "log0" => YulBuiltInFunction::Log0,
187 "log1" => YulBuiltInFunction::Log1,
188 "log2" => YulBuiltInFunction::Log2,
189 "log3" => YulBuiltInFunction::Log3,
190 "log4" => YulBuiltInFunction::Log4,
191 "chainid" => YulBuiltInFunction::ChainId,
192 "basefee" => YulBuiltInFunction::BaseFee,
193 "origin" => YulBuiltInFunction::Origin,
194 "gasprice" => YulBuiltInFunction::GasPrice,
195 "blockhash" => YulBuiltInFunction::BlockHash,
196 "coinbase" => YulBuiltInFunction::CoinBase,
197 "timestamp" => YulBuiltInFunction::Timestamp,
198 "number" => YulBuiltInFunction::Number,
199 "difficulty" => YulBuiltInFunction::Difficulty,
200 "gaslimit" => YulBuiltInFunction::GasLimit,
201 "prevrandao" => YulBuiltInFunction::PrevRandao,
202};
203
204pub fn parse_builtin_keyword(keyword: &str) -> Option<&YulBuiltInFunction> {
206 BUILTIN_YUL_FUNCTIONS.get(keyword)
207}
208
209impl YulBuiltInFunction {
210 pub(crate) fn get_prototype_info(self) -> &'static YulBuiltinPrototype {
212 let index = self as usize;
213 &YUL_BUILTIN[index]
214 }
215
216 pub(crate) fn modify_state(self) -> bool {
217 matches!(
218 self,
219 YulBuiltInFunction::SStore
220 | YulBuiltInFunction::Log0
221 | YulBuiltInFunction::Log1
222 | YulBuiltInFunction::Log2
223 | YulBuiltInFunction::Log3
224 | YulBuiltInFunction::Log4
225 | YulBuiltInFunction::Create
226 | YulBuiltInFunction::Call
227 | YulBuiltInFunction::CallCode
228 | YulBuiltInFunction::DelegateCall
229 | YulBuiltInFunction::Create2
230 | YulBuiltInFunction::SelfDestruct
231 )
232 }
233
234 pub(crate) fn read_state(self) -> bool {
235 matches!(
236 self,
237 YulBuiltInFunction::Address
238 | YulBuiltInFunction::SelfBalance
239 | YulBuiltInFunction::Balance
240 | YulBuiltInFunction::Origin
241 | YulBuiltInFunction::Caller
242 | YulBuiltInFunction::CallValue
243 | YulBuiltInFunction::ChainId
244 | YulBuiltInFunction::BaseFee
245 | YulBuiltInFunction::PrevRandao
246 | YulBuiltInFunction::Gas
247 | YulBuiltInFunction::GasPrice
248 | YulBuiltInFunction::ExtCodeSize
249 | YulBuiltInFunction::ExtCodeCopy
250 | YulBuiltInFunction::ExtCodeHash
251 | YulBuiltInFunction::BlockHash
252 | YulBuiltInFunction::CoinBase
253 | YulBuiltInFunction::Timestamp
254 | YulBuiltInFunction::Number
255 | YulBuiltInFunction::Difficulty
256 | YulBuiltInFunction::GasLimit
257 | YulBuiltInFunction::StaticCall
258 | YulBuiltInFunction::SLoad
259 )
260 }
261}
262
263impl fmt::Display for YulBuiltInFunction {
264 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
265 let prototype = self.get_prototype_info();
266 f.write_str(prototype.name)
267 }
268}
269
270static YUL_BUILTIN: [YulBuiltinPrototype; 77] =
273 [
274 YulBuiltinPrototype {
275 name: "stop",
276 no_args: 0,
277 no_returns: 0,
278 doc: "Stop execution",
279 ty: YulBuiltInFunction::Stop,
280 stops_execution: true,
281 availability: [true, false, false],
282 },
283 YulBuiltinPrototype {
284 name: "add",
285 no_args: 2,
286 no_returns: 1,
287 doc: "add(x, y) returns x + y",
288 ty: YulBuiltInFunction::Add,
289 stops_execution: false,
290 availability: [true, true, true],
291 },
292 YulBuiltinPrototype {
293 name: "sub",
294 no_args: 2,
295 no_returns: 1,
296 doc: "sub(x, y) returns x - y",
297 ty: YulBuiltInFunction::Sub,
298 stops_execution: false,
299 availability: [true, true, true],
300 },
301 YulBuiltinPrototype {
302 name: "mul",
303 no_args: 2,
304 no_returns: 1,
305 doc: "mul(x, y) returns x*y",
306 ty: YulBuiltInFunction::Mul,
307 stops_execution: false,
308 availability: [true, true, true],
309 },
310 YulBuiltinPrototype {
311 name: "div",
312 no_args: 2,
313 no_returns: 1,
314 doc: "div(x, y) returns x/y or 0 if y == 0",
315 ty: YulBuiltInFunction::Div,
316 stops_execution: false,
317 availability: [true, true, true],
318 },
319 YulBuiltinPrototype {
320 name: "sdiv",
321 no_args: 2,
322 no_returns: 1,
323 doc: "sdiv(x, y) returns x/y or 0 if y==0. Used for signed numbers in two's complement",
324 ty: YulBuiltInFunction::SDiv,
325 stops_execution: false,
326 availability: [true, true, true],
327 },
328 YulBuiltinPrototype {
329 name: "mod",
330 no_args: 2,
331 no_returns: 1,
332 doc: "mod(x, y) returns x % y or 0 if y == 0",
333 ty: YulBuiltInFunction::Mod,
334 stops_execution: false,
335 availability: [true, true, true],
336 },
337 YulBuiltinPrototype {
338 name: "smod",
339 no_args: 2,
340 no_returns: 1,
341 doc: "smod(x, y) returns x % y or 0 if y == 0. Used for signed numbers in two's complement",
342 ty: YulBuiltInFunction::SMod,
343 stops_execution: false,
344 availability: [true, true, true],
345 },
346 YulBuiltinPrototype {
347 name: "exp",
348 no_args: 2,
349 no_returns: 1,
350 doc: "exp(x, y) returns x to the power of y",
351 ty: YulBuiltInFunction::Exp,
352 stops_execution: false,
353 availability: [true, true, true],
354 },
355 YulBuiltinPrototype {
356 name: "not",
357 no_args: 1,
358 no_returns: 1,
359 doc: "not(x): bitwise \"not\" of x (every bit is negated)",
360 ty: YulBuiltInFunction::Not,
361 stops_execution: false,
362 availability: [true, true, true],
363 },
364 YulBuiltinPrototype {
365 name: "lt",
366 no_args: 2,
367 no_returns: 1,
368 doc: "lt(x, y) returns 1 if x < y, 0 otherwise",
369 ty: YulBuiltInFunction::Lt,
370 stops_execution: false,
371 availability: [true, true, true],
372 },
373 YulBuiltinPrototype {
374 name: "gt",
375 no_args: 2,
376 no_returns: 1,
377 doc: "gt(x, y) returns 1 if x > y, 0 otherwise",
378 ty: YulBuiltInFunction::Gt,
379 stops_execution: false,
380 availability: [true, true, true],
381 },
382 YulBuiltinPrototype {
383 name: "slt",
384 no_args: 2,
385 no_returns: 1,
386 doc: "slt(x, y) returns 1 if x > y, 0 otherwise. Used for signed numbers in two's complement",
387 ty: YulBuiltInFunction::Slt,
388 stops_execution: false,
389 availability: [true, true, true],
390 },
391 YulBuiltinPrototype {
392 name: "sgt",
393 no_args: 2,
394 no_returns: 1,
395 doc: "sgt(x, y) returns 1 if x > y, 0 otherwise. Used for signed numbers in two's complement",
396 ty: YulBuiltInFunction::Sgt,
397 stops_execution: false,
398 availability: [true, true, true],
399 },
400 YulBuiltinPrototype {
401 name: "eq",
402 no_args: 2,
403 no_returns: 1,
404 doc: "eq(x, y) returns 1 if x == y, 0 otherwise",
405 ty: YulBuiltInFunction::Eq,
406 stops_execution: false,
407 availability: [true, true, true],
408 },
409 YulBuiltinPrototype {
410 name: "iszero",
411 no_args: 1,
412 no_returns: 1,
413 doc: "iszero(x) returns 1 if x == 0, 0 otherwise",
414 ty: YulBuiltInFunction::IsZero,
415 stops_execution: false,
416 availability: [true, true, true],
417 },
418 YulBuiltinPrototype {
419 name: "and",
420 no_args: 2,
421 no_returns: 1,
422 doc: "and(x, y) returns the bitwise \"and\" between x and y",
423 ty: YulBuiltInFunction::And,
424 stops_execution: false,
425 availability: [true, true, true],
426 },
427 YulBuiltinPrototype {
428 name: "or",
429 no_args: 2,
430 no_returns: 1,
431 doc: "or(x, y) returns the bitwise \"or\" between x and y",
432 ty: YulBuiltInFunction::Or,
433 stops_execution: false,
434 availability: [true, true, true],
435 },
436 YulBuiltinPrototype {
437 name: "xor",
438 no_args: 2,
439 no_returns: 1,
440 doc: "xor(x, y) returns the bitwise \"xor\" between x and y",
441 ty: YulBuiltInFunction::Xor,
442 stops_execution: false,
443 availability: [true, true, true],
444 },
445 YulBuiltinPrototype {
446 name: "byte",
447 no_args: 2,
448 no_returns: 1,
449 doc: "byte(n, x) returns the nth byte of x, where the most significant byte is the 0th",
450 ty: YulBuiltInFunction::Byte,
451 stops_execution: false,
452 availability: [true, true, true],
453 },
454 YulBuiltinPrototype {
455 name: "shl",
456 no_args: 2,
457 no_returns: 1,
458 doc: "shl(x, y) returns the logical shift left of y by x bits",
459 ty: YulBuiltInFunction::Shl,
460 stops_execution: false,
461 availability: [true, true, true],
462 },
463 YulBuiltinPrototype {
464 name: "shr",
465 no_args: 2,
466 no_returns: 1,
467 doc: "shr(x, y) returns the logical shift right of y by x bits",
468 ty: YulBuiltInFunction::Shr,
469 stops_execution: false,
470 availability: [true, true, true],
471 },
472 YulBuiltinPrototype {
473 name: "sar",
474 no_args: 2,
475 no_returns: 1,
476 doc: "signed arithmetic shift right y by x bits",
477 ty: YulBuiltInFunction::Sar,
478 stops_execution: false,
479 availability: [true, true, true],
480 },
481 YulBuiltinPrototype {
482 name: "addmod",
483 no_args: 3,
484 no_returns: 1,
485 doc: "addmod(x, y, m) returns (x + y) % m or 0 if m == 0",
486 ty: YulBuiltInFunction::AddMod,
487 stops_execution: false,
488 availability: [true, true, true],
489 },
490 YulBuiltinPrototype {
491 name: "mulmod",
492 no_args: 3,
493 no_returns: 1,
494 doc: "mulmod(x, y, m) returns (x * y) % m or 0 if m == 0",
495 ty: YulBuiltInFunction::MulMod,
496 stops_execution: false,
497 availability: [true, true, true],
498 },
499 YulBuiltinPrototype {
500 name: "signextend",
501 no_args: 2,
502 no_returns: 1,
503 doc: "signextend(i, x) sign extends from (i*8+7)th bit counting from least significant",
504 ty: YulBuiltInFunction::SignExtend,
505 stops_execution: false,
506 availability: [true, false, false],
507 },
508 YulBuiltinPrototype {
509 name: "keccak256",
510 no_args: 2,
511 no_returns: 1,
512 doc: "keccak256(p, n) performs keccak(mem[p...(p+n)])",
513 ty: YulBuiltInFunction::Keccak256,
514 stops_execution: false,
515 availability: [true, false, false],
516 },
517 YulBuiltinPrototype {
518 name: "pc",
519 no_args: 0,
520 no_returns: 1,
521 doc: "Returns the current position in code, i.e. the program counter",
522 ty: YulBuiltInFunction::Pc,
523 stops_execution: false,
524 availability: [true, false, false],
525 },
526 YulBuiltinPrototype {
527 name: "pop",
528 no_args: 1,
529 no_returns: 0,
530 doc: "pop(x) discard value x",
531 ty: YulBuiltInFunction::Pop,
532 stops_execution: false,
533 availability: [true, false, false],
534 },
535 YulBuiltinPrototype {
536 name: "mload",
537 no_args: 1,
538 no_returns: 1,
539 doc: "mload(p) returns mem[p...(p+32)]",
540 ty: YulBuiltInFunction::MLoad,
541 stops_execution: false,
542 availability: [true, false, false],
543 },
544 YulBuiltinPrototype {
545 name: "mstore",
546 no_args: 2,
547 no_returns: 0,
548 doc: "mstore(p, v) stores v into mem[p...(p+32)]",
549 ty: YulBuiltInFunction::MStore,
550 stops_execution: false,
551 availability: [true, false, false],
552 },
553 YulBuiltinPrototype {
554 name: "mstore8",
555 no_args: 2,
556 no_returns: 0,
557 doc: "mstore8(p, v) stores (v & 0xff) into mem[p] (modified a single byte of v)",
558 ty: YulBuiltInFunction::MStore8,
559 stops_execution: false,
560 availability: [true, false, false],
561 },
562 YulBuiltinPrototype {
563 name: "sload",
564 no_args: 1,
565 no_returns: 1,
566 doc: "sload(p) returns storage[p], i.e. memory on contract's storage",
567 ty: YulBuiltInFunction::SLoad,
568 stops_execution: false,
569 availability: [true, false, false],
570 },
571 YulBuiltinPrototype {
572 name: "sstore",
573 no_args: 2,
574 no_returns: 0,
575 doc: "sstore(p) stores v into storage[p]",
576 ty: YulBuiltInFunction::SStore,
577 stops_execution: false,
578 availability: [true, false, false],
579 },
580 YulBuiltinPrototype {
581 name: "msize",
582 no_args: 0,
583 no_returns: 1,
584 doc: "Returns the size of memory, i.e largest accessed memory index",
585 ty: YulBuiltInFunction::MSize,
586 stops_execution: false,
587 availability: [true, false, false],
588 },
589 YulBuiltinPrototype {
590 name: "gas",
591 no_args: 0,
592 no_returns: 1,
593 doc: "Returns gas still available to execution",
594 ty: YulBuiltInFunction::Gas,
595 stops_execution: false,
596 availability: [true, true, false],
597 },
598 YulBuiltinPrototype {
599 name: "address",
600 no_args: 0,
601 no_returns: 1,
602 doc: "Returns the address of the current contract / execution context",
603 ty: YulBuiltInFunction::Address,
604 stops_execution: false,
605 availability: [true, true, true],
606 },
607 YulBuiltinPrototype {
608 name: "balance",
609 no_args: 1,
610 no_returns: 1,
611 doc: "balance(a) returns the wei balance at address a",
612 ty: YulBuiltInFunction::Balance,
613 stops_execution: false,
614 availability: [true, true, false],
615 },
616 YulBuiltinPrototype {
617 name: "selfbalance",
618 no_args: 0,
619 no_returns: 1,
620 doc: "Returns the wei balance at the address of the current contract / execution context",
621 ty: YulBuiltInFunction::SelfBalance,
622 stops_execution: false,
623 availability: [true, true, false],
624 },
625 YulBuiltinPrototype {
626 name: "caller",
627 no_args: 0,
628 no_returns: 1,
629 doc: "Returns the call sender",
630 ty: YulBuiltInFunction::Caller,
631 stops_execution: false,
632 availability: [true, true, false],
633 },
634 YulBuiltinPrototype {
635 name: "callvalue",
636 no_args: 0,
637 no_returns: 1,
638 doc: "Returns the wei sent together with the current call",
639 ty: YulBuiltInFunction::CallValue,
640 stops_execution: false,
641 availability: [true, true, false],
642 },
643 YulBuiltinPrototype {
644 name: "calldataload",
645 no_args: 1,
646 no_returns: 1,
647 doc: "calldataload(p) returns call data starting from position p (32 bytes)",
648 ty: YulBuiltInFunction::CallDataLoad,
649 stops_execution: false,
650 availability: [true, false, false],
651 },
652 YulBuiltinPrototype {
653 name: "calldatasize",
654 no_args: 0,
655 no_returns: 1,
656 doc: "Returns the size of call data in bytes",
657 ty: YulBuiltInFunction::CallDataSize,
658 stops_execution: false,
659 availability: [true, false, false],
660 },
661 YulBuiltinPrototype {
662 name: "calldatacopy",
663 no_args: 3,
664 no_returns: 0,
665 doc: "calldatacopy(t, f, s) copies s bytes from calldata at position f to mem at position t",
666 ty: YulBuiltInFunction::CallDataCopy,
667 stops_execution: false,
668 availability: [true, false, false],
669 },
670 YulBuiltinPrototype {
671 name: "codesize",
672 no_args: 0,
673 no_returns: 1,
674 doc: "Returns the size of the current contract / execution context",
675 ty: YulBuiltInFunction::CodeSize,
676 stops_execution: false,
677 availability: [true, false, false],
678 },
679 YulBuiltinPrototype {
680 name: "codecopy",
681 no_args: 3,
682 no_returns: 0,
683 doc: "codecopy(t, f, s) copies s bytes from code at position f to mem at position t",
684 ty: YulBuiltInFunction::CodeCopy,
685 stops_execution: false,
686 availability: [true, false, false],
687 },
688 YulBuiltinPrototype {
689 name: "extcodesize",
690 no_args: 1,
691 no_returns: 1,
692 doc: "extcodesize(a) returns the size of the code at address a",
693 ty: YulBuiltInFunction::ExtCodeSize,
694 stops_execution: false,
695 availability: [true, false, false],
696 },
697 YulBuiltinPrototype {
698 name: "extcodecopy",
699 no_args: 4,
700 no_returns: 0,
701 doc: "extcodecopy(a, t, f, s) copies s bytes from code located at address a at position f to mem at position t",
702 ty: YulBuiltInFunction::ExtCodeCopy,
703 stops_execution: false,
704 availability: [true, false, false],
705 },
706 YulBuiltinPrototype {
707 name: "returndatasize",
708 no_args: 0,
709 no_returns: 1,
710 doc: "Returns the size of the last returndata",
711 ty: YulBuiltInFunction::ReturnDataSize,
712 stops_execution: false,
713 availability: [true, false, false],
714 },
715 YulBuiltinPrototype {
716 name: "returndatacopy",
717 no_args: 3,
718 no_returns: 0,
719 doc: "returndatacopy(t, f, s) copy s bytes from return data at position f to mem at position t",
720 ty: YulBuiltInFunction::ReturnDataCopy,
721 stops_execution: false,
722 availability: [true, false, false],
723 },
724 YulBuiltinPrototype {
725 name: "extcodehash",
726 no_args: 1,
727 no_returns: 1,
728 doc: "extcodehash(a) returns the code hash of address a",
729 ty: YulBuiltInFunction::ExtCodeHash,
730 stops_execution: false,
731 availability: [true, false, false],
732 },
733 YulBuiltinPrototype {
734 name: "create",
735 no_args: 3,
736 no_returns: 1,
737 doc: "create(v, p, n) creates new contract with code mem[p..(p+n)] and sends v wei. It returns the new address or 0 on error",
738 ty: YulBuiltInFunction::Create,
739 stops_execution: false,
740 availability: [true, false, false],
741 },
742 YulBuiltinPrototype {
743 name: "create2",
744 no_args: 4,
745 no_returns: 1,
746 doc: "create2(v, p, n, s) new contract with code mem[p...(p+n)] at address keccak256(0xff . this . s . keccak256(mem[p...(p+n)]) and sends v wei.\n 0xff is a 1 byte value, 'this' is the current contract's address as a 20 byte value and 's' is a big endian 256-bit value. it returns 0 on error.",
747 ty: YulBuiltInFunction::Create2,
748 stops_execution: false,
749 availability: [true, false, false],
750 },
751 YulBuiltinPrototype {
752 name: "call",
753 no_args: 7,
754 no_returns: 1,
755 doc: "call(g, a, v, in, insize, out, outsize) calls contract at address a with input mem[in...(in+insize)] providing f cas and v wei and outputs area mem[out...(out+outsize)]. It returns 0 on error and 1 on success",
756 ty: YulBuiltInFunction::Call,
757 stops_execution: false,
758 availability: [true, false, false],
759 },
760 YulBuiltinPrototype {
761 name: "callcode",
762 no_args: 7,
763 no_returns: 1,
764 doc: "Identical to call(g, a, v, in, insize, out, outsize), but only use the code from a and stay in the context of the current contract otherwise",
765 ty: YulBuiltInFunction::CallCode,
766 stops_execution: false,
767 availability: [true, false, false],
768 },
769 YulBuiltinPrototype {
770 name: "delegatecall",
771 no_args: 6,
772 no_returns: 1,
773 doc: "Identical to 'callcode' but also keep caller and callvalue",
774 ty: YulBuiltInFunction::DelegateCall,
775 stops_execution: false,
776 availability: [true, false, false],
777 },
778 YulBuiltinPrototype {
779 name: "staticcall",
780 no_args: 6,
781 no_returns: 1,
782 doc: "Identical to call(g, a, 0, in, insize, out, outsize), but do not allow state modifications",
783 ty: YulBuiltInFunction::StaticCall,
784 stops_execution: false,
785 availability: [true, false, false],
786 },
787 YulBuiltinPrototype {
788 name: "return",
789 no_args: 2,
790 no_returns: 0,
791 doc: "return(p, s) ends execution and returns data mem[p...(p+s)]",
792 ty: YulBuiltInFunction::Return,
793 stops_execution: true,
794 availability: [true, false, false],
795 },
796 YulBuiltinPrototype {
797 name: "revert",
798 no_args: 2,
799 no_returns: 0,
800 doc: "revert(p, s) ends execution, reverts state changes and returns data mem[p...(p+s)]",
801 ty: YulBuiltInFunction::Revert,
802 stops_execution: true,
803 availability: [true, false, false],
804 },
805 YulBuiltinPrototype {
806 name: "selfdestruct",
807 no_args: 1,
808 no_returns: 0,
809 doc: "selfdestruct(a) ends execution, destroy current contract and sends funds to a",
810 ty: YulBuiltInFunction::SelfDestruct,
811 stops_execution: true,
812 availability: [true, true, true],
813 },
814 YulBuiltinPrototype {
815 name: "invalid",
816 no_args: 0,
817 no_returns: 0,
818 doc: "Ends execution with invalid instruction",
819 ty: YulBuiltInFunction::Invalid,
820 stops_execution: true,
821 availability: [true, true, true],
822 },
823 YulBuiltinPrototype {
824 name: "log0",
825 no_args: 2,
826 no_returns: 0,
827 doc: "log(p, s): log without topics and data mem[p...(p+s)]",
828 ty: YulBuiltInFunction::Log0,
829 stops_execution: false,
830 availability: [true, false, false],
831 },
832 YulBuiltinPrototype {
833 name: "log1",
834 no_args: 3,
835 no_returns: 0,
836 doc: "log1(p, s, t1): log with topic t1 and data mem[p...(p+s)]",
837 ty: YulBuiltInFunction::Log1,
838 stops_execution: false,
839 availability: [true, false, false],
840 },
841 YulBuiltinPrototype {
842 name: "log2",
843 no_args: 4,
844 no_returns: 0,
845 doc: "log2(p, s, t1, t2): log with topics t1, t2 and data mem[p...(p+s)]",
846 ty: YulBuiltInFunction::Log2,
847 stops_execution: false,
848 availability: [true, false, false],
849 },
850 YulBuiltinPrototype {
851 name: "log3",
852 no_args: 5,
853 no_returns: 0,
854 doc: "log3(p, s, t1, t2, t3): log with topics t1, t2, t3 and data mem[p...(p+s)]",
855 ty: YulBuiltInFunction::Log3,
856 stops_execution: false,
857 availability: [true, false, false],
858 },
859 YulBuiltinPrototype {
860 name: "log4",
861 no_args: 6,
862 no_returns: 0,
863 doc: "log4(p, s, t1, t2, t3, t4): log with topics t1, t2, t3, t4 with data mem[p...(p+s)]",
864 ty: YulBuiltInFunction::Log4,
865 stops_execution: false,
866 availability: [true, false, false],
867 },
868 YulBuiltinPrototype {
869 name: "chainid",
870 no_args: 0,
871 no_returns: 1,
872 doc: "Returns the ID of the executing chain",
873 ty: YulBuiltInFunction::ChainId,
874 stops_execution: false,
875 availability: [true, false, false],
876 },
877 YulBuiltinPrototype {
878 name: "basefee",
879 no_args: 0,
880 no_returns: 1,
881 doc: "Return the current block's base fee",
882 ty: YulBuiltInFunction::BaseFee,
883 stops_execution: false,
884 availability: [true, false, false],
885 },
886 YulBuiltinPrototype {
887 name: "origin",
888 no_args: 0,
889 no_returns: 1,
890 doc: "Returns the transaction sender",
891 ty: YulBuiltInFunction::Origin,
892 stops_execution: false,
893 availability: [true, true, true],
894 },
895 YulBuiltinPrototype {
896 name: "gasprice",
897 no_args: 0,
898 no_returns: 1,
899 doc: "Returns the gas price of the transaction",
900 ty: YulBuiltInFunction::GasPrice,
901 stops_execution: false,
902 availability: [true, true, false],
903 },
904 YulBuiltinPrototype {
905 name: "blockhash",
906 no_args: 1,
907 no_returns: 1,
908 doc: "blockhash(b) return the hash of block #b - only valid for the last 256 executing block excluding current",
909 ty: YulBuiltInFunction::BlockHash,
910 stops_execution: false,
911 availability: [true, false, false],
912 },
913 YulBuiltinPrototype {
914 name: "coinbase",
915 no_args: 0,
916 no_returns: 1,
917 doc: "Returns the current mining beneficiary",
918 ty: YulBuiltInFunction::CoinBase,
919 stops_execution: false,
920 availability: [true, false, false],
921 },
922 YulBuiltinPrototype {
923 name: "timestamp",
924 no_args: 0,
925 no_returns: 1,
926 doc: "Returns the timestamp of the current block in seconds since the epoch",
927 ty: YulBuiltInFunction::Timestamp,
928 stops_execution: false,
929 availability: [true, true, true],
930 },
931 YulBuiltinPrototype {
932 name: "number",
933 no_args: 0,
934 no_returns: 1,
935 doc: "Returns the current block's number",
936 ty: YulBuiltInFunction::Number,
937 stops_execution: false,
938 availability: [true, true, true],
939 },
940 YulBuiltinPrototype {
941 name: "difficulty",
942 no_args: 0,
943 no_returns: 1,
944 doc: "Returns the difficulty of the current block",
945 ty: YulBuiltInFunction::Difficulty,
946 stops_execution: false,
947 availability: [true, false, false],
948 },
949 YulBuiltinPrototype {
950 name: "gaslimit",
951 no_args: 0,
952 no_returns: 1,
953 doc: "Returns the current block's gas limit",
954 ty: YulBuiltInFunction::GasLimit,
955 stops_execution: false,
956 availability: [true, false, false],
957 },
958 YulBuiltinPrototype {
959 name: "prevrandao",
960 no_args: 0,
961 no_returns: 1,
962 doc: "Random number provided by the beacon chain",
963 ty: YulBuiltInFunction::PrevRandao,
964 stops_execution: false,
965 availability: [true, false, false],
966 },
967 ];
968
969#[test]
970fn test_builtin_indexes() {
971 for item in &YUL_BUILTIN {
972 let name = item.name;
973 let ty = item.ty;
974
975 let parsed_ty = parse_builtin_keyword(name).unwrap();
976 assert_eq!(ty, *parsed_ty);
977 assert_eq!(name, parsed_ty.get_prototype_info().name);
978 }
979}