bobcat_proxy/
lib.rs

1#![no_std]
2
3use array_concat::concat_arrays;
4
5use bobcat_interfaces::sels::SEL_IMPLEMENTATION;
6
7pub type Address = [u8; 20];
8
9pub const fn make_minimal_proxy(addr: Address) -> [u8; 18 + 16 + 20] {
10    // I can't remember where this comes from (TODO), but we use this in
11    // 9lives for our share proxies.
12    concat_arrays!(
13        [
14            0x60, 0x2d, 0x5f, 0x81, 0x60, 0x09, 0x5f, 0x39, 0xf3, 0x5f, 0x5f, 0x36, 0x5f, 0x5f,
15            0x37, 0x36, 0x5f, 0x73,
16        ],
17        addr,
18        [
19            0x5a, 0xf4, 0x3d, 0x5f, 0x5f, 0x3e, 0x60, 0x29, 0x57, 0x3d, 0x5f, 0xfd, 0x5b, 0x3d,
20            0x5f, 0xf3,
21        ]
22    )
23}
24
25macro_rules! unpack_arr {
26    ($b:expr, $l:expr) => {
27        match const_hex::const_decode_to_array::<$l>($b) {
28            Ok(v) => v,
29            Err(_) => panic!("bad code"),
30        }
31    };
32}
33
34/// Make a EIP1967 proxy that reads from the standard storage slot.
35pub const fn make_eip1967_proxy(logic: Address) -> [u8; 1 + 20 + 102] {
36    // Created from eip1967.huff .
37    concat_arrays!(
38      [0x73],
39      logic,
40      unpack_arr!(
41          b"7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55603a8060403d393df3365f5f375f5f365f7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af45f3d5f5f3e3d9161003857fd5bf3",
42          101
43      )
44    )
45}
46
47/// Make beacon proxy that calls "implementation()(address)" on a
48/// hardcoded beacon address to get the logic address to delegate to.
49pub const fn make_beacon_proxy(beacon: Address) -> [u8; 20 + 110] {
50    // Created from beacon-proxy.huff .
51    concat_arrays!(
52        unpack_arr!(
53            b"60438060093d393df3365f5f375f5f365f635c60da1b602052602060206004603c73",
54            34
55        ),
56        beacon,
57        unpack_arr!(
58          b"60438060093d393df3365f5f375f5f365f635c60da1b602052602060206004603c7390b75e378f50a871e4125ba9d1ef9a3826cedf415afa506020515af45f3d5f5f3e3d9161004157fd5bf3",
59          76
60        )
61    )
62}
63
64/// Make a beacon proxy that loads from the beacon slot to get the
65/// "implementation()(address)" to get the logic address to delegate to.
66pub const fn make_upgradeable_beacon_proxy(beacon: Address) -> [u8; 1 + 20 + 123] {
67    // Created from beacon-proxy.huff .
68    concat_arrays!(
69        [0x73],
70        beacon,
71        unpack_arr!(
72            b"7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d505560508060403d393df3365f5f375f5f365f635c60da1b602052602060206004603c7fa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50545afa506020515af45f3d5f5f3e3d9161004e57fd5bf3",
73            123
74        )
75    )
76}
77
78pub const fn make_multi3_proxy(
79    one: Address,
80    two: Address,
81    three: Address,
82    all: Address,
83) -> [u8; 46 + 20 + 7 + 20 + 7 + 20 + 6 + 20 + 21] {
84    // Created from multi3-proxy.huff .
85    concat_arrays!(
86        unpack_arr!(
87            b"609e8060093d393df3365f5f375f5f365f6002355f1a8060011461003d5780600214610058576003146100735773",
88            46
89        ),
90        all,
91        unpack_arr!(b"61008d565b5073", 7),
92        one,
93        unpack_arr!(b"61008d565b5073", 7),
94        two,
95        unpack_arr!(b"61008d565b73", 6),
96        three,
97        unpack_arr!(b"61008d565b5af45f3d5f5f3e3d9161009c57fd5bf3", 21)
98    )
99}
100
101/// Create a proxy that calls the selector on the beacon given
102/// to figure out where to delegatecall its calldata to.
103pub const fn make_beacon_sel_proxy_sel(sel: [u8; 4], beacon: Address) -> [u8; 42 + 20 + 33] {
104    // Created from sel-beacon-proxy.huff .
105    concat_arrays!(
106        unpack_arr!(b"60568060093d393df33660046020355f5f36602063", 21),
107        sel,
108        unpack_arr!(b"5f5260045f602037602060246024601c73", 17),
109        beacon,
110        unpack_arr!(
111            b"5afa15610054576024513660046024375af43d5f5f3e5f3d911561005457f35bfd",
112            33
113        )
114    )
115}
116
117/// Create a proxy that calls "implementation(bytes4)" on the beacon
118/// address given with the selector in the calldata to this proxy. Use the
119/// returned address as the target of a delegatecall.
120pub const fn make_beacon_sel_proxy(beacon: Address) -> [u8; 42 + 20 + 33] {
121    make_beacon_sel_proxy_sel(SEL_IMPLEMENTATION, beacon)
122}