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