alloy_sol_types/abi/
encoder.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
10use crate::{
11    abi::{Token, TokenSeq},
12    utils, Word,
13};
14use alloc::vec::Vec;
15use core::{mem, ptr};
16
17/// An ABI encoder.
18///
19/// This is not intended for public consumption. It should be used only by the
20/// token types. If you have found yourself here, you probably want to use the
21/// high-level [`crate::SolType`] interface (or its dynamic equivalent) instead.
22#[derive(Clone, Debug, Default)]
23pub struct Encoder {
24    buf: Vec<Word>,
25    suffix_offset: Vec<usize>,
26}
27
28impl Encoder {
29    /// Instantiate a new empty encoder.
30    #[inline]
31    pub const fn new() -> Self {
32        Self { buf: Vec::new(), suffix_offset: Vec::new() }
33    }
34
35    /// Instantiate a new encoder with a given capacity in words.
36    #[inline]
37    pub fn with_capacity(size: usize) -> Self {
38        Self {
39            buf: Vec::with_capacity(size),
40            // Note: this has to be non-zero even if it won't get used. The compiler will optimize
41            // it out, but it won't for `Vec::new` (??).
42            suffix_offset: Vec::with_capacity(4),
43        }
44    }
45
46    /// Return a reference to the encoded words.
47    #[inline]
48    pub fn words(&self) -> &[Word] {
49        &self.buf
50    }
51
52    /// Finish the encoding process, returning the encoded words.
53    ///
54    /// Use `into_bytes` instead to flatten the words into bytes.
55    // https://github.com/rust-lang/rust-clippy/issues/4979
56    #[allow(clippy::missing_const_for_fn)]
57    #[inline]
58    pub fn finish(self) -> Vec<Word> {
59        self.buf
60    }
61
62    /// Return a reference to the encoded bytes.
63    #[inline]
64    pub fn bytes(&self) -> &[u8] {
65        // SAFETY: `#[repr(transparent)] FixedBytes<N>([u8; N])`
66        unsafe { &*(self.words() as *const [Word] as *const [[u8; 32]]) }.as_flattened()
67    }
68
69    /// Finish the encoding process, returning the encoded bytes.
70    #[inline]
71    pub fn into_bytes(self) -> Vec<u8> {
72        // SAFETY: `#[repr(transparent)] FixedBytes<N>([u8; N])`
73        unsafe { mem::transmute::<Vec<Word>, Vec<[u8; 32]>>(self.finish()) }.into_flattened()
74    }
75
76    /// Determine the current suffix offset.
77    ///
78    /// # Panics
79    ///
80    /// Panics if there is no current suffix offset.
81    #[inline]
82    #[cfg_attr(debug_assertions, track_caller)]
83    pub fn suffix_offset(&self) -> usize {
84        debug_assert!(!self.suffix_offset.is_empty());
85        unsafe { *self.suffix_offset.last().unwrap_unchecked() }
86    }
87
88    /// Appends a suffix offset.
89    #[inline]
90    pub fn push_offset(&mut self, words: usize) {
91        self.suffix_offset.push(words * 32);
92    }
93
94    /// Removes the last offset and returns it.
95    #[inline]
96    pub fn pop_offset(&mut self) -> Option<usize> {
97        self.suffix_offset.pop()
98    }
99
100    /// Bump the suffix offset by a given number of words.
101    #[inline]
102    pub fn bump_offset(&mut self, words: usize) {
103        if let Some(last) = self.suffix_offset.last_mut() {
104            *last += words * 32;
105        }
106    }
107
108    /// Append a word to the encoder.
109    #[inline]
110    pub fn append_word(&mut self, word: Word) {
111        self.buf.push(word);
112    }
113
114    /// Append a pointer to the current suffix offset.
115    ///
116    /// # Panics
117    ///
118    /// Panics if there is no current suffix offset.
119    #[inline]
120    #[cfg_attr(debug_assertions, track_caller)]
121    pub fn append_indirection(&mut self) {
122        self.append_word(utils::pad_usize(self.suffix_offset()));
123    }
124
125    /// Append a sequence length.
126    #[inline]
127    pub fn append_seq_len(&mut self, len: usize) {
128        self.append_word(utils::pad_usize(len));
129    }
130
131    /// Append a sequence of bytes as a packed sequence with a length prefix.
132    #[inline]
133    pub fn append_packed_seq(&mut self, bytes: &[u8]) {
134        self.append_seq_len(bytes.len());
135        self.append_bytes(bytes);
136    }
137
138    /// Shortcut for appending a token sequence.
139    #[inline]
140    pub fn append_head_tail<'a, T: TokenSeq<'a>>(&mut self, token: &T) {
141        token.encode_sequence(self);
142    }
143
144    /// Append a sequence of bytes, padding to the next word.
145    #[inline(always)]
146    fn append_bytes(&mut self, bytes: &[u8]) {
147        if bytes.is_empty() {
148            return;
149        }
150
151        let n_words = utils::words_for(bytes);
152        self.buf.reserve(n_words);
153        unsafe {
154            // set length before copying
155            // this is fine because we reserved above and we don't panic below
156            let len = self.buf.len();
157            self.buf.set_len(len + n_words);
158
159            // copy
160            let cnt = bytes.len();
161            let dst = self.buf.as_mut_ptr().add(len).cast::<u8>();
162            ptr::copy_nonoverlapping(bytes.as_ptr(), dst, cnt);
163
164            // set remaining bytes to zero if necessary
165            let rem = cnt % 32;
166            if rem != 0 {
167                let pad = 32 - rem;
168                ptr::write_bytes(dst.add(cnt), 0, pad);
169            }
170        }
171    }
172}
173
174/// ABI-encodes a single token.
175///
176/// You are probably looking for
177/// [`SolValue::abi_encode`](crate::SolValue::abi_encode) if
178/// you are not intending to use raw tokens.
179///
180/// See the [`abi`](super) module for more information.
181#[inline(always)]
182pub fn encode<'a, T: Token<'a>>(token: &T) -> Vec<u8> {
183    encode_sequence::<(T,)>(tuple_from_ref(token))
184}
185
186/// ABI-encodes a tuple as ABI function params, suitable for passing to a
187/// function.
188///
189/// You are probably looking for
190/// [`SolValue::abi_encode_params`](crate::SolValue::abi_encode_params) if
191/// you are not intending to use raw tokens.
192///
193/// See the [`abi`](super) module for more information.
194#[inline(always)]
195pub fn encode_params<'a, T: TokenSeq<'a>>(token: &T) -> Vec<u8> {
196    let encode = const {
197        if T::IS_TUPLE {
198            encode_sequence
199        } else {
200            encode
201        }
202    };
203    encode(token)
204}
205
206/// ABI-encodes a token sequence.
207///
208/// You are probably looking for
209/// [`SolValue::abi_encode_sequence`](crate::SolValue::abi_encode_sequence) if
210/// you are not intending to use raw tokens.
211///
212/// See the [`abi`](super) module for more information.
213#[inline]
214pub fn encode_sequence<'a, T: TokenSeq<'a>>(token: &T) -> Vec<u8> {
215    let mut enc = Encoder::with_capacity(token.total_words());
216    enc.append_head_tail(token);
217    enc.into_bytes()
218}
219
220/// Converts a reference to `T` into a reference to a tuple of length 1 (without
221/// copying).
222///
223/// Same as [`core::array::from_ref`].
224#[inline(always)]
225const fn tuple_from_ref<T>(s: &T) -> &(T,) {
226    // SAFETY: Converting `&T` to `&(T,)` is sound.
227    unsafe { &*(s as *const T).cast::<(T,)>() }
228}
229
230#[cfg(test)]
231mod tests {
232    use crate::{sol_data, SolType};
233    use alloc::{borrow::ToOwned, string::ToString, vec::Vec};
234    use alloy_primitives::{address, bytes, hex, Address, U256};
235    use alloy_sol_macro::sol;
236
237    #[test]
238    fn encode_address() {
239        let address = Address::from([0x11u8; 20]);
240        let expected = hex!("0000000000000000000000001111111111111111111111111111111111111111");
241        let encoded = sol_data::Address::abi_encode(&address);
242        assert_eq!(encoded, expected);
243        assert_eq!(encoded.len(), sol_data::Address::abi_encoded_size(&address));
244    }
245
246    #[test]
247    fn encode_dynamic_array_of_addresses() {
248        type MyTy = sol_data::Array<sol_data::Address>;
249        let data = vec![Address::from([0x11u8; 20]), Address::from([0x22u8; 20])];
250        let encoded = MyTy::abi_encode(&data);
251        let expected = hex!(
252            "
253			0000000000000000000000000000000000000000000000000000000000000020
254			0000000000000000000000000000000000000000000000000000000000000002
255			0000000000000000000000001111111111111111111111111111111111111111
256			0000000000000000000000002222222222222222222222222222222222222222
257		"
258        );
259        assert_eq!(encoded, expected);
260        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
261    }
262
263    #[test]
264    fn encode_fixed_array_of_addresses() {
265        type MyTy = sol_data::FixedArray<sol_data::Address, 2>;
266
267        let addresses = [Address::from([0x11u8; 20]), Address::from([0x22u8; 20])];
268
269        let encoded = MyTy::abi_encode(&addresses);
270        let encoded_params = MyTy::abi_encode_params(&addresses);
271        let expected = hex!(
272            "
273    		0000000000000000000000001111111111111111111111111111111111111111
274    		0000000000000000000000002222222222222222222222222222222222222222
275    	"
276        );
277        assert_eq!(encoded_params, expected);
278        assert_eq!(encoded, expected);
279        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&addresses));
280    }
281
282    #[test]
283    fn encode_two_addresses() {
284        type MyTy = (sol_data::Address, sol_data::Address);
285        let addresses = (Address::from([0x11u8; 20]), Address::from([0x22u8; 20]));
286
287        let encoded = MyTy::abi_encode_sequence(&addresses);
288        let encoded_params = MyTy::abi_encode_params(&addresses);
289        let expected = hex!(
290            "
291    		0000000000000000000000001111111111111111111111111111111111111111
292    		0000000000000000000000002222222222222222222222222222222222222222
293    	"
294        );
295        assert_eq!(encoded, expected);
296        assert_eq!(encoded_params, expected);
297        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&addresses));
298    }
299
300    #[test]
301    fn encode_fixed_array_of_dynamic_array_of_addresses() {
302        type MyTy = sol_data::FixedArray<sol_data::Array<sol_data::Address>, 2>;
303        let data = [
304            vec![Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
305            vec![Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
306        ];
307
308        let expected = hex!(
309            "
310    		0000000000000000000000000000000000000000000000000000000000000020
311    		0000000000000000000000000000000000000000000000000000000000000040
312    		00000000000000000000000000000000000000000000000000000000000000a0
313    		0000000000000000000000000000000000000000000000000000000000000002
314    		0000000000000000000000001111111111111111111111111111111111111111
315    		0000000000000000000000002222222222222222222222222222222222222222
316    		0000000000000000000000000000000000000000000000000000000000000002
317    		0000000000000000000000003333333333333333333333333333333333333333
318    		0000000000000000000000004444444444444444444444444444444444444444
319    	"
320        );
321        let encoded = MyTy::abi_encode(&data);
322        assert_eq!(encoded, expected);
323        let encoded_params = MyTy::abi_encode_params(&data);
324        assert_eq!(encoded_params, expected);
325
326        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
327    }
328
329    #[test]
330    fn encode_dynamic_array_of_fixed_array_of_addresses() {
331        type TwoAddrs = sol_data::FixedArray<sol_data::Address, 2>;
332        type MyTy = sol_data::Array<TwoAddrs>;
333
334        let data = vec![
335            [Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
336            [Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
337        ];
338
339        let expected = hex!(
340            "
341    		0000000000000000000000000000000000000000000000000000000000000020
342    		0000000000000000000000000000000000000000000000000000000000000002
343    		0000000000000000000000001111111111111111111111111111111111111111
344    		0000000000000000000000002222222222222222222222222222222222222222
345    		0000000000000000000000003333333333333333333333333333333333333333
346    		0000000000000000000000004444444444444444444444444444444444444444
347    	"
348        );
349        // a DynSeq at top level ALWAYS has extra indirection
350        let encoded = MyTy::abi_encode(&data);
351        assert_eq!(encoded, expected);
352        let encoded_params = MyTy::abi_encode_params(&data);
353        assert_eq!(encoded_params, expected);
354        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
355    }
356
357    #[test]
358    fn encode_dynamic_array_of_dynamic_arrays() {
359        type MyTy = sol_data::Array<sol_data::Array<sol_data::Address>>;
360
361        let data = vec![vec![Address::from([0x11u8; 20])], vec![Address::from([0x22u8; 20])]];
362
363        let expected = hex!(
364            "
365    		0000000000000000000000000000000000000000000000000000000000000020
366    		0000000000000000000000000000000000000000000000000000000000000002
367    		0000000000000000000000000000000000000000000000000000000000000040
368    		0000000000000000000000000000000000000000000000000000000000000080
369    		0000000000000000000000000000000000000000000000000000000000000001
370    		0000000000000000000000001111111111111111111111111111111111111111
371    		0000000000000000000000000000000000000000000000000000000000000001
372    		0000000000000000000000002222222222222222222222222222222222222222
373    	"
374        );
375        // a DynSeq at top level ALWAYS has extra indirection
376        let encoded = MyTy::abi_encode(&data);
377        assert_eq!(encoded, expected);
378        let encoded_params = MyTy::abi_encode_params(&data);
379        assert_eq!(encoded_params, expected);
380        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
381    }
382
383    #[test]
384    fn encode_dynamic_array_of_dynamic_arrays2() {
385        type MyTy = sol_data::Array<sol_data::Array<sol_data::Address>>;
386
387        let data = vec![
388            vec![Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
389            vec![Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
390        ];
391        let expected = hex!(
392            "
393    		0000000000000000000000000000000000000000000000000000000000000020
394    		0000000000000000000000000000000000000000000000000000000000000002
395    		0000000000000000000000000000000000000000000000000000000000000040
396    		00000000000000000000000000000000000000000000000000000000000000a0
397    		0000000000000000000000000000000000000000000000000000000000000002
398    		0000000000000000000000001111111111111111111111111111111111111111
399    		0000000000000000000000002222222222222222222222222222222222222222
400    		0000000000000000000000000000000000000000000000000000000000000002
401    		0000000000000000000000003333333333333333333333333333333333333333
402    		0000000000000000000000004444444444444444444444444444444444444444
403    	"
404        );
405        // a DynSeq at top level ALWAYS has extra indirection
406        let encoded = MyTy::abi_encode(&data);
407        assert_eq!(encoded, expected);
408        let encoded_params = MyTy::abi_encode_params(&data);
409        assert_eq!(encoded_params, expected);
410        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
411    }
412
413    #[test]
414    fn encode_fixed_array_of_fixed_arrays() {
415        type MyTy = sol_data::FixedArray<sol_data::FixedArray<sol_data::Address, 2>, 2>;
416
417        let fixed = [
418            [Address::from([0x11u8; 20]), Address::from([0x22u8; 20])],
419            [Address::from([0x33u8; 20]), Address::from([0x44u8; 20])],
420        ];
421
422        let encoded = MyTy::abi_encode_sequence(&fixed);
423        let encoded_params = MyTy::abi_encode_params(&fixed);
424        let expected = hex!(
425            "
426    		0000000000000000000000001111111111111111111111111111111111111111
427    		0000000000000000000000002222222222222222222222222222222222222222
428    		0000000000000000000000003333333333333333333333333333333333333333
429    		0000000000000000000000004444444444444444444444444444444444444444
430    	"
431        );
432        // a non-dynamic FixedSeq at top level NEVER has extra indirection
433        assert_eq!(encoded, expected);
434        assert_eq!(encoded_params, expected);
435        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&fixed));
436    }
437
438    #[test]
439    fn encode_fixed_array_of_static_tuples_followed_by_dynamic_type() {
440        type Tup = (sol_data::Uint<256>, sol_data::Uint<256>, sol_data::Address);
441        type Fixed = sol_data::FixedArray<Tup, 2>;
442        type MyTy = (Fixed, sol_data::String);
443
444        let data = (
445            [
446                (U256::from(93523141), U256::from(352332135), Address::from([0x44u8; 20])),
447                (U256::from(12411), U256::from(451), Address::from([0x22u8; 20])),
448            ],
449            "gavofyork".to_string(),
450        );
451
452        let expected = hex!(
453            "
454    		0000000000000000000000000000000000000000000000000000000005930cc5
455    		0000000000000000000000000000000000000000000000000000000015002967
456    		0000000000000000000000004444444444444444444444444444444444444444
457    		000000000000000000000000000000000000000000000000000000000000307b
458    		00000000000000000000000000000000000000000000000000000000000001c3
459    		0000000000000000000000002222222222222222222222222222222222222222
460    		00000000000000000000000000000000000000000000000000000000000000e0
461    		0000000000000000000000000000000000000000000000000000000000000009
462    		6761766f66796f726b0000000000000000000000000000000000000000000000
463    	"
464        );
465
466        let encoded = MyTy::abi_encode(&data);
467        let encoded_params = MyTy::abi_encode_params(&data);
468        assert_ne!(encoded, expected);
469        assert_eq!(encoded_params, expected);
470        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
471    }
472
473    #[test]
474    fn encode_empty_array() {
475        type MyTy0 = sol_data::Array<sol_data::Address>;
476
477        let data: Vec<Address> = vec![];
478
479        // Empty arrays
480        let encoded = MyTy0::abi_encode_params(&data);
481        let expected = hex!(
482            "
483    		0000000000000000000000000000000000000000000000000000000000000020
484    		0000000000000000000000000000000000000000000000000000000000000000
485    	    "
486        );
487
488        assert_eq!(encoded, expected);
489        assert_eq!(encoded.len(), MyTy0::abi_encoded_size(&data));
490
491        type MyTy = (sol_data::Array<sol_data::Address>, sol_data::Array<sol_data::Address>);
492        let data: (Vec<Address>, Vec<Address>) = (vec![], vec![]);
493
494        let expected = hex!(
495            "
496    		0000000000000000000000000000000000000000000000000000000000000040
497    		0000000000000000000000000000000000000000000000000000000000000060
498    		0000000000000000000000000000000000000000000000000000000000000000
499    		0000000000000000000000000000000000000000000000000000000000000000
500    	    "
501        );
502
503        // Empty arrays
504        let encoded = MyTy::abi_encode(&data);
505        assert_ne!(encoded, expected);
506
507        let encoded_params = MyTy::abi_encode_params(&data);
508        assert_eq!(encoded_params, expected);
509        assert_eq!(encoded_params.len() + 32, encoded.len());
510        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
511
512        type MyTy2 = (
513            sol_data::Array<sol_data::Array<sol_data::Address>>,
514            sol_data::Array<sol_data::Array<sol_data::Address>>,
515        );
516
517        let data: (Vec<Vec<Address>>, Vec<Vec<Address>>) = (vec![vec![]], vec![vec![]]);
518
519        // Nested empty arrays
520        let expected = hex!(
521            "
522    		0000000000000000000000000000000000000000000000000000000000000040
523    		00000000000000000000000000000000000000000000000000000000000000a0
524    		0000000000000000000000000000000000000000000000000000000000000001
525    		0000000000000000000000000000000000000000000000000000000000000020
526    		0000000000000000000000000000000000000000000000000000000000000000
527    		0000000000000000000000000000000000000000000000000000000000000001
528    		0000000000000000000000000000000000000000000000000000000000000020
529    		0000000000000000000000000000000000000000000000000000000000000000
530    	"
531        );
532        // A Dynamic FixedSeq may be a top-level sequence to `encode` or may
533        // itself be an item in a top-level sequence. Which is to say, it could
534        // be (as `abi_encode(T)` or `abi_encode((T,))`). This test was `abi_encode(T)`
535        let encoded = MyTy2::abi_encode(&data);
536        assert_ne!(encoded, expected);
537        let encoded_params = MyTy2::abi_encode_params(&data);
538
539        assert_eq!(encoded_params, expected);
540        assert_eq!(encoded_params.len() + 32, encoded.len());
541        assert_eq!(encoded.len(), MyTy2::abi_encoded_size(&data));
542    }
543
544    #[test]
545    fn encode_empty_bytes() {
546        let bytes = Vec::<u8>::new();
547
548        let encoded = sol_data::Bytes::abi_encode(&bytes);
549        let expected = hex!(
550            "
551    		0000000000000000000000000000000000000000000000000000000000000020
552    		0000000000000000000000000000000000000000000000000000000000000000
553    	"
554        );
555        assert_eq!(encoded, expected);
556        assert_eq!(encoded.len(), sol_data::Bytes::abi_encoded_size(&bytes));
557    }
558
559    #[test]
560    fn encode_bytes() {
561        let bytes = vec![0x12, 0x34];
562
563        let encoded = sol_data::Bytes::abi_encode(&bytes);
564        let expected = hex!(
565            "
566    		0000000000000000000000000000000000000000000000000000000000000020
567    		0000000000000000000000000000000000000000000000000000000000000002
568    		1234000000000000000000000000000000000000000000000000000000000000
569    	"
570        );
571        assert_eq!(encoded, expected);
572        assert_eq!(encoded.len(), sol_data::Bytes::abi_encoded_size(&bytes));
573    }
574
575    #[test]
576    fn encode_fixed_bytes() {
577        let encoded = sol_data::FixedBytes::<2>::abi_encode(&[0x12, 0x34]);
578        let expected = hex!("1234000000000000000000000000000000000000000000000000000000000000");
579        assert_eq!(encoded, expected);
580        assert_eq!(encoded.len(), sol_data::FixedBytes::<2>::abi_encoded_size(&[0x12, 0x34]));
581    }
582
583    #[test]
584    fn encode_empty_string() {
585        let s = "";
586        let encoded = sol_data::String::abi_encode(s);
587        let expected = hex!(
588            "
589    		0000000000000000000000000000000000000000000000000000000000000020
590    		0000000000000000000000000000000000000000000000000000000000000000
591    	"
592        );
593        assert_eq!(encoded, expected);
594        assert_eq!(encoded.len(), sol_data::String::abi_encoded_size(&s));
595    }
596
597    #[test]
598    fn encode_string() {
599        let s = "gavofyork".to_string();
600        let encoded = sol_data::String::abi_encode(&s);
601        let expected = hex!(
602            "
603    		0000000000000000000000000000000000000000000000000000000000000020
604    		0000000000000000000000000000000000000000000000000000000000000009
605    		6761766f66796f726b0000000000000000000000000000000000000000000000
606    	"
607        );
608        assert_eq!(encoded, expected);
609        assert_eq!(encoded.len(), sol_data::String::abi_encoded_size(&s));
610    }
611
612    #[test]
613    fn encode_bytes2() {
614        let bytes = hex!("10000000000000000000000000000000000000000000000000000000000002").to_vec();
615        let encoded = sol_data::Bytes::abi_encode(&bytes);
616        let expected = hex!(
617            "
618    		0000000000000000000000000000000000000000000000000000000000000020
619    		000000000000000000000000000000000000000000000000000000000000001f
620    		1000000000000000000000000000000000000000000000000000000000000200
621    	"
622        );
623        assert_eq!(encoded, expected);
624        assert_eq!(encoded.len(), sol_data::Bytes::abi_encoded_size(&bytes));
625    }
626
627    #[test]
628    fn encode_bytes3() {
629        let bytes = hex!(
630            "
631    		1000000000000000000000000000000000000000000000000000000000000000
632    		1000000000000000000000000000000000000000000000000000000000000000
633    	"
634        );
635        let encoded = sol_data::Bytes::abi_encode(&bytes);
636        let expected = hex!(
637            "
638    		0000000000000000000000000000000000000000000000000000000000000020
639    		0000000000000000000000000000000000000000000000000000000000000040
640    		1000000000000000000000000000000000000000000000000000000000000000
641    		1000000000000000000000000000000000000000000000000000000000000000
642    	"
643        );
644        assert_eq!(encoded, expected);
645        assert_eq!(encoded.len(), sol_data::Bytes::abi_encoded_size(&bytes));
646    }
647
648    #[test]
649    fn encode_two_bytes() {
650        type MyTy = (sol_data::Bytes, sol_data::Bytes);
651
652        let bytes = (
653            hex!("10000000000000000000000000000000000000000000000000000000000002").to_vec(),
654            hex!("0010000000000000000000000000000000000000000000000000000000000002").to_vec(),
655        );
656        let encoded = MyTy::abi_encode(&bytes);
657        let encoded_params = MyTy::abi_encode_params(&bytes);
658        let expected = hex!(
659            "
660    		0000000000000000000000000000000000000000000000000000000000000040
661    		0000000000000000000000000000000000000000000000000000000000000080
662    		000000000000000000000000000000000000000000000000000000000000001f
663    		1000000000000000000000000000000000000000000000000000000000000200
664    		0000000000000000000000000000000000000000000000000000000000000020
665    		0010000000000000000000000000000000000000000000000000000000000002
666    	"
667        );
668        // A Dynamic FixedSeq may be a top-level sequence to `encode` or may
669        // itself be an item in a top-level sequence. Which is to say, it could
670        // be (as `abi_encode(T)` or `abi_encode((T,))`). This test was `abi_encode(T)`
671        assert_ne!(encoded, expected);
672        assert_eq!(encoded_params, expected);
673        assert_eq!(encoded_params.len() + 32, encoded.len());
674        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&bytes));
675    }
676
677    #[test]
678    fn encode_uint() {
679        let uint = 4;
680        let encoded = sol_data::Uint::<8>::abi_encode(&uint);
681        let expected = hex!("0000000000000000000000000000000000000000000000000000000000000004");
682        assert_eq!(encoded, expected);
683        assert_eq!(encoded.len(), sol_data::Uint::<8>::abi_encoded_size(&uint));
684    }
685
686    #[test]
687    fn encode_int() {
688        let int = 4;
689        let encoded = sol_data::Int::<8>::abi_encode(&int);
690        let expected = hex!("0000000000000000000000000000000000000000000000000000000000000004");
691        assert_eq!(encoded, expected);
692        assert_eq!(encoded.len(), sol_data::Int::<8>::abi_encoded_size(&int));
693    }
694
695    #[test]
696    fn encode_bool() {
697        let encoded = sol_data::Bool::abi_encode(&true);
698        let expected = hex!("0000000000000000000000000000000000000000000000000000000000000001");
699        assert_eq!(encoded, expected);
700        assert_eq!(encoded.len(), sol_data::Bool::abi_encoded_size(&true));
701    }
702
703    #[test]
704    fn encode_bool2() {
705        let encoded = sol_data::Bool::abi_encode(&false);
706        let expected = hex!("0000000000000000000000000000000000000000000000000000000000000000");
707        assert_eq!(encoded, expected);
708        assert_eq!(encoded.len(), sol_data::Bool::abi_encoded_size(&false));
709    }
710
711    #[test]
712    fn comprehensive_test() {
713        type MyTy = (sol_data::Uint<8>, sol_data::Bytes, sol_data::Uint<8>, sol_data::Bytes);
714
715        let bytes = hex!(
716            "
717    		131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b
718    		131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b
719    	"
720        );
721
722        let data = (5, bytes, 3, bytes);
723
724        let encoded = MyTy::abi_encode(&data);
725        let encoded_params = MyTy::abi_encode_params(&data);
726
727        let expected = hex!(
728            "
729    		0000000000000000000000000000000000000000000000000000000000000005
730    		0000000000000000000000000000000000000000000000000000000000000080
731    		0000000000000000000000000000000000000000000000000000000000000003
732    		00000000000000000000000000000000000000000000000000000000000000e0
733    		0000000000000000000000000000000000000000000000000000000000000040
734    		131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b
735    		131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b
736    		0000000000000000000000000000000000000000000000000000000000000040
737    		131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b
738    		131a3afc00d1b1e3461b955e53fc866dcf303b3eb9f4c16f89e388930f48134b
739    	"
740        );
741        // A Dynamic FixedSeq may be a top-level sequence to `encode` or may
742        // itself be an item in a top-level sequence. Which is to say, it could
743        // be (as `abi_encode(T)` or `abi_encode((T,))`). This test was `abi_encode(T)`
744        assert_ne!(encoded, expected);
745        assert_eq!(encoded_params, expected);
746        assert_eq!(encoded_params.len() + 32, encoded.len());
747        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
748    }
749
750    #[test]
751    fn comprehensive_test2() {
752        type MyTy = (
753            sol_data::Bool,
754            sol_data::String,
755            sol_data::Uint<8>,
756            sol_data::Uint<8>,
757            sol_data::Uint<8>,
758            sol_data::Array<sol_data::Uint<8>>,
759        );
760
761        let data = (true, "gavofyork".to_string(), 2, 3, 4, vec![5, 6, 7]);
762
763        let expected = hex!(
764            "
765    		0000000000000000000000000000000000000000000000000000000000000001
766    		00000000000000000000000000000000000000000000000000000000000000c0
767    		0000000000000000000000000000000000000000000000000000000000000002
768    		0000000000000000000000000000000000000000000000000000000000000003
769    		0000000000000000000000000000000000000000000000000000000000000004
770    		0000000000000000000000000000000000000000000000000000000000000100
771    		0000000000000000000000000000000000000000000000000000000000000009
772    		6761766f66796f726b0000000000000000000000000000000000000000000000
773    		0000000000000000000000000000000000000000000000000000000000000003
774    		0000000000000000000000000000000000000000000000000000000000000005
775    		0000000000000000000000000000000000000000000000000000000000000006
776    		0000000000000000000000000000000000000000000000000000000000000007
777    	"
778        );
779        // A Dynamic FixedSeq may be a top-level sequence to `encode` or may
780        // itself be an item in a top-level sequence. Which is to say, it could
781        // be (as `abi_encode(T)` or `abi_encode((T,))`). This test was `abi_encode(T)`
782        let encoded = MyTy::abi_encode(&data);
783        assert_ne!(encoded, expected);
784        let encoded_params = MyTy::abi_encode_params(&data);
785        assert_eq!(encoded_params, expected);
786        assert_eq!(encoded_params.len() + 32, encoded.len());
787        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
788    }
789
790    #[test]
791    fn encode_dynamic_array_of_bytes() {
792        type MyTy = sol_data::Array<sol_data::Bytes>;
793        let data = vec![hex!(
794            "019c80031b20d5e69c8093a571162299032018d913930d93ab320ae5ea44a4218a274f00d607"
795        )
796        .to_vec()];
797
798        let expected = hex!(
799            "
800    		0000000000000000000000000000000000000000000000000000000000000020
801    		0000000000000000000000000000000000000000000000000000000000000001
802    		0000000000000000000000000000000000000000000000000000000000000020
803    		0000000000000000000000000000000000000000000000000000000000000026
804    		019c80031b20d5e69c8093a571162299032018d913930d93ab320ae5ea44a421
805    		8a274f00d6070000000000000000000000000000000000000000000000000000
806    	"
807        );
808        // a DynSeq at top level ALWAYS has extra indirection
809        let encoded = MyTy::abi_encode(&data);
810        assert_eq!(encoded, expected);
811        let encoded_params = MyTy::abi_encode_params(&data);
812        assert_eq!(encoded_params, expected);
813        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
814    }
815
816    #[test]
817    fn encode_dynamic_array_of_bytes2() {
818        type MyTy = sol_data::Array<sol_data::Bytes>;
819
820        let data = vec![
821            hex!("4444444444444444444444444444444444444444444444444444444444444444444444444444")
822                .to_vec(),
823            hex!("6666666666666666666666666666666666666666666666666666666666666666666666666666")
824                .to_vec(),
825        ];
826
827        let expected = hex!(
828            "
829    		0000000000000000000000000000000000000000000000000000000000000020
830    		0000000000000000000000000000000000000000000000000000000000000002
831    		0000000000000000000000000000000000000000000000000000000000000040
832    		00000000000000000000000000000000000000000000000000000000000000a0
833    		0000000000000000000000000000000000000000000000000000000000000026
834    		4444444444444444444444444444444444444444444444444444444444444444
835    		4444444444440000000000000000000000000000000000000000000000000000
836    		0000000000000000000000000000000000000000000000000000000000000026
837    		6666666666666666666666666666666666666666666666666666666666666666
838    		6666666666660000000000000000000000000000000000000000000000000000
839    	"
840        );
841        // a DynSeq at top level ALWAYS has extra indirection
842        let encoded = MyTy::abi_encode(&data);
843        assert_eq!(encoded, expected);
844        let encoded_params = MyTy::abi_encode_params(&data);
845        assert_eq!(encoded_params, expected);
846        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
847    }
848
849    #[test]
850    fn encode_static_tuple_of_addresses() {
851        type MyTy = (sol_data::Address, sol_data::Address);
852        let data = (Address::from([0x11u8; 20]), Address::from([0x22u8; 20]));
853
854        let encoded = MyTy::abi_encode_sequence(&data);
855        let encoded_params = MyTy::abi_encode_params(&data);
856
857        let expected = hex!(
858            "
859    		0000000000000000000000001111111111111111111111111111111111111111
860    		0000000000000000000000002222222222222222222222222222222222222222
861    	"
862        );
863        assert_eq!(encoded, expected);
864        assert_eq!(encoded_params, expected);
865        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
866    }
867
868    #[test]
869    fn encode_dynamic_tuple() {
870        type MyTy = (sol_data::String, sol_data::String);
871        let data = ("gavofyork".to_string(), "gavofyork".to_string());
872
873        let expected = hex!(
874            "
875    		0000000000000000000000000000000000000000000000000000000000000020
876    		0000000000000000000000000000000000000000000000000000000000000040
877    		0000000000000000000000000000000000000000000000000000000000000080
878    		0000000000000000000000000000000000000000000000000000000000000009
879    		6761766f66796f726b0000000000000000000000000000000000000000000000
880    		0000000000000000000000000000000000000000000000000000000000000009
881    		6761766f66796f726b0000000000000000000000000000000000000000000000
882    	"
883        );
884        // a dynamic FixedSeq at top level should start with indirection
885        // when not param encoded.
886        let encoded = MyTy::abi_encode(&data);
887        assert_eq!(encoded, expected);
888        let encoded_params = MyTy::abi_encode_params(&data);
889        assert_ne!(encoded_params, expected);
890        assert_eq!(encoded_params.len() + 32, encoded.len());
891        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
892    }
893
894    #[test]
895    fn encode_dynamic_tuple_of_bytes2() {
896        type MyTy = (sol_data::Bytes, sol_data::Bytes);
897
898        let data = (
899            hex!("4444444444444444444444444444444444444444444444444444444444444444444444444444")
900                .to_vec(),
901            hex!("6666666666666666666666666666666666666666666666666666666666666666666666666666")
902                .to_vec(),
903        );
904
905        let encoded = MyTy::abi_encode(&data);
906        let encoded_params = MyTy::abi_encode_params(&data);
907
908        let expected = hex!(
909            "
910    		0000000000000000000000000000000000000000000000000000000000000020
911    		0000000000000000000000000000000000000000000000000000000000000040
912    		00000000000000000000000000000000000000000000000000000000000000a0
913    		0000000000000000000000000000000000000000000000000000000000000026
914    		4444444444444444444444444444444444444444444444444444444444444444
915    		4444444444440000000000000000000000000000000000000000000000000000
916    		0000000000000000000000000000000000000000000000000000000000000026
917    		6666666666666666666666666666666666666666666666666666666666666666
918    		6666666666660000000000000000000000000000000000000000000000000000
919    	"
920        );
921        // a dynamic FixedSeq at top level should start with indirection
922        // when not param encoded.
923        assert_eq!(encoded, expected);
924        assert_ne!(encoded_params, expected);
925        assert_eq!(encoded_params.len() + 32, encoded.len());
926        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
927    }
928
929    #[test]
930    fn encode_complex_tuple() {
931        type MyTy = (sol_data::Uint<256>, sol_data::String, sol_data::Address, sol_data::Address);
932
933        let data = (
934            U256::from_be_bytes::<32>([0x11u8; 32]),
935            "gavofyork".to_owned(),
936            Address::from([0x11u8; 20]),
937            Address::from([0x22u8; 20]),
938        );
939
940        let expected = hex!(
941            "
942            0000000000000000000000000000000000000000000000000000000000000020
943            1111111111111111111111111111111111111111111111111111111111111111
944            0000000000000000000000000000000000000000000000000000000000000080
945            0000000000000000000000001111111111111111111111111111111111111111
946    		0000000000000000000000002222222222222222222222222222222222222222
947    		0000000000000000000000000000000000000000000000000000000000000009
948    		6761766f66796f726b0000000000000000000000000000000000000000000000
949    	"
950        );
951        // a dynamic FixedSeq at top level should start with indirection
952        // when not param encoded.
953        let encoded = MyTy::abi_encode(&data);
954        assert_eq!(encoded, expected);
955        let encoded_params = MyTy::abi_encode_params(&data);
956        assert_ne!(encoded_params, expected);
957        assert_eq!(encoded_params.len() + 32, encoded.len());
958        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
959    }
960
961    #[test]
962    fn encode_nested_tuple() {
963        type MyTy = (
964            sol_data::String,
965            sol_data::Bool,
966            sol_data::String,
967            (sol_data::String, sol_data::String, (sol_data::String, sol_data::String)),
968        );
969
970        let data = (
971            "test".to_string(),
972            true,
973            "cyborg".to_string(),
974            ("night".to_string(), "day".to_string(), ("weee".to_string(), "funtests".to_string())),
975        );
976
977        let encoded = MyTy::abi_encode(&data);
978        let encoded_params = MyTy::abi_encode_sequence(&data);
979
980        let expected = hex!(
981            "
982    		0000000000000000000000000000000000000000000000000000000000000020
983    		0000000000000000000000000000000000000000000000000000000000000080
984    		0000000000000000000000000000000000000000000000000000000000000001
985    		00000000000000000000000000000000000000000000000000000000000000c0
986    		0000000000000000000000000000000000000000000000000000000000000100
987    		0000000000000000000000000000000000000000000000000000000000000004
988    		7465737400000000000000000000000000000000000000000000000000000000
989    		0000000000000000000000000000000000000000000000000000000000000006
990    		6379626f72670000000000000000000000000000000000000000000000000000
991    		0000000000000000000000000000000000000000000000000000000000000060
992    		00000000000000000000000000000000000000000000000000000000000000a0
993    		00000000000000000000000000000000000000000000000000000000000000e0
994    		0000000000000000000000000000000000000000000000000000000000000005
995    		6e69676874000000000000000000000000000000000000000000000000000000
996    		0000000000000000000000000000000000000000000000000000000000000003
997    		6461790000000000000000000000000000000000000000000000000000000000
998    		0000000000000000000000000000000000000000000000000000000000000040
999    		0000000000000000000000000000000000000000000000000000000000000080
1000    		0000000000000000000000000000000000000000000000000000000000000004
1001    		7765656500000000000000000000000000000000000000000000000000000000
1002    		0000000000000000000000000000000000000000000000000000000000000008
1003    		66756e7465737473000000000000000000000000000000000000000000000000
1004    	"
1005        );
1006        // a dynamic FixedSeq at top level should start with indirection
1007        // when not param encoded
1008        assert_eq!(encoded, expected);
1009        assert_ne!(encoded_params, expected);
1010        assert_eq!(encoded_params.len() + 32, encoded.len());
1011        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
1012    }
1013
1014    #[test]
1015    fn encode_params_containing_dynamic_tuple() {
1016        type MyTy = (
1017            sol_data::Address,
1018            (sol_data::Bool, sol_data::String, sol_data::String),
1019            sol_data::Address,
1020            sol_data::Address,
1021            sol_data::Bool,
1022        );
1023        let data = (
1024            Address::from([0x22u8; 20]),
1025            (true, "spaceship".to_owned(), "cyborg".to_owned()),
1026            Address::from([0x33u8; 20]),
1027            Address::from([0x44u8; 20]),
1028            false,
1029        );
1030
1031        let encoded_single = MyTy::abi_encode(&data);
1032        let encoded = MyTy::abi_encode_sequence(&data);
1033
1034        let expected = hex!(
1035            "
1036    		0000000000000000000000002222222222222222222222222222222222222222
1037    		00000000000000000000000000000000000000000000000000000000000000a0
1038    		0000000000000000000000003333333333333333333333333333333333333333
1039    		0000000000000000000000004444444444444444444444444444444444444444
1040    		0000000000000000000000000000000000000000000000000000000000000000
1041    		0000000000000000000000000000000000000000000000000000000000000001
1042    		0000000000000000000000000000000000000000000000000000000000000060
1043    		00000000000000000000000000000000000000000000000000000000000000a0
1044    		0000000000000000000000000000000000000000000000000000000000000009
1045    		7370616365736869700000000000000000000000000000000000000000000000
1046    		0000000000000000000000000000000000000000000000000000000000000006
1047    		6379626f72670000000000000000000000000000000000000000000000000000
1048    	"
1049        );
1050        // A Dynamic FixedSeq may be a top-level sequence to `encode` or may
1051        // itself be an item in a top-level sequence. Which is to say, it could
1052        // be (as `abi_encode(T)` or `abi_encode((T,))`). This test was `abi_encode(T)`
1053        assert_ne!(encoded_single, expected);
1054        assert_eq!(encoded, expected);
1055        assert_eq!(encoded.len() + 32, encoded_single.len());
1056        assert_eq!(encoded_single.len(), MyTy::abi_encoded_size(&data));
1057    }
1058
1059    #[test]
1060    fn encode_params_containing_static_tuple() {
1061        type MyTy = (
1062            sol_data::Address,
1063            (sol_data::Address, sol_data::Bool, sol_data::Bool),
1064            sol_data::Address,
1065            sol_data::Address,
1066        );
1067
1068        let data = (
1069            Address::from([0x11u8; 20]),
1070            (Address::from([0x22u8; 20]), true, false),
1071            Address::from([0x33u8; 20]),
1072            Address::from([0x44u8; 20]),
1073        );
1074
1075        let encoded = MyTy::abi_encode_sequence(&data);
1076        let encoded_params = MyTy::abi_encode_params(&data);
1077
1078        let expected = hex!(
1079            "
1080    		0000000000000000000000001111111111111111111111111111111111111111
1081    		0000000000000000000000002222222222222222222222222222222222222222
1082    		0000000000000000000000000000000000000000000000000000000000000001
1083    		0000000000000000000000000000000000000000000000000000000000000000
1084    		0000000000000000000000003333333333333333333333333333333333333333
1085    		0000000000000000000000004444444444444444444444444444444444444444
1086    	"
1087        );
1088
1089        // a static FixedSeq should NEVER indirect
1090        assert_eq!(encoded, expected);
1091        assert_eq!(encoded_params, expected);
1092        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
1093    }
1094
1095    #[test]
1096    fn encode_dynamic_tuple_with_nested_static_tuples() {
1097        type MyTy = (((sol_data::Bool, sol_data::Uint<16>),), sol_data::Array<sol_data::Uint<16>>);
1098
1099        let data = (((false, 0x777),), vec![0x42, 0x1337]);
1100
1101        let encoded = MyTy::abi_encode(&data);
1102        let encoded_params = MyTy::abi_encode_params(&data);
1103
1104        let expected = hex!(
1105            "
1106    		0000000000000000000000000000000000000000000000000000000000000020
1107    		0000000000000000000000000000000000000000000000000000000000000000
1108    		0000000000000000000000000000000000000000000000000000000000000777
1109    		0000000000000000000000000000000000000000000000000000000000000060
1110    		0000000000000000000000000000000000000000000000000000000000000002
1111    		0000000000000000000000000000000000000000000000000000000000000042
1112    		0000000000000000000000000000000000000000000000000000000000001337
1113    	"
1114        );
1115        // a dynamic FixedSeq at top level should start with indirection
1116        // when not param encoded
1117        assert_eq!(encoded, expected);
1118        assert_ne!(encoded_params, expected);
1119        assert_eq!(encoded_params.len() + 32, encoded.len());
1120        assert_eq!(encoded.len(), MyTy::abi_encoded_size(&data));
1121    }
1122
1123    // https://github.com/foundry-rs/foundry/issues/7280
1124    #[test]
1125    fn encode_empty_bytes_array_in_tuple() {
1126        type MyTy = sol! { (bytes, address, bytes[]) };
1127
1128        let data = (
1129            Vec::from(bytes!("09736b79736b79736b79026f7300")),
1130            address!("0xB7b54cd129e6D8B24e6AE652a473449B273eE3E4"),
1131            Vec::<Vec<u8>>::new(),
1132        );
1133
1134        let encoded_params = MyTy::abi_encode_params(&data);
1135
1136        let expected = hex!(
1137            "
1138            0000000000000000000000000000000000000000000000000000000000000060
1139            000000000000000000000000B7b54cd129e6D8B24e6AE652a473449B273eE3E4
1140            00000000000000000000000000000000000000000000000000000000000000a0
1141            000000000000000000000000000000000000000000000000000000000000000e
1142            09736b79736b79736b79026f7300000000000000000000000000000000000000
1143            0000000000000000000000000000000000000000000000000000000000000000
1144    	"
1145        );
1146        assert_eq!(encoded_params, expected);
1147    }
1148}