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