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