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