generated from huff-language/huff-project-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CustomDispatcher.huff
74 lines (59 loc) · 3.15 KB
/
CustomDispatcher.huff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// Custom Jumptable
// every 2-byte entry represents a program counter location for the selected function:
// 0x 002C 0060 0002 0003 0004 0005 0006 0007 0008 0009 000A 000B 000C 000D 000E 000F
// 002C : jumpdest of the first function (__EXAMPLE_FUNCTION_1 as defined below)
// 0060 : jumpdest of the second function (__EXAMPLE_FUNCTION_2 as defined below)
// 0002 : jumpdest of the third function, and so on.
#define constant _JUMPTABLE = 0x002C006000020003000400050006000700080009000A000B000C000D000E000F
// Define some demo functions
#define function __EXAMPLE_FUNCTION_1() pure returns ()
#define function __EXAMPLE_FUNCTION_2() pure returns ()
// example calldata to reach function 1: 0xF0 (=240 bits =30 bytes)
// in this case:
// 0x002C003300020003000400050006000700080009000A000B000C000D000E000F original jumptable
// ^-----------------------------------------------------------v
// 0x000000000000000000000000000000000000000000000000000000000000002C shitfted by 30 bytes to the right
// result: 0x2C
// mask: 0xFFFF
// AND: 0x2C -> 0x2C is the jumpdest PC value of __EXAMPLE_FUNCTION_1 -> make jump
#define macro MAIN() = takes (0) returns (0) {
// load the jump table on the stack as we need to read from it later
[_JUMPTABLE] // [_JUMPTABLE]
// load first 32 bytes of calldata on the stack
0x00 calldataload // [calldata, _JUMPTABLE]
// take the first byte of calldata
0x00 byte // [calldata first byte, _JUMPTABLE]
// shift the jump table right by [calldata first byte] bytes
// 0x002C003300020003000400050006000700080009000A000B000C000D000E000F original jumptable
// 0x000000000000000000000000000000000000000000000000000000000000002C shitfted jumptable
shr // [jumptable shifted]
// mask the shifted result with 0xFFFF (2-bytes mask)
// 0x000000000000000000000000000000000000000000000000000000000000FFFF
// 0x000000000000000000000000000000000000000000000000000000000000002C
// AND operation will result in:
// 0x000000000000000000000000000000000000000000000000000000000000002C
// which is the jumpdest PC value of __EXAMPLE_FUNCTION_1
0xFFFF and // [jumptable entry]
// go to the jumpdest associated with the value on the stack
// it will fail and revert if jumpdest is not valid
jump // []
// now call all the functions so they are included in the binary
// and from here we can figure out the PC of each function's beginning
__EXAMPLE_FUNCTION_1()
__EXAMPLE_FUNCTION_2()
}
// ---------- demo functions ---------------
#define macro __EXAMPLE_FUNCTION_1() = takes (0) returns (0) {
jumpdest // PC: 0x2C
0x20 0x00 mstore // Return "hello from function 1"
0x15 0x20 mstore
__RIGHTPAD(0x68656c6c6f2066726f6d2066756e6374696f6e2031) 0x40 mstore
0x60 0x00 return
}
#define macro __EXAMPLE_FUNCTION_2() = takes (0) returns (0) {
jumpdest // PC: 0x60
0x20 0x00 mstore // Return "hello from function 2"
0x15 0x20 mstore
__RIGHTPAD(0x68656c6c6f2066726f6d2066756e6374696f6e2032) 0x40 mstore
0x60 0x00 return
}