1use 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
20pub const RECURSION_LIMIT: u8 = 16;
23
24#[derive(Clone, Copy)]
32pub struct Decoder<'de> {
33 buf: &'de [u8],
35 offset: usize,
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("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 #[inline]
74 pub const fn new(buf: &'de [u8]) -> Self {
75 Self { buf, offset: 0, depth: 0 }
76 }
77
78 #[inline]
80 pub const fn offset(&self) -> usize {
81 self.offset
82 }
83
84 #[inline]
86 pub const fn remaining(&self) -> Option<usize> {
87 self.buf.len().checked_sub(self.offset)
88 }
89
90 #[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 #[inline]
98 pub fn remaining_buf(&self) -> Option<&'de [u8]> {
99 self.buf.get(self.offset..)
100 }
101
102 #[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 #[inline]
116 pub fn raw_child(&self) -> Result<Self> {
117 self.child(self.offset)
118 }
119
120 #[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 #[inline]
136 const fn increase_offset(&mut self, len: usize) {
137 self.offset += len;
138 }
139
140 #[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 #[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 #[inline]
155 pub fn peek_len(&self, len: usize) -> Result<&'de [u8], Error> {
156 self.peek_len_at(self.offset, len)
157 }
158
159 #[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 #[inline]
168 pub fn peek_word(&self) -> Result<&'de Word, Error> {
169 self.peek_word_at(self.offset)
170 }
171
172 #[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 #[inline]
181 pub fn peek_offset(&self) -> Result<usize> {
182 self.peek_word().and_then(utils::as_offset)
183 }
184
185 #[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 #[inline]
196 pub fn take_indirection(&mut self) -> Result<Self, Error> {
197 self.take_offset().and_then(|offset| self.child(offset))
198 }
199
200 #[inline]
202 pub fn take_offset(&mut self) -> Result<usize> {
203 self.take_word().and_then(utils::as_offset)
204 }
205
206 #[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 #[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 #[inline]
221 pub const fn set_offset(&mut self, offset: usize) {
222 self.offset = offset;
223 }
224
225 #[inline]
227 pub fn decode<T: Token<'de>>(&mut self) -> Result<T> {
228 T::decode_from(self)
229 }
230
231 #[inline]
233 pub fn decode_sequence<T: Token<'de> + TokenSeq<'de>>(&mut self) -> Result<T> {
234 T::decode_sequence(self)
235 }
236}
237
238#[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#[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#[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 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 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 #[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" "0000000000000000000000000000000000000000000000000000000000000040" "0000000000000000000000000000000000000000000000000000000000000160" "0000000000000000000000000000000000000000000000000000000000000060" "00000000000000000000000000000000000000000000000000000000000000a0" "00000000000000000000000000000000000000000000000000000000000000e0" "0000000000000000000000000000000000000000000000000000000000000020" "1111111111111111111111111111111111111111111111111111111111111111"
711 "0000000000000000000000000000000000000000000000000000000000000020" "2222222222222222222222222222222222222222222222222222222222222222"
713 "0000000000000000000000000000000000000000000000000000000000000020" "3333333333333333333333333333333333333333333333333333333333333333"
715 "0000000000000000000000000000000000000000000000000000000000000004" "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}