git.delta.rocks / unique-network / refs/commits / be088e7492dc

difftreelog

refactor reuse code generation patterns

Yaroslav Bolyukin2022-12-22parent: #81e4f2e.patch.diff
in: master

22 files changed

modifiedcrates/evm-coder/procedural/src/abi_derive/derive_enum.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/derive_enum.rs
@@ -1,20 +1,52 @@
 use quote::quote;
 
+use super::extract_docs;
+
 pub fn impl_solidity_option<'a>(
+	docs: Vec<String>,
 	name: &proc_macro2::Ident,
-	enum_options: impl Iterator<Item = &'a syn::Ident>,
+	enum_options: impl Iterator<Item = &'a syn::Variant> + Clone,
 ) -> proc_macro2::TokenStream {
-	let enum_options = enum_options.map(|opt| {
+	let variant_names = enum_options.clone().map(|opt| {
+		let opt = &opt.ident;
 		let s = name.to_string() + "." + opt.to_string().as_str();
 		let as_string = proc_macro2::Literal::string(s.as_str());
 		quote!(#name::#opt => #as_string,)
 	});
+	let solidity_name = name.to_string();
+
+	let solidity_fields = enum_options.map(|v| {
+		let docs = extract_docs(&v.attrs).expect("TODO: handle bad docs");
+		let name = v.ident.to_string();
+		quote! {
+			SolidityEnumVariant {
+				docs: &[#(#docs),*],
+				name: #name,
+			}
+		}
+	});
+
 	quote!(
 		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityEnum for #name {
+		impl ::evm_coder::solidity::SolidityEnumTy for #name {
+			fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
+				use evm_coder::solidity::*;
+				use core::fmt::Write;
+				let interface = SolidityEnum {
+					docs: &[#(#docs),*],
+					name: #solidity_name,
+					fields: &[#(
+						#solidity_fields,
+					)*],
+				};
+				let mut out = String::new();
+				let _ = interface.format(&mut out, tc);
+				tc.collect(out);
+				#solidity_name.to_string()
+			}
 			fn solidity_option(&self) -> &str {
 				match self {
-					#(#enum_options)*
+					#(#variant_names)*
 				}
 			}
 		}
@@ -23,11 +55,12 @@
 
 pub fn impl_enum_from_u8<'a>(
 	name: &proc_macro2::Ident,
-	enum_options: impl Iterator<Item = &'a syn::Ident>,
+	enum_options: impl Iterator<Item = &'a syn::Variant>,
 ) -> proc_macro2::TokenStream {
 	let error_str = format!("Value not convertible into enum \"{name}\"");
 	let error_str = proc_macro2::Literal::string(&error_str);
 	let enum_options = enum_options.enumerate().map(|(i, opt)| {
+		let opt = &opt.ident;
 		let n = proc_macro2::Literal::u8_suffixed(i as u8);
 		quote! {#n => Ok(#name::#opt),}
 	});
@@ -83,21 +116,6 @@
 			}
 		}
 	)
-}
-
-pub fn impl_enum_solidity_type<'a>(name: &syn::Ident) -> proc_macro2::TokenStream {
-	quote! {
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityType for #name {
-			fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {
-				Vec::new()
-			}
-
-			fn len() -> usize {
-				1
-			}
-		}
-	}
 }
 
 pub fn impl_enum_solidity_type_name(name: &syn::Ident) -> proc_macro2::TokenStream {
@@ -108,7 +126,7 @@
 				writer: &mut impl ::core::fmt::Write,
 				tc: &::evm_coder::solidity::TypeCollector,
 			) -> ::core::fmt::Result {
-				write!(writer, "{}", tc.collect_struct::<Self>())
+				write!(writer, "{}", tc.collect_enum::<Self>())
 			}
 
 			fn is_simple() -> bool {
@@ -119,49 +137,7 @@
 				writer: &mut impl ::core::fmt::Write,
 				tc: &::evm_coder::solidity::TypeCollector,
 			) -> ::core::fmt::Result {
-				write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnum>::solidity_option(&<#name>::default()))
-			}
-		}
-	)
-}
-
-pub fn impl_enum_solidity_struct_collect<'a>(
-	name: &syn::Ident,
-	enum_options: impl Iterator<Item = &'a syn::Ident>,
-	option_count: usize,
-	enum_options_docs: impl Iterator<Item = syn::Result<Vec<proc_macro2::TokenStream>>>,
-	docs: &[proc_macro2::TokenStream],
-) -> proc_macro2::TokenStream {
-	let string_name = name.to_string();
-	let enum_options = enum_options
-		.zip(enum_options_docs)
-		.enumerate()
-		.map(|(i, (opt, doc))| {
-			let opt = proc_macro2::Literal::string(opt.to_string().as_str());
-			let doc = doc.expect("Doc parsing error");
-			let comma = if i != option_count - 1 { "," } else { "" };
-			quote! {
-				#(#doc)*
-				writeln!(str, "\t{}{}", #opt, #comma).expect("Enum format option");
-			}
-		});
-
-	quote!(
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::StructCollect for #name {
-			fn name() -> String {
-				#string_name.into()
-			}
-
-			fn declaration() -> String {
-				use std::fmt::Write;
-
-				let mut str = String::new();
-				#(#docs)*
-				writeln!(str, "enum {} {{", <Self as ::evm_coder::solidity::StructCollect>::name()).unwrap();
-				#(#enum_options)*
-				writeln!(str, "}}").unwrap();
-				str
+				write!(writer, "{}", <#name as ::evm_coder::solidity::SolidityEnumTy>::solidity_option(&<#name>::default()))
 			}
 		}
 	)
modifiedcrates/evm-coder/procedural/src/abi_derive/derive_struct.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/derive_struct.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/derive_struct.rs
@@ -1,5 +1,6 @@
 use super::extract_docs;
 use quote::quote;
+use syn::Field;
 
 pub fn tuple_type<'a>(
 	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
@@ -87,10 +88,6 @@
 	&field.ty
 }
 
-pub fn map_field_to_doc(field: &syn::Field) -> syn::Result<Vec<proc_macro2::TokenStream>> {
-	extract_docs(&field.attrs, true)
-}
-
 pub fn impl_can_be_placed_in_vec(ident: &syn::Ident) -> proc_macro2::TokenStream {
 	quote! {
 		impl ::evm_coder::sealed::CanBePlacedInVec for #ident {}
@@ -147,27 +144,44 @@
 
 pub fn impl_struct_solidity_type<'a>(
 	name: &syn::Ident,
-	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-	params_count: usize,
+	docs: Vec<String>,
+	fields: impl Iterator<Item = &'a Field> + Clone,
 ) -> proc_macro2::TokenStream {
-	let len = proc_macro2::Literal::usize_suffixed(params_count);
+	let solidity_name = name.to_string();
+	let solidity_fields = fields.enumerate().map(|(i, f)| {
+		let name = f
+			.ident
+			.as_ref()
+			.map(|i| i.to_string())
+			.unwrap_or_else(|| format!("field_{i}"));
+		let ty = &f.ty;
+		let docs = extract_docs(&f.attrs).expect("TODO: handle bad docs");
+		quote! {
+			SolidityStructField::<#ty> {
+				docs: &[#(#docs),*],
+				name: #name,
+				ty: ::core::marker::PhantomData,
+			}
+		}
+	});
 	quote! {
 		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::SolidityType for #name {
-			fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec<String> {
-				let mut collected =
-					Vec::with_capacity(<Self as ::evm_coder::solidity::SolidityType>::len());
-				#({
-					let mut out = String::new();
-					<#field_types as ::evm_coder::solidity::SolidityTypeName>::solidity_name(&mut out, tc)
-						.expect("no fmt error");
-					collected.push(out);
-				})*
-				collected
-			}
-
-			fn len() -> usize {
-				#len
+		impl ::evm_coder::solidity::SolidityStructTy for #name {
+			/// Generate solidity definitions for methods described in this struct
+			fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector) -> String {
+				use evm_coder::solidity::*;
+				use core::fmt::Write;
+				let interface = SolidityStruct {
+					docs: &[#(#docs),*],
+					name: #solidity_name,
+					fields: (#(
+						#solidity_fields,
+					)*),
+				};
+				let mut out = String::new();
+				let _ = interface.format(&mut out, tc);
+				tc.collect(out);
+				#solidity_name.to_string()
 			}
 		}
 	}
@@ -214,47 +228,4 @@
 			}
 		}
 	}
-}
-
-pub fn impl_struct_solidity_struct_collect<'a>(
-	name: &syn::Ident,
-	field_names: impl Iterator<Item = proc_macro2::Ident> + Clone,
-	field_types: impl Iterator<Item = &'a syn::Type> + Clone,
-	field_docs: impl Iterator<Item = syn::Result<Vec<proc_macro2::TokenStream>>> + Clone,
-	docs: &[proc_macro2::TokenStream],
-) -> syn::Result<proc_macro2::TokenStream> {
-	let string_name = name.to_string();
-	let name_type = field_names
-		.into_iter()
-		.zip(field_types)
-		.zip(field_docs)
-		.map(|((name, ty), doc)| {
-			let field_docs = doc.expect("Doc parse error");
-			let name = format!("{}", name);
-			quote!(
-				#(#field_docs)*
-				write!(str, "\t{} ", <#ty as ::evm_coder::solidity::StructCollect>::name()).unwrap();
-				writeln!(str, "{};", #name).unwrap();
-			)
-		});
-
-	Ok(quote! {
-		#[cfg(feature = "stubgen")]
-		impl ::evm_coder::solidity::StructCollect for #name {
-			fn name() -> String {
-				#string_name.into()
-			}
-
-			fn declaration() -> String {
-				use std::fmt::Write;
-
-				let mut str = String::new();
-				#(#docs)*
-				writeln!(str, "struct {} {{", Self::name()).unwrap();
-				#(#name_type)*
-				writeln!(str, "}}").unwrap();
-				str
-			}
-		}
-	})
 }
modifiedcrates/evm-coder/procedural/src/abi_derive/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/abi_derive/mod.rs
+++ b/crates/evm-coder/procedural/src/abi_derive/mod.rs
@@ -19,20 +19,18 @@
 	ast: &syn::DeriveInput,
 ) -> syn::Result<proc_macro2::TokenStream> {
 	let name = &ast.ident;
-	let docs = extract_docs(&ast.attrs, false)?;
-	let (is_named_fields, field_names, field_types, field_docs, params_count) = match ds.fields {
+	let docs = extract_docs(&ast.attrs)?;
+	let (is_named_fields, field_names, field_types, params_count) = match ds.fields {
 		syn::Fields::Named(ref fields) => Ok((
 			true,
 			fields.named.iter().enumerate().map(map_field_to_name),
 			fields.named.iter().map(map_field_to_type),
-			fields.named.iter().map(map_field_to_doc),
 			fields.named.len(),
 		)),
 		syn::Fields::Unnamed(ref fields) => Ok((
 			false,
 			fields.unnamed.iter().enumerate().map(map_field_to_name),
 			fields.unnamed.iter().map(map_field_to_type),
-			fields.unnamed.iter().map(map_field_to_doc),
 			fields.unnamed.len(),
 		)),
 		syn::Fields::Unit => Err(syn::Error::new(name.span(), "Unit structs not supported")),
@@ -52,11 +50,9 @@
 	let abi_type = impl_struct_abi_type(name, tuple_type.clone());
 	let abi_read = impl_struct_abi_read(name, tuple_type, tuple_names, struct_from_tuple);
 	let abi_write = impl_struct_abi_write(name, is_named_fields, tuple_ref_type, tuple_data);
-	let solidity_type = impl_struct_solidity_type(name, field_types.clone(), params_count);
+	let solidity_type = impl_struct_solidity_type(name, docs, ds.fields.iter());
 	let solidity_type_name =
 		impl_struct_solidity_type_name(name, field_types.clone(), params_count);
-	let solidity_struct_collect =
-		impl_struct_solidity_struct_collect(name, field_names, field_types, field_docs, &docs)?;
 
 	Ok(quote! {
 		#can_be_plcaed_in_vec
@@ -65,7 +61,6 @@
 		#abi_write
 		#solidity_type
 		#solidity_type_name
-		#solidity_struct_collect
 	})
 }
 
@@ -75,26 +70,16 @@
 ) -> syn::Result<proc_macro2::TokenStream> {
 	let name = &ast.ident;
 	check_repr_u8(name, &ast.attrs)?;
-	let docs = extract_docs(&ast.attrs, false)?;
-	let option_count = check_and_count_options(de)?;
-	let enum_options = de.variants.iter().map(|v| &v.ident);
-	let enum_options_docs = de.variants.iter().map(|v| extract_docs(&v.attrs, true));
+	let docs = extract_docs(&ast.attrs)?;
+	let enum_options = de.variants.iter();
 
 	let from = impl_enum_from_u8(name, enum_options.clone());
-	let solidity_option = impl_solidity_option(name, enum_options.clone());
+	let solidity_option = impl_solidity_option(docs, name, enum_options.clone());
 	let can_be_plcaed_in_vec = impl_can_be_placed_in_vec(name);
 	let abi_type = impl_enum_abi_type(name);
 	let abi_read = impl_enum_abi_read(name);
 	let abi_write = impl_enum_abi_write(name);
-	let solidity_type = impl_enum_solidity_type(name);
 	let solidity_type_name = impl_enum_solidity_type_name(name);
-	let solidity_struct_collect = impl_enum_solidity_struct_collect(
-		name,
-		enum_options,
-		option_count,
-		enum_options_docs,
-		&docs,
-	);
 
 	Ok(quote! {
 		#from
@@ -103,16 +88,11 @@
 		#abi_type
 		#abi_read
 		#abi_write
-		#solidity_type
 		#solidity_type_name
-		#solidity_struct_collect
 	})
 }
 
-fn extract_docs(
-	attrs: &[syn::Attribute],
-	is_field_doc: bool,
-) -> syn::Result<Vec<proc_macro2::TokenStream>> {
+fn extract_docs(attrs: &[syn::Attribute]) -> syn::Result<Vec<String>> {
 	attrs
 		.iter()
 		.filter_map(|attr| {
@@ -132,16 +112,6 @@
 				}
 			}
 			None
-		})
-		.enumerate()
-		.map(|(i, doc)| {
-			let doc = doc?;
-			let doc = doc.trim();
-			let dev = if i == 0 { " @dev" } else { "" };
-			let tab = if is_field_doc { "\t" } else { "" };
-			Ok(quote! {
-				writeln!(str, "{}///{} {}", #tab, #dev, #doc).unwrap();
-			})
 		})
 		.collect()
 }
modifiedcrates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/impls.rs
+++ b/crates/evm-coder/src/solidity/impls.rs
@@ -1,4 +1,4 @@
-use super::{TypeCollector, SolidityTypeName, SolidityType, StructCollect};
+use super::{TypeCollector, SolidityTypeName, SolidityTupleTy};
 use crate::{sealed, types::*};
 use core::fmt;
 use primitive_types::{U256, H160};
@@ -17,16 +17,6 @@
 					write!(writer, $default)
 				}
             }
-
-			impl StructCollect for $ty {
-				fn name() -> String {
-					$name.to_string()
-				}
-
-				fn declaration() -> String {
-					String::default()
-				}
-			}
         )*
     };
 }
@@ -71,17 +61,7 @@
 		write!(writer, "new ")?;
 		T::solidity_name(writer, tc)?;
 		write!(writer, "[](0)")
-	}
-}
-
-impl<T: StructCollect + sealed::CanBePlacedInVec> StructCollect for Vec<T> {
-	fn name() -> String {
-		<T as StructCollect>::name() + "[]"
 	}
-
-	fn declaration() -> String {
-		unimplemented!("Vectors have not declarations.")
-	}
 }
 
 macro_rules! count {
@@ -91,8 +71,8 @@
 
 macro_rules! impl_tuples {
 	($($ident:ident)+) => {
-		impl<$($ident: SolidityTypeName + 'static),+> SolidityType for ($($ident,)+) {
-			fn names(tc: &TypeCollector) -> Vec<string> {
+		impl<$($ident: SolidityTypeName + 'static),+> SolidityTupleTy for ($($ident,)+) {
+			fn fields(tc: &TypeCollector) -> Vec<string> {
 				let mut collected = Vec::with_capacity(Self::len());
 				$({
 					let mut out = string::new();
modifiedcrates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/mod.rs
+++ b/crates/evm-coder/src/solidity/mod.rs
@@ -44,6 +44,7 @@
 	/// id ordering is required to perform topo-sort on the resulting data
 	structs: RefCell<BTreeMap<string, usize>>,
 	anonymous: RefCell<BTreeMap<Vec<string>, usize>>,
+	// generic: RefCell<BTreeMap<string, usize>>,
 	id: Cell<usize>,
 }
 impl TypeCollector {
@@ -59,8 +60,9 @@
 		self.id.set(v + 1);
 		v
 	}
-	pub fn collect_tuple<T: SolidityType>(&self) -> String {
-		let names = T::names(self);
+	/// Collect typle, deduplicating it by type, and returning generated name
+	pub fn collect_tuple<T: SolidityTupleTy>(&self) -> String {
+		let names = T::fields(self);
 		if let Some(id) = self.anonymous.borrow().get(&names).cloned() {
 			return format!("Tuple{}", id);
 		}
@@ -76,11 +78,12 @@
 		self.anonymous.borrow_mut().insert(names, id);
 		format!("Tuple{}", id)
 	}
-	pub fn collect_struct<T: StructCollect + SolidityType>(&self) -> String {
-		let _names = T::names(self);
-		self.collect(<T as StructCollect>::declaration());
-		<T as StructCollect>::name()
+	pub fn collect_struct<T: SolidityStructTy>(&self) -> String {
+		T::generate_solidity_interface(self)
 	}
+	pub fn collect_enum<T: SolidityEnumTy>(&self) -> String {
+		T::generate_solidity_interface(self)
+	}
 	pub fn finish(self) -> Vec<string> {
 		let mut data = self.structs.into_inner().into_iter().collect::<Vec<_>>();
 		data.sort_by_key(|(_, id)| Reverse(*id));
@@ -420,3 +423,93 @@
 		writeln!(writer, ");")
 	}
 }
+
+#[impl_for_tuples(0, 48)]
+impl SolidityItems for Tuple {
+	for_tuples!( where #( Tuple: SolidityItems ),* );
+
+	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
+		for_tuples!( #(
+            Tuple.solidity_name(writer, tc)?;
+        )* );
+		Ok(())
+	}
+}
+
+pub struct SolidityStructField<T> {
+	pub docs: &'static [&'static str],
+	pub name: &'static str,
+	pub ty: PhantomData<*const T>,
+}
+
+impl<T> SolidityItems for SolidityStructField<T>
+where
+	T: SolidityTypeName,
+{
+	fn solidity_name(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
+		for doc in self.docs {
+			writeln!(out, "///{}", doc)?;
+		}
+		write!(out, "\t")?;
+		T::solidity_name(out, tc)?;
+		writeln!(out, " {};", self.name)?;
+		Ok(())
+	}
+}
+pub struct SolidityStruct<F> {
+	pub docs: &'static [&'static str],
+	// pub generics:
+	pub name: &'static str,
+	pub fields: F,
+}
+impl<F> SolidityStruct<F>
+where
+	F: SolidityItems,
+{
+	pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
+		for doc in self.docs {
+			writeln!(out, "///{}", doc)?;
+		}
+		writeln!(out, "struct {} {{", self.name)?;
+		self.fields.solidity_name(out, tc)?;
+		writeln!(out, "}}")?;
+		Ok(())
+	}
+}
+
+pub struct SolidityEnumVariant {
+	pub docs: &'static [&'static str],
+	pub name: &'static str,
+}
+impl SolidityItems for SolidityEnumVariant {
+	fn solidity_name(&self, out: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
+		for doc in self.docs {
+			writeln!(out, "///{}", doc)?;
+		}
+		write!(out, "\t{}", self.name)?;
+		Ok(())
+	}
+}
+pub struct SolidityEnum {
+	pub docs: &'static [&'static str],
+	pub name: &'static str,
+	pub fields: &'static [SolidityEnumVariant],
+}
+impl SolidityEnum {
+	pub fn format(&self, out: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result {
+		for doc in self.docs {
+			writeln!(out, "///{}", doc)?;
+		}
+		write!(out, "enum {} {{", self.name)?;
+		for (i, field) in self.fields.iter().enumerate() {
+			if i != 0 {
+				write!(out, ",")?;
+			}
+			writeln!(out)?;
+			field.solidity_name(out, tc)?;
+		}
+		writeln!(out)?;
+		writeln!(out, "}}")?;
+		Ok(())
+	}
+}
modifiedcrates/evm-coder/src/solidity/traits.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/traits.rs
+++ b/crates/evm-coder/src/solidity/traits.rs
@@ -1,17 +1,6 @@
 use super::TypeCollector;
 use core::fmt;
 
-pub trait StructCollect: 'static {
-	/// Structure name.
-	fn name() -> String;
-	/// Structure declaration.
-	fn declaration() -> String;
-}
-
-pub trait SolidityEnum: 'static {
-	fn solidity_option(&self) -> &str;
-}
-
 pub trait SolidityTypeName: 'static {
 	fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
 	/// "simple" types are stored inline, no `memory` modifier should be used in solidity
@@ -23,10 +12,17 @@
 	}
 }
 
-pub trait SolidityType {
-	fn names(tc: &TypeCollector) -> Vec<String>;
+pub trait SolidityTupleTy: 'static {
+	fn fields(tc: &TypeCollector) -> Vec<String>;
 	fn len() -> usize;
 }
+pub trait SolidityStructTy: 'static {
+	fn generate_solidity_interface(tc: &TypeCollector) -> String;
+}
+pub trait SolidityEnumTy: 'static {
+	fn generate_solidity_interface(tc: &TypeCollector) -> String;
+	fn solidity_option(&self) -> &str;
+}
 
 pub trait SolidityArguments {
 	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
@@ -46,3 +42,9 @@
 		tc: &TypeCollector,
 	) -> fmt::Result;
 }
+
+pub trait SolidityItems {
+	fn solidity_name(&self, writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result;
+	// For PhantomData fields
+	// fn is_void()
+}
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
@@ -74,41 +74,6 @@
 	}
 
 	#[test]
-	#[cfg(feature = "stubgen")]
-	fn struct_collect_type_struct3_derived_mixed_param() {
-		assert_eq!(
-			<TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),
-			"TypeStruct3DerivedMixedParam"
-		);
-		similar_asserts::assert_eq!(
-			<TypeStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),
-			r#"/// @dev Some docs
-/// At multi
-/// line
-struct TypeStruct3DerivedMixedParam {
-	/// @dev Docs for A
-	/// multi
-	/// line
-	TypeStruct1SimpleParam _a;
-	/// @dev Docs for B
-	TypeStruct2DynamicParam _b;
-	/// @dev Docs for C
-	TypeStruct2MixedParam _c;
-}
-"#
-		);
-	}
-
-	#[test]
-	#[cfg(feature = "stubgen")]
-	fn struct_collect_vec() {
-		assert_eq!(
-			<Vec<u8> as ::evm_coder::solidity::StructCollect>::name(),
-			"uint8[]"
-		);
-	}
-
-	#[test]
 	fn impl_abi_type_signature() {
 		assert_eq!(
 			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
@@ -303,31 +268,6 @@
 	);
 
 	#[test]
-	#[cfg(feature = "stubgen")]
-	fn struct_collect_tuple_struct3_derived_mixed_param() {
-		assert_eq!(
-			<TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::name(),
-			"TupleStruct3DerivedMixedParam"
-		);
-		similar_asserts::assert_eq!(
-			<TupleStruct3DerivedMixedParam as ::evm_coder::solidity::StructCollect>::declaration(),
-			r#"/// @dev Some docs
-/// At multi
-/// line
-struct TupleStruct3DerivedMixedParam {
-	/// @dev Docs for A
-	/// multi
-	/// line
-	TupleStruct1SimpleParam field0;
-	TupleStruct2DynamicParam field1;
-	/// @dev Docs for C
-	TupleStruct2MixedParam field2;
-}
-"#
-		);
-	}
-
-	#[test]
 	fn impl_abi_type_signature_same_for_structs() {
 		assert_eq!(
 			<TypeStruct1SimpleParam as evm_coder::abi::AbiType>::SIGNATURE
@@ -821,30 +761,5 @@
 				<Color as evm_coder::abi::AbiRead>::abi_read(&mut decoder).unwrap();
 			assert_eq!(restored_enum_data, Color::Green);
 		}
-	}
-
-	#[test]
-	#[cfg(feature = "stubgen")]
-	fn struct_collect_enum() {
-		assert_eq!(
-			<Color as ::evm_coder::solidity::StructCollect>::name(),
-			"Color"
-		);
-		similar_asserts::assert_eq!(
-			<Color as ::evm_coder::solidity::StructCollect>::declaration(),
-			r#"/// @dev Some docs
-/// At multi
-/// line
-enum Color {
-	/// @dev Docs for Red
-	/// multi
-	/// line
-	Red,
-	Green,
-	/// @dev Docs for Blue
-	Blue
-}
-"#
-		);
 	}
 }
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
+++ b/pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol
@@ -265,13 +265,13 @@
 	}
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of Optional value with CrossAddress.
+/// Ethereum representation of Optional value with CrossAddress.
 struct OptionCrossAddress {
 	bool status;
 	CrossAddress value;
modifiedpallets/fungible/src/stubs/UniqueFungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/stubs/UniqueFungible.soldiffbeforeafterboth
--- a/pallets/fungible/src/stubs/UniqueFungible.sol
+++ b/pallets/fungible/src/stubs/UniqueFungible.sol
@@ -437,67 +437,67 @@
 	}
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
 	bool value;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
 enum CollectionPermissionField {
-	/// @dev Owner of token can nest tokens under it.
+	/// Owner of token can nest tokens under it.
 	TokenOwner,
-	/// @dev Admin of token collection can nest tokens under token.
+	/// Admin of token collection can nest tokens under token.
 	CollectionAdmin
 }
 
-/// @dev Nested collections.
+/// Nested collections.
 struct CollectionNesting {
 	bool token_owner;
 	uint256[] ids;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
 	OptionUint value;
 }
 
-/// @dev Ethereum representation of Optional value with uint256.
+/// Ethereum representation of Optional value with uint256.
 struct OptionUint {
 	bool status;
 	uint256 value;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
 enum CollectionLimitField {
-	/// @dev How many tokens can a user have on one account.
+	/// How many tokens can a user have on one account.
 	AccountTokenOwnership,
-	/// @dev How many bytes of data are available for sponsorship.
+	/// How many bytes of data are available for sponsorship.
 	SponsoredDataSize,
-	/// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	SponsoredDataRateLimit,
-	/// @dev How many tokens can be mined into this collection.
+	/// How many tokens can be mined into this collection.
 	TokenLimit,
-	/// @dev Timeouts for transfer sponsoring.
+	/// Timeouts for transfer sponsoring.
 	SponsorTransferTimeout,
-	/// @dev Timeout for sponsoring an approval in passed blocks.
+	/// Timeout for sponsoring an approval in passed blocks.
 	SponsorApproveTimeout,
-	/// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
 	OwnerCanTransfer,
-	/// @dev Can the collection owner burn other people's tokens.
+	/// Can the collection owner burn other people's tokens.
 	OwnerCanDestroy,
-	/// @dev Is it possible to send tokens from this collection between users.
+	/// Is it possible to send tokens from this collection between users.
 	TransferEnabled
 }
 
-/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
+/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 struct Property {
 	string key;
 	bytes value;
modifiedpallets/nonfungible/src/stubs/UniqueNFT.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/nonfungible/src/stubs/UniqueNFT.soldiffbeforeafterboth
--- a/pallets/nonfungible/src/stubs/UniqueNFT.sol
+++ b/pallets/nonfungible/src/stubs/UniqueNFT.sol
@@ -127,35 +127,35 @@
 	}
 }
 
-/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
+/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 struct Property {
 	string key;
 	bytes value;
 }
 
-/// @dev Ethereum representation of Token Property Permissions.
+/// Ethereum representation of Token Property Permissions.
 struct TokenPropertyPermission {
-	/// @dev Token property key.
+	/// Token property key.
 	string key;
-	/// @dev Token property permissions.
+	/// Token property permissions.
 	PropertyPermission[] permissions;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
 struct PropertyPermission {
-	/// @dev TokenPermission field.
+	/// TokenPermission field.
 	TokenPermissionField code;
-	/// @dev TokenPermission value.
+	/// TokenPermission value.
 	bool value;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
 enum TokenPermissionField {
-	/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
+	/// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
 	Mutable,
-	/// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
+	/// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
 	TokenOwner,
-	/// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
+	/// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
 	CollectionAdmin
 }
 
@@ -579,63 +579,63 @@
 	}
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
 	bool value;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
 enum CollectionPermissionField {
-	/// @dev Owner of token can nest tokens under it.
+	/// Owner of token can nest tokens under it.
 	TokenOwner,
-	/// @dev Admin of token collection can nest tokens under token.
+	/// Admin of token collection can nest tokens under token.
 	CollectionAdmin
 }
 
-/// @dev Nested collections.
+/// Nested collections.
 struct CollectionNesting {
 	bool token_owner;
 	uint256[] ids;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
 	OptionUint value;
 }
 
-/// @dev Ethereum representation of Optional value with uint256.
+/// Ethereum representation of Optional value with uint256.
 struct OptionUint {
 	bool status;
 	uint256 value;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
 enum CollectionLimitField {
-	/// @dev How many tokens can a user have on one account.
+	/// How many tokens can a user have on one account.
 	AccountTokenOwnership,
-	/// @dev How many bytes of data are available for sponsorship.
+	/// How many bytes of data are available for sponsorship.
 	SponsoredDataSize,
-	/// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	SponsoredDataRateLimit,
-	/// @dev How many tokens can be mined into this collection.
+	/// How many tokens can be mined into this collection.
 	TokenLimit,
-	/// @dev Timeouts for transfer sponsoring.
+	/// Timeouts for transfer sponsoring.
 	SponsorTransferTimeout,
-	/// @dev Timeout for sponsoring an approval in passed blocks.
+	/// Timeout for sponsoring an approval in passed blocks.
 	SponsorApproveTimeout,
-	/// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
 	OwnerCanTransfer,
-	/// @dev Can the collection owner burn other people's tokens.
+	/// Can the collection owner burn other people's tokens.
 	OwnerCanDestroy,
-	/// @dev Is it possible to send tokens from this collection between users.
+	/// Is it possible to send tokens from this collection between users.
 	TransferEnabled
 }
 
modifiedpallets/refungible/src/stubs/UniqueRefungible.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungible.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungible.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungible.sol
@@ -127,35 +127,35 @@
 	}
 }
 
-/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
+/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 struct Property {
 	string key;
 	bytes value;
 }
 
-/// @dev Ethereum representation of Token Property Permissions.
+/// Ethereum representation of Token Property Permissions.
 struct TokenPropertyPermission {
-	/// @dev Token property key.
+	/// Token property key.
 	string key;
-	/// @dev Token property permissions.
+	/// Token property permissions.
 	PropertyPermission[] permissions;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
 struct PropertyPermission {
-	/// @dev TokenPermission field.
+	/// TokenPermission field.
 	TokenPermissionField code;
-	/// @dev TokenPermission value.
+	/// TokenPermission value.
 	bool value;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
 enum TokenPermissionField {
-	/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
+	/// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
 	Mutable,
-	/// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
+	/// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
 	TokenOwner,
-	/// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
+	/// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
 	CollectionAdmin
 }
 
@@ -579,63 +579,63 @@
 	}
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
 	bool value;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
 enum CollectionPermissionField {
-	/// @dev Owner of token can nest tokens under it.
+	/// Owner of token can nest tokens under it.
 	TokenOwner,
-	/// @dev Admin of token collection can nest tokens under token.
+	/// Admin of token collection can nest tokens under token.
 	CollectionAdmin
 }
 
-/// @dev Nested collections.
+/// Nested collections.
 struct CollectionNesting {
 	bool token_owner;
 	uint256[] ids;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
 	OptionUint value;
 }
 
-/// @dev Ethereum representation of Optional value with uint256.
+/// Ethereum representation of Optional value with uint256.
 struct OptionUint {
 	bool status;
 	uint256 value;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
 enum CollectionLimitField {
-	/// @dev How many tokens can a user have on one account.
+	/// How many tokens can a user have on one account.
 	AccountTokenOwnership,
-	/// @dev How many bytes of data are available for sponsorship.
+	/// How many bytes of data are available for sponsorship.
 	SponsoredDataSize,
-	/// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	SponsoredDataRateLimit,
-	/// @dev How many tokens can be mined into this collection.
+	/// How many tokens can be mined into this collection.
 	TokenLimit,
-	/// @dev Timeouts for transfer sponsoring.
+	/// Timeouts for transfer sponsoring.
 	SponsorTransferTimeout,
-	/// @dev Timeout for sponsoring an approval in passed blocks.
+	/// Timeout for sponsoring an approval in passed blocks.
 	SponsorApproveTimeout,
-	/// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
 	OwnerCanTransfer,
-	/// @dev Can the collection owner burn other people's tokens.
+	/// Can the collection owner burn other people's tokens.
 	OwnerCanDestroy,
-	/// @dev Is it possible to send tokens from this collection between users.
+	/// Is it possible to send tokens from this collection between users.
 	TransferEnabled
 }
 
modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/refungible/src/stubs/UniqueRefungibleToken.soldiffbeforeafterboth
--- a/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
+++ b/pallets/refungible/src/stubs/UniqueRefungibleToken.sol
@@ -128,7 +128,7 @@
 	}
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
modifiedtests/src/eth/api/ContractHelpers.soldiffbeforeafterboth
--- a/tests/src/eth/api/ContractHelpers.sol
+++ b/tests/src/eth/api/ContractHelpers.sol
@@ -171,13 +171,13 @@
 	function toggleAllowlist(address contractAddress, bool enabled) external;
 }
 
-/// @dev Ethereum representation of Optional value with CrossAddress.
+/// Ethereum representation of Optional value with CrossAddress.
 struct OptionCrossAddress {
 	bool status;
 	CrossAddress value;
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -279,67 +279,67 @@
 	function changeCollectionOwnerCross(CrossAddress memory newOwner) external;
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
 	bool value;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
 enum CollectionPermissionField {
-	/// @dev Owner of token can nest tokens under it.
+	/// Owner of token can nest tokens under it.
 	TokenOwner,
-	/// @dev Admin of token collection can nest tokens under token.
+	/// Admin of token collection can nest tokens under token.
 	CollectionAdmin
 }
 
-/// @dev Nested collections.
+/// Nested collections.
 struct CollectionNesting {
 	bool token_owner;
 	uint256[] ids;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
 	OptionUint value;
 }
 
-/// @dev Ethereum representation of Optional value with uint256.
+/// Ethereum representation of Optional value with uint256.
 struct OptionUint {
 	bool status;
 	uint256 value;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
 enum CollectionLimitField {
-	/// @dev How many tokens can a user have on one account.
+	/// How many tokens can a user have on one account.
 	AccountTokenOwnership,
-	/// @dev How many bytes of data are available for sponsorship.
+	/// How many bytes of data are available for sponsorship.
 	SponsoredDataSize,
-	/// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	SponsoredDataRateLimit,
-	/// @dev How many tokens can be mined into this collection.
+	/// How many tokens can be mined into this collection.
 	TokenLimit,
-	/// @dev Timeouts for transfer sponsoring.
+	/// Timeouts for transfer sponsoring.
 	SponsorTransferTimeout,
-	/// @dev Timeout for sponsoring an approval in passed blocks.
+	/// Timeout for sponsoring an approval in passed blocks.
 	SponsorApproveTimeout,
-	/// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
 	OwnerCanTransfer,
-	/// @dev Can the collection owner burn other people's tokens.
+	/// Can the collection owner burn other people's tokens.
 	OwnerCanDestroy,
-	/// @dev Is it possible to send tokens from this collection between users.
+	/// Is it possible to send tokens from this collection between users.
 	TransferEnabled
 }
 
-/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
+/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 struct Property {
 	string key;
 	bytes value;
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -80,35 +80,35 @@
 	function property(uint256 tokenId, string memory key) external view returns (bytes memory);
 }
 
-/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
+/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 struct Property {
 	string key;
 	bytes value;
 }
 
-/// @dev Ethereum representation of Token Property Permissions.
+/// Ethereum representation of Token Property Permissions.
 struct TokenPropertyPermission {
-	/// @dev Token property key.
+	/// Token property key.
 	string key;
-	/// @dev Token property permissions.
+	/// Token property permissions.
 	PropertyPermission[] permissions;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
 struct PropertyPermission {
-	/// @dev TokenPermission field.
+	/// TokenPermission field.
 	TokenPermissionField code;
-	/// @dev TokenPermission value.
+	/// TokenPermission value.
 	bool value;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
 enum TokenPermissionField {
-	/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
+	/// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
 	Mutable,
-	/// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
+	/// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
 	TokenOwner,
-	/// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
+	/// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
 	CollectionAdmin
 }
 
@@ -379,63 +379,63 @@
 	function changeCollectionOwnerCross(CrossAddress memory newOwner) external;
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
 	bool value;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
 enum CollectionPermissionField {
-	/// @dev Owner of token can nest tokens under it.
+	/// Owner of token can nest tokens under it.
 	TokenOwner,
-	/// @dev Admin of token collection can nest tokens under token.
+	/// Admin of token collection can nest tokens under token.
 	CollectionAdmin
 }
 
-/// @dev Nested collections.
+/// Nested collections.
 struct CollectionNesting {
 	bool token_owner;
 	uint256[] ids;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
 	OptionUint value;
 }
 
-/// @dev Ethereum representation of Optional value with uint256.
+/// Ethereum representation of Optional value with uint256.
 struct OptionUint {
 	bool status;
 	uint256 value;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
 enum CollectionLimitField {
-	/// @dev How many tokens can a user have on one account.
+	/// How many tokens can a user have on one account.
 	AccountTokenOwnership,
-	/// @dev How many bytes of data are available for sponsorship.
+	/// How many bytes of data are available for sponsorship.
 	SponsoredDataSize,
-	/// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	SponsoredDataRateLimit,
-	/// @dev How many tokens can be mined into this collection.
+	/// How many tokens can be mined into this collection.
 	TokenLimit,
-	/// @dev Timeouts for transfer sponsoring.
+	/// Timeouts for transfer sponsoring.
 	SponsorTransferTimeout,
-	/// @dev Timeout for sponsoring an approval in passed blocks.
+	/// Timeout for sponsoring an approval in passed blocks.
 	SponsorApproveTimeout,
-	/// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
 	OwnerCanTransfer,
-	/// @dev Can the collection owner burn other people's tokens.
+	/// Can the collection owner burn other people's tokens.
 	OwnerCanDestroy,
-	/// @dev Is it possible to send tokens from this collection between users.
+	/// Is it possible to send tokens from this collection between users.
 	TransferEnabled
 }
 
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -80,35 +80,35 @@
 	function property(uint256 tokenId, string memory key) external view returns (bytes memory);
 }
 
-/// @dev Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
+/// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 struct Property {
 	string key;
 	bytes value;
 }
 
-/// @dev Ethereum representation of Token Property Permissions.
+/// Ethereum representation of Token Property Permissions.
 struct TokenPropertyPermission {
-	/// @dev Token property key.
+	/// Token property key.
 	string key;
-	/// @dev Token property permissions.
+	/// Token property permissions.
 	PropertyPermission[] permissions;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) as an key and value.
 struct PropertyPermission {
-	/// @dev TokenPermission field.
+	/// TokenPermission field.
 	TokenPermissionField code;
-	/// @dev TokenPermission value.
+	/// TokenPermission value.
 	bool value;
 }
 
-/// @dev Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
+/// Ethereum representation of TokenPermissions (see [`up_data_structs::PropertyPermission`]) fields as an enumeration.
 enum TokenPermissionField {
-	/// @dev Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
+	/// Permission to change the property and property permission. See [`up_data_structs::PropertyPermission::mutable`]
 	Mutable,
-	/// @dev Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
+	/// Change permission for the collection administrator. See [`up_data_structs::PropertyPermission::token_owner`]
 	TokenOwner,
-	/// @dev Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
+	/// Permission to change the property for the owner of the token. See [`up_data_structs::PropertyPermission::collection_admin`]
 	CollectionAdmin
 }
 
@@ -379,63 +379,63 @@
 	function changeCollectionOwnerCross(CrossAddress memory newOwner) external;
 }
 
-/// @dev Cross account struct
+/// Cross account struct
 struct CrossAddress {
 	address eth;
 	uint256 sub;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
 	bool value;
 }
 
-/// @dev Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
+/// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) fields as an enumeration.
 enum CollectionPermissionField {
-	/// @dev Owner of token can nest tokens under it.
+	/// Owner of token can nest tokens under it.
 	TokenOwner,
-	/// @dev Admin of token collection can nest tokens under token.
+	/// Admin of token collection can nest tokens under token.
 	CollectionAdmin
 }
 
-/// @dev Nested collections.
+/// Nested collections.
 struct CollectionNesting {
 	bool token_owner;
 	uint256[] ids;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) field representation for EVM.
 struct CollectionLimit {
 	CollectionLimitField field;
 	OptionUint value;
 }
 
-/// @dev Ethereum representation of Optional value with uint256.
+/// Ethereum representation of Optional value with uint256.
 struct OptionUint {
 	bool status;
 	uint256 value;
 }
 
-/// @dev [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
+/// [`CollectionLimits`](up_data_structs::CollectionLimits) fields representation for EVM.
 enum CollectionLimitField {
-	/// @dev How many tokens can a user have on one account.
+	/// How many tokens can a user have on one account.
 	AccountTokenOwnership,
-	/// @dev How many bytes of data are available for sponsorship.
+	/// How many bytes of data are available for sponsorship.
 	SponsoredDataSize,
-	/// @dev In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
+	/// In any case, chain default: [`SponsoringRateLimit::SponsoringDisabled`]
 	SponsoredDataRateLimit,
-	/// @dev How many tokens can be mined into this collection.
+	/// How many tokens can be mined into this collection.
 	TokenLimit,
-	/// @dev Timeouts for transfer sponsoring.
+	/// Timeouts for transfer sponsoring.
 	SponsorTransferTimeout,
-	/// @dev Timeout for sponsoring an approval in passed blocks.
+	/// Timeout for sponsoring an approval in passed blocks.
 	SponsorApproveTimeout,
-	/// @dev Whether the collection owner of the collection can send tokens (which belong to other users).
+	/// Whether the collection owner of the collection can send tokens (which belong to other users).
 	OwnerCanTransfer,
-	/// @dev Can the collection owner burn other people's tokens.
+	/// Can the collection owner burn other people's tokens.
 	OwnerCanDestroy,
-	/// @dev Is it possible to send tokens from this collection between users.
+	/// Is it possible to send tokens from this collection between users.
 	TransferEnabled
 }
 
modifiedtests/src/eth/api/UniqueRefungibleToken.soldiffbeforeafterboth
before · tests/src/eth/api/UniqueRefungibleToken.sol
1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7interface Dummy {89}1011interface ERC165 is Dummy {12	function supportsInterface(bytes4 interfaceID) external view returns (bool);13}1415/// @dev the ERC-165 identifier for this interface is 0x5755c3f216interface ERC1633 is Dummy, ERC165 {17	/// @dev EVM selector for this function is: 0x80a54001,18	///  or in textual repr: parentToken()19	function parentToken() external view returns (address);2021	/// @dev EVM selector for this function is: 0xd7f083f3,22	///  or in textual repr: parentTokenId()23	function parentTokenId() external view returns (uint256);24}2526/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b27interface ERC20UniqueExtensions is Dummy, ERC165 {28	/// @dev Function that burns an amount of the token of a given account,29	/// deducting from the sender's allowance for said account.30	/// @param from The account whose tokens will be burnt.31	/// @param amount The amount that will be burnt.32	/// @dev EVM selector for this function is: 0x79cc6790,33	///  or in textual repr: burnFrom(address,uint256)34	function burnFrom(address from, uint256 amount) external returns (bool);3536	/// @dev Function that burns an amount of the token of a given account,37	/// deducting from the sender's allowance for said account.38	/// @param from The account whose tokens will be burnt.39	/// @param amount The amount that will be burnt.40	/// @dev EVM selector for this function is: 0xbb2f5a58,41	///  or in textual repr: burnFromCross((address,uint256),uint256)42	function burnFromCross(CrossAddress memory from, uint256 amount) external returns (bool);4344	/// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.45	/// Beware that changing an allowance with this method brings the risk that someone may use both the old46	/// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this47	/// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:48	/// https://github.com/ethereum/EIPs/issues/20#issuecomment-26352472949	/// @param spender The crossaccount which will spend the funds.50	/// @param amount The amount of tokens to be spent.51	/// @dev EVM selector for this function is: 0x0ecd0ab0,52	///  or in textual repr: approveCross((address,uint256),uint256)53	function approveCross(CrossAddress memory spender, uint256 amount) external returns (bool);5455	/// @dev Function that changes total amount of the tokens.56	///  Throws if `msg.sender` doesn't owns all of the tokens.57	/// @param amount New total amount of the tokens.58	/// @dev EVM selector for this function is: 0xd2418ca7,59	///  or in textual repr: repartition(uint256)60	function repartition(uint256 amount) external returns (bool);6162	/// @dev Transfer token for a specified address63	/// @param to The crossaccount to transfer to.64	/// @param amount The amount to be transferred.65	/// @dev EVM selector for this function is: 0x2ada85ff,66	///  or in textual repr: transferCross((address,uint256),uint256)67	function transferCross(CrossAddress memory to, uint256 amount) external returns (bool);6869	/// @dev Transfer tokens from one address to another70	/// @param from The address which you want to send tokens from71	/// @param to The address which you want to transfer to72	/// @param amount the amount of tokens to be transferred73	/// @dev EVM selector for this function is: 0xd5cf430b,74	///  or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)75	function transferFromCross(76		CrossAddress memory from,77		CrossAddress memory to,78		uint256 amount79	) external returns (bool);80}8182/// @dev Cross account struct83struct CrossAddress {84	address eth;85	uint256 sub;86}8788/// @dev inlined interface89interface ERC20Events {90	event Transfer(address indexed from, address indexed to, uint256 value);91	event Approval(address indexed owner, address indexed spender, uint256 value);92}9394/// @title Standard ERC20 token95///96/// @dev Implementation of the basic standard token.97/// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md98/// @dev the ERC-165 identifier for this interface is 0x942e8b2299interface ERC20 is Dummy, ERC165, ERC20Events {100	/// @return the name of the token.101	/// @dev EVM selector for this function is: 0x06fdde03,102	///  or in textual repr: name()103	function name() external view returns (string memory);104105	/// @return the symbol of the token.106	/// @dev EVM selector for this function is: 0x95d89b41,107	///  or in textual repr: symbol()108	function symbol() external view returns (string memory);109110	/// @dev Total number of tokens in existence111	/// @dev EVM selector for this function is: 0x18160ddd,112	///  or in textual repr: totalSupply()113	function totalSupply() external view returns (uint256);114115	/// @dev Not supported116	/// @dev EVM selector for this function is: 0x313ce567,117	///  or in textual repr: decimals()118	function decimals() external view returns (uint8);119120	/// @dev Gets the balance of the specified address.121	/// @param owner The address to query the balance of.122	/// @return An uint256 representing the amount owned by the passed address.123	/// @dev EVM selector for this function is: 0x70a08231,124	///  or in textual repr: balanceOf(address)125	function balanceOf(address owner) external view returns (uint256);126127	/// @dev Transfer token for a specified address128	/// @param to The address to transfer to.129	/// @param amount The amount to be transferred.130	/// @dev EVM selector for this function is: 0xa9059cbb,131	///  or in textual repr: transfer(address,uint256)132	function transfer(address to, uint256 amount) external returns (bool);133134	/// @dev Transfer tokens from one address to another135	/// @param from address The address which you want to send tokens from136	/// @param to address The address which you want to transfer to137	/// @param amount uint256 the amount of tokens to be transferred138	/// @dev EVM selector for this function is: 0x23b872dd,139	///  or in textual repr: transferFrom(address,address,uint256)140	function transferFrom(141		address from,142		address to,143		uint256 amount144	) external returns (bool);145146	/// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.147	/// Beware that changing an allowance with this method brings the risk that someone may use both the old148	/// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this149	/// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:150	/// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729151	/// @param spender The address which will spend the funds.152	/// @param amount The amount of tokens to be spent.153	/// @dev EVM selector for this function is: 0x095ea7b3,154	///  or in textual repr: approve(address,uint256)155	function approve(address spender, uint256 amount) external returns (bool);156157	/// @dev Function to check the amount of tokens that an owner allowed to a spender.158	/// @param owner address The address which owns the funds.159	/// @param spender address The address which will spend the funds.160	/// @return A uint256 specifying the amount of tokens still available for the spender.161	/// @dev EVM selector for this function is: 0xdd62ed3e,162	///  or in textual repr: allowance(address,address)163	function allowance(address owner, address spender) external view returns (uint256);164}165166interface UniqueRefungibleToken is Dummy, ERC165, ERC20, ERC20UniqueExtensions, ERC1633 {}
after · tests/src/eth/api/UniqueRefungibleToken.sol
1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56/// @dev common stubs holder7interface Dummy {89}1011interface ERC165 is Dummy {12	function supportsInterface(bytes4 interfaceID) external view returns (bool);13}1415/// @dev the ERC-165 identifier for this interface is 0x5755c3f216interface ERC1633 is Dummy, ERC165 {17	/// @dev EVM selector for this function is: 0x80a54001,18	///  or in textual repr: parentToken()19	function parentToken() external view returns (address);2021	/// @dev EVM selector for this function is: 0xd7f083f3,22	///  or in textual repr: parentTokenId()23	function parentTokenId() external view returns (uint256);24}2526/// @dev the ERC-165 identifier for this interface is 0xe17a7d2b27interface ERC20UniqueExtensions is Dummy, ERC165 {28	/// @dev Function that burns an amount of the token of a given account,29	/// deducting from the sender's allowance for said account.30	/// @param from The account whose tokens will be burnt.31	/// @param amount The amount that will be burnt.32	/// @dev EVM selector for this function is: 0x79cc6790,33	///  or in textual repr: burnFrom(address,uint256)34	function burnFrom(address from, uint256 amount) external returns (bool);3536	/// @dev Function that burns an amount of the token of a given account,37	/// deducting from the sender's allowance for said account.38	/// @param from The account whose tokens will be burnt.39	/// @param amount The amount that will be burnt.40	/// @dev EVM selector for this function is: 0xbb2f5a58,41	///  or in textual repr: burnFromCross((address,uint256),uint256)42	function burnFromCross(CrossAddress memory from, uint256 amount) external returns (bool);4344	/// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.45	/// Beware that changing an allowance with this method brings the risk that someone may use both the old46	/// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this47	/// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:48	/// https://github.com/ethereum/EIPs/issues/20#issuecomment-26352472949	/// @param spender The crossaccount which will spend the funds.50	/// @param amount The amount of tokens to be spent.51	/// @dev EVM selector for this function is: 0x0ecd0ab0,52	///  or in textual repr: approveCross((address,uint256),uint256)53	function approveCross(CrossAddress memory spender, uint256 amount) external returns (bool);5455	/// @dev Function that changes total amount of the tokens.56	///  Throws if `msg.sender` doesn't owns all of the tokens.57	/// @param amount New total amount of the tokens.58	/// @dev EVM selector for this function is: 0xd2418ca7,59	///  or in textual repr: repartition(uint256)60	function repartition(uint256 amount) external returns (bool);6162	/// @dev Transfer token for a specified address63	/// @param to The crossaccount to transfer to.64	/// @param amount The amount to be transferred.65	/// @dev EVM selector for this function is: 0x2ada85ff,66	///  or in textual repr: transferCross((address,uint256),uint256)67	function transferCross(CrossAddress memory to, uint256 amount) external returns (bool);6869	/// @dev Transfer tokens from one address to another70	/// @param from The address which you want to send tokens from71	/// @param to The address which you want to transfer to72	/// @param amount the amount of tokens to be transferred73	/// @dev EVM selector for this function is: 0xd5cf430b,74	///  or in textual repr: transferFromCross((address,uint256),(address,uint256),uint256)75	function transferFromCross(76		CrossAddress memory from,77		CrossAddress memory to,78		uint256 amount79	) external returns (bool);80}8182/// Cross account struct83struct CrossAddress {84	address eth;85	uint256 sub;86}8788/// @dev inlined interface89interface ERC20Events {90	event Transfer(address indexed from, address indexed to, uint256 value);91	event Approval(address indexed owner, address indexed spender, uint256 value);92}9394/// @title Standard ERC20 token95///96/// @dev Implementation of the basic standard token.97/// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md98/// @dev the ERC-165 identifier for this interface is 0x942e8b2299interface ERC20 is Dummy, ERC165, ERC20Events {100	/// @return the name of the token.101	/// @dev EVM selector for this function is: 0x06fdde03,102	///  or in textual repr: name()103	function name() external view returns (string memory);104105	/// @return the symbol of the token.106	/// @dev EVM selector for this function is: 0x95d89b41,107	///  or in textual repr: symbol()108	function symbol() external view returns (string memory);109110	/// @dev Total number of tokens in existence111	/// @dev EVM selector for this function is: 0x18160ddd,112	///  or in textual repr: totalSupply()113	function totalSupply() external view returns (uint256);114115	/// @dev Not supported116	/// @dev EVM selector for this function is: 0x313ce567,117	///  or in textual repr: decimals()118	function decimals() external view returns (uint8);119120	/// @dev Gets the balance of the specified address.121	/// @param owner The address to query the balance of.122	/// @return An uint256 representing the amount owned by the passed address.123	/// @dev EVM selector for this function is: 0x70a08231,124	///  or in textual repr: balanceOf(address)125	function balanceOf(address owner) external view returns (uint256);126127	/// @dev Transfer token for a specified address128	/// @param to The address to transfer to.129	/// @param amount The amount to be transferred.130	/// @dev EVM selector for this function is: 0xa9059cbb,131	///  or in textual repr: transfer(address,uint256)132	function transfer(address to, uint256 amount) external returns (bool);133134	/// @dev Transfer tokens from one address to another135	/// @param from address The address which you want to send tokens from136	/// @param to address The address which you want to transfer to137	/// @param amount uint256 the amount of tokens to be transferred138	/// @dev EVM selector for this function is: 0x23b872dd,139	///  or in textual repr: transferFrom(address,address,uint256)140	function transferFrom(141		address from,142		address to,143		uint256 amount144	) external returns (bool);145146	/// @dev Approve the passed address to spend the specified amount of tokens on behalf of `msg.sender`.147	/// Beware that changing an allowance with this method brings the risk that someone may use both the old148	/// and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this149	/// race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:150	/// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729151	/// @param spender The address which will spend the funds.152	/// @param amount The amount of tokens to be spent.153	/// @dev EVM selector for this function is: 0x095ea7b3,154	///  or in textual repr: approve(address,uint256)155	function approve(address spender, uint256 amount) external returns (bool);156157	/// @dev Function to check the amount of tokens that an owner allowed to a spender.158	/// @param owner address The address which owns the funds.159	/// @param spender address The address which will spend the funds.160	/// @return A uint256 specifying the amount of tokens still available for the spender.161	/// @dev EVM selector for this function is: 0xdd62ed3e,162	///  or in textual repr: allowance(address,address)163	function allowance(address owner, address spender) external view returns (uint256);164}165166interface UniqueRefungibleToken is Dummy, ERC165, ERC20, ERC20UniqueExtensions, ERC1633 {}