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