alloy_sol_types/abi/
decoder.rs

1// Copyright 2015-2020 Parity Technologies
2// Copyright 2023-2023 Alloy Contributors
3//
4// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7// option. This file may not be copied, modified, or distributed
8// except according to those terms.
9//
10
11use crate::{
12    abi::{token::TokenSeq, Token},
13    utils, Error, Result, Word,
14};
15use alloc::vec::Vec;
16use alloy_primitives::hex;
17use core::{fmt, slice::SliceIndex};
18
19/// The decoder recursion limit.
20/// This is currently hardcoded, but may be parameterizable in the future.
21pub const RECURSION_LIMIT: u8 = 16;
22
23/// The [`Decoder`] wraps a byte slice with necessary info to progressively
24/// deserialize the bytes into a sequence of tokens.
25///
26/// # Usage Note
27///
28/// While the Decoder contains the necessary info, the actual deserialization
29/// is done in the [`crate::SolType`] trait.
30#[derive(Clone, Copy)]
31pub struct Decoder<'de> {
32    // The underlying buffer.
33    buf: &'de [u8],
34    // The current offset in the buffer.
35    offset: usize,
36    /// The current recursion depth.
37    depth: u8,
38}
39
40impl fmt::Debug for Decoder<'_> {
41    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
42        let mut body = self.buf.chunks(32).map(hex::encode_prefixed).collect::<Vec<_>>();
43        body[self.offset / 32].push_str(" <-- Next Word");
44
45        f.debug_struct("Decoder")
46            .field("buf", &body)
47            .field("offset", &self.offset)
48            .field("depth", &self.depth)
49            .finish()
50    }
51}
52
53impl fmt::Display for Decoder<'_> {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        writeln!(f, "Abi Decode Buffer")?;
56
57        for (i, chunk) in self.buf.chunks(32).enumerate() {
58            let idx = i * 32;
59            writeln!(
60                f,
61                "0x{idx:04x}: {}{}",
62                hex::encode_prefixed(chunk),
63                if idx == self.offset { " <-- Next Word" } else { "" }
64            )?;
65        }
66        Ok(())
67    }
68}
69
70impl<'de> Decoder<'de> {
71    /// Instantiate a new decoder from a byte slice and a validation flag.
72    #[inline]
73    pub const fn new(buf: &'de [u8]) -> Self {
74        Self { buf, offset: 0, depth: 0 }
75    }
76
77    /// Returns the current offset in the buffer.
78    #[inline]
79    pub const fn offset(&self) -> usize {
80        self.offset
81    }
82
83    /// Returns the number of bytes in the remaining buffer.
84    #[inline]
85    pub const fn remaining(&self) -> Option<usize> {
86        self.buf.len().checked_sub(self.offset)
87    }
88
89    /// Returns the number of words in the remaining buffer.
90    #[inline]
91    pub const fn remaining_words(&self) -> usize {
92        if let Some(remaining) = self.remaining() {
93            remaining / Word::len_bytes()
94        } else {
95            0
96        }
97    }
98
99    /// Returns a reference to the remaining bytes in the buffer.
100    #[inline]
101    pub fn remaining_buf(&self) -> Option<&'de [u8]> {
102        self.buf.get(self.offset..)
103    }
104
105    /// Returns whether the remaining buffer is empty.
106    #[inline]
107    pub const fn is_empty(&self) -> bool {
108        match self.remaining() {
109            Some(0) | None => true,
110            Some(_) => false,
111        }
112    }
113
114    /// Create a child decoder, starting at `offset` bytes from the current
115    /// decoder's offset.
116    ///
117    /// See [`child`](Self::child).
118    #[inline]
119    pub fn raw_child(&self) -> Result<Self> {
120        self.child(self.offset)
121    }
122
123    /// Create a child decoder, starting at `offset` bytes from the current
124    /// decoder's offset.
125    /// The child decoder shares the buffer.
126    #[inline]
127    pub fn child(&self, offset: usize) -> Result<Self, Error> {
128        if self.depth >= RECURSION_LIMIT {
129            return Err(Error::RecursionLimitExceeded(RECURSION_LIMIT));
130        }
131        match self.buf.get(offset..) {
132            Some(buf) => Ok(Decoder { buf, offset: 0, depth: self.depth + 1 }),
133            None => Err(Error::Overrun),
134        }
135    }
136
137    /// Advance the offset by `len` bytes.
138    #[inline]
139    fn increase_offset(&mut self, len: usize) {
140        self.offset += len;
141    }
142
143    /// Peek into the buffer.
144    #[inline]
145    pub fn peek<I: SliceIndex<[u8]>>(&self, index: I) -> Result<&'de I::Output, Error> {
146        self.buf.get(index).ok_or(Error::Overrun)
147    }
148
149    /// Peek a slice of size `len` from the buffer at a specific offset, without
150    /// advancing the offset.
151    #[inline]
152    pub fn peek_len_at(&self, offset: usize, len: usize) -> Result<&'de [u8], Error> {
153        self.peek(offset..offset + len)
154    }
155
156    /// Peek a slice of size `len` from the buffer without advancing the offset.
157    #[inline]
158    pub fn peek_len(&self, len: usize) -> Result<&'de [u8], Error> {
159        self.peek_len_at(self.offset, len)
160    }
161
162    /// Peek a word from the buffer at a specific offset, without advancing the
163    /// offset.
164    #[inline]
165    pub fn peek_word_at(&self, offset: usize) -> Result<&'de Word, Error> {
166        self.peek_len_at(offset, Word::len_bytes()).map(|w| <&Word>::try_from(w).unwrap())
167    }
168
169    /// Peek the next word from the buffer without advancing the offset.
170    #[inline]
171    pub fn peek_word(&self) -> Result<&'de Word, Error> {
172        self.peek_word_at(self.offset)
173    }
174
175    /// Peek a `usize` from the buffer at a specific offset, without advancing
176    /// the offset.
177    #[inline]
178    pub fn peek_offset_at(&self, offset: usize) -> Result<usize> {
179        self.peek_word_at(offset).and_then(utils::as_offset)
180    }
181
182    /// Peek a `usize` from the buffer, without advancing the offset.
183    #[inline]
184    pub fn peek_offset(&self) -> Result<usize> {
185        self.peek_word().and_then(utils::as_offset)
186    }
187
188    /// Take a word from the buffer, advancing the offset.
189    #[inline]
190    pub fn take_word(&mut self) -> Result<&'de Word, Error> {
191        let contents = self.peek_word()?;
192        self.increase_offset(Word::len_bytes());
193        Ok(contents)
194    }
195
196    /// Return a child decoder by consuming a word, interpreting it as a
197    /// pointer, and following it.
198    #[inline]
199    pub fn take_indirection(&mut self) -> Result<Self, Error> {
200        self.take_offset().and_then(|offset| self.child(offset))
201    }
202
203    /// Takes a `usize` offset from the buffer by consuming a word.
204    #[inline]
205    pub fn take_offset(&mut self) -> Result<usize> {
206        self.take_word().and_then(utils::as_offset)
207    }
208
209    /// Takes a slice of bytes of the given length.
210    #[inline]
211    pub fn take_slice(&mut self, len: usize) -> Result<&'de [u8]> {
212        self.peek_len(len).inspect(|_| self.increase_offset(len))
213    }
214
215    /// Takes the offset from the child decoder and sets it as the current
216    /// offset.
217    #[inline]
218    pub fn take_offset_from(&mut self, child: &Self) {
219        self.set_offset(child.offset + (self.buf.len() - child.buf.len()));
220    }
221
222    /// Sets the current offset in the buffer.
223    #[inline]
224    pub fn set_offset(&mut self, offset: usize) {
225        self.offset = offset;
226    }
227
228    /// Decodes a single token from the underlying buffer.
229    #[inline]
230    pub fn decode<T: Token<'de>>(&mut self) -> Result<T> {
231        T::decode_from(self)
232    }
233
234    /// Decodes a sequence of tokens from the underlying buffer.
235    #[inline]
236    pub fn decode_sequence<T: Token<'de> + TokenSeq<'de>>(&mut self) -> Result<T> {
237        T::decode_sequence(self)
238    }
239}
240
241/// ABI-decodes a token by wrapping it in a single-element tuple.
242///
243/// You are probably looking for
244/// [`SolValue::abi_decode`](crate::SolValue::abi_decode) if you are not
245/// intending to use raw tokens.
246///
247/// See the [`abi`](super) module for more information.
248#[inline(always)]
249pub fn decode<'de, T: Token<'de>>(data: &'de [u8]) -> Result<T> {
250    decode_sequence::<(T,)>(data).map(|(t,)| t)
251}
252
253/// ABI-decodes top-level function args.
254///
255/// Decodes as function parameters if [`T` is a tuple](TokenSeq::IS_TUPLE).
256/// Otherwise, decodes it as a single-element tuple.
257///
258/// You are probably looking for
259/// [`SolValue::abi_decode_params`](crate::SolValue::abi_decode_params) if
260/// you are not intending to use raw tokens.
261///
262/// See the [`abi`](super) module for more information.
263#[inline(always)]
264pub fn decode_params<'de, T: TokenSeq<'de>>(data: &'de [u8]) -> Result<T> {
265    let decode = const {
266        if T::IS_TUPLE {
267            decode_sequence
268        } else {
269            decode
270        }
271    };
272    decode(data)
273}
274
275/// Decodes ABI compliant vector of bytes into vector of tokens described by
276/// types param.
277///
278/// You are probably looking for
279/// [`SolValue::abi_decode_sequence`](crate::SolValue::abi_decode_sequence) if
280/// you are not intending to use raw tokens.
281///
282/// See the [`abi`](super) module for more information.
283#[inline]
284pub fn decode_sequence<'de, T: TokenSeq<'de>>(data: &'de [u8]) -> Result<T> {
285    let mut decoder = Decoder::new(data);
286    let result = decoder.decode_sequence::<T>()?;
287    Ok(result)
288}
289
290#[cfg(test)]
291mod tests {
292    use crate::{sol, sol_data, utils::pad_usize, SolType, SolValue};
293    use alloc::string::ToString;
294    use alloy_primitives::{address, bytes, hex, Address, B256, U256};
295
296    #[test]
297    fn dynamic_array_of_dynamic_arrays() {
298        type MyTy = sol_data::Array<sol_data::Array<sol_data::Address>>;
299        let encoded = hex!(
300            "
301    		0000000000000000000000000000000000000000000000000000000000000020
302    		0000000000000000000000000000000000000000000000000000000000000002
303    		0000000000000000000000000000000000000000000000000000000000000040
304    		0000000000000000000000000000000000000000000000000000000000000080
305    		0000000000000000000000000000000000000000000000000000000000000001
306    		0000000000000000000000001111111111111111111111111111111111111111
307    		0000000000000000000000000000000000000000000000000000000000000001
308    		0000000000000000000000002222222222222222222222222222222222222222
309    	"
310        );
311
312        let ty = vec![vec![Address::repeat_byte(0x11)], vec![Address::repeat_byte(0x22)]];
313        assert_eq!(MyTy::abi_encode_params(&ty), encoded);
314
315        let decoded = MyTy::abi_decode_params(&encoded).unwrap();
316        assert_eq!(decoded, ty);
317        assert_eq!(decoded.abi_encode_params(), encoded);
318        assert_eq!(decoded.abi_encoded_size(), encoded.len());
319    }
320
321    #[test]
322    fn decode_static_tuple_of_addresses_and_uints() {
323        type MyTy = (sol_data::Address, sol_data::Address, sol_data::Uint<256>);
324
325        let encoded = hex!(
326            "
327    		0000000000000000000000001111111111111111111111111111111111111111
328    		0000000000000000000000002222222222222222222222222222222222222222
329    		1111111111111111111111111111111111111111111111111111111111111111
330    	"
331        );
332        let address1 = Address::from([0x11u8; 20]);
333        let address2 = Address::from([0x22u8; 20]);
334        let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
335        let expected = (address1, address2, uint);
336        let decoded = MyTy::abi_decode_sequence(&encoded).unwrap();
337        assert_eq!(decoded, expected);
338        assert_eq!(decoded.abi_encode_params(), encoded);
339        assert_eq!(decoded.abi_encoded_size(), encoded.len());
340    }
341
342    #[test]
343    fn decode_dynamic_tuple() {
344        type MyTy = (sol_data::String, sol_data::String);
345        let encoded = hex!(
346            "
347    		0000000000000000000000000000000000000000000000000000000000000020
348    		0000000000000000000000000000000000000000000000000000000000000040
349    		0000000000000000000000000000000000000000000000000000000000000080
350    		0000000000000000000000000000000000000000000000000000000000000009
351    		6761766f66796f726b0000000000000000000000000000000000000000000000
352    		0000000000000000000000000000000000000000000000000000000000000009
353    		6761766f66796f726b0000000000000000000000000000000000000000000000
354    	"
355        );
356        let string1 = "gavofyork".to_string();
357        let string2 = "gavofyork".to_string();
358        let expected = (string1, string2);
359
360        // this test vector contains a top-level indirect
361        let decoded = MyTy::abi_decode(&encoded).unwrap();
362        assert_eq!(decoded, expected);
363        assert_eq!(decoded.abi_encode(), encoded);
364        assert_eq!(decoded.abi_encoded_size(), encoded.len());
365    }
366
367    #[test]
368    fn decode_nested_tuple() {
369        type MyTy = (
370            sol_data::String,
371            sol_data::Bool,
372            sol_data::String,
373            (sol_data::String, sol_data::String, (sol_data::String, sol_data::String)),
374        );
375
376        let encoded = hex!(
377            "
378    		0000000000000000000000000000000000000000000000000000000000000020
379    		0000000000000000000000000000000000000000000000000000000000000080
380    		0000000000000000000000000000000000000000000000000000000000000001
381    		00000000000000000000000000000000000000000000000000000000000000c0
382    		0000000000000000000000000000000000000000000000000000000000000100
383    		0000000000000000000000000000000000000000000000000000000000000004
384    		7465737400000000000000000000000000000000000000000000000000000000
385    		0000000000000000000000000000000000000000000000000000000000000006
386    		6379626f72670000000000000000000000000000000000000000000000000000
387    		0000000000000000000000000000000000000000000000000000000000000060
388    		00000000000000000000000000000000000000000000000000000000000000a0
389    		00000000000000000000000000000000000000000000000000000000000000e0
390    		0000000000000000000000000000000000000000000000000000000000000005
391    		6e69676874000000000000000000000000000000000000000000000000000000
392    		0000000000000000000000000000000000000000000000000000000000000003
393    		6461790000000000000000000000000000000000000000000000000000000000
394    		0000000000000000000000000000000000000000000000000000000000000040
395    		0000000000000000000000000000000000000000000000000000000000000080
396    		0000000000000000000000000000000000000000000000000000000000000004
397    		7765656500000000000000000000000000000000000000000000000000000000
398    		0000000000000000000000000000000000000000000000000000000000000008
399    		66756e7465737473000000000000000000000000000000000000000000000000
400    	"
401        );
402        let string1 = "test".into();
403        let string2 = "cyborg".into();
404        let string3 = "night".into();
405        let string4 = "day".into();
406        let string5 = "weee".into();
407        let string6 = "funtests".into();
408        let bool = true;
409        let deep_tuple = (string5, string6);
410        let inner_tuple = (string3, string4, deep_tuple);
411        let expected = (string1, bool, string2, inner_tuple);
412
413        let decoded = MyTy::abi_decode(&encoded).unwrap();
414        assert_eq!(decoded, expected);
415        assert_eq!(decoded.abi_encode(), encoded);
416        assert_eq!(decoded.abi_encoded_size(), encoded.len());
417    }
418
419    #[test]
420    fn decode_complex_tuple_of_dynamic_and_static_types() {
421        type MyTy = (sol_data::Uint<256>, sol_data::String, sol_data::Address, sol_data::Address);
422
423        let encoded = hex!(
424            "
425    		0000000000000000000000000000000000000000000000000000000000000020
426    		1111111111111111111111111111111111111111111111111111111111111111
427    		0000000000000000000000000000000000000000000000000000000000000080
428    		0000000000000000000000001111111111111111111111111111111111111111
429    		0000000000000000000000002222222222222222222222222222222222222222
430    		0000000000000000000000000000000000000000000000000000000000000009
431    		6761766f66796f726b0000000000000000000000000000000000000000000000
432    	"
433        );
434        let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
435        let string = "gavofyork".to_string();
436        let address1 = Address::from([0x11u8; 20]);
437        let address2 = Address::from([0x22u8; 20]);
438        let expected = (uint, string, address1, address2);
439
440        let decoded = MyTy::abi_decode(&encoded).unwrap();
441        assert_eq!(decoded, expected);
442        assert_eq!(decoded.abi_encode(), encoded);
443        assert_eq!(decoded.abi_encoded_size(), encoded.len());
444    }
445
446    #[test]
447    fn decode_params_containing_dynamic_tuple() {
448        type MyTy = (
449            sol_data::Address,
450            (sol_data::Bool, sol_data::String, sol_data::String),
451            sol_data::Address,
452            sol_data::Address,
453            sol_data::Bool,
454        );
455
456        let encoded = hex!(
457            "
458    		0000000000000000000000002222222222222222222222222222222222222222
459    		00000000000000000000000000000000000000000000000000000000000000a0
460    		0000000000000000000000003333333333333333333333333333333333333333
461    		0000000000000000000000004444444444444444444444444444444444444444
462    		0000000000000000000000000000000000000000000000000000000000000000
463    		0000000000000000000000000000000000000000000000000000000000000001
464    		0000000000000000000000000000000000000000000000000000000000000060
465    		00000000000000000000000000000000000000000000000000000000000000a0
466    		0000000000000000000000000000000000000000000000000000000000000009
467    		7370616365736869700000000000000000000000000000000000000000000000
468    		0000000000000000000000000000000000000000000000000000000000000006
469    		6379626f72670000000000000000000000000000000000000000000000000000
470    	"
471        );
472        let address1 = Address::from([0x22u8; 20]);
473        let bool1 = true;
474        let string1 = "spaceship".to_string();
475        let string2 = "cyborg".to_string();
476        let tuple = (bool1, string1, string2);
477        let address2 = Address::from([0x33u8; 20]);
478        let address3 = Address::from([0x44u8; 20]);
479        let bool2 = false;
480        let expected = (address1, tuple, address2, address3, bool2);
481
482        let decoded = MyTy::abi_decode_params(&encoded).unwrap();
483        assert_eq!(decoded, expected);
484        assert_eq!(decoded.abi_encode_params(), encoded);
485        assert_eq!(decoded.abi_encoded_size(), encoded.len() + 32);
486    }
487
488    #[test]
489    fn decode_params_containing_static_tuple() {
490        type MyTy = (
491            sol_data::Address,
492            (sol_data::Address, sol_data::Bool, sol_data::Bool),
493            sol_data::Address,
494            sol_data::Address,
495        );
496
497        let encoded = hex!(
498            "
499    		0000000000000000000000001111111111111111111111111111111111111111
500    		0000000000000000000000002222222222222222222222222222222222222222
501    		0000000000000000000000000000000000000000000000000000000000000001
502    		0000000000000000000000000000000000000000000000000000000000000000
503    		0000000000000000000000003333333333333333333333333333333333333333
504    		0000000000000000000000004444444444444444444444444444444444444444
505    	"
506        );
507        let address1 = Address::from([0x11u8; 20]);
508        let address2 = Address::from([0x22u8; 20]);
509        let bool1 = true;
510        let bool2 = false;
511        let tuple = (address2, bool1, bool2);
512        let address3 = Address::from([0x33u8; 20]);
513        let address4 = Address::from([0x44u8; 20]);
514
515        let expected = (address1, tuple, address3, address4);
516
517        let decoded = MyTy::abi_decode_params(&encoded).unwrap();
518        assert_eq!(decoded, expected);
519    }
520
521    #[test]
522    fn decode_data_with_size_that_is_not_a_multiple_of_32() {
523        type MyTy = (
524            sol_data::Uint<256>,
525            sol_data::String,
526            sol_data::String,
527            sol_data::Uint<256>,
528            sol_data::Uint<256>,
529        );
530
531        let data = (
532            pad_usize(0).into(),
533            "12203967b532a0c14c980b5aeffb17048bdfaef2c293a9509f08eb3c6b0f5f8f0942e7b9cc76ca51cca26ce546920448e308fda6870b5e2ae12a2409d942de428113P720p30fps16x9".to_string(),
534            "93c717e7c0a6517a".to_string(),
535            pad_usize(1).into(),
536            pad_usize(5538829).into()
537        );
538
539        let encoded = hex!(
540            "
541            0000000000000000000000000000000000000000000000000000000000000000
542            00000000000000000000000000000000000000000000000000000000000000a0
543            0000000000000000000000000000000000000000000000000000000000000152
544            0000000000000000000000000000000000000000000000000000000000000001
545            000000000000000000000000000000000000000000000000000000000054840d
546            0000000000000000000000000000000000000000000000000000000000000092
547            3132323033393637623533326130633134633938306235616566666231373034
548            3862646661656632633239336139353039663038656233633662306635663866
549            3039343265376239636337366361353163636132366365353436393230343438
550            6533303866646136383730623565326165313261323430396439343264653432
551            3831313350373230703330667073313678390000000000000000000000000000
552            0000000000000000000000000000000000103933633731376537633061363531
553            3761
554        "
555        );
556
557        assert_eq!(MyTy::abi_decode_sequence(&encoded).unwrap(), data);
558    }
559
560    #[test]
561    fn decode_after_fixed_bytes_with_less_than_32_bytes() {
562        type MyTy = (
563            sol_data::Address,
564            sol_data::FixedBytes<32>,
565            sol_data::FixedBytes<4>,
566            sol_data::String,
567        );
568
569        let encoded = hex!(
570            "
571    		0000000000000000000000008497afefdc5ac170a664a231f6efb25526ef813f
572    		0101010101010101010101010101010101010101010101010101010101010101
573    		0202020202020202020202020202020202020202020202020202020202020202
574    		0000000000000000000000000000000000000000000000000000000000000080
575    		000000000000000000000000000000000000000000000000000000000000000a
576    		3078303030303030314600000000000000000000000000000000000000000000
577    	    "
578        );
579
580        assert_eq!(
581            MyTy::abi_decode_params(&encoded).unwrap(),
582            (
583                address!("0x8497afefdc5ac170a664a231f6efb25526ef813f"),
584                B256::repeat_byte(0x01),
585                [0x02; 4].into(),
586                "0x0000001F".into(),
587            )
588        );
589    }
590
591    #[test]
592    fn decode_broken_utf8() {
593        let encoded = hex!(
594            "
595    		0000000000000000000000000000000000000000000000000000000000000020
596    		0000000000000000000000000000000000000000000000000000000000000004
597    		e4b88de500000000000000000000000000000000000000000000000000000000
598            "
599        );
600
601        assert_eq!(sol_data::String::abi_decode(&encoded).unwrap(), "不�".to_string());
602    }
603
604    #[test]
605    #[cfg_attr(miri, ignore = "OOM https://github.com/rust-lang/miri/issues/3637")]
606    fn decode_corrupted_dynamic_array() {
607        type MyTy = sol_data::Array<sol_data::Uint<32>>;
608        // line 1 at 0x00 =   0: tail offset of array
609        // line 2 at 0x20 =  32: length of array
610        // line 3 at 0x40 =  64: first word
611        // line 4 at 0x60 =  96: second word
612        let encoded = hex!(
613            "
614    	0000000000000000000000000000000000000000000000000000000000000020
615    	00000000000000000000000000000000000000000000000000000000ffffffff
616    	0000000000000000000000000000000000000000000000000000000000000001
617    	0000000000000000000000000000000000000000000000000000000000000002
618        "
619        );
620        assert!(MyTy::abi_decode_sequence(&encoded).is_err());
621    }
622
623    #[test]
624    fn decode_verify_addresses() {
625        let input = hex!(
626            "
627    	0000000000000000000000000000000000000000000000000000000000012345
628    	0000000000000000000000000000000000000000000000000000000000054321
629    	"
630        );
631
632        assert_eq!(
633            sol_data::Address::abi_decode(&input).unwrap(),
634            address!("0000000000000000000000000000000000012345")
635        );
636        assert!(<(sol_data::Address, sol_data::Address)>::abi_decode(&input).is_ok());
637    }
638
639    #[test]
640    fn decode_verify_bytes() {
641        type MyTy2 = (sol_data::Address, sol_data::Address);
642
643        let input = hex!(
644            "
645    	0000000000000000000000001234500000000000000000000000000000012345
646    	0000000000000000000000005432100000000000000000000000000000054321
647    	"
648        );
649        assert!(MyTy2::abi_decode_params(&input).is_ok());
650    }
651
652    #[test]
653    fn signed_int_dirty_high_bytes() {
654        type MyTy = sol_data::Int<8>;
655
656        let dirty_negative =
657            hex!("f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
658
659        assert_eq!(MyTy::abi_decode(&dirty_negative).unwrap(), -1);
660
661        let dirty_positive =
662            hex!("700000000000000000000000000000000000000000000000000000000000007f");
663
664        assert_eq!(MyTy::abi_decode(&dirty_positive).unwrap(), 127);
665    }
666
667    // https://github.com/alloy-rs/core/issues/433
668    #[test]
669    fn fixed_before_dynamic() {
670        sol! {
671            #[derive(Debug, PartialEq, Eq)]
672            struct Ty {
673                bytes32[3] arr;
674                bytes dyn;
675            }
676        }
677
678        let ty = Ty {
679            arr: [[0x11u8; 32].into(), [0x22u8; 32].into(), [0x33u8; 32].into()],
680            r#dyn: bytes![0x44u8; 4],
681        };
682        let encoded = hex!(
683            "0000000000000000000000000000000000000000000000000000000000000020"
684            "1111111111111111111111111111111111111111111111111111111111111111"
685            "2222222222222222222222222222222222222222222222222222222222222222"
686            "3333333333333333333333333333333333333333333333333333333333333333"
687            "0000000000000000000000000000000000000000000000000000000000000080"
688            "0000000000000000000000000000000000000000000000000000000000000004"
689            "4444444400000000000000000000000000000000000000000000000000000000"
690        );
691        assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
692        assert_eq!(ty.abi_encoded_size(), encoded.len());
693
694        assert_eq!(<Ty as SolType>::abi_decode(&encoded).unwrap(), ty);
695    }
696
697    #[test]
698    fn dynarray_before_dynamic() {
699        sol! {
700            #[derive(Debug, PartialEq, Eq)]
701            struct Ty {
702                bytes[3] arr;
703                bytes dyn;
704            }
705        }
706
707        let ty = Ty {
708            arr: [bytes![0x11u8; 32], bytes![0x22u8; 32], bytes![0x33u8; 32]],
709            r#dyn: bytes![0x44u8; 4],
710        };
711        let encoded = hex!(
712            "0000000000000000000000000000000000000000000000000000000000000020" // struct offset
713            "0000000000000000000000000000000000000000000000000000000000000040" // arr offset
714            "0000000000000000000000000000000000000000000000000000000000000160" // dyn offset
715            "0000000000000000000000000000000000000000000000000000000000000060" // arr[0] offset
716            "00000000000000000000000000000000000000000000000000000000000000a0" // arr[1] offset
717            "00000000000000000000000000000000000000000000000000000000000000e0" // arr[2] offset
718            "0000000000000000000000000000000000000000000000000000000000000020" // arr[0]
719            "1111111111111111111111111111111111111111111111111111111111111111"
720            "0000000000000000000000000000000000000000000000000000000000000020" // arr[1]
721            "2222222222222222222222222222222222222222222222222222222222222222"
722            "0000000000000000000000000000000000000000000000000000000000000020" // arr[2]
723            "3333333333333333333333333333333333333333333333333333333333333333"
724            "0000000000000000000000000000000000000000000000000000000000000004" // dyn
725            "4444444400000000000000000000000000000000000000000000000000000000"
726        );
727        assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
728        assert_eq!(ty.abi_encoded_size(), encoded.len());
729
730        assert_eq!(<Ty as SolType>::abi_decode(&encoded).unwrap(), ty);
731    }
732}