git.delta.rocks / unique-network / refs/commits / 7eec33a3cc63

difftreelog

fix AbiRead implementations

Trubnikov Sergey2022-11-16parent: #b3e1096.patch.diff
in: master

5 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive.rs
+++ b/crates/evm-coder/procedural/src/abi_derive.rs
@@ -1,7 +1,6 @@
 use quote::quote;
 
 pub(crate) fn impl_abi_macro(ast: &syn::DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
-	// dbg!(ast);
 	let name = &ast.ident;
 	let (is_named_fields, field_names, field_types, params_count) = match &ast.data {
 		syn::Data::Struct(ds) => match ds.fields {
@@ -31,7 +30,7 @@
 	let abi_type = impl_abi_type(name, field_types.clone());
 	let abi_read = impl_abi_read(name, is_named_fields, field_names.clone(), field_types);
 	let abi_write = impl_abi_write(name, is_named_fields, params_count, field_names);
-	println!("{}", abi_write);
+
 	Ok(quote! {
 		#can_be_plcaed_in_vec
 		#abi_type
@@ -112,14 +111,19 @@
 	quote!(
 		impl ::evm_coder::abi::AbiRead for #name {
 			fn abi_read(reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Self> {
-				let size = if !<Self as ::evm_coder::abi::AbiType>::is_dynamic() {
+				let is_dynamic = <Self as ::evm_coder::abi::AbiType>::is_dynamic();
+				let size = if !is_dynamic {
 					Some(<Self as ::evm_coder::abi::AbiType>::size())
 				} else {
 					None
 				};
 				let mut subresult = reader.subresult(size)?;
 				#(
-					let #field_names = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;
+					let #field_names = {
+						let value = <#field_types as ::evm_coder::abi::AbiRead>::abi_read(&mut subresult)?;
+						if !is_dynamic {subresult.seek(<#field_types as ::evm_coder::abi::AbiType>::size())};
+						value
+					};
 				)*
 
 				#struct_constructor
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -92,7 +92,7 @@
 	}
 }
 
-impl<R: AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {
+impl<R: AbiType + AbiRead + sealed::CanBePlacedInVec> AbiRead for Vec<R> {
 	fn abi_read(reader: &mut AbiReader) -> Result<Vec<R>> {
 		let mut sub = reader.subresult(None)?;
 		let size = sub.uint32()? as usize;
@@ -100,6 +100,9 @@
 		let mut out = Vec::with_capacity(size);
 		for _ in 0..size {
 			out.push(<R>::abi_read(&mut sub)?);
+			if !<R>::is_dynamic() {
+				sub.subresult_offset += <R>::size()
+			};
 		}
 		Ok(out)
 	}
@@ -295,14 +298,19 @@
 
 		impl<$($ident),+> AbiRead for ($($ident,)+)
 		where
-			$($ident: AbiRead,)+
+			$($ident: AbiRead + AbiType,)+
 			($($ident,)+): AbiType,
 		{
 			fn abi_read(reader: &mut AbiReader) -> Result<($($ident,)+)> {
-				let size = if !<($($ident,)+)>::is_dynamic() { Some(<($($ident,)+)>::size()) } else { None };
+				let is_dynamic = <($($ident,)+)>::is_dynamic();
+				let size = if !is_dynamic { Some(<($($ident,)+)>::size()) } else { None };
 				let mut subresult = reader.subresult(size)?;
 				Ok((
-					$(<$ident>::abi_read(&mut subresult)?,)+
+					$({
+						let value = <$ident>::abi_read(&mut subresult)?;
+						if !is_dynamic {subresult.seek(<$ident as AbiType>::size())};
+						value
+					},)+
 				))
 			}
 		}
modifiedcrates/evm-coder/src/abi/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/mod.rs
+++ b/crates/evm-coder/src/abi/mod.rs
@@ -75,19 +75,19 @@
 		buf: &[u8],
 		offset: usize,
 		pad_start: usize,
-		pad_size: usize,
+		pad_end: usize,
 		block_start: usize,
-		block_size: usize,
+		block_end: usize,
 	) -> Result<[u8; S]> {
 		if buf.len() - offset < ABI_ALIGNMENT {
 			return Err(Error::Error(ExitError::OutOfOffset));
 		}
 		let mut block = [0; S];
-		let is_pad_zeroed = buf[pad_start..pad_size].iter().all(|&v| v == 0);
+		let is_pad_zeroed = buf[pad_start..pad_end].iter().all(|&v| v == 0);
 		if !is_pad_zeroed {
 			return Err(Error::Error(ExitError::InvalidRange));
 		}
-		block.copy_from_slice(&buf[block_start..block_size]);
+		block.copy_from_slice(&buf[block_start..block_end]);
 		Ok(block)
 	}
 
@@ -190,7 +190,6 @@
 		let subresult_offset = self.subresult_offset;
 		let offset = if let Some(size) = size {
 			self.offset += size;
-			self.subresult_offset += size;
 			0
 		} else {
 			self.uint32()? as usize
@@ -208,6 +207,11 @@
 		})
 	}
 
+	/// Notify about readed data portion.
+	pub fn seek(&mut self, size: usize) {
+		self.subresult_offset += size;
+	}
+
 	/// Is this parser reached end of buffer?
 	pub fn is_finished(&self) -> bool {
 		self.buf.len() == self.offset
modifiedcrates/evm-coder/src/abi/test.rsdiffbeforeafterboth
before · crates/evm-coder/src/abi/test.rs
1use crate::{2	abi::{AbiRead, AbiWrite},3	types::*,4};56use super::{AbiReader, AbiWriter};7use hex_literal::hex;8use primitive_types::{H160, U256};910fn test_impl<T>(function_identifier: u32, decoded_data: T, encoded_data: &[u8])11where12	T: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,13{14	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();15	assert_eq!(call, u32::to_be_bytes(function_identifier));16	let data = <T>::abi_read(&mut decoder).unwrap();17	assert_eq!(data, decoded_data);1819	let mut writer = AbiWriter::new_call(function_identifier);20	decoded_data.abi_write(&mut writer);21	let ed = writer.finish();22	similar_asserts::assert_eq!(encoded_data, ed.as_slice());23}2425macro_rules! test_impl_uint {26	($type:ident) => {27		test_impl::<$type>(28			0xdeadbeef,29			255 as $type,30			&hex!(31				"32                    deadbeef33                    00000000000000000000000000000000000000000000000000000000000000ff34                "35			),36		);37	};38}3940#[test]41fn encode_decode_uint8() {42	test_impl_uint!(uint8);43}4445#[test]46fn encode_decode_uint32() {47	test_impl_uint!(uint32);48}4950#[test]51fn encode_decode_uint128() {52	test_impl_uint!(uint128);53}5455#[test]56fn encode_decode_uint256() {57	test_impl::<uint256>(58		0xdeadbeef,59		U256([255, 0, 0, 0]),60		&hex!(61			"62                deadbeef63                00000000000000000000000000000000000000000000000000000000000000ff64            "65		),66	);67}6869#[test]70fn encode_decode_string() {71	test_impl::<String>(72		0xdeadbeef,73		"some string".to_string(),74		&hex!(75			"76                deadbeef77                000000000000000000000000000000000000000000000000000000000000002078                000000000000000000000000000000000000000000000000000000000000000b79                736f6d6520737472696e6700000000000000000000000000000000000000000080            "81		),82	);83}8485#[test]86fn encode_decode_tuple_string() {87	test_impl::<(String,)>(88		0xdeadbeef,89		("some string".to_string(),),90		&hex!(91			"92                deadbeef93                000000000000000000000000000000000000000000000000000000000000002094                000000000000000000000000000000000000000000000000000000000000002095                000000000000000000000000000000000000000000000000000000000000000b96                736f6d6520737472696e6700000000000000000000000000000000000000000097            "98		),99	);100}101102#[test]103fn encode_decode_vec_tuple_address_uint256() {104	test_impl::<Vec<(address, uint256)>>(105        0x1ACF2D55,106        vec![107            (108                H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),109                U256([10, 0, 0, 0]),110            ),111            (112                H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),113                U256([20, 0, 0, 0]),114            ),115            (116                H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),117                U256([30, 0, 0, 0]),118            ),119        ],120        &hex!(121            "122                1ACF2D55123                0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]124                0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]125126                0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address127                000000000000000000000000000000000000000000000000000000000000000A // uint256128129                000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address130                0000000000000000000000000000000000000000000000000000000000000014 // uint256131132                0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address133                000000000000000000000000000000000000000000000000000000000000001E // uint256134            "135        )136    );137}138139#[test]140fn encode_decode_vec_tuple_uint256_string() {141	test_impl::<Vec<(uint256, string)>>(142        0xdeadbeef,143        vec![144            (1.into(), "Test URI 0".to_string()),145            (11.into(), "Test URI 1".to_string()),146            (12.into(), "Test URI 2".to_string()),147        ],148        &hex!(149            "150                deadbeef151                0000000000000000000000000000000000000000000000000000000000000020 // offset of (uint256, string)[]152                0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]153154                0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem155                00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem156                0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem157158                0000000000000000000000000000000000000000000000000000000000000001 // first token id?   					#60159                0000000000000000000000000000000000000000000000000000000000000040 // offset of string160                000000000000000000000000000000000000000000000000000000000000000a // size of string161                5465737420555249203000000000000000000000000000000000000000000000 // string162163                000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11?			#e0164                0000000000000000000000000000000000000000000000000000000000000040 // offset of string165                000000000000000000000000000000000000000000000000000000000000000a // size of string166                5465737420555249203100000000000000000000000000000000000000000000 // string167168                000000000000000000000000000000000000000000000000000000000000000c // third token id?  Why ==12?			#160169                0000000000000000000000000000000000000000000000000000000000000040 // offset of string170                000000000000000000000000000000000000000000000000000000000000000a // size of string171                5465737420555249203200000000000000000000000000000000000000000000 // string172            "173        )174    );175}176177#[test]178fn dynamic_after_static() {179	let mut encoder = AbiWriter::new();180	encoder.bool(&true);181	encoder.string("test");182	let encoded = encoder.finish();183184	let mut encoder = AbiWriter::new();185	encoder.bool(&true);186	// Offset to subresult187	encoder.uint32(&(32 * 2));188	// Len of "test"189	encoder.uint32(&4);190	encoder.write_padright(&[b't', b'e', b's', b't']);191	let alternative_encoded = encoder.finish();192193	assert_eq!(encoded, alternative_encoded);194195	let mut decoder = AbiReader::new(&encoded);196	assert!(decoder.bool().unwrap());197	assert_eq!(decoder.string().unwrap(), "test");198}199200#[test]201fn mint_sample() {202	let (call, mut decoder) = AbiReader::new_call(&hex!(203		"204            50bb4e7f205            000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374206            0000000000000000000000000000000000000000000000000000000000000001207            0000000000000000000000000000000000000000000000000000000000000060208            0000000000000000000000000000000000000000000000000000000000000008209            5465737420555249000000000000000000000000000000000000000000000000210        "211	))212	.unwrap();213	assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));214	assert_eq!(215		format!("{:?}", decoder.address().unwrap()),216		"0xad2c0954693c2b5404b7e50967d3481bea432374"217	);218	assert_eq!(decoder.uint32().unwrap(), 1);219	assert_eq!(decoder.string().unwrap(), "Test URI");220}221222#[test]223fn parse_vec_with_dynamic_type() {224	let decoded_data = (225		0x36543006,226		vec![227			(1.into(), "Test URI 0".to_string()),228			(11.into(), "Test URI 1".to_string()),229			(12.into(), "Test URI 2".to_string()),230		],231	);232233	let encoded_data = &hex!(234        "235            36543006236            00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address237            0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]238            0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]239240            0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem241            00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem242            0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem243244            0000000000000000000000000000000000000000000000000000000000000001 // first token id?   					#60245            0000000000000000000000000000000000000000000000000000000000000040 // offset of string246            000000000000000000000000000000000000000000000000000000000000000a // size of string247            5465737420555249203000000000000000000000000000000000000000000000 // string248249            000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11?			#e0250            0000000000000000000000000000000000000000000000000000000000000040 // offset of string251            000000000000000000000000000000000000000000000000000000000000000a // size of string252            5465737420555249203100000000000000000000000000000000000000000000 // string253254            000000000000000000000000000000000000000000000000000000000000000c // third token id?  Why ==12?			#160255            0000000000000000000000000000000000000000000000000000000000000040 // offset of string256            000000000000000000000000000000000000000000000000000000000000000a // size of string257            5465737420555249203200000000000000000000000000000000000000000000 // string258        "259    );260261	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();262	assert_eq!(call, u32::to_be_bytes(decoded_data.0));263	let address = decoder.address().unwrap();264	let data = <Vec<(uint256, string)>>::abi_read(&mut decoder).unwrap();265	assert_eq!(data, decoded_data.1);266267	let mut writer = AbiWriter::new_call(decoded_data.0);268	address.abi_write(&mut writer);269	decoded_data.1.abi_write(&mut writer);270	let ed = writer.finish();271	similar_asserts::assert_eq!(encoded_data, ed.as_slice());272}273274#[test]275fn encode_decode_vec_tuple_string_bytes() {276	test_impl::<Vec<(string, bytes)>>(277		0xdeadbeef,278		vec![279			(280				"Test URI 0".to_string(),281				bytes(vec![282					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,283					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,284					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,285					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,286				]),287			),288			(289				"Test URI 1".to_string(),290				bytes(vec![291					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,292					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,293					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,294					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,295				]),296			),297			("Test URI 2".to_string(), bytes(vec![0x33, 0x33])),298		],299		&hex!(300			"301                deadbeef302                0000000000000000000000000000000000000000000000000000000000000020303                0000000000000000000000000000000000000000000000000000000000000003304305                0000000000000000000000000000000000000000000000000000000000000060306                0000000000000000000000000000000000000000000000000000000000000140307                0000000000000000000000000000000000000000000000000000000000000220308309                0000000000000000000000000000000000000000000000000000000000000040310                0000000000000000000000000000000000000000000000000000000000000080311                000000000000000000000000000000000000000000000000000000000000000a312                5465737420555249203000000000000000000000000000000000000000000000313                0000000000000000000000000000000000000000000000000000000000000030314                1111111111111111111111111111111111111111111111111111111111111111315                1111111111111111111111111111111100000000000000000000000000000000316317                0000000000000000000000000000000000000000000000000000000000000040318                0000000000000000000000000000000000000000000000000000000000000080319                000000000000000000000000000000000000000000000000000000000000000a320                5465737420555249203100000000000000000000000000000000000000000000321                000000000000000000000000000000000000000000000000000000000000002f322                2222222222222222222222222222222222222222222222222222222222222222323                2222222222222222222222222222220000000000000000000000000000000000324325                0000000000000000000000000000000000000000000000000000000000000040326                0000000000000000000000000000000000000000000000000000000000000080327                000000000000000000000000000000000000000000000000000000000000000a328                5465737420555249203200000000000000000000000000000000000000000000329                0000000000000000000000000000000000000000000000000000000000000002330                3333000000000000000000000000000000000000000000000000000000000000331            "332		),333	);334}
after · crates/evm-coder/src/abi/test.rs
1use crate::{2	abi::{AbiRead, AbiWrite},3	types::*,4};56use super::{AbiReader, AbiWriter};7use hex_literal::hex;8use primitive_types::{H160, U256};910fn test_impl<T>(function_identifier: u32, decoded_data: T, encoded_data: &[u8])11where12	T: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,13{14	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();15	assert_eq!(call, u32::to_be_bytes(function_identifier));16	let data = <T>::abi_read(&mut decoder).unwrap();17	assert_eq!(data, decoded_data);1819	let mut writer = AbiWriter::new_call(function_identifier);20	decoded_data.abi_write(&mut writer);21	let ed = writer.finish();22	similar_asserts::assert_eq!(encoded_data, ed.as_slice());23}2425macro_rules! test_impl_uint {26	($type:ident) => {27		test_impl::<$type>(28			0xdeadbeef,29			255 as $type,30			&hex!(31				"32                    deadbeef33                    00000000000000000000000000000000000000000000000000000000000000ff34                "35			),36		);37	};38}3940#[test]41fn encode_decode_uint8() {42	test_impl_uint!(uint8);43}4445#[test]46fn encode_decode_uint32() {47	test_impl_uint!(uint32);48}4950#[test]51fn encode_decode_uint128() {52	test_impl_uint!(uint128);53}5455#[test]56fn encode_decode_uint256() {57	test_impl::<uint256>(58		0xdeadbeef,59		U256([255, 0, 0, 0]),60		&hex!(61			"62                deadbeef63                00000000000000000000000000000000000000000000000000000000000000ff64            "65		),66	);67}6869#[test]70fn encode_decode_string() {71	test_impl::<String>(72		0xdeadbeef,73		"some string".to_string(),74		&hex!(75			"76                deadbeef77                000000000000000000000000000000000000000000000000000000000000002078                000000000000000000000000000000000000000000000000000000000000000b79                736f6d6520737472696e6700000000000000000000000000000000000000000080            "81		),82	);83}8485#[test]86fn encode_decode_tuple_string() {87	test_impl::<(String,)>(88		0xdeadbeef,89		("some string".to_string(),),90		&hex!(91			"92                deadbeef93                000000000000000000000000000000000000000000000000000000000000002094                000000000000000000000000000000000000000000000000000000000000002095                000000000000000000000000000000000000000000000000000000000000000b96                736f6d6520737472696e6700000000000000000000000000000000000000000097            "98		),99	);100}101102#[test]103fn encode_decode_vec_tuple_address_uint256() {104	test_impl::<Vec<(address, uint256)>>(105        0x1ACF2D55,106        vec![107            (108                H160(hex!("2D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC")),109                U256([10, 0, 0, 0]),110            ),111            (112                H160(hex!("AB8E3D9134955566483B11E6825C9223B6737B10")),113                U256([20, 0, 0, 0]),114            ),115            (116                H160(hex!("8C582BDF2953046705FC56F189385255EFC1BE18")),117                U256([30, 0, 0, 0]),118            ),119        ],120        &hex!(121            "122                1ACF2D55123                0000000000000000000000000000000000000000000000000000000000000020 // offset of (address, uint256)[]124                0000000000000000000000000000000000000000000000000000000000000003 // length of (address, uint256)[]125126                0000000000000000000000002D2FF76104B7BACB2E8F6731D5BFC184EBECDDBC // address127                000000000000000000000000000000000000000000000000000000000000000A // uint256128129                000000000000000000000000AB8E3D9134955566483B11E6825C9223B6737B10 // address130                0000000000000000000000000000000000000000000000000000000000000014 // uint256131132                0000000000000000000000008C582BDF2953046705FC56F189385255EFC1BE18 // address133                000000000000000000000000000000000000000000000000000000000000001E // uint256134            "135        )136    );137}138139#[test]140fn encode_decode_vec_tuple_uint8_uint8() {141	test_impl::<Vec<(u8, u8)>>(142		0xdeadbeef,143		vec![(0x0A, 0x0B), (0x0C, 0x0D), (0x0E, 0x0F)],144		&hex!(145			"146                deadbeef147                0000000000000000000000000000000000000000000000000000000000000020148                0000000000000000000000000000000000000000000000000000000000000003149                000000000000000000000000000000000000000000000000000000000000000a150                000000000000000000000000000000000000000000000000000000000000000b151                000000000000000000000000000000000000000000000000000000000000000c152                000000000000000000000000000000000000000000000000000000000000000d153                000000000000000000000000000000000000000000000000000000000000000e154                000000000000000000000000000000000000000000000000000000000000000f155            "156		),157	);158}159160#[test]161fn encode_decode_vec_tuple_uint256_string() {162	test_impl::<Vec<(uint256, string)>>(163        0xdeadbeef,164        vec![165            (1.into(), "Test URI 0".to_string()),166            (11.into(), "Test URI 1".to_string()),167            (12.into(), "Test URI 2".to_string()),168        ],169        &hex!(170            "171                deadbeef172                0000000000000000000000000000000000000000000000000000000000000020 // offset of (uint256, string)[]173                0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]174175                0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem176                00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem177                0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem178179                0000000000000000000000000000000000000000000000000000000000000001 // first token id?   					#60180                0000000000000000000000000000000000000000000000000000000000000040 // offset of string181                000000000000000000000000000000000000000000000000000000000000000a // size of string182                5465737420555249203000000000000000000000000000000000000000000000 // string183184                000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11?			#e0185                0000000000000000000000000000000000000000000000000000000000000040 // offset of string186                000000000000000000000000000000000000000000000000000000000000000a // size of string187                5465737420555249203100000000000000000000000000000000000000000000 // string188189                000000000000000000000000000000000000000000000000000000000000000c // third token id?  Why ==12?			#160190                0000000000000000000000000000000000000000000000000000000000000040 // offset of string191                000000000000000000000000000000000000000000000000000000000000000a // size of string192                5465737420555249203200000000000000000000000000000000000000000000 // string193            "194        )195    );196}197198#[test]199fn dynamic_after_static() {200	let mut encoder = AbiWriter::new();201	encoder.bool(&true);202	encoder.string("test");203	let encoded = encoder.finish();204205	let mut encoder = AbiWriter::new();206	encoder.bool(&true);207	// Offset to subresult208	encoder.uint32(&(32 * 2));209	// Len of "test"210	encoder.uint32(&4);211	encoder.write_padright(&[b't', b'e', b's', b't']);212	let alternative_encoded = encoder.finish();213214	assert_eq!(encoded, alternative_encoded);215216	let mut decoder = AbiReader::new(&encoded);217	assert!(decoder.bool().unwrap());218	assert_eq!(decoder.string().unwrap(), "test");219}220221#[test]222fn mint_sample() {223	let (call, mut decoder) = AbiReader::new_call(&hex!(224		"225            50bb4e7f226            000000000000000000000000ad2c0954693c2b5404b7e50967d3481bea432374227            0000000000000000000000000000000000000000000000000000000000000001228            0000000000000000000000000000000000000000000000000000000000000060229            0000000000000000000000000000000000000000000000000000000000000008230            5465737420555249000000000000000000000000000000000000000000000000231        "232	))233	.unwrap();234	assert_eq!(call, u32::to_be_bytes(0x50bb4e7f));235	assert_eq!(236		format!("{:?}", decoder.address().unwrap()),237		"0xad2c0954693c2b5404b7e50967d3481bea432374"238	);239	assert_eq!(decoder.uint32().unwrap(), 1);240	assert_eq!(decoder.string().unwrap(), "Test URI");241}242243#[test]244fn parse_vec_with_dynamic_type() {245	let decoded_data = (246		0x36543006,247		vec![248			(1.into(), "Test URI 0".to_string()),249			(11.into(), "Test URI 1".to_string()),250			(12.into(), "Test URI 2".to_string()),251		],252	);253254	let encoded_data = &hex!(255        "256            36543006257            00000000000000000000000053744e6da587ba10b32a2554d2efdcd985bc27a3 // address258            0000000000000000000000000000000000000000000000000000000000000040 // offset of (uint256, string)[]259            0000000000000000000000000000000000000000000000000000000000000003 // length of (uint256, string)[]260261            0000000000000000000000000000000000000000000000000000000000000060 // offset of first elem262            00000000000000000000000000000000000000000000000000000000000000e0 // offset of second elem263            0000000000000000000000000000000000000000000000000000000000000160 // offset of third elem264265            0000000000000000000000000000000000000000000000000000000000000001 // first token id?   					#60266            0000000000000000000000000000000000000000000000000000000000000040 // offset of string267            000000000000000000000000000000000000000000000000000000000000000a // size of string268            5465737420555249203000000000000000000000000000000000000000000000 // string269270            000000000000000000000000000000000000000000000000000000000000000b // second token id? Why ==11?			#e0271            0000000000000000000000000000000000000000000000000000000000000040 // offset of string272            000000000000000000000000000000000000000000000000000000000000000a // size of string273            5465737420555249203100000000000000000000000000000000000000000000 // string274275            000000000000000000000000000000000000000000000000000000000000000c // third token id?  Why ==12?			#160276            0000000000000000000000000000000000000000000000000000000000000040 // offset of string277            000000000000000000000000000000000000000000000000000000000000000a // size of string278            5465737420555249203200000000000000000000000000000000000000000000 // string279        "280    );281282	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();283	assert_eq!(call, u32::to_be_bytes(decoded_data.0));284	let address = decoder.address().unwrap();285	let data = <Vec<(uint256, string)>>::abi_read(&mut decoder).unwrap();286	assert_eq!(data, decoded_data.1);287288	let mut writer = AbiWriter::new_call(decoded_data.0);289	address.abi_write(&mut writer);290	decoded_data.1.abi_write(&mut writer);291	let ed = writer.finish();292	similar_asserts::assert_eq!(encoded_data, ed.as_slice());293}294295#[test]296fn encode_decode_vec_tuple_string_bytes() {297	test_impl::<Vec<(string, bytes)>>(298		0xdeadbeef,299		vec![300			(301				"Test URI 0".to_string(),302				bytes(vec![303					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,304					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,305					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,306					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,307				]),308			),309			(310				"Test URI 1".to_string(),311				bytes(vec![312					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,313					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,314					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,315					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,316				]),317			),318			("Test URI 2".to_string(), bytes(vec![0x33, 0x33])),319		],320		&hex!(321			"322                deadbeef323                0000000000000000000000000000000000000000000000000000000000000020324                0000000000000000000000000000000000000000000000000000000000000003325326                0000000000000000000000000000000000000000000000000000000000000060327                0000000000000000000000000000000000000000000000000000000000000140328                0000000000000000000000000000000000000000000000000000000000000220329330                0000000000000000000000000000000000000000000000000000000000000040331                0000000000000000000000000000000000000000000000000000000000000080332                000000000000000000000000000000000000000000000000000000000000000a333                5465737420555249203000000000000000000000000000000000000000000000334                0000000000000000000000000000000000000000000000000000000000000030335                1111111111111111111111111111111111111111111111111111111111111111336                1111111111111111111111111111111100000000000000000000000000000000337338                0000000000000000000000000000000000000000000000000000000000000040339                0000000000000000000000000000000000000000000000000000000000000080340                000000000000000000000000000000000000000000000000000000000000000a341                5465737420555249203100000000000000000000000000000000000000000000342                000000000000000000000000000000000000000000000000000000000000002f343                2222222222222222222222222222222222222222222222222222222222222222344                2222222222222222222222222222220000000000000000000000000000000000345346                0000000000000000000000000000000000000000000000000000000000000040347                0000000000000000000000000000000000000000000000000000000000000080348                000000000000000000000000000000000000000000000000000000000000000a349                5465737420555249203200000000000000000000000000000000000000000000350                0000000000000000000000000000000000000000000000000000000000000002351                3333000000000000000000000000000000000000000000000000000000000000352            "353		),354	);355}356357#[test]358// #[ignore = "reason"]359fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {360	let int = 0xff;361	let by = bytes(vec![0x11, 0x22, 0x33]);362	let string = "some string".to_string();363364	test_impl::<((u8,), (String, bytes), (u8, bytes))>(365		0xdeadbeef,366		((int,), (string.clone(), by.clone()), (int, by)),367		&hex!(368			"369                deadbeef370                0000000000000000000000000000000000000000000000000000000000000020371                00000000000000000000000000000000000000000000000000000000000000ff372                0000000000000000000000000000000000000000000000000000000000000060373                0000000000000000000000000000000000000000000000000000000000000120374                0000000000000000000000000000000000000000000000000000000000000040375                0000000000000000000000000000000000000000000000000000000000000080376                000000000000000000000000000000000000000000000000000000000000000b377                736f6d6520737472696e67000000000000000000000000000000000000000000378                0000000000000000000000000000000000000000000000000000000000000003379                1122330000000000000000000000000000000000000000000000000000000000380                00000000000000000000000000000000000000000000000000000000000000ff381                0000000000000000000000000000000000000000000000000000000000000040382                0000000000000000000000000000000000000000000000000000000000000003383                1122330000000000000000000000000000000000000000000000000000000000384            "385		),386	);387}388389#[test]390fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8_uint8_tuple1_uint8_uint8() {391	test_impl::<((u8,), (u8, u8), (u8, u8))>(392		0xdeadbeef,393		((43,), (44, 45), (46, 47)),394		&hex!(395			"396                deadbeef397                000000000000000000000000000000000000000000000000000000000000002b398                000000000000000000000000000000000000000000000000000000000000002c399                000000000000000000000000000000000000000000000000000000000000002d400                000000000000000000000000000000000000000000000000000000000000002e401                000000000000000000000000000000000000000000000000000000000000002f402            "403		),404	);405}406407#[test]408fn encode_decode_tuple0_tuple1_uint8_tuple1_uint8() {409	test_impl::<((u8,), (u8,))>(410		0xdeadbeef,411		((43,), (44,)),412		&hex!(413			"414                deadbeef415                000000000000000000000000000000000000000000000000000000000000002b416                000000000000000000000000000000000000000000000000000000000000002c417            "418		),419	);420}421422#[test]423fn encode_decode_tuple0_tuple1_uint8_uint8() {424	test_impl::<((u8, u8),)>(425		0xdeadbeef,426		((43, 44),),427		&hex!(428			"429                deadbeef430                000000000000000000000000000000000000000000000000000000000000002b431                000000000000000000000000000000000000000000000000000000000000002c432            "433		),434	);435}436437#[test]438fn encode_decode_tuple_uint8_uint8() {439	test_impl::<(u8, u8)>(440		0xdeadbeef,441		(43, 44),442		&hex!(443			"444                deadbeef445                000000000000000000000000000000000000000000000000000000000000002b446                000000000000000000000000000000000000000000000000000000000000002c447            "448		),449	);450}451452#[test]453fn encode_decode_tuple0_tuple1_string() {454	test_impl::<((String,),)>(455		0xdeadbeef,456		(("some string".to_string(),),),457		&hex!(458			"459                deadbeef460                0000000000000000000000000000000000000000000000000000000000000020461                0000000000000000000000000000000000000000000000000000000000000020462                0000000000000000000000000000000000000000000000000000000000000020463                000000000000000000000000000000000000000000000000000000000000000b464                736f6d6520737472696e67000000000000000000000000000000000000000000465            "466		),467	);468}469470#[test]471fn encode_decode_tuple0_tuple1_uint8_string() {472	test_impl::<((u8, String),)>(473		0xdeadbeef,474		((0xff, "some string".to_string()),),475		&hex!(476			"477                deadbeef478                0000000000000000000000000000000000000000000000000000000000000020479                0000000000000000000000000000000000000000000000000000000000000020480                00000000000000000000000000000000000000000000000000000000000000ff481                0000000000000000000000000000000000000000000000000000000000000040482                000000000000000000000000000000000000000000000000000000000000000b483                736f6d6520737472696e67000000000000000000000000000000000000000000484            "485		),486	);487}488489#[test]490fn encode_decode_tuple0_tuple1_string_bytes() {491	test_impl::<((String, bytes),)>(492		0xdeadbeef,493		(("some string".to_string(), bytes(vec![1, 2, 3])),),494		&hex!(495			"496                deadbeef497                0000000000000000000000000000000000000000000000000000000000000020498                0000000000000000000000000000000000000000000000000000000000000020499                0000000000000000000000000000000000000000000000000000000000000040500                0000000000000000000000000000000000000000000000000000000000000080501                000000000000000000000000000000000000000000000000000000000000000b502                736f6d6520737472696e67000000000000000000000000000000000000000000503                0000000000000000000000000000000000000000000000000000000000000003504                0102030000000000000000000000000000000000000000000000000000000000505            "506		),507	);508}509510#[test]511fn encode_decode_tuple0_tuple1_uint8_tuple1_string() {512	test_impl::<((u8,), (String,))>(513		0xdeadbeef,514		((0xff,), ("some string".to_string(),)),515		&hex!(516			"517                deadbeef518                0000000000000000000000000000000000000000000000000000000000000020519                00000000000000000000000000000000000000000000000000000000000000ff520                0000000000000000000000000000000000000000000000000000000000000040521                0000000000000000000000000000000000000000000000000000000000000020522                000000000000000000000000000000000000000000000000000000000000000b523                736f6d6520737472696e67000000000000000000000000000000000000000000524            "525		),526	);527}
modifiedcrates/evm-coder/tests/abi_derive_generation.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/abi_derive_generation.rs
+++ b/crates/evm-coder/tests/abi_derive_generation.rs
@@ -1,7 +1,7 @@
 use evm_coder_procedural::AbiCoder;
 use evm_coder::{
 	types::*,
-	abi::{AbiType, AbiRead, AbiWrite},
+	abi::{AbiType, AbiRead, AbiWrite, AbiReader, AbiWriter},
 };
 
 // TODO: move to build_failed tests
@@ -406,66 +406,199 @@
 	);
 }
 
-fn test_impl<TypeStruct, TupleStruct, Tuple>(
-	type_struct_data: TypeStruct,
-	tuple_struct_data: TupleStruct,
+const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
+
+fn test_impl<Tuple, TupleStruct, TypeStruct>(
 	tuple_data: Tuple,
+	tuple_struct_data: TupleStruct,
+	type_struct_data: TypeStruct,
 ) where
 	TypeStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
+	TupleStruct: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
 	Tuple: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
 {
-	use evm_coder::abi::{AbiReader, AbiWriter};
-	const FUNCTION_IDENTIFIER: u32 = 0xdeadbeef;
+	let encoded_type_struct = test_abi_write_impl(&type_struct_data);
+	let encoded_tuple_struct = test_abi_write_impl(&tuple_struct_data);
+	let encoded_tuple = test_abi_write_impl(&tuple_data);
 
-	let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);
-	tuple_data.abi_write(&mut writer);
-	let encoded_tuple = writer.finish();
+	similar_asserts::assert_eq!(encoded_tuple, encoded_type_struct);
+	similar_asserts::assert_eq!(encoded_tuple, encoded_tuple_struct);
 
-	let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);
-	type_struct_data.abi_write(&mut writer);
-	let encoded_struct = writer.finish();
+	// dbg!(&encoded_tuple);
+	// dbg!(&encoded_tuple_struct);
+	// dbg!(&encoded_type_struct);
 
-	similar_asserts::assert_eq!(encoded_tuple, encoded_struct);
+	{
+		let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
+		let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
+		assert_eq!(restored_struct_data, type_struct_data);
+	}
+	{
+		let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
+		let restored_struct_data = <TupleStruct>::abi_read(&mut decoder).unwrap();
+		assert_eq!(restored_struct_data, tuple_struct_data);
+	}
 
-	// let (_, mut decoder) = AbiReader::new_call(&encoded_tuple).unwrap();
-	// let restored_struct_data = <TypeStruct>::abi_read(&mut decoder).unwrap();
-	// assert_eq!(restored_struct_data, type_struct_data);
+	{
+		let (_, mut decoder) = AbiReader::new_call(&encoded_type_struct).unwrap();
+		let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
+		assert_eq!(restored_tuple_data, tuple_data);
+	}
+	{
+		let (_, mut decoder) = AbiReader::new_call(&encoded_tuple_struct).unwrap();
+		let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
+		assert_eq!(restored_tuple_data, tuple_data);
+	}
+}
 
-	// let (_, mut decoder) = AbiReader::new_call(&encoded_struct).unwrap();
-	// let restored_tuple_data = <Tuple>::abi_read(&mut decoder).unwrap();
-	// assert_eq!(restored_tuple_data, tuple_data);
+fn test_abi_write_impl<A>(data: &A) -> Vec<u8>
+where
+	A: AbiWrite + AbiRead + std::cmp::PartialEq + std::fmt::Debug,
+{
+	let mut writer = AbiWriter::new_call(FUNCTION_IDENTIFIER);
+	data.abi_write(&mut writer);
+	let encoded_tuple = writer.finish();
+	encoded_tuple
 }
 
 #[test]
 fn codec_struct_1_simple() {
 	let _a = 0xff;
-	test_impl::<TypeStruct1SimpleParam, TupleStruct1SimpleParam, (uint8,)>(
-		TypeStruct1SimpleParam { _a },
+	test_impl::<(uint8,), TupleStruct1SimpleParam, TypeStruct1SimpleParam>(
+		(_a,),
 		TupleStruct1SimpleParam(_a),
-		(_a,),
+		TypeStruct1SimpleParam { _a },
 	);
 }
 
 #[test]
 fn codec_struct_1_dynamic() {
 	let _a: String = "some string".into();
-	test_impl::<TypeStruct1DynamicParam, TupleStruct1DynamicParam, (String,)>(
-		TypeStruct1DynamicParam { _a: _a.clone() },
+	test_impl::<(String,), TupleStruct1DynamicParam, TypeStruct1DynamicParam>(
+		(_a.clone(),),
 		TupleStruct1DynamicParam(_a.clone()),
-		(_a,),
+		TypeStruct1DynamicParam { _a },
+	);
+}
+
+#[test]
+fn codec_struct_1_derived_simple() {
+	let _a: u8 = 0xff;
+	test_impl::<((u8,),), TupleStruct1DerivedSimpleParam, TypeStruct1DerivedSimpleParam>(
+		((_a,),),
+		TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam(_a)),
+		TypeStruct1DerivedSimpleParam {
+			_a: TypeStruct1SimpleParam { _a },
+		},
 	);
 }
 
 #[test]
+fn codec_struct_1_derived_dynamic() {
+	let _a: String = "some string".into();
+	test_impl::<((String,),), TupleStruct1DerivedDynamicParam, TypeStruct1DerivedDynamicParam>(
+		((_a.clone(),),),
+		TupleStruct1DerivedDynamicParam(TupleStruct1DynamicParam(_a.clone())),
+		TypeStruct1DerivedDynamicParam {
+			_a: TypeStruct1DynamicParam { _a },
+		},
+	);
+}
+
+#[test]
+fn codec_struct_2_simple() {
+	let _a = 0xff;
+	let _b = 0xbeefbaba;
+	test_impl::<(u8, u32), TupleStruct2SimpleParam, TypeStruct2SimpleParam>(
+		(_a, _b),
+		TupleStruct2SimpleParam(_a, _b),
+		TypeStruct2SimpleParam { _a, _b },
+	);
+}
+
+#[test]
 fn codec_struct_2_dynamic() {
 	let _a: String = "some string".into();
 	let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
-	test_impl::<TypeStruct2DynamicParam, TupleStruct2DynamicParam, (String, bytes)>(
-		TypeStruct2DynamicParam {
-			_a: _a.clone(),
-			_b: _b.clone(),
-		},
+	test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
+		(_a.clone(), _b.clone()),
 		TupleStruct2DynamicParam(_a.clone(), _b.clone()),
-		(_a, _b),
+		TypeStruct2DynamicParam { _a, _b },
+	);
+}
+
+#[test]
+fn codec_struct_2_mixed() {
+	let _a: u8 = 0xff;
+	let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
+	test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
+		(_a.clone(), _b.clone()),
+		TupleStruct2MixedParam(_a.clone(), _b.clone()),
+		TypeStruct2MixedParam { _a, _b },
+	);
+}
+
+#[test]
+fn codec_struct_2_derived_simple() {
+	let _a = 0xff;
+	let _b = 0xbeefbaba;
+	test_impl::<((u8,), (u8, u32)), TupleStruct2DerivedSimpleParam, TypeStruct2DerivedSimpleParam>(
+		((_a,), (_a, _b)),
+		TupleStruct2DerivedSimpleParam(
+			TupleStruct1SimpleParam(_a),
+			TupleStruct2SimpleParam(_a, _b),
+		),
+		TypeStruct2DerivedSimpleParam {
+			_a: TypeStruct1SimpleParam { _a },
+			_b: TypeStruct2SimpleParam { _a, _b },
+		},
+	);
+}
+
+#[test]
+fn codec_struct_2_derived_dynamic() {
+	let _a = "some string".to_string();
+	let _b = bytes(vec![0x11, 0x22, 0x33]);
+	test_impl::<
+		((String,), (String, bytes)),
+		TupleStruct2DerivedDynamicParam,
+		TypeStruct2DerivedDynamicParam,
+	>(
+		((_a.clone(),), (_a.clone(), _b.clone())),
+		TupleStruct2DerivedDynamicParam(
+			TupleStruct1DynamicParam(_a.clone()),
+			TupleStruct2DynamicParam(_a.clone(), _b.clone()),
+		),
+		TypeStruct2DerivedDynamicParam {
+			_a: TypeStruct1DynamicParam { _a: _a.clone() },
+			_b: TypeStruct2DynamicParam { _a, _b },
+		},
+	);
+}
+
+#[test]
+fn codec_struct_3_derived_mixed() {
+	let int = 0xff;
+	let by = bytes(vec![0x11, 0x22, 0x33]);
+	let string = "some string".to_string();
+	test_impl::<
+		((u8,), (String, bytes), (u8, bytes)),
+		TupleStruct3DerivedMixedParam,
+		TypeStruct3DerivedMixedParam,
+	>(
+		((int,), (string.clone(), by.clone()), (int, by.clone())),
+		TupleStruct3DerivedMixedParam(
+			TupleStruct1SimpleParam(int),
+			TupleStruct2DynamicParam(string.clone(), by.clone()),
+			TupleStruct2MixedParam(int, by.clone()),
+		),
+		TypeStruct3DerivedMixedParam {
+			_a: TypeStruct1SimpleParam { _a: int },
+			_b: TypeStruct2DynamicParam {
+				_a: string.clone(),
+				_b: by.clone(),
+			},
+			_c: TypeStruct2MixedParam { _a: int, _b: by },
+		},
 	);
 }