1use crate::{
12 abi::{encode_sequence, token::TokenSeq, Token},
13 utils, Error, Result, Word,
14};
15use alloc::{borrow::Cow, vec::Vec};
16use core::{fmt, slice::SliceIndex};
17
18pub const RECURSION_LIMIT: u8 = 16;
21
22#[derive(Clone, Copy)]
30pub struct Decoder<'de> {
31 buf: &'de [u8],
33 offset: usize,
35 validate: bool,
37 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("validate", &self.validate)
50 .field("depth", &self.depth)
51 .finish()
52 }
53}
54
55impl fmt::Display for Decoder<'_> {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 writeln!(f, "Abi Decode Buffer")?;
58
59 for (i, chunk) in self.buf.chunks(32).enumerate() {
60 let idx = i * 32;
61 writeln!(
62 f,
63 "0x{idx:04x}: {}{}",
64 hex::encode_prefixed(chunk),
65 if idx == self.offset { " <-- Next Word" } else { "" }
66 )?;
67 }
68 Ok(())
69 }
70}
71
72impl<'de> Decoder<'de> {
73 #[inline]
79 pub const fn new(buf: &'de [u8], validate: bool) -> Self {
80 Self { buf, offset: 0, validate, depth: 0 }
81 }
82
83 #[inline]
85 pub const fn offset(&self) -> usize {
86 self.offset
87 }
88
89 #[inline]
91 pub const fn remaining(&self) -> Option<usize> {
92 self.buf.len().checked_sub(self.offset)
93 }
94
95 #[inline]
97 pub const fn remaining_words(&self) -> usize {
98 if let Some(remaining) = self.remaining() {
99 remaining / Word::len_bytes()
100 } else {
101 0
102 }
103 }
104
105 #[inline]
107 pub fn remaining_buf(&self) -> Option<&'de [u8]> {
108 self.buf.get(self.offset..)
109 }
110
111 #[inline]
113 pub const fn is_empty(&self) -> bool {
114 match self.remaining() {
115 Some(0) | None => true,
116 Some(_) => false,
117 }
118 }
119
120 #[inline]
122 pub const fn validate(&self) -> bool {
123 self.validate
124 }
125
126 #[inline]
128 pub fn set_validate(&mut self, validate: bool) {
129 self.validate = validate;
130 }
131
132 #[inline]
137 pub fn raw_child(&self) -> Result<Self> {
138 self.child(self.offset)
139 }
140
141 #[inline]
145 pub fn child(&self, offset: usize) -> Result<Self, Error> {
146 if self.depth >= RECURSION_LIMIT {
147 return Err(Error::RecursionLimitExceeded(RECURSION_LIMIT));
148 }
149 match self.buf.get(offset..) {
150 Some(buf) => {
151 Ok(Decoder { buf, offset: 0, validate: self.validate, depth: self.depth + 1 })
152 }
153 None => Err(Error::Overrun),
154 }
155 }
156
157 #[inline]
159 fn increase_offset(&mut self, len: usize) {
160 self.offset += len;
161 }
162
163 #[inline]
165 pub fn peek<I: SliceIndex<[u8]>>(&self, index: I) -> Result<&'de I::Output, Error> {
166 self.buf.get(index).ok_or(Error::Overrun)
167 }
168
169 #[inline]
172 pub fn peek_len_at(&self, offset: usize, len: usize) -> Result<&'de [u8], Error> {
173 self.peek(offset..offset + len)
174 }
175
176 #[inline]
178 pub fn peek_len(&self, len: usize) -> Result<&'de [u8], Error> {
179 self.peek_len_at(self.offset, len)
180 }
181
182 #[inline]
185 pub fn peek_word_at(&self, offset: usize) -> Result<&'de Word, Error> {
186 self.peek_len_at(offset, Word::len_bytes()).map(|w| <&Word>::try_from(w).unwrap())
187 }
188
189 #[inline]
191 pub fn peek_word(&self) -> Result<&'de Word, Error> {
192 self.peek_word_at(self.offset)
193 }
194
195 #[inline]
198 pub fn peek_offset_at(&self, offset: usize) -> Result<usize> {
199 self.peek_word_at(offset).and_then(|word| utils::as_offset(word, self.validate))
200 }
201
202 #[inline]
204 pub fn peek_offset(&self) -> Result<usize> {
205 self.peek_word().and_then(|word| utils::as_offset(word, self.validate))
206 }
207
208 #[inline]
210 pub fn take_word(&mut self) -> Result<&'de Word, Error> {
211 let contents = self.peek_word()?;
212 self.increase_offset(Word::len_bytes());
213 Ok(contents)
214 }
215
216 #[inline]
219 pub fn take_indirection(&mut self) -> Result<Self, Error> {
220 self.take_offset().and_then(|offset| self.child(offset))
221 }
222
223 #[inline]
225 pub fn take_offset(&mut self) -> Result<usize> {
226 self.take_word().and_then(|word| utils::as_offset(word, self.validate))
227 }
228
229 pub fn take_slice(&mut self, len: usize) -> Result<&'de [u8]> {
232 if self.validate {
233 let padded_len = utils::next_multiple_of_32(len);
234 if self.offset + padded_len > self.buf.len() {
235 return Err(Error::Overrun);
236 }
237 if !utils::check_zeroes(self.peek(self.offset + len..self.offset + padded_len)?) {
238 return Err(Error::Other(Cow::Borrowed("non-empty bytes after packed array")));
239 }
240 }
241 self.take_slice_unchecked(len)
242 }
243
244 #[inline]
246 pub fn take_slice_unchecked(&mut self, len: usize) -> Result<&'de [u8]> {
247 self.peek_len(len).inspect(|_| self.increase_offset(len))
248 }
249
250 #[inline]
253 pub fn take_offset_from(&mut self, child: &Self) {
254 self.set_offset(child.offset + (self.buf.len() - child.buf.len()));
255 }
256
257 #[inline]
259 pub fn set_offset(&mut self, offset: usize) {
260 self.offset = offset;
261 }
262
263 #[inline]
265 pub fn decode<T: Token<'de>>(&mut self) -> Result<T> {
266 T::decode_from(self)
267 }
268
269 #[inline]
271 pub fn decode_sequence<T: Token<'de> + TokenSeq<'de>>(&mut self) -> Result<T> {
272 T::decode_sequence(self)
273 }
274}
275
276#[inline(always)]
284pub fn decode<'de, T: Token<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
285 decode_sequence::<(T,)>(data, validate).map(|(t,)| t)
286}
287
288#[inline(always)]
299pub fn decode_params<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
300 let decode = const {
301 if T::IS_TUPLE {
302 decode_sequence
303 } else {
304 decode
305 }
306 };
307 decode(data, validate)
308}
309
310#[inline]
319pub fn decode_sequence<'de, T: TokenSeq<'de>>(data: &'de [u8], validate: bool) -> Result<T> {
320 let mut decoder = Decoder::new(data, validate);
321 let result = decoder.decode_sequence::<T>()?;
322 if validate && encode_sequence(&result) != data {
323 return Err(Error::ReserMismatch);
324 }
325 Ok(result)
326}
327
328#[cfg(test)]
329mod tests {
330 use crate::{sol, sol_data, utils::pad_usize, SolType, SolValue};
331 use alloc::string::ToString;
332 use alloy_primitives::{address, bytes, hex, Address, B256, U256};
333
334 #[test]
335 fn dynamic_array_of_dynamic_arrays() {
336 type MyTy = sol_data::Array<sol_data::Array<sol_data::Address>>;
337 let encoded = hex!(
338 "
339 0000000000000000000000000000000000000000000000000000000000000020
340 0000000000000000000000000000000000000000000000000000000000000002
341 0000000000000000000000000000000000000000000000000000000000000040
342 0000000000000000000000000000000000000000000000000000000000000080
343 0000000000000000000000000000000000000000000000000000000000000001
344 0000000000000000000000001111111111111111111111111111111111111111
345 0000000000000000000000000000000000000000000000000000000000000001
346 0000000000000000000000002222222222222222222222222222222222222222
347 "
348 );
349
350 let ty = vec![vec![Address::repeat_byte(0x11)], vec![Address::repeat_byte(0x22)]];
351 assert_eq!(MyTy::abi_encode_params(&ty), encoded);
352
353 let decoded = MyTy::abi_decode_params(&encoded, false).unwrap();
354 assert_eq!(decoded, ty);
355 assert_eq!(decoded.abi_encode_params(), encoded);
356 assert_eq!(decoded.abi_encoded_size(), encoded.len());
357 }
358
359 #[test]
360 fn decode_static_tuple_of_addresses_and_uints() {
361 type MyTy = (sol_data::Address, sol_data::Address, sol_data::Uint<256>);
362
363 let encoded = hex!(
364 "
365 0000000000000000000000001111111111111111111111111111111111111111
366 0000000000000000000000002222222222222222222222222222222222222222
367 1111111111111111111111111111111111111111111111111111111111111111
368 "
369 );
370 let address1 = Address::from([0x11u8; 20]);
371 let address2 = Address::from([0x22u8; 20]);
372 let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
373 let expected = (address1, address2, uint);
374 let decoded = MyTy::abi_decode_sequence(&encoded, true).unwrap();
375 assert_eq!(decoded, expected);
376 assert_eq!(decoded.abi_encode_params(), encoded);
377 assert_eq!(decoded.abi_encoded_size(), encoded.len());
378 }
379
380 #[test]
381 fn decode_dynamic_tuple() {
382 type MyTy = (sol_data::String, sol_data::String);
383 let encoded = hex!(
384 "
385 0000000000000000000000000000000000000000000000000000000000000020
386 0000000000000000000000000000000000000000000000000000000000000040
387 0000000000000000000000000000000000000000000000000000000000000080
388 0000000000000000000000000000000000000000000000000000000000000009
389 6761766f66796f726b0000000000000000000000000000000000000000000000
390 0000000000000000000000000000000000000000000000000000000000000009
391 6761766f66796f726b0000000000000000000000000000000000000000000000
392 "
393 );
394 let string1 = "gavofyork".to_string();
395 let string2 = "gavofyork".to_string();
396 let expected = (string1, string2);
397
398 let decoded = MyTy::abi_decode(&encoded, true).unwrap();
400 assert_eq!(decoded, expected);
401 assert_eq!(decoded.abi_encode(), encoded);
402 assert_eq!(decoded.abi_encoded_size(), encoded.len());
403 }
404
405 #[test]
406 fn decode_nested_tuple() {
407 type MyTy = (
408 sol_data::String,
409 sol_data::Bool,
410 sol_data::String,
411 (sol_data::String, sol_data::String, (sol_data::String, sol_data::String)),
412 );
413
414 let encoded = hex!(
415 "
416 0000000000000000000000000000000000000000000000000000000000000020
417 0000000000000000000000000000000000000000000000000000000000000080
418 0000000000000000000000000000000000000000000000000000000000000001
419 00000000000000000000000000000000000000000000000000000000000000c0
420 0000000000000000000000000000000000000000000000000000000000000100
421 0000000000000000000000000000000000000000000000000000000000000004
422 7465737400000000000000000000000000000000000000000000000000000000
423 0000000000000000000000000000000000000000000000000000000000000006
424 6379626f72670000000000000000000000000000000000000000000000000000
425 0000000000000000000000000000000000000000000000000000000000000060
426 00000000000000000000000000000000000000000000000000000000000000a0
427 00000000000000000000000000000000000000000000000000000000000000e0
428 0000000000000000000000000000000000000000000000000000000000000005
429 6e69676874000000000000000000000000000000000000000000000000000000
430 0000000000000000000000000000000000000000000000000000000000000003
431 6461790000000000000000000000000000000000000000000000000000000000
432 0000000000000000000000000000000000000000000000000000000000000040
433 0000000000000000000000000000000000000000000000000000000000000080
434 0000000000000000000000000000000000000000000000000000000000000004
435 7765656500000000000000000000000000000000000000000000000000000000
436 0000000000000000000000000000000000000000000000000000000000000008
437 66756e7465737473000000000000000000000000000000000000000000000000
438 "
439 );
440 let string1 = "test".into();
441 let string2 = "cyborg".into();
442 let string3 = "night".into();
443 let string4 = "day".into();
444 let string5 = "weee".into();
445 let string6 = "funtests".into();
446 let bool = true;
447 let deep_tuple = (string5, string6);
448 let inner_tuple = (string3, string4, deep_tuple);
449 let expected = (string1, bool, string2, inner_tuple);
450
451 let decoded = MyTy::abi_decode(&encoded, true).unwrap();
452 assert_eq!(decoded, expected);
453 assert_eq!(decoded.abi_encode(), encoded);
454 assert_eq!(decoded.abi_encoded_size(), encoded.len());
455 }
456
457 #[test]
458 fn decode_complex_tuple_of_dynamic_and_static_types() {
459 type MyTy = (sol_data::Uint<256>, sol_data::String, sol_data::Address, sol_data::Address);
460
461 let encoded = hex!(
462 "
463 0000000000000000000000000000000000000000000000000000000000000020
464 1111111111111111111111111111111111111111111111111111111111111111
465 0000000000000000000000000000000000000000000000000000000000000080
466 0000000000000000000000001111111111111111111111111111111111111111
467 0000000000000000000000002222222222222222222222222222222222222222
468 0000000000000000000000000000000000000000000000000000000000000009
469 6761766f66796f726b0000000000000000000000000000000000000000000000
470 "
471 );
472 let uint = U256::from_be_bytes::<32>([0x11u8; 32]);
473 let string = "gavofyork".to_string();
474 let address1 = Address::from([0x11u8; 20]);
475 let address2 = Address::from([0x22u8; 20]);
476 let expected = (uint, string, address1, address2);
477
478 let decoded = MyTy::abi_decode(&encoded, true).unwrap();
479 assert_eq!(decoded, expected);
480 assert_eq!(decoded.abi_encode(), encoded);
481 assert_eq!(decoded.abi_encoded_size(), encoded.len());
482 }
483
484 #[test]
485 fn decode_params_containing_dynamic_tuple() {
486 type MyTy = (
487 sol_data::Address,
488 (sol_data::Bool, sol_data::String, sol_data::String),
489 sol_data::Address,
490 sol_data::Address,
491 sol_data::Bool,
492 );
493
494 let encoded = hex!(
495 "
496 0000000000000000000000002222222222222222222222222222222222222222
497 00000000000000000000000000000000000000000000000000000000000000a0
498 0000000000000000000000003333333333333333333333333333333333333333
499 0000000000000000000000004444444444444444444444444444444444444444
500 0000000000000000000000000000000000000000000000000000000000000000
501 0000000000000000000000000000000000000000000000000000000000000001
502 0000000000000000000000000000000000000000000000000000000000000060
503 00000000000000000000000000000000000000000000000000000000000000a0
504 0000000000000000000000000000000000000000000000000000000000000009
505 7370616365736869700000000000000000000000000000000000000000000000
506 0000000000000000000000000000000000000000000000000000000000000006
507 6379626f72670000000000000000000000000000000000000000000000000000
508 "
509 );
510 let address1 = Address::from([0x22u8; 20]);
511 let bool1 = true;
512 let string1 = "spaceship".to_string();
513 let string2 = "cyborg".to_string();
514 let tuple = (bool1, string1, string2);
515 let address2 = Address::from([0x33u8; 20]);
516 let address3 = Address::from([0x44u8; 20]);
517 let bool2 = false;
518 let expected = (address1, tuple, address2, address3, bool2);
519
520 let decoded = MyTy::abi_decode_params(&encoded, true).unwrap();
521 assert_eq!(decoded, expected);
522 assert_eq!(decoded.abi_encode_params(), encoded);
523 assert_eq!(decoded.abi_encoded_size(), encoded.len() + 32);
524 }
525
526 #[test]
527 fn decode_params_containing_static_tuple() {
528 type MyTy = (
529 sol_data::Address,
530 (sol_data::Address, sol_data::Bool, sol_data::Bool),
531 sol_data::Address,
532 sol_data::Address,
533 );
534
535 let encoded = hex!(
536 "
537 0000000000000000000000001111111111111111111111111111111111111111
538 0000000000000000000000002222222222222222222222222222222222222222
539 0000000000000000000000000000000000000000000000000000000000000001
540 0000000000000000000000000000000000000000000000000000000000000000
541 0000000000000000000000003333333333333333333333333333333333333333
542 0000000000000000000000004444444444444444444444444444444444444444
543 "
544 );
545 let address1 = Address::from([0x11u8; 20]);
546 let address2 = Address::from([0x22u8; 20]);
547 let bool1 = true;
548 let bool2 = false;
549 let tuple = (address2, bool1, bool2);
550 let address3 = Address::from([0x33u8; 20]);
551 let address4 = Address::from([0x44u8; 20]);
552
553 let expected = (address1, tuple, address3, address4);
554
555 let decoded = MyTy::abi_decode_params(&encoded, false).unwrap();
556 assert_eq!(decoded, expected);
557 }
558
559 #[test]
560 fn decode_data_with_size_that_is_not_a_multiple_of_32() {
561 type MyTy = (
562 sol_data::Uint<256>,
563 sol_data::String,
564 sol_data::String,
565 sol_data::Uint<256>,
566 sol_data::Uint<256>,
567 );
568
569 let data = (
570 pad_usize(0).into(),
571 "12203967b532a0c14c980b5aeffb17048bdfaef2c293a9509f08eb3c6b0f5f8f0942e7b9cc76ca51cca26ce546920448e308fda6870b5e2ae12a2409d942de428113P720p30fps16x9".to_string(),
572 "93c717e7c0a6517a".to_string(),
573 pad_usize(1).into(),
574 pad_usize(5538829).into()
575 );
576
577 let encoded = hex!(
578 "
579 0000000000000000000000000000000000000000000000000000000000000000
580 00000000000000000000000000000000000000000000000000000000000000a0
581 0000000000000000000000000000000000000000000000000000000000000152
582 0000000000000000000000000000000000000000000000000000000000000001
583 000000000000000000000000000000000000000000000000000000000054840d
584 0000000000000000000000000000000000000000000000000000000000000092
585 3132323033393637623533326130633134633938306235616566666231373034
586 3862646661656632633239336139353039663038656233633662306635663866
587 3039343265376239636337366361353163636132366365353436393230343438
588 6533303866646136383730623565326165313261323430396439343264653432
589 3831313350373230703330667073313678390000000000000000000000000000
590 0000000000000000000000000000000000103933633731376537633061363531
591 3761
592 "
593 );
594
595 assert_eq!(MyTy::abi_decode_sequence(&encoded, false).unwrap(), data);
596 }
597
598 #[test]
599 fn decode_after_fixed_bytes_with_less_than_32_bytes() {
600 type MyTy = (
601 sol_data::Address,
602 sol_data::FixedBytes<32>,
603 sol_data::FixedBytes<4>,
604 sol_data::String,
605 );
606
607 let encoded = hex!(
608 "
609 0000000000000000000000008497afefdc5ac170a664a231f6efb25526ef813f
610 0101010101010101010101010101010101010101010101010101010101010101
611 0202020202020202020202020202020202020202020202020202020202020202
612 0000000000000000000000000000000000000000000000000000000000000080
613 000000000000000000000000000000000000000000000000000000000000000a
614 3078303030303030314600000000000000000000000000000000000000000000
615 "
616 );
617
618 assert_eq!(
619 MyTy::abi_decode_params(&encoded, false).unwrap(),
620 (
621 address!("0x8497afefdc5ac170a664a231f6efb25526ef813f"),
622 B256::repeat_byte(0x01),
623 [0x02; 4].into(),
624 "0x0000001F".into(),
625 )
626 );
627 }
628
629 #[test]
630 fn decode_broken_utf8() {
631 let encoded = hex!(
632 "
633 0000000000000000000000000000000000000000000000000000000000000020
634 0000000000000000000000000000000000000000000000000000000000000004
635 e4b88de500000000000000000000000000000000000000000000000000000000
636 "
637 );
638
639 assert_eq!(sol_data::String::abi_decode(&encoded, false).unwrap(), "不�".to_string());
640 }
641
642 #[test]
643 #[cfg_attr(miri, ignore = "OOM https://github.com/rust-lang/miri/issues/3637")]
644 fn decode_corrupted_dynamic_array() {
645 type MyTy = sol_data::Array<sol_data::Uint<32>>;
646 let encoded = hex!(
651 "
652 0000000000000000000000000000000000000000000000000000000000000020
653 00000000000000000000000000000000000000000000000000000000ffffffff
654 0000000000000000000000000000000000000000000000000000000000000001
655 0000000000000000000000000000000000000000000000000000000000000002
656 "
657 );
658 assert!(MyTy::abi_decode_sequence(&encoded, true).is_err());
659 }
660
661 #[test]
662 fn decode_verify_addresses() {
663 let input = hex!(
664 "
665 0000000000000000000000000000000000000000000000000000000000012345
666 0000000000000000000000000000000000000000000000000000000000054321
667 "
668 );
669 assert!(sol_data::Address::abi_decode(&input, false).is_ok());
670 assert!(sol_data::Address::abi_decode(&input, true).is_err());
671 assert!(<(sol_data::Address, sol_data::Address)>::abi_decode(&input, true).is_ok());
672 }
673
674 #[test]
675 fn decode_verify_bytes() {
676 type MyTy = (sol_data::Address, sol_data::FixedBytes<20>);
677 type MyTy2 = (sol_data::Address, sol_data::Address);
678
679 let input = hex!(
680 "
681 0000000000000000000000001234500000000000000000000000000000012345
682 0000000000000000000000005432100000000000000000000000000000054321
683 "
684 );
685 MyTy::abi_decode_params(&input, true).unwrap_err();
686 assert!(MyTy2::abi_decode_params(&input, true).is_ok());
687 }
688
689 #[test]
690 fn signed_int_dirty_high_bytes() {
691 type MyTy = sol_data::Int<8>;
692
693 let dirty_negative =
694 hex!("f0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
695
696 assert_eq!(MyTy::abi_decode(&dirty_negative, false).unwrap(), -1);
697
698 assert!(
699 matches!(
700 MyTy::abi_decode(&dirty_negative, true),
701 Err(crate::Error::TypeCheckFail { .. }),
702 ),
703 "did not match error"
704 );
705
706 let dirty_positive =
707 hex!("700000000000000000000000000000000000000000000000000000000000007f");
708
709 assert_eq!(MyTy::abi_decode(&dirty_positive, false).unwrap(), 127);
710
711 assert!(
712 matches!(
713 MyTy::abi_decode(&dirty_positive, true),
714 Err(crate::Error::TypeCheckFail { .. }),
715 ),
716 "did not match error"
717 );
718 }
719
720 #[test]
722 fn fixed_before_dynamic() {
723 sol! {
724 #[derive(Debug, PartialEq, Eq)]
725 struct Ty {
726 bytes32[3] arr;
727 bytes dyn;
728 }
729 }
730
731 let ty = Ty {
732 arr: [[0x11u8; 32].into(), [0x22u8; 32].into(), [0x33u8; 32].into()],
733 r#dyn: bytes![0x44u8; 4],
734 };
735 let encoded = hex!(
736 "0000000000000000000000000000000000000000000000000000000000000020"
737 "1111111111111111111111111111111111111111111111111111111111111111"
738 "2222222222222222222222222222222222222222222222222222222222222222"
739 "3333333333333333333333333333333333333333333333333333333333333333"
740 "0000000000000000000000000000000000000000000000000000000000000080"
741 "0000000000000000000000000000000000000000000000000000000000000004"
742 "4444444400000000000000000000000000000000000000000000000000000000"
743 );
744 assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
745 assert_eq!(ty.abi_encoded_size(), encoded.len());
746
747 assert_eq!(<Ty as SolType>::abi_decode(&encoded, true).unwrap(), ty);
748 }
749
750 #[test]
751 fn dynarray_before_dynamic() {
752 sol! {
753 #[derive(Debug, PartialEq, Eq)]
754 struct Ty {
755 bytes[3] arr;
756 bytes dyn;
757 }
758 }
759
760 let ty = Ty {
761 arr: [bytes![0x11u8; 32], bytes![0x22u8; 32], bytes![0x33u8; 32]],
762 r#dyn: bytes![0x44u8; 4],
763 };
764 let encoded = hex!(
765 "0000000000000000000000000000000000000000000000000000000000000020" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000160" "0000000000000000000000000000000000000000000000000000000000000060" "00000000000000000000000000000000000000000000000000000000000000a0" "00000000000000000000000000000000000000000000000000000000000000e0" "0000000000000000000000000000000000000000000000000000000000000020" "1111111111111111111111111111111111111111111111111111111111111111"
773 "0000000000000000000000000000000000000000000000000000000000000020" "2222222222222222222222222222222222222222222222222222222222222222"
775 "0000000000000000000000000000000000000000000000000000000000000020" "3333333333333333333333333333333333333333333333333333333333333333"
777 "0000000000000000000000000000000000000000000000000000000000000004" "4444444400000000000000000000000000000000000000000000000000000000"
779 );
780 assert_eq!(hex::encode(ty.abi_encode()), hex::encode(encoded));
781 assert_eq!(ty.abi_encoded_size(), encoded.len());
782
783 assert_eq!(<Ty as SolType>::abi_decode(&encoded, false).unwrap(), ty);
784 }
785}