1#![no_std]
2
3pub use bobcat_maths::U;
4
5pub use bobcat_storage::const_keccak256;
6
7use array_concat::concat_arrays;
8
9#[macro_export]
10macro_rules! read_word_slices {
11 ($slice:expr, 1) => {{
12 let s = $slice;
13 assert!(s.len() >= 32);
14 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) })
15 }};
16 ($slice:expr, 2) => {{
17 let s = $slice;
18 assert!(s.len() >= 64);
19 (
20 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
21 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
22 )
23 }};
24 ($slice:expr, 3) => {{
25 let s = $slice;
26 assert!(s.len() >= 96);
27 (
28 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
29 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
30 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
31 )
32 }};
33 ($slice:expr, 4) => {{
34 let s = $slice;
35 assert!(s.len() >= 128);
36 (
37 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
38 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
39 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
40 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
41 )
42 }};
43 ($slice:expr, 5) => {{
44 let s = $slice;
45 assert!(s.len() >= 160);
46 (
47 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
48 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
49 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
50 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
51 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
52 )
53 }};
54 ($slice:expr, 6) => {{
55 let s = $slice;
56 assert!(s.len() >= 192);
57 (
58 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
59 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
60 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
61 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
62 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
63 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
64 )
65 }};
66 ($slice:expr, 7) => {{
67 let s = $slice;
68 assert!(s.len() >= 224);
69 (
70 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
71 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
72 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
73 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
74 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
75 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
76 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
77 )
78 }};
79 ($slice:expr, 8) => {{
80 let s = $slice;
81 assert!(s.len() >= 256);
82 (
83 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
84 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
85 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
86 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
87 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
88 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
89 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
90 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
91 )
92 }};
93 ($slice:expr, 9) => {{
94 let s = $slice;
95 assert!(s.len() >= 288);
96 (
97 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
98 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
99 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
100 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
101 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
102 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
103 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
104 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
105 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
106 )
107 }};
108 ($slice:expr, 10) => {{
109 let s = $slice;
110 assert!(s.len() >= 320);
111 (
112 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
113 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
114 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
115 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
116 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
117 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
118 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
119 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
120 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
121 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
122 )
123 }};
124 ($slice:expr, 11) => {{
125 let s = $slice;
126 assert!(s.len() >= 352);
127 (
128 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
129 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
130 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
131 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
132 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
133 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
134 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
135 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
136 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
137 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
138 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
139 )
140 }};
141 ($slice:expr, 12) => {{
142 let s = $slice;
143 assert!(s.len() >= 384);
144 (
145 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
146 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
147 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
148 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
149 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
150 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
151 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
152 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
153 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
154 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
155 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
156 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
157 )
158 }};
159 ($slice:expr, 13) => {{
160 let s = $slice;
161 assert!(s.len() >= 416);
162 (
163 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
164 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
165 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
166 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
167 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
168 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
169 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
170 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
171 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
172 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
173 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
174 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
175 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
176 )
177 }};
178 ($slice:expr, 14) => {{
179 let s = $slice;
180 assert!(s.len() >= 448);
181 (
182 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
183 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
184 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
185 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
186 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
187 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
188 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
189 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
190 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
191 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
192 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
193 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
194 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
195 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
196 )
197 }};
198 ($slice:expr, 15) => {{
199 let s = $slice;
200 assert!(s.len() >= 480);
201 (
202 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
203 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
204 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
205 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
206 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
207 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
208 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
209 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
210 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
211 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
212 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
213 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
214 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
215 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
216 &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
217 )
218 }};
219 ($slice:expr, 16) => {{
220 let s = $slice;
221 assert!(s.len() >= 512);
222 (
223 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
224 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
225 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
226 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
227 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
228 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
229 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
230 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
231 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
232 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
233 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
234 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
235 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
236 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
237 &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
238 &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
239 )
240 }};
241 ($slice:expr, 17) => {{
242 let s = $slice;
243 assert!(s.len() >= 544);
244 (
245 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
246 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
247 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
248 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
249 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
250 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
251 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
252 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
253 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
254 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
255 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
256 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
257 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
258 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
259 &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
260 &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
261 &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
262 )
263 }};
264 ($slice:expr, 18) => {{
265 let s = $slice;
266 assert!(s.len() >= 576);
267 (
268 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
269 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
270 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
271 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
272 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
273 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
274 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
275 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
276 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
277 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
278 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
279 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
280 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
281 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
282 &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
283 &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
284 &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
285 &U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
286 )
287 }};
288 ($slice:expr, 19) => {{
289 let s = $slice;
290 assert!(s.len() >= 608);
291 (
292 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
293 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
294 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
295 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
296 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
297 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
298 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
299 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
300 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
301 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
302 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
303 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
304 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
305 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
306 &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
307 &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
308 &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
309 &U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
310 &U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
311 )
312 }};
313 ($slice:expr, 20) => {{
314 let s = $slice;
315 assert!(s.len() >= 640);
316 (
317 &U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
318 &U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
319 &U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
320 &U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
321 &U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
322 &U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
323 &U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
324 &U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
325 &U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
326 &U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
327 &U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
328 &U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
329 &U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
330 &U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
331 &U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
332 &U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
333 &U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
334 &U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
335 &U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
336 &U::from(unsafe { *(s[608..640].as_ptr() as *const [u8; 32]) }),
337 )
338 }};
339}
340
341pub const fn leftpad_addr(x: [u8; 20]) -> [u8; 32] {
342 concat_arrays!([0u8; 32 - 20], x)
343}
344
345pub const fn leftpad_u8(x: u8) -> [u8; 32] {
346 concat_arrays!([0u8; 32 - 1], [x])
347}
348
349pub const fn const_keccak_sel(x: &[u8]) -> [u8; 4] {
350 let x = const_keccak256(x).0;
351 [x[0], x[1], x[2], x[3]]
352}
353
354#[test]
355fn test_access() {
356 use bobcat_maths::Address;
357 let cd = const_hex::const_decode_to_array::<{ 32 * 2 + 4 }>(b"a9059cbb0000000000000000000000006221a9c005f6e47eb398fd867784cacfdcfff4e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
358 let a = const_hex::const_decode_to_array::<20>(b"6221a9c005f6e47eb398fd867784cacfdcfff4e7")
359 .unwrap();
360 let (addr, amt) = read_word_slices!(&cd[4..], 2);
361 assert_eq!((a, U::MAX), (Address::from(U::from(*addr)), U::from(*amt)));
362}