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