Skip to main content

bobcat_cd/
lib.rs

1#![cfg_attr(not(feature = "std"), no_std)]
2
3pub mod serialisation;
4
5pub use serialisation::{
6    Error as EvmCdError, EvmCdAddress, EvmCdArray, EvmCdArrayError, EvmCdDeserialise,
7    EvmCdSerialise, EvmCdString, EvmCdStringError, EvmCdWriteTarget, Read as EvmCdRead,
8    Write as EvmCdWrite,
9};
10
11#[cfg(feature = "derive")]
12pub use bobcat_cd_derive::{EvmCdDeserialise, EvmCdSerialise};
13
14pub use bobcat_maths::U;
15
16pub use bobcat_storage::{const_keccak256, const_keccak256_two};
17
18pub use const_hex::const_decode_to_array as const_hex_decode_to_array;
19
20use array_concat::concat_arrays;
21
22#[cfg(feature = "alloc")]
23extern crate alloc;
24
25#[cfg(feature = "alloc")]
26use alloc::string::String;
27
28#[macro_export]
29macro_rules! address {
30    ($a:expr) => {{
31        match $crate::const_hex_decode_to_array::<20>($a) {
32            Ok(v) => v,
33            Err(_) => core::panic!("bad address"),
34        }
35    }};
36}
37
38#[macro_export]
39macro_rules! read_words {
40    ($slice:expr, 1) => {{
41        let s = $slice;
42        core::assert!(s.len() >= 32);
43        &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) })
44    }};
45    ($slice:expr, 2) => {{
46        let s = $slice;
47        core::assert!(s.len() >= 64);
48        (
49            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
50            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
51        )
52    }};
53    ($slice:expr, 3) => {{
54        let s = $slice;
55        core::assert!(s.len() >= 96);
56        (
57            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
58            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
59            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
60        )
61    }};
62    ($slice:expr, 4) => {{
63        let s = $slice;
64        core::assert!(s.len() >= 128);
65        (
66            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
67            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
68            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
69            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
70        )
71    }};
72    ($slice:expr, 5) => {{
73        let s = $slice;
74        core::assert!(s.len() >= 160);
75        (
76            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
77            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
78            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
79            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
80            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
81        )
82    }};
83    ($slice:expr, 6) => {{
84        let s = $slice;
85        core::assert!(s.len() >= 192);
86        (
87            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
88            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
89            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
90            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
91            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
92            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
93        )
94    }};
95    ($slice:expr, 7) => {{
96        let s = $slice;
97        core::assert!(s.len() >= 224);
98        (
99            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
100            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
101            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
102            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
103            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
104            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
105            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
106        )
107    }};
108    ($slice:expr, 8) => {{
109        let s = $slice;
110        core::assert!(s.len() >= 256);
111        (
112            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
113            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
114            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
115            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
116            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
117            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
118            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
119            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
120        )
121    }};
122    ($slice:expr, 9) => {{
123        let s = $slice;
124        core::assert!(s.len() >= 288);
125        (
126            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
127            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
128            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
129            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
130            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
131            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
132            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
133            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
134            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
135        )
136    }};
137    ($slice:expr, 10) => {{
138        let s = $slice;
139        core::assert!(s.len() >= 320);
140        (
141            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
142            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
143            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
144            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
145            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
146            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
147            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
148            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
149            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
150            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
151        )
152    }};
153    ($slice:expr, 11) => {{
154        let s = $slice;
155        core::assert!(s.len() >= 352);
156        (
157            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
158            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
159            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
160            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
161            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
162            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
163            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
164            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
165            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
166            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
167            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
168        )
169    }};
170    ($slice:expr, 12) => {{
171        let s = $slice;
172        core::assert!(s.len() >= 384);
173        (
174            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
175            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
176            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
177            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
178            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
179            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
180            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
181            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
182            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
183            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
184            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
185            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
186        )
187    }};
188    ($slice:expr, 13) => {{
189        let s = $slice;
190        core::assert!(s.len() >= 416);
191        (
192            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
193            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
194            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
195            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
196            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
197            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
198            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
199            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
200            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
201            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
202            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
203            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
204            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
205        )
206    }};
207    ($slice:expr, 14) => {{
208        let s = $slice;
209        core::assert!(s.len() >= 448);
210        (
211            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
212            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
213            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
214            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
215            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
216            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
217            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
218            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
219            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
220            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
221            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
222            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
223            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
224            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
225        )
226    }};
227    ($slice:expr, 15) => {{
228        let s = $slice;
229        core::assert!(s.len() >= 480);
230        (
231            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
232            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
233            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
234            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
235            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
236            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
237            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
238            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
239            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
240            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
241            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
242            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
243            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
244            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
245            &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
246        )
247    }};
248    ($slice:expr, 16) => {{
249        let s = $slice;
250        core::assert!(s.len() >= 512);
251        (
252            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
253            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
254            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
255            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
256            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
257            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
258            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
259            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
260            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
261            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
262            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
263            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
264            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
265            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
266            &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
267            &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
268        )
269    }};
270    ($slice:expr, 17) => {{
271        let s = $slice;
272        core::assert!(s.len() >= 544);
273        (
274            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
275            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
276            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
277            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
278            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
279            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
280            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
281            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
282            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
283            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
284            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
285            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
286            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
287            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
288            &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
289            &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
290            &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
291        )
292    }};
293    ($slice:expr, 18) => {{
294        let s = $slice;
295        core::assert!(s.len() >= 576);
296        (
297            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
298            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
299            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
300            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
301            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
302            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
303            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
304            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
305            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
306            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
307            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
308            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
309            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
310            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
311            &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
312            &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
313            &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
314            &$crate::U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
315        )
316    }};
317    ($slice:expr, 19) => {{
318        let s = $slice;
319        core::assert!(s.len() >= 608);
320        (
321            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
322            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
323            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
324            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
325            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
326            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
327            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
328            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
329            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
330            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
331            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
332            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
333            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
334            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
335            &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
336            &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
337            &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
338            &$crate::U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
339            &$crate::U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
340        )
341    }};
342    ($slice:expr, 20) => {{
343        let s = $slice;
344        core::assert!(s.len() >= 640);
345        (
346            &$crate::U::from(unsafe { *(s[..32].as_ptr() as *const [u8; 32]) }),
347            &$crate::U::from(unsafe { *(s[32..64].as_ptr() as *const [u8; 32]) }),
348            &$crate::U::from(unsafe { *(s[64..96].as_ptr() as *const [u8; 32]) }),
349            &$crate::U::from(unsafe { *(s[96..128].as_ptr() as *const [u8; 32]) }),
350            &$crate::U::from(unsafe { *(s[128..160].as_ptr() as *const [u8; 32]) }),
351            &$crate::U::from(unsafe { *(s[16..192].as_ptr() as *const [u8; 32]) }),
352            &$crate::U::from(unsafe { *(s[192..224].as_ptr() as *const [u8; 32]) }),
353            &$crate::U::from(unsafe { *(s[224..256].as_ptr() as *const [u8; 32]) }),
354            &$crate::U::from(unsafe { *(s[256..288].as_ptr() as *const [u8; 32]) }),
355            &$crate::U::from(unsafe { *(s[288..320].as_ptr() as *const [u8; 32]) }),
356            &$crate::U::from(unsafe { *(s[32..352].as_ptr() as *const [u8; 32]) }),
357            &$crate::U::from(unsafe { *(s[352..384].as_ptr() as *const [u8; 32]) }),
358            &$crate::U::from(unsafe { *(s[384..416].as_ptr() as *const [u8; 32]) }),
359            &$crate::U::from(unsafe { *(s[416..448].as_ptr() as *const [u8; 32]) }),
360            &$crate::U::from(unsafe { *(s[448..480].as_ptr() as *const [u8; 32]) }),
361            &$crate::U::from(unsafe { *(s[48..512].as_ptr() as *const [u8; 32]) }),
362            &$crate::U::from(unsafe { *(s[512..544].as_ptr() as *const [u8; 32]) }),
363            &$crate::U::from(unsafe { *(s[544..576].as_ptr() as *const [u8; 32]) }),
364            &$crate::U::from(unsafe { *(s[576..608].as_ptr() as *const [u8; 32]) }),
365            &$crate::U::from(unsafe { *(s[608..640].as_ptr() as *const [u8; 32]) }),
366        )
367    }};
368}
369
370pub const fn leftpad_bool(x: bool) -> [u8; 32] {
371    leftpad_u8(x as u8)
372}
373
374pub const fn leftpad_u24(x: [u8; 3]) -> [u8; 32] {
375    concat_arrays!([0u8; 32 - 3], x)
376}
377
378pub const fn leftpad_u8(x: u8) -> [u8; 32] {
379    concat_arrays!([0u8; 32 - 1], [x])
380}
381
382pub const fn rightpad_b8(x: [u8; 8]) -> [u8; 32] {
383    concat_arrays!(x, [0u8; 32 - 8])
384}
385
386pub const fn leftpad_addr(x: [u8; 20]) -> [u8; 32] {
387    concat_arrays!([0u8; 32 - 20], x)
388}
389
390pub const fn leftpad_u16(x: u16) -> [u8; 32] {
391    concat_arrays!([0u8; 32 - 2], x.to_be_bytes())
392}
393
394pub const fn leftpad_usize(x: usize) -> [u8; 32] {
395    concat_arrays!([0u8; 32 - core::mem::size_of::<usize>()], x.to_be_bytes())
396}
397
398pub const fn leftpad_u32(x: u32) -> [u8; 32] {
399    concat_arrays!([0u8; 32 - 4], x.to_be_bytes())
400}
401
402pub const fn const_keccak_sel(x: &[u8]) -> [u8; 4] {
403    let x = const_keccak256(x).0;
404    [x[0], x[1], x[2], x[3]]
405}
406
407pub const fn const_keccak_two_sel(x: &[u8], y: &[u8]) -> [u8; 4] {
408    let x = const_keccak256_two(x, y).0;
409    [x[0], x[1], x[2], x[3]]
410}
411
412pub fn decode_to_array(x: &[u8]) -> Option<&[u8]> {
413    if x.len() < 32 {
414        return None;
415    }
416    let offset = usize::from_be_bytes(x[32 - size_of::<usize>()..32].try_into().unwrap());
417    if x.len() < offset + 32 {
418        return None;
419    }
420    let len = usize::from_be_bytes(
421        x[offset + 32 - size_of::<usize>()..offset + 32]
422            .try_into()
423            .unwrap(),
424    );
425    let start = offset + 32;
426    let end = start.checked_add(len)?;
427    x.get(start..end)
428}
429
430pub fn decode_to_str(x: &[u8]) -> Option<&str> {
431    str::from_utf8(decode_to_array(x)?).ok()
432}
433
434#[cfg(feature = "alloc")]
435pub fn decode_to_string(x: &[u8]) -> Option<String> {
436    Some(String::from_utf8_lossy(decode_to_array(x)?).into_owned())
437}
438
439#[test]
440fn test_access() {
441    let cd = const_hex_decode_to_array::<{ 32 * 2 + 4 }>(b"a9059cbb0000000000000000000000006221a9c005f6e47eb398fd867784cacfdcfff4e7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
442    let a = const_hex_decode_to_array::<20>(b"6221a9c005f6e47eb398fd867784cacfdcfff4e7").unwrap();
443    let (addr, amt) = read_words!(&cd[4..], 2);
444    assert_eq!((a, U::MAX), (U::from(*addr).into(), U::from(*amt)));
445}
446
447#[test]
448fn test_address() {
449    address!(b"6221a9c005f6e47eb398fd867784cacfdcfff4e7");
450}
451
452#[cfg(all(test, feature = "proptest"))]
453mod test {
454    use proptest::prelude::*;
455
456    use super::*;
457
458    use alloc::string::String;
459
460    use alloy_sol_types::SolType;
461
462    proptest! {
463        #[test]
464        fn test_array_decoding(x in proptest::collection::vec(any::<u8>(), 1..20000usize)) {
465            let e = alloy_sol_types::sol_data::Bytes::abi_encode(&x);
466            assert_eq!(&x, decode_to_array(&e).unwrap());
467        }
468
469        #[test]
470        fn test_string_decoding(x in any::<String>()) {
471            let e = alloy_sol_types::sol_data::String::abi_encode(&x);
472            assert_eq!(x, decode_to_string(&e).unwrap());
473            assert_eq!(x, decode_to_str(&e).unwrap());
474        }
475    }
476}