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

difftreelog

Merge pull request #825 from UniqueNetwork/feature/evm_coder_types_refactor

Yaroslav Bolyukin2023-01-18parents: #2489f62 #4540472.patch.diff
in: master
Feature/evm_coder_types_refactor

39 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2330,7 +2330,6 @@
  "hex",
  "hex-literal",
  "impl-trait-for-tuples",
- "pallet-evm",
  "primitive-types 0.12.1",
  "sha3-const",
  "similar-asserts",
modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -19,8 +19,6 @@
 # We have tuple-heavy code in solidity.rs
 impl-trait-for-tuples = "0.2.2"
 
-pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.36" }
-
 [dev-dependencies]
 # We want to assert some large binary blobs equality in tests
 hex = "0.4.3"
modifiedcrates/evm-coder/procedural/src/solidity_interface.rsdiffbeforeafterboth
before · crates/evm-coder/procedural/src/solidity_interface.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![allow(dead_code)]1819// NOTE: In order to understand this Rust macro better, first read this chapter20// about Procedural Macros in Rust book:21// https://doc.rust-lang.org/reference/procedural-macros.html2223use proc_macro2::TokenStream;24use quote::{quote, format_ident};25use inflector::cases;26use syn::{27	Expr, FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Lit, Meta, MetaNameValue,28	PatType, ReturnType, Type,29	spanned::Spanned,30	parse::{Parse, ParseStream},31	parenthesized, Token, LitInt, LitStr,32};3334use crate::{35	parse_ident_from_pat, parse_ident_from_path, parse_path, parse_path_segment, parse_result_ok,36	pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,37	snake_ident_to_screaming,38};3940struct Is {41	name: Ident,42	pascal_call_name: Ident,43	snake_call_name: Ident,44	via: Option<(Type, Ident)>,45	condition: Option<Expr>,46}47impl Is {48	fn expand_call_def(&self, gen_ref: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {49		let name = &self.name;50		let pascal_call_name = &self.pascal_call_name;51		quote! {52			#name(#pascal_call_name #gen_ref)53		}54	}5556	fn expand_interface_id(&self) -> proc_macro2::TokenStream {57		let pascal_call_name = &self.pascal_call_name;58		quote! {59			interface_id ^= u32::from_be_bytes(#pascal_call_name::interface_id());60		}61	}6263	fn expand_supports_interface(64		&self,65		generics: &proc_macro2::TokenStream,66	) -> proc_macro2::TokenStream {67		let pascal_call_name = &self.pascal_call_name;68		let condition = self.condition.as_ref().map(|condition| {69			quote! {70				(#condition) &&71			}72		});73		quote! {74			#condition <#pascal_call_name #generics>::supports_interface(this, interface_id)75		}76	}7778	fn expand_variant_weight(&self) -> proc_macro2::TokenStream {79		let name = &self.name;80		quote! {81			Self::#name(call) => call.weight()82		}83	}8485	fn expand_variant_call(86		&self,87		call_name: &proc_macro2::Ident,88		generics: &proc_macro2::TokenStream,89	) -> proc_macro2::TokenStream {90		let name = &self.name;91		let pascal_call_name = &self.pascal_call_name;92		let via_typ = self93			.via94			.as_ref()95			.map(|(t, _)| quote! {#t})96			.unwrap_or_else(|| quote! {Self});97		let via_map = self98			.via99			.as_ref()100			.map(|(_, i)| quote! {.#i()})101			.unwrap_or_default();102		let condition = self.condition.as_ref().map(|condition| {103			quote! {104				if ({let this = &self; (#condition)})105			}106		});107		quote! {108			#call_name::#name(call) #condition => return <#via_typ as ::evm_coder::Callable<#pascal_call_name #generics>>::call(self #via_map, Msg {109				call,110				caller: c.caller,111				value: c.value,112			})113		}114	}115116	fn expand_parse(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {117		let name = &self.name;118		let pascal_call_name = &self.pascal_call_name;119		quote! {120			if let Some(parsed_call) = <#pascal_call_name #generics>::parse(method_id, reader)? {121				return Ok(Some(Self::#name(parsed_call)))122			}123		}124	}125126	fn expand_generator(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {127		let pascal_call_name = &self.pascal_call_name;128		quote! {129			<#pascal_call_name #generics>::generate_solidity_interface(tc, is_impl);130		}131	}132133	fn expand_event_generator(&self) -> proc_macro2::TokenStream {134		let name = &self.name;135		quote! {136			#name::generate_solidity_interface(tc, is_impl);137		}138	}139}140141#[derive(Default)]142struct IsList(Vec<Is>);143impl Parse for IsList {144	fn parse(input: ParseStream) -> syn::Result<Self> {145		let mut out = vec![];146		loop {147			if input.is_empty() {148				break;149			}150			let name = input.parse::<Ident>()?;151			let lookahead = input.lookahead1();152153			let mut condition: Option<Expr> = None;154			let mut via: Option<(Type, Ident)> = None;155156			if lookahead.peek(syn::token::Paren) {157				let contents;158				parenthesized!(contents in input);159				let input = contents;160161				while !input.is_empty() {162					let lookahead = input.lookahead1();163					if lookahead.peek(Token![if]) {164						input.parse::<Token![if]>()?;165						let contents;166						parenthesized!(contents in input);167						let contents = contents.parse::<Expr>()?;168169						if condition.replace(contents).is_some() {170							return Err(syn::Error::new(input.span(), "condition is already set"));171						}172					} else if lookahead.peek(kw::via) {173						input.parse::<kw::via>()?;174						let contents;175						parenthesized!(contents in input);176177						let method = contents.parse::<Ident>()?;178						contents.parse::<kw::returns>()?;179						let ty = contents.parse::<Type>()?;180181						if via.replace((ty, method)).is_some() {182							return Err(syn::Error::new(input.span(), "via is already set"));183						}184					} else {185						return Err(lookahead.error());186					}187188					if input.peek(Token![,]) {189						input.parse::<Token![,]>()?;190					} else if !input.is_empty() {191						return Err(syn::Error::new(input.span(), "expected end"));192					}193				}194			} else if lookahead.peek(Token![,]) || input.is_empty() {195				// Pass196			} else {197				return Err(lookahead.error());198			};199			out.push(Is {200				pascal_call_name: pascal_ident_to_call(&name),201				snake_call_name: pascal_ident_to_snake_call(&name),202				name,203				via,204				condition,205			});206			if input.peek(Token![,]) {207				input.parse::<Token![,]>()?;208				continue;209			} else {210				break;211			}212		}213		Ok(Self(out))214	}215}216217pub struct InterfaceInfo {218	name: Ident,219	is: IsList,220	inline_is: IsList,221	events: IsList,222	expect_selector: Option<u32>,223}224impl Parse for InterfaceInfo {225	fn parse(input: ParseStream) -> syn::Result<Self> {226		let mut name = None;227		let mut is = None;228		let mut inline_is = None;229		let mut events = None;230		let mut expect_selector = None;231		// TODO: create proc-macro to optimize proc-macro boilerplate? :D232		loop {233			let lookahead = input.lookahead1();234			if lookahead.peek(kw::name) {235				let k = input.parse::<kw::name>()?;236				input.parse::<Token![=]>()?;237				if name.replace(input.parse::<Ident>()?).is_some() {238					return Err(syn::Error::new(k.span(), "name is already set"));239				}240			} else if lookahead.peek(kw::is) {241				let k = input.parse::<kw::is>()?;242				let contents;243				parenthesized!(contents in input);244				if is.replace(contents.parse::<IsList>()?).is_some() {245					return Err(syn::Error::new(k.span(), "is is already set"));246				}247			} else if lookahead.peek(kw::inline_is) {248				let k = input.parse::<kw::inline_is>()?;249				let contents;250				parenthesized!(contents in input);251				if inline_is.replace(contents.parse::<IsList>()?).is_some() {252					return Err(syn::Error::new(k.span(), "inline_is is already set"));253				}254			} else if lookahead.peek(kw::events) {255				let k = input.parse::<kw::events>()?;256				let contents;257				parenthesized!(contents in input);258				if events.replace(contents.parse::<IsList>()?).is_some() {259					return Err(syn::Error::new(k.span(), "events is already set"));260				}261			} else if lookahead.peek(kw::expect_selector) {262				let k = input.parse::<kw::expect_selector>()?;263				input.parse::<Token![=]>()?;264				let value = input.parse::<LitInt>()?;265				if expect_selector266					.replace(value.base10_parse::<u32>()?)267					.is_some()268				{269					return Err(syn::Error::new(k.span(), "expect_selector is already set"));270				}271			} else if input.is_empty() {272				break;273			} else {274				return Err(lookahead.error());275			}276			if input.peek(Token![,]) {277				input.parse::<Token![,]>()?;278			} else {279				break;280			}281		}282		Ok(Self {283			name: name.ok_or_else(|| syn::Error::new(input.span(), "missing name"))?,284			is: is.unwrap_or_default(),285			inline_is: inline_is.unwrap_or_default(),286			events: events.unwrap_or_default(),287			expect_selector,288		})289	}290}291292struct MethodInfo {293	rename_selector: Option<String>,294	hide: bool,295}296impl Parse for MethodInfo {297	fn parse(input: ParseStream) -> syn::Result<Self> {298		let mut rename_selector = None;299		let mut hide = false;300		while !input.is_empty() {301			let lookahead = input.lookahead1();302			if lookahead.peek(kw::rename_selector) {303				let k = input.parse::<kw::rename_selector>()?;304				input.parse::<Token![=]>()?;305				if rename_selector306					.replace(input.parse::<LitStr>()?.value())307					.is_some()308				{309					return Err(syn::Error::new(k.span(), "rename_selector is already set"));310				}311			} else if lookahead.peek(kw::hide) {312				input.parse::<kw::hide>()?;313				hide = true;314			} else {315				return Err(lookahead.error());316			}317318			if input.peek(Token![,]) {319				input.parse::<Token![,]>()?;320			} else if !input.is_empty() {321				return Err(syn::Error::new(input.span(), "expected end"));322			}323		}324		Ok(Self {325			rename_selector,326			hide,327		})328	}329}330331trait AbiTypeHelper {332	fn plain(&self) -> syn::Result<&Ident>;333	fn is_value(&self) -> bool;334	fn is_caller(&self) -> bool;335	fn is_special(&self) -> bool;336}337338impl AbiTypeHelper for Type {339	fn plain(&self) -> syn::Result<&Ident> {340		let path = parse_path(self)?;341		let segment = parse_path_segment(path)?;342		if !segment.arguments.is_empty() {343			return Err(syn::Error::new(self.span(), "Not plain type"));344		}345		Ok(&segment.ident)346	}347348	fn is_value(&self) -> bool {349		if let Ok(ident) = self.plain() {350			return ident == "value";351		}352		false353	}354355	fn is_caller(&self) -> bool {356		if let Ok(ident) = self.plain() {357			return ident == "caller";358		}359		false360	}361362	fn is_special(&self) -> bool {363		self.is_caller() || self.is_value()364	}365}366367#[derive(Debug)]368struct MethodArg {369	name: Ident,370	camel_name: String,371	ty: Type,372}373impl MethodArg {374	fn try_from(value: &PatType) -> syn::Result<Self> {375		let name = parse_ident_from_pat(&value.pat)?.clone();376		Ok(Self {377			camel_name: cases::camelcase::to_camel_case(&name.to_string()),378			name,379			ty: value.ty.as_ref().clone(),380		})381	}382	fn is_value(&self) -> bool {383		self.ty.is_value()384	}385	fn is_caller(&self) -> bool {386		self.ty.is_caller()387	}388	fn is_special(&self) -> bool {389		self.ty.is_special()390	}391392	fn expand_call_def(&self) -> proc_macro2::TokenStream {393		assert!(!self.is_special());394		let name = &self.name;395		let ty = &self.ty;396397		quote! {398			#name: #ty399		}400	}401402	fn expand_parse(&self) -> proc_macro2::TokenStream {403		assert!(!self.is_special());404		let name = &self.name;405		let ty = &self.ty;406		quote! {407			#name: {408				let value = <#ty as ::evm_coder::abi::AbiRead>::abi_read(reader)?;409				if !is_dynamic {reader.bytes_read(<#ty as ::evm_coder::abi::AbiType>::size())};410				value411			}412		}413	}414415	fn expand_call_arg(&self) -> proc_macro2::TokenStream {416		if self.is_value() {417			quote! {418				c.value.clone()419			}420		} else if self.is_caller() {421			quote! {422				c.caller.clone()423			}424		} else {425			let name = &self.name;426			quote! {427				#name428			}429		}430	}431432	fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {433		let camel_name = &self.camel_name.to_string();434		let ty = &self.ty;435		quote! {436			<NamedArgument<#ty>>::new(#camel_name)437		}438	}439}440441#[derive(PartialEq)]442enum Mutability {443	Mutable,444	View,445	Pure,446}447448/// Group all keywords for this macro. Usage example:449/// #[solidity_interface(name = "B", inline_is(A))]450mod kw {451	syn::custom_keyword!(weight);452453	syn::custom_keyword!(via);454	syn::custom_keyword!(returns);455	syn::custom_keyword!(name);456	syn::custom_keyword!(is);457	syn::custom_keyword!(inline_is);458	syn::custom_keyword!(events);459	syn::custom_keyword!(expect_selector);460461	syn::custom_keyword!(rename_selector);462	syn::custom_keyword!(hide);463}464465/// Rust methods are parsed into this structure when Solidity code is generated466struct Method {467	name: Ident,468	camel_name: String,469	pascal_name: Ident,470	screaming_name: Ident,471	hide: bool,472	args: Vec<MethodArg>,473	has_normal_args: bool,474	has_value_args: bool,475	mutability: Mutability,476	result: Type,477	weight: Option<Expr>,478	docs: Vec<String>,479}480impl Method {481	fn try_from(value: &ImplItemMethod) -> syn::Result<Self> {482		let mut info = MethodInfo {483			rename_selector: None,484			hide: false,485		};486		let mut docs = Vec::new();487		let mut weight = None;488		for attr in &value.attrs {489			let ident = parse_ident_from_path(&attr.path, false)?;490			if ident == "solidity" {491				info = attr.parse_args::<MethodInfo>()?;492			} else if ident == "doc" {493				let args = attr.parse_meta().unwrap();494				let value = match args {495					Meta::NameValue(MetaNameValue {496						lit: Lit::Str(str), ..497					}) => str.value(),498					_ => unreachable!(),499				};500				docs.push(value);501			} else if ident == "weight" {502				weight = Some(attr.parse_args::<Expr>()?);503			}504		}505		let ident = &value.sig.ident;506		let ident_str = ident.to_string();507		if !cases::snakecase::is_snake_case(&ident_str) {508			return Err(syn::Error::new(ident.span(), "method name should be snake_cased\nif alternative solidity name needs to be set - use #[solidity] attribute"));509		}510511		let mut mutability = Mutability::Pure;512513		if let Some(FnArg::Receiver(receiver)) = value514			.sig515			.inputs516			.iter()517			.find(|arg| matches!(arg, FnArg::Receiver(_)))518		{519			if receiver.reference.is_none() {520				return Err(syn::Error::new(521					receiver.span(),522					"receiver should be by ref",523				));524			}525			if receiver.mutability.is_some() {526				mutability = Mutability::Mutable;527			} else {528				mutability = Mutability::View;529			}530		}531		let mut args = Vec::new();532		for typ in value533			.sig534			.inputs535			.iter()536			.filter(|arg| matches!(arg, FnArg::Typed(_)))537		{538			let typ = match typ {539				FnArg::Typed(typ) => typ,540				_ => unreachable!(),541			};542			args.push(MethodArg::try_from(typ)?);543		}544545		if mutability != Mutability::Mutable && args.iter().any(|arg| arg.is_value()) {546			return Err(syn::Error::new(547				args.iter().find(|arg| arg.is_value()).unwrap().ty.span(),548				"payable function should be mutable",549			));550		}551552		let result = match &value.sig.output {553			ReturnType::Type(_, ty) => ty,554			_ => return Err(syn::Error::new(value.sig.output.span(), "interface method should return Result<value>\nif there is no value to return - specify void (which is alias to unit)")),555		};556		let result = parse_result_ok(result)?;557558		let camel_name = info559			.rename_selector560			.unwrap_or_else(|| cases::camelcase::to_camel_case(&ident.to_string()));561		let has_normal_args = args.iter().filter(|arg| !arg.is_special()).count() != 0;562		let has_value_args = args.iter().any(|a| a.is_value());563564		Ok(Self {565			name: ident.clone(),566			camel_name,567			pascal_name: snake_ident_to_pascal(ident),568			screaming_name: snake_ident_to_screaming(ident),569			hide: info.hide,570			args,571			has_normal_args,572			has_value_args,573			mutability,574			result: result.clone(),575			weight,576			docs,577		})578	}579	fn expand_call_def(&self) -> proc_macro2::TokenStream {580		let defs = self581			.args582			.iter()583			.filter(|a| !a.is_special())584			.map(|a| a.expand_call_def());585		let pascal_name = &self.pascal_name;586		let docs = &self.docs;587588		if self.has_normal_args {589			quote! {590				#(#[doc = #docs])*591				#[allow(missing_docs)]592				#pascal_name {593					#(594						#defs,595					)*596				}597			}598		} else {599			quote! {600				#(#[doc = #docs])*601				#[allow(missing_docs)]602				#pascal_name603			}604		}605	}606607	fn expand_const(&self) -> proc_macro2::TokenStream {608		let screaming_name = &self.screaming_name;609		let screaming_name_signature = format_ident!("{}_SIGNATURE", &self.screaming_name);610		let custom_signature = self.expand_custom_signature();611		quote! {612			const #screaming_name_signature: ::evm_coder::custom_signature::SignatureUnit = #custom_signature;613			const #screaming_name: ::evm_coder::types::bytes4 = {614				let mut sum = ::evm_coder::sha3_const::Keccak256::new();615				let mut pos = 0;616				while pos < Self::#screaming_name_signature.len {617					sum = sum.update(&[Self::#screaming_name_signature.data[pos]; 1]);618					pos += 1;619				}620				let a = sum.finalize();621				[a[0], a[1], a[2], a[3]]622			};623		}624	}625626	fn expand_interface_id(&self) -> proc_macro2::TokenStream {627		let screaming_name = &self.screaming_name;628		quote! {629			interface_id ^= u32::from_be_bytes(Self::#screaming_name);630		}631	}632633	fn expand_parse(&self) -> proc_macro2::TokenStream {634		let pascal_name = &self.pascal_name;635		let screaming_name = &self.screaming_name;636		if self.has_normal_args {637			let args_iter = self.args.iter().filter(|a| !a.is_special());638			let arg_type = args_iter.clone().map(|a| &a.ty);639			let parsers = args_iter.map(|a| a.expand_parse());640			quote! {641				Self::#screaming_name => {642					let is_dynamic = false #(|| <#arg_type as ::evm_coder::abi::AbiType>::is_dynamic())*;643					return Ok(Some(Self::#pascal_name {644						#(645							#parsers,646						)*647					}))648				}649			}650		} else {651			quote! { Self::#screaming_name => return Ok(Some(Self::#pascal_name)) }652		}653	}654655	fn expand_variant_call(&self, call_name: &proc_macro2::Ident) -> proc_macro2::TokenStream {656		let pascal_name = &self.pascal_name;657		let name = &self.name;658659		let matcher = if self.has_normal_args {660			let names = self661				.args662				.iter()663				.filter(|a| !a.is_special())664				.map(|a| &a.name);665666			quote! {{667				#(668					#names,669				)*670			}}671		} else {672			quote! {}673		};674675		let receiver = match self.mutability {676			Mutability::Mutable | Mutability::View => quote! {self.},677			Mutability::Pure => quote! {Self::},678		};679		let args = self.args.iter().map(|a| a.expand_call_arg());680681		quote! {682			#call_name::#pascal_name #matcher => {683				#[allow(deprecated)]684				let result = #receiver #name(685					#(686						#args,687					)*688				)?;689				(&result).to_result()690			}691		}692	}693694	fn expand_variant_weight(&self) -> proc_macro2::TokenStream {695		let pascal_name = &self.pascal_name;696		if let Some(weight) = &self.weight {697			let matcher = if self.has_normal_args {698				let names = self699					.args700					.iter()701					.filter(|a| !a.is_special())702					.map(|a| &a.name);703704				quote! {{705					#(706						#names,707					)*708				}}709			} else {710				quote! {}711			};712			quote! {713				Self::#pascal_name #matcher => (#weight).into()714			}715		} else {716			let matcher = if self.has_normal_args {717				quote! {{..}}718			} else {719				quote! {}720			};721			quote! {722				Self::#pascal_name #matcher => ().into()723			}724		}725	}726727	fn expand_custom_signature(&self) -> proc_macro2::TokenStream {728		let mut args = TokenStream::new();729730		let mut has_params = false;731		for arg in self.args.iter().filter(|a| !a.is_special()) {732			has_params = true;733			let ty = &arg.ty;734			args.extend(quote! {nameof(<#ty>::SIGNATURE)});735			args.extend(quote! {fixed(",")})736		}737738		// Remove trailing comma739		if has_params {740			args.extend(quote! {shift_left(1)})741		}742743		let func_name = self.camel_name.clone();744		quote! { ::evm_coder::make_signature!(new fixed(#func_name) fixed("(") #args fixed(")")) }745	}746747	fn expand_solidity_function(&self) -> proc_macro2::TokenStream {748		let camel_name = &self.camel_name;749		let mutability = match self.mutability {750			Mutability::Mutable => quote! {SolidityMutability::Mutable},751			Mutability::View => quote! { SolidityMutability::View },752			Mutability::Pure => quote! {SolidityMutability::Pure},753		};754		let result = &self.result;755756		let args = self757			.args758			.iter()759			.filter(|a| !a.is_special())760			.map(MethodArg::expand_solidity_argument);761		let docs = &self.docs;762		let screaming_name = &self.screaming_name;763		let hide = self.hide;764		let custom_signature = self.expand_custom_signature();765		let is_payable = self.has_value_args;766767		quote! {768			SolidityFunction {769				docs: &[#(#docs),*],770				hide: #hide,771				selector: u32::from_be_bytes(Self::#screaming_name),772				custom_signature: #custom_signature,773				name: #camel_name,774				mutability: #mutability,775				is_payable: #is_payable,776				args: (777					#(778						#args,779					)*780				),781				result: <UnnamedArgument<#result>>::default(),782			}783		}784	}785}786787fn generics_list(gen: &Generics) -> proc_macro2::TokenStream {788	if gen.params.is_empty() {789		return quote! {};790	}791	let params = gen.params.iter().map(|p| match p {792		syn::GenericParam::Type(id) => {793			let v = &id.ident;794			quote! {#v}795		}796		syn::GenericParam::Lifetime(lt) => {797			let v = &lt.lifetime;798			quote! {#v}799		}800		syn::GenericParam::Const(c) => {801			let i = &c.ident;802			quote! {#i}803		}804	});805	quote! { #(#params),* }806}807fn generics_reference(gen: &Generics) -> proc_macro2::TokenStream {808	if gen.params.is_empty() {809		return quote! {};810	}811	let list = generics_list(gen);812	quote! { <#list> }813}814fn generics_stub(gen: &Generics) -> proc_macro2::TokenStream {815	if gen.params.is_empty() {816		return quote! {};817	}818	let params = (0..gen.params.len()).map(|_| quote! {()});819	quote! {<#(#params,)*>}820}821fn generics_data(gen: &Generics) -> proc_macro2::TokenStream {822	let list = generics_list(gen);823	if gen.params.len() == 1 {824		quote! {#list}825	} else {826		quote! { (#list) }827	}828}829830pub struct SolidityInterface {831	generics: Generics,832	name: Box<syn::Type>,833	info: InterfaceInfo,834	methods: Vec<Method>,835	docs: Vec<String>,836}837impl SolidityInterface {838	pub fn try_from(info: InterfaceInfo, value: &ItemImpl) -> syn::Result<Self> {839		let mut methods = Vec::new();840841		for item in &value.items {842			if let ImplItem::Method(method) = item {843				methods.push(Method::try_from(method)?)844			}845		}846		let mut docs = vec![];847		for attr in &value.attrs {848			let ident = parse_ident_from_path(&attr.path, false)?;849			if ident == "doc" {850				let args = attr.parse_meta().unwrap();851				let value = match args {852					Meta::NameValue(MetaNameValue {853						lit: Lit::Str(str), ..854					}) => str.value(),855					_ => unreachable!(),856				};857				docs.push(value);858			}859		}860		Ok(Self {861			generics: value.generics.clone(),862			name: value.self_ty.clone(),863			info,864			methods,865			docs,866		})867	}868	pub fn expand(self) -> proc_macro2::TokenStream {869		let name = self.name;870871		let solidity_name = self.info.name.to_string();872		let call_name = pascal_ident_to_call(&self.info.name);873		let generics = self.generics;874		let gen_ref = generics_reference(&generics);875		let gen_data = generics_data(&generics);876		let gen_stub = generics_stub(&generics);877		let gen_where = &generics.where_clause;878879		let call_sub = self880			.info881			.inline_is882			.0883			.iter()884			.chain(self.info.is.0.iter())885			.map(|c| Is::expand_call_def(c, &gen_ref));886		let call_parse = self887			.info888			.inline_is889			.0890			.iter()891			.chain(self.info.is.0.iter())892			.map(|is| Is::expand_parse(is, &gen_ref));893		let call_variants = self894			.info895			.inline_is896			.0897			.iter()898			.chain(self.info.is.0.iter())899			.map(|c| Is::expand_variant_call(c, &call_name, &gen_ref));900		let weight_variants = self901			.info902			.inline_is903			.0904			.iter()905			.chain(self.info.is.0.iter())906			.map(Is::expand_variant_weight);907908		let inline_interface_id = self.info.inline_is.0.iter().map(Is::expand_interface_id);909		let supports_interface = self910			.info911			.is912			.0913			.iter()914			.map(|is| Is::expand_supports_interface(is, &gen_ref));915916		let calls = self.methods.iter().map(Method::expand_call_def);917		let consts = self.methods.iter().map(Method::expand_const);918		let interface_id = self.methods.iter().map(Method::expand_interface_id);919		let parsers = self.methods.iter().map(Method::expand_parse);920		let call_variants_this = self921			.methods922			.iter()923			.map(|m| Method::expand_variant_call(m, &call_name));924		let weight_variants_this = self.methods.iter().map(Method::expand_variant_weight);925		let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);926927		// TODO: Inline inline_is928		let solidity_is = self929			.info930			.is931			.0932			.iter()933			.chain(self.info.inline_is.0.iter())934			.map(|is| is.name.to_string());935		let solidity_events_is = self.info.events.0.iter().map(|is| is.name.to_string());936		let solidity_generators = self937			.info938			.is939			.0940			.iter()941			.chain(self.info.inline_is.0.iter())942			.map(|is| Is::expand_generator(is, &gen_ref));943		let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator);944		let solidity_events_idents = self.info.events.0.iter().map(|is| is.name.clone());945		let docs = &self.docs;946947		let expect_selector = self.info.expect_selector.map(|s| {948            quote! {949                const _: () = assert!(#s == u32::from_be_bytes(<#call_name #gen_stub>::interface_id()), "selector mismatch, review contained function selectors");950            }951        });952953		quote! {954			#(955				const _: ::core::marker::PhantomData<#solidity_events_idents> = ::core::marker::PhantomData;956			)*957			#[derive(Debug)]958			#(#[doc = #docs])*959			pub enum #call_name #gen_ref {960				/// Inherited method961				ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<#gen_data>),962				#(963					#calls,964				)*965				#(966					#call_sub,967				)*968			}969970			#expect_selector971972			impl #gen_ref #call_name #gen_ref {973				#(974					#consts975				)*976				/// Return this call ERC165 selector977				pub const fn interface_id() -> ::evm_coder::types::bytes4 {978					let mut interface_id = 0;979					#(#interface_id)*980					#(#inline_interface_id)*981					u32::to_be_bytes(interface_id)982				}983				/// Generate solidity definitions for methods described in this interface984				#[cfg(feature = "stubgen")]985				pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {986					use evm_coder::solidity::*;987					use core::fmt::Write;988					let interface = SolidityInterface {989						docs: &[#(#docs),*],990						name: #solidity_name,991						selector: Self::interface_id(),992						is: &["Dummy", "ERC165", #(993							#solidity_is,994						)* #(995							#solidity_events_is,996						)* ],997						functions: (#(998							#solidity_functions,999						)*),1000					};10011002					let mut out = ::evm_coder::types::string::new();1003					if #solidity_name.starts_with("Inline") {1004						out.push_str("/// @dev inlined interface\n");1005					}1006					let _ = interface.format(is_impl, &mut out, tc);1007					tc.collect(out);1008					#(1009						#solidity_event_generators1010					)*1011					#(1012						#solidity_generators1013					)*1014					if is_impl {1015						tc.collect("/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());1016					} else {1017						tc.collect("/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());1018					}1019				}1020			}1021			impl #gen_ref ::evm_coder::Call for #call_name #gen_ref {1022				fn parse(method_id: ::evm_coder::types::bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {1023					use ::evm_coder::abi::AbiRead;1024					match method_id {1025						::evm_coder::ERC165Call::INTERFACE_ID => return Ok(1026							::evm_coder::ERC165Call::parse(method_id, reader)?1027							.map(|c| Self::ERC165Call(c, ::core::marker::PhantomData))1028						),1029						#(1030							#parsers,1031						)*1032						_ => {},1033					}1034					#(1035						#call_parse1036					)else*1037					return Ok(None);1038				}1039			}1040			impl #generics #call_name #gen_ref1041			#gen_where1042			{1043				/// Is this contract implements specified ERC165 selector1044				pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::bytes4) -> bool {1045					interface_id != u32::to_be_bytes(0xffffff) && (1046						interface_id == ::evm_coder::ERC165Call::INTERFACE_ID ||1047						interface_id == Self::interface_id()1048						#(1049							|| #supports_interface1050						)*1051					)1052				}1053			}1054			impl #generics ::evm_coder::Weighted for #call_name #gen_ref1055			#gen_where1056			{1057				#[allow(unused_variables)]1058				fn weight(&self) -> ::evm_coder::execution::DispatchInfo {1059					match self {1060						#(1061							#weight_variants,1062						)*1063						// TODO: It should be very cheap, but not free1064						Self::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {..}, _) => ::frame_support::weights::Weight::from_ref_time(100).into(),1065						#(1066							#weight_variants_this,1067						)*1068					}1069				}1070			}1071			impl #generics ::evm_coder::Callable<#call_name #gen_ref> for #name1072			#gen_where1073			{1074				#[allow(unreachable_code)] // In case of no inner calls1075				fn call(&mut self, c: Msg<#call_name #gen_ref>) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {1076					use ::evm_coder::abi::AbiWrite;1077					match c.call {1078						#(1079							#call_variants,1080						)*1081						#call_name::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}, _) => {1082							let mut writer = ::evm_coder::abi::AbiWriter::default();1083							writer.bool(&<#call_name #gen_ref>::supports_interface(self, interface_id));1084							return Ok(writer.into());1085						}1086						_ => {},1087					}1088					let mut writer = ::evm_coder::abi::AbiWriter::default();1089					match c.call {1090						#(1091							#call_variants_this,1092						)*1093						_ => Err(::evm_coder::execution::Error::from("method is not available").into()),1094					}1095				}1096			}1097		}1098	}1099}
after · crates/evm-coder/procedural/src/solidity_interface.rs
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![allow(dead_code)]1819// NOTE: In order to understand this Rust macro better, first read this chapter20// about Procedural Macros in Rust book:21// https://doc.rust-lang.org/reference/procedural-macros.html2223use proc_macro2::TokenStream;24use quote::{quote, format_ident};25use inflector::cases;26use syn::{27	Expr, FnArg, Generics, Ident, ImplItem, ImplItemMethod, ItemImpl, Lit, Meta, MetaNameValue,28	PatType, ReturnType, Type,29	spanned::Spanned,30	parse::{Parse, ParseStream},31	parenthesized, Token, LitInt, LitStr,32};3334use crate::{35	parse_ident_from_pat, parse_ident_from_path, parse_path, parse_path_segment, parse_result_ok,36	pascal_ident_to_call, pascal_ident_to_snake_call, snake_ident_to_pascal,37	snake_ident_to_screaming,38};3940struct Is {41	name: Ident,42	pascal_call_name: Ident,43	snake_call_name: Ident,44	via: Option<(Type, Ident)>,45	condition: Option<Expr>,46}47impl Is {48	fn expand_call_def(&self, gen_ref: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {49		let name = &self.name;50		let pascal_call_name = &self.pascal_call_name;51		quote! {52			#name(#pascal_call_name #gen_ref)53		}54	}5556	fn expand_interface_id(&self) -> proc_macro2::TokenStream {57		let pascal_call_name = &self.pascal_call_name;58		quote! {59			interface_id ^= u32::from_be_bytes(#pascal_call_name::interface_id());60		}61	}6263	fn expand_supports_interface(64		&self,65		generics: &proc_macro2::TokenStream,66	) -> proc_macro2::TokenStream {67		let pascal_call_name = &self.pascal_call_name;68		let condition = self.condition.as_ref().map(|condition| {69			quote! {70				(#condition) &&71			}72		});73		quote! {74			#condition <#pascal_call_name #generics>::supports_interface(this, interface_id)75		}76	}7778	fn expand_variant_weight(&self) -> proc_macro2::TokenStream {79		let name = &self.name;80		quote! {81			Self::#name(call) => call.weight()82		}83	}8485	fn expand_variant_call(86		&self,87		call_name: &proc_macro2::Ident,88		generics: &proc_macro2::TokenStream,89	) -> proc_macro2::TokenStream {90		let name = &self.name;91		let pascal_call_name = &self.pascal_call_name;92		let via_typ = self93			.via94			.as_ref()95			.map(|(t, _)| quote! {#t})96			.unwrap_or_else(|| quote! {Self});97		let via_map = self98			.via99			.as_ref()100			.map(|(_, i)| quote! {.#i()})101			.unwrap_or_default();102		let condition = self.condition.as_ref().map(|condition| {103			quote! {104				if ({let this = &self; (#condition)})105			}106		});107		quote! {108			#call_name::#name(call) #condition => return <#via_typ as ::evm_coder::Callable<#pascal_call_name #generics>>::call(self #via_map, Msg {109				call,110				caller: c.caller,111				value: c.value,112			})113		}114	}115116	fn expand_parse(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {117		let name = &self.name;118		let pascal_call_name = &self.pascal_call_name;119		quote! {120			if let Some(parsed_call) = <#pascal_call_name #generics>::parse(method_id, reader)? {121				return Ok(Some(Self::#name(parsed_call)))122			}123		}124	}125126	fn expand_generator(&self, generics: &proc_macro2::TokenStream) -> proc_macro2::TokenStream {127		let pascal_call_name = &self.pascal_call_name;128		quote! {129			<#pascal_call_name #generics>::generate_solidity_interface(tc, is_impl);130		}131	}132133	fn expand_event_generator(&self) -> proc_macro2::TokenStream {134		let name = &self.name;135		quote! {136			#name::generate_solidity_interface(tc, is_impl);137		}138	}139}140141#[derive(Default)]142struct IsList(Vec<Is>);143impl Parse for IsList {144	fn parse(input: ParseStream) -> syn::Result<Self> {145		let mut out = vec![];146		loop {147			if input.is_empty() {148				break;149			}150			let name = input.parse::<Ident>()?;151			let lookahead = input.lookahead1();152153			let mut condition: Option<Expr> = None;154			let mut via: Option<(Type, Ident)> = None;155156			if lookahead.peek(syn::token::Paren) {157				let contents;158				parenthesized!(contents in input);159				let input = contents;160161				while !input.is_empty() {162					let lookahead = input.lookahead1();163					if lookahead.peek(Token![if]) {164						input.parse::<Token![if]>()?;165						let contents;166						parenthesized!(contents in input);167						let contents = contents.parse::<Expr>()?;168169						if condition.replace(contents).is_some() {170							return Err(syn::Error::new(input.span(), "condition is already set"));171						}172					} else if lookahead.peek(kw::via) {173						input.parse::<kw::via>()?;174						let contents;175						parenthesized!(contents in input);176177						let method = contents.parse::<Ident>()?;178						contents.parse::<kw::returns>()?;179						let ty = contents.parse::<Type>()?;180181						if via.replace((ty, method)).is_some() {182							return Err(syn::Error::new(input.span(), "via is already set"));183						}184					} else {185						return Err(lookahead.error());186					}187188					if input.peek(Token![,]) {189						input.parse::<Token![,]>()?;190					} else if !input.is_empty() {191						return Err(syn::Error::new(input.span(), "expected end"));192					}193				}194			} else if lookahead.peek(Token![,]) || input.is_empty() {195				// Pass196			} else {197				return Err(lookahead.error());198			};199			out.push(Is {200				pascal_call_name: pascal_ident_to_call(&name),201				snake_call_name: pascal_ident_to_snake_call(&name),202				name,203				via,204				condition,205			});206			if input.peek(Token![,]) {207				input.parse::<Token![,]>()?;208				continue;209			} else {210				break;211			}212		}213		Ok(Self(out))214	}215}216217pub struct InterfaceInfo {218	name: Ident,219	is: IsList,220	inline_is: IsList,221	events: IsList,222	expect_selector: Option<u32>,223}224impl Parse for InterfaceInfo {225	fn parse(input: ParseStream) -> syn::Result<Self> {226		let mut name = None;227		let mut is = None;228		let mut inline_is = None;229		let mut events = None;230		let mut expect_selector = None;231		// TODO: create proc-macro to optimize proc-macro boilerplate? :D232		loop {233			let lookahead = input.lookahead1();234			if lookahead.peek(kw::name) {235				let k = input.parse::<kw::name>()?;236				input.parse::<Token![=]>()?;237				if name.replace(input.parse::<Ident>()?).is_some() {238					return Err(syn::Error::new(k.span(), "name is already set"));239				}240			} else if lookahead.peek(kw::is) {241				let k = input.parse::<kw::is>()?;242				let contents;243				parenthesized!(contents in input);244				if is.replace(contents.parse::<IsList>()?).is_some() {245					return Err(syn::Error::new(k.span(), "is is already set"));246				}247			} else if lookahead.peek(kw::inline_is) {248				let k = input.parse::<kw::inline_is>()?;249				let contents;250				parenthesized!(contents in input);251				if inline_is.replace(contents.parse::<IsList>()?).is_some() {252					return Err(syn::Error::new(k.span(), "inline_is is already set"));253				}254			} else if lookahead.peek(kw::events) {255				let k = input.parse::<kw::events>()?;256				let contents;257				parenthesized!(contents in input);258				if events.replace(contents.parse::<IsList>()?).is_some() {259					return Err(syn::Error::new(k.span(), "events is already set"));260				}261			} else if lookahead.peek(kw::expect_selector) {262				let k = input.parse::<kw::expect_selector>()?;263				input.parse::<Token![=]>()?;264				let value = input.parse::<LitInt>()?;265				if expect_selector266					.replace(value.base10_parse::<u32>()?)267					.is_some()268				{269					return Err(syn::Error::new(k.span(), "expect_selector is already set"));270				}271			} else if input.is_empty() {272				break;273			} else {274				return Err(lookahead.error());275			}276			if input.peek(Token![,]) {277				input.parse::<Token![,]>()?;278			} else {279				break;280			}281		}282		Ok(Self {283			name: name.ok_or_else(|| syn::Error::new(input.span(), "missing name"))?,284			is: is.unwrap_or_default(),285			inline_is: inline_is.unwrap_or_default(),286			events: events.unwrap_or_default(),287			expect_selector,288		})289	}290}291292struct MethodInfo {293	rename_selector: Option<String>,294	hide: bool,295}296impl Parse for MethodInfo {297	fn parse(input: ParseStream) -> syn::Result<Self> {298		let mut rename_selector = None;299		let mut hide = false;300		while !input.is_empty() {301			let lookahead = input.lookahead1();302			if lookahead.peek(kw::rename_selector) {303				let k = input.parse::<kw::rename_selector>()?;304				input.parse::<Token![=]>()?;305				if rename_selector306					.replace(input.parse::<LitStr>()?.value())307					.is_some()308				{309					return Err(syn::Error::new(k.span(), "rename_selector is already set"));310				}311			} else if lookahead.peek(kw::hide) {312				input.parse::<kw::hide>()?;313				hide = true;314			} else {315				return Err(lookahead.error());316			}317318			if input.peek(Token![,]) {319				input.parse::<Token![,]>()?;320			} else if !input.is_empty() {321				return Err(syn::Error::new(input.span(), "expected end"));322			}323		}324		Ok(Self {325			rename_selector,326			hide,327		})328	}329}330331trait AbiTypeHelper {332	fn plain(&self) -> syn::Result<&Ident>;333	fn is_value(&self) -> bool;334	fn is_caller(&self) -> bool;335	fn is_special(&self) -> bool;336}337338impl AbiTypeHelper for Type {339	fn plain(&self) -> syn::Result<&Ident> {340		let path = parse_path(self)?;341		let segment = parse_path_segment(path)?;342		if !segment.arguments.is_empty() {343			return Err(syn::Error::new(self.span(), "Not plain type"));344		}345		Ok(&segment.ident)346	}347348	fn is_value(&self) -> bool {349		if let Ok(ident) = self.plain() {350			return ident == "Value";351		}352		false353	}354355	fn is_caller(&self) -> bool {356		if let Ok(ident) = self.plain() {357			return ident == "Caller";358		}359		false360	}361362	fn is_special(&self) -> bool {363		self.is_caller() || self.is_value()364	}365}366367#[derive(Debug)]368struct MethodArg {369	name: Ident,370	camel_name: String,371	ty: Type,372}373impl MethodArg {374	fn try_from(value: &PatType) -> syn::Result<Self> {375		let name = parse_ident_from_pat(&value.pat)?.clone();376		Ok(Self {377			camel_name: cases::camelcase::to_camel_case(&name.to_string()),378			name,379			ty: value.ty.as_ref().clone(),380		})381	}382	fn is_value(&self) -> bool {383		self.ty.is_value()384	}385	fn is_caller(&self) -> bool {386		self.ty.is_caller()387	}388	fn is_special(&self) -> bool {389		self.ty.is_special()390	}391392	fn expand_call_def(&self) -> proc_macro2::TokenStream {393		assert!(!self.is_special());394		let name = &self.name;395		let ty = &self.ty;396397		quote! {398			#name: #ty399		}400	}401402	fn expand_parse(&self) -> proc_macro2::TokenStream {403		assert!(!self.is_special());404		let name = &self.name;405		let ty = &self.ty;406		quote! {407			#name: {408				let value = <#ty as ::evm_coder::abi::AbiRead>::abi_read(reader)?;409				if !is_dynamic {reader.bytes_read(<#ty as ::evm_coder::abi::AbiType>::size())};410				value411			}412		}413	}414415	fn expand_call_arg(&self) -> proc_macro2::TokenStream {416		if self.is_value() {417			quote! {418				c.value.clone()419			}420		} else if self.is_caller() {421			quote! {422				c.caller.clone()423			}424		} else {425			let name = &self.name;426			quote! {427				#name428			}429		}430	}431432	fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {433		let camel_name = &self.camel_name.to_string();434		let ty = &self.ty;435		quote! {436			<NamedArgument<#ty>>::new(#camel_name)437		}438	}439}440441#[derive(PartialEq)]442enum Mutability {443	Mutable,444	View,445	Pure,446}447448/// Group all keywords for this macro. Usage example:449/// #[solidity_interface(name = "B", inline_is(A))]450mod kw {451	syn::custom_keyword!(weight);452453	syn::custom_keyword!(via);454	syn::custom_keyword!(returns);455	syn::custom_keyword!(name);456	syn::custom_keyword!(is);457	syn::custom_keyword!(inline_is);458	syn::custom_keyword!(events);459	syn::custom_keyword!(expect_selector);460461	syn::custom_keyword!(rename_selector);462	syn::custom_keyword!(hide);463}464465/// Rust methods are parsed into this structure when Solidity code is generated466struct Method {467	name: Ident,468	camel_name: String,469	pascal_name: Ident,470	screaming_name: Ident,471	hide: bool,472	args: Vec<MethodArg>,473	has_normal_args: bool,474	has_value_args: bool,475	mutability: Mutability,476	result: Type,477	weight: Option<Expr>,478	docs: Vec<String>,479}480impl Method {481	fn try_from(value: &ImplItemMethod) -> syn::Result<Self> {482		let mut info = MethodInfo {483			rename_selector: None,484			hide: false,485		};486		let mut docs = Vec::new();487		let mut weight = None;488		for attr in &value.attrs {489			let ident = parse_ident_from_path(&attr.path, false)?;490			if ident == "solidity" {491				info = attr.parse_args::<MethodInfo>()?;492			} else if ident == "doc" {493				let args = attr.parse_meta().unwrap();494				let value = match args {495					Meta::NameValue(MetaNameValue {496						lit: Lit::Str(str), ..497					}) => str.value(),498					_ => unreachable!(),499				};500				docs.push(value);501			} else if ident == "weight" {502				weight = Some(attr.parse_args::<Expr>()?);503			}504		}505		let ident = &value.sig.ident;506		let ident_str = ident.to_string();507		if !cases::snakecase::is_snake_case(&ident_str) {508			return Err(syn::Error::new(ident.span(), "method name should be snake_cased\nif alternative solidity name needs to be set - use #[solidity] attribute"));509		}510511		let mut mutability = Mutability::Pure;512513		if let Some(FnArg::Receiver(receiver)) = value514			.sig515			.inputs516			.iter()517			.find(|arg| matches!(arg, FnArg::Receiver(_)))518		{519			if receiver.reference.is_none() {520				return Err(syn::Error::new(521					receiver.span(),522					"receiver should be by ref",523				));524			}525			if receiver.mutability.is_some() {526				mutability = Mutability::Mutable;527			} else {528				mutability = Mutability::View;529			}530		}531		let mut args = Vec::new();532		for typ in value533			.sig534			.inputs535			.iter()536			.filter(|arg| matches!(arg, FnArg::Typed(_)))537		{538			let typ = match typ {539				FnArg::Typed(typ) => typ,540				_ => unreachable!(),541			};542			args.push(MethodArg::try_from(typ)?);543		}544545		if mutability != Mutability::Mutable && args.iter().any(|arg| arg.is_value()) {546			return Err(syn::Error::new(547				args.iter().find(|arg| arg.is_value()).unwrap().ty.span(),548				"payable function should be mutable",549			));550		}551552		let result = match &value.sig.output {553			ReturnType::Type(_, ty) => ty,554			_ => return Err(syn::Error::new(value.sig.output.span(), "interface method should return Result<value>\nif there is no value to return - specify void (which is alias to unit)")),555		};556		let result = parse_result_ok(result)?;557558		let camel_name = info559			.rename_selector560			.unwrap_or_else(|| cases::camelcase::to_camel_case(&ident.to_string()));561		let has_normal_args = args.iter().filter(|arg| !arg.is_special()).count() != 0;562		let has_value_args = args.iter().any(|a| a.is_value());563564		Ok(Self {565			name: ident.clone(),566			camel_name,567			pascal_name: snake_ident_to_pascal(ident),568			screaming_name: snake_ident_to_screaming(ident),569			hide: info.hide,570			args,571			has_normal_args,572			has_value_args,573			mutability,574			result: result.clone(),575			weight,576			docs,577		})578	}579	fn expand_call_def(&self) -> proc_macro2::TokenStream {580		let defs = self581			.args582			.iter()583			.filter(|a| !a.is_special())584			.map(|a| a.expand_call_def());585		let pascal_name = &self.pascal_name;586		let docs = &self.docs;587588		if self.has_normal_args {589			quote! {590				#(#[doc = #docs])*591				#[allow(missing_docs)]592				#pascal_name {593					#(594						#defs,595					)*596				}597			}598		} else {599			quote! {600				#(#[doc = #docs])*601				#[allow(missing_docs)]602				#pascal_name603			}604		}605	}606607	fn expand_const(&self) -> proc_macro2::TokenStream {608		let screaming_name = &self.screaming_name;609		let screaming_name_signature = format_ident!("{}_SIGNATURE", &self.screaming_name);610		let custom_signature = self.expand_custom_signature();611		quote! {612			const #screaming_name_signature: ::evm_coder::custom_signature::SignatureUnit = #custom_signature;613			const #screaming_name: ::evm_coder::types::Bytes4 = {614				let mut sum = ::evm_coder::sha3_const::Keccak256::new();615				let mut pos = 0;616				while pos < Self::#screaming_name_signature.len {617					sum = sum.update(&[Self::#screaming_name_signature.data[pos]; 1]);618					pos += 1;619				}620				let a = sum.finalize();621				[a[0], a[1], a[2], a[3]]622			};623		}624	}625626	fn expand_interface_id(&self) -> proc_macro2::TokenStream {627		let screaming_name = &self.screaming_name;628		quote! {629			interface_id ^= u32::from_be_bytes(Self::#screaming_name);630		}631	}632633	fn expand_parse(&self) -> proc_macro2::TokenStream {634		let pascal_name = &self.pascal_name;635		let screaming_name = &self.screaming_name;636		if self.has_normal_args {637			let args_iter = self.args.iter().filter(|a| !a.is_special());638			let arg_type = args_iter.clone().map(|a| &a.ty);639			let parsers = args_iter.map(|a| a.expand_parse());640			quote! {641				Self::#screaming_name => {642					let is_dynamic = false #(|| <#arg_type as ::evm_coder::abi::AbiType>::is_dynamic())*;643					return Ok(Some(Self::#pascal_name {644						#(645							#parsers,646						)*647					}))648				}649			}650		} else {651			quote! { Self::#screaming_name => return Ok(Some(Self::#pascal_name)) }652		}653	}654655	fn expand_variant_call(&self, call_name: &proc_macro2::Ident) -> proc_macro2::TokenStream {656		let pascal_name = &self.pascal_name;657		let name = &self.name;658659		let matcher = if self.has_normal_args {660			let names = self661				.args662				.iter()663				.filter(|a| !a.is_special())664				.map(|a| &a.name);665666			quote! {{667				#(668					#names,669				)*670			}}671		} else {672			quote! {}673		};674675		let receiver = match self.mutability {676			Mutability::Mutable | Mutability::View => quote! {self.},677			Mutability::Pure => quote! {Self::},678		};679		let args = self.args.iter().map(|a| a.expand_call_arg());680681		quote! {682			#call_name::#pascal_name #matcher => {683				#[allow(deprecated)]684				let result = #receiver #name(685					#(686						#args,687					)*688				)?;689				(&result).to_result()690			}691		}692	}693694	fn expand_variant_weight(&self) -> proc_macro2::TokenStream {695		let pascal_name = &self.pascal_name;696		if let Some(weight) = &self.weight {697			let matcher = if self.has_normal_args {698				let names = self699					.args700					.iter()701					.filter(|a| !a.is_special())702					.map(|a| &a.name);703704				quote! {{705					#(706						#names,707					)*708				}}709			} else {710				quote! {}711			};712			quote! {713				Self::#pascal_name #matcher => (#weight).into()714			}715		} else {716			let matcher = if self.has_normal_args {717				quote! {{..}}718			} else {719				quote! {}720			};721			quote! {722				Self::#pascal_name #matcher => ().into()723			}724		}725	}726727	fn expand_custom_signature(&self) -> proc_macro2::TokenStream {728		let mut args = TokenStream::new();729730		let mut has_params = false;731		for arg in self.args.iter().filter(|a| !a.is_special()) {732			has_params = true;733			let ty = &arg.ty;734			args.extend(quote! {nameof(<#ty>::SIGNATURE)});735			args.extend(quote! {fixed(",")})736		}737738		// Remove trailing comma739		if has_params {740			args.extend(quote! {shift_left(1)})741		}742743		let func_name = self.camel_name.clone();744		quote! { ::evm_coder::make_signature!(new fixed(#func_name) fixed("(") #args fixed(")")) }745	}746747	fn expand_solidity_function(&self) -> proc_macro2::TokenStream {748		let camel_name = &self.camel_name;749		let mutability = match self.mutability {750			Mutability::Mutable => quote! {SolidityMutability::Mutable},751			Mutability::View => quote! { SolidityMutability::View },752			Mutability::Pure => quote! {SolidityMutability::Pure},753		};754		let result = &self.result;755756		let args = self757			.args758			.iter()759			.filter(|a| !a.is_special())760			.map(MethodArg::expand_solidity_argument);761		let docs = &self.docs;762		let screaming_name = &self.screaming_name;763		let hide = self.hide;764		let custom_signature = self.expand_custom_signature();765		let is_payable = self.has_value_args;766767		quote! {768			SolidityFunction {769				docs: &[#(#docs),*],770				hide: #hide,771				selector: u32::from_be_bytes(Self::#screaming_name),772				custom_signature: #custom_signature,773				name: #camel_name,774				mutability: #mutability,775				is_payable: #is_payable,776				args: (777					#(778						#args,779					)*780				),781				result: <UnnamedArgument<#result>>::default(),782			}783		}784	}785}786787fn generics_list(gen: &Generics) -> proc_macro2::TokenStream {788	if gen.params.is_empty() {789		return quote! {};790	}791	let params = gen.params.iter().map(|p| match p {792		syn::GenericParam::Type(id) => {793			let v = &id.ident;794			quote! {#v}795		}796		syn::GenericParam::Lifetime(lt) => {797			let v = &lt.lifetime;798			quote! {#v}799		}800		syn::GenericParam::Const(c) => {801			let i = &c.ident;802			quote! {#i}803		}804	});805	quote! { #(#params),* }806}807fn generics_reference(gen: &Generics) -> proc_macro2::TokenStream {808	if gen.params.is_empty() {809		return quote! {};810	}811	let list = generics_list(gen);812	quote! { <#list> }813}814fn generics_stub(gen: &Generics) -> proc_macro2::TokenStream {815	if gen.params.is_empty() {816		return quote! {};817	}818	let params = (0..gen.params.len()).map(|_| quote! {()});819	quote! {<#(#params,)*>}820}821fn generics_data(gen: &Generics) -> proc_macro2::TokenStream {822	let list = generics_list(gen);823	if gen.params.len() == 1 {824		quote! {#list}825	} else {826		quote! { (#list) }827	}828}829830pub struct SolidityInterface {831	generics: Generics,832	name: Box<syn::Type>,833	info: InterfaceInfo,834	methods: Vec<Method>,835	docs: Vec<String>,836}837impl SolidityInterface {838	pub fn try_from(info: InterfaceInfo, value: &ItemImpl) -> syn::Result<Self> {839		let mut methods = Vec::new();840841		for item in &value.items {842			if let ImplItem::Method(method) = item {843				methods.push(Method::try_from(method)?)844			}845		}846		let mut docs = vec![];847		for attr in &value.attrs {848			let ident = parse_ident_from_path(&attr.path, false)?;849			if ident == "doc" {850				let args = attr.parse_meta().unwrap();851				let value = match args {852					Meta::NameValue(MetaNameValue {853						lit: Lit::Str(str), ..854					}) => str.value(),855					_ => unreachable!(),856				};857				docs.push(value);858			}859		}860		Ok(Self {861			generics: value.generics.clone(),862			name: value.self_ty.clone(),863			info,864			methods,865			docs,866		})867	}868	pub fn expand(self) -> proc_macro2::TokenStream {869		let name = self.name;870871		let solidity_name = self.info.name.to_string();872		let call_name = pascal_ident_to_call(&self.info.name);873		let generics = self.generics;874		let gen_ref = generics_reference(&generics);875		let gen_data = generics_data(&generics);876		let gen_stub = generics_stub(&generics);877		let gen_where = &generics.where_clause;878879		let call_sub = self880			.info881			.inline_is882			.0883			.iter()884			.chain(self.info.is.0.iter())885			.map(|c| Is::expand_call_def(c, &gen_ref));886		let call_parse = self887			.info888			.inline_is889			.0890			.iter()891			.chain(self.info.is.0.iter())892			.map(|is| Is::expand_parse(is, &gen_ref));893		let call_variants = self894			.info895			.inline_is896			.0897			.iter()898			.chain(self.info.is.0.iter())899			.map(|c| Is::expand_variant_call(c, &call_name, &gen_ref));900		let weight_variants = self901			.info902			.inline_is903			.0904			.iter()905			.chain(self.info.is.0.iter())906			.map(Is::expand_variant_weight);907908		let inline_interface_id = self.info.inline_is.0.iter().map(Is::expand_interface_id);909		let supports_interface = self910			.info911			.is912			.0913			.iter()914			.map(|is| Is::expand_supports_interface(is, &gen_ref));915916		let calls = self.methods.iter().map(Method::expand_call_def);917		let consts = self.methods.iter().map(Method::expand_const);918		let interface_id = self.methods.iter().map(Method::expand_interface_id);919		let parsers = self.methods.iter().map(Method::expand_parse);920		let call_variants_this = self921			.methods922			.iter()923			.map(|m| Method::expand_variant_call(m, &call_name));924		let weight_variants_this = self.methods.iter().map(Method::expand_variant_weight);925		let solidity_functions = self.methods.iter().map(Method::expand_solidity_function);926927		// TODO: Inline inline_is928		let solidity_is = self929			.info930			.is931			.0932			.iter()933			.chain(self.info.inline_is.0.iter())934			.map(|is| is.name.to_string());935		let solidity_events_is = self.info.events.0.iter().map(|is| is.name.to_string());936		let solidity_generators = self937			.info938			.is939			.0940			.iter()941			.chain(self.info.inline_is.0.iter())942			.map(|is| Is::expand_generator(is, &gen_ref));943		let solidity_event_generators = self.info.events.0.iter().map(Is::expand_event_generator);944		let solidity_events_idents = self.info.events.0.iter().map(|is| is.name.clone());945		let docs = &self.docs;946947		let expect_selector = self.info.expect_selector.map(|s| {948            quote! {949                const _: () = assert!(#s == u32::from_be_bytes(<#call_name #gen_stub>::interface_id()), "selector mismatch, review contained function selectors");950            }951        });952953		quote! {954			#(955				const _: ::core::marker::PhantomData<#solidity_events_idents> = ::core::marker::PhantomData;956			)*957			#[derive(Debug)]958			#(#[doc = #docs])*959			pub enum #call_name #gen_ref {960				/// Inherited method961				ERC165Call(::evm_coder::ERC165Call, ::core::marker::PhantomData<#gen_data>),962				#(963					#calls,964				)*965				#(966					#call_sub,967				)*968			}969970			#expect_selector971972			impl #gen_ref #call_name #gen_ref {973				#(974					#consts975				)*976				/// Return this call ERC165 selector977				pub const fn interface_id() -> ::evm_coder::types::Bytes4 {978					let mut interface_id = 0;979					#(#interface_id)*980					#(#inline_interface_id)*981					u32::to_be_bytes(interface_id)982				}983				/// Generate solidity definitions for methods described in this interface984				#[cfg(feature = "stubgen")]985				pub fn generate_solidity_interface(tc: &evm_coder::solidity::TypeCollector, is_impl: bool) {986					use evm_coder::solidity::*;987					use core::fmt::Write;988					let interface = SolidityInterface {989						docs: &[#(#docs),*],990						name: #solidity_name,991						selector: Self::interface_id(),992						is: &["Dummy", "ERC165", #(993							#solidity_is,994						)* #(995							#solidity_events_is,996						)* ],997						functions: (#(998							#solidity_functions,999						)*),1000					};10011002					let mut out = ::evm_coder::types::String::new();1003					if #solidity_name.starts_with("Inline") {1004						out.push_str("/// @dev inlined interface\n");1005					}1006					let _ = interface.format(is_impl, &mut out, tc);1007					tc.collect(out);1008					#(1009						#solidity_event_generators1010					)*1011					#(1012						#solidity_generators1013					)*1014					if is_impl {1015						tc.collect("/// @dev common stubs holder\ncontract Dummy {\n\tuint8 dummy;\n\tstring stub_error = \"this contract is implemented in native\";\n}\ncontract ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool) {\n\t\trequire(false, stub_error);\n\t\tinterfaceID;\n\t\treturn true;\n\t}\n}\n".into());1016					} else {1017						tc.collect("/// @dev common stubs holder\ninterface Dummy {\n}\ninterface ERC165 is Dummy {\n\tfunction supportsInterface(bytes4 interfaceID) external view returns (bool);\n}\n".into());1018					}1019				}1020			}1021			impl #gen_ref ::evm_coder::Call for #call_name #gen_ref {1022				fn parse(method_id: ::evm_coder::types::Bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {1023					use ::evm_coder::abi::AbiRead;1024					match method_id {1025						::evm_coder::ERC165Call::INTERFACE_ID => return Ok(1026							::evm_coder::ERC165Call::parse(method_id, reader)?1027							.map(|c| Self::ERC165Call(c, ::core::marker::PhantomData))1028						),1029						#(1030							#parsers,1031						)*1032						_ => {},1033					}1034					#(1035						#call_parse1036					)else*1037					return Ok(None);1038				}1039			}1040			impl #generics #call_name #gen_ref1041			#gen_where1042			{1043				/// Is this contract implements specified ERC165 selector1044				pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::Bytes4) -> bool {1045					interface_id != u32::to_be_bytes(0xffffff) && (1046						interface_id == ::evm_coder::ERC165Call::INTERFACE_ID ||1047						interface_id == Self::interface_id()1048						#(1049							|| #supports_interface1050						)*1051					)1052				}1053			}1054			impl #generics ::evm_coder::Weighted for #call_name #gen_ref1055			#gen_where1056			{1057				#[allow(unused_variables)]1058				fn weight(&self) -> ::evm_coder::execution::DispatchInfo {1059					match self {1060						#(1061							#weight_variants,1062						)*1063						// TODO: It should be very cheap, but not free1064						Self::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {..}, _) => ::frame_support::weights::Weight::from_ref_time(100).into(),1065						#(1066							#weight_variants_this,1067						)*1068					}1069				}1070			}1071			impl #generics ::evm_coder::Callable<#call_name #gen_ref> for #name1072			#gen_where1073			{1074				#[allow(unreachable_code)] // In case of no inner calls1075				fn call(&mut self, c: Msg<#call_name #gen_ref>) -> ::evm_coder::execution::ResultWithPostInfo<::evm_coder::abi::AbiWriter> {1076					use ::evm_coder::abi::AbiWrite;1077					match c.call {1078						#(1079							#call_variants,1080						)*1081						#call_name::ERC165Call(::evm_coder::ERC165Call::SupportsInterface {interface_id}, _) => {1082							let mut writer = ::evm_coder::abi::AbiWriter::default();1083							writer.bool(&<#call_name #gen_ref>::supports_interface(self, interface_id));1084							return Ok(writer.into());1085						}1086						_ => {},1087					}1088					let mut writer = ::evm_coder::abi::AbiWriter::default();1089					match c.call {1090						#(1091							#call_variants_this,1092						)*1093						_ => Err(::evm_coder::execution::Error::from("method is not available").into()),1094					}1095				}1096			}1097		}1098	}1099}
modifiedcrates/evm-coder/procedural/src/to_log.rsdiffbeforeafterboth
--- a/crates/evm-coder/procedural/src/to_log.rs
+++ b/crates/evm-coder/procedural/src/to_log.rs
@@ -137,7 +137,7 @@
 			Self::#name {#(
 				#fields,
 			)*} => {
-				topics.push(topic::from(Self::#name_screaming));
+				topics.push(::evm_coder::types::Topic::from(Self::#name_screaming));
 				#(
 					topics.push(#indexed.to_topic());
 				)*
@@ -222,7 +222,7 @@
 							#solidity_functions,
 						)*),
 					};
-					let mut out = string::new();
+					let mut out = ::evm_coder::types::String::new();
 					out.push_str("/// @dev inlined interface\n");
 					let _ = interface.format(is_impl, &mut out, tc);
 					tc.collect(out);
@@ -231,7 +231,7 @@
 
 			#[automatically_derived]
 			impl ::evm_coder::events::ToLog for #name {
-				fn to_log(&self, contract: address) -> ::ethereum::Log {
+				fn to_log(&self, contract: Address) -> ::ethereum::Log {
 					use ::evm_coder::events::ToTopic;
 					use ::evm_coder::abi::AbiWrite;
 					let mut writer = ::evm_coder::abi::AbiWriter::new();
modifiedcrates/evm-coder/src/abi/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/impls.rs
+++ b/crates/evm-coder/src/abi/impls.rs
@@ -63,27 +63,27 @@
 impl_abi!(u128, uint128, false);
 impl_abi!(U256, uint256, false);
 impl_abi!(H160, address, false);
-impl_abi!(string, string, true);
+impl_abi!(String, string, true);
 
 impl_abi_writeable!(&str, string);
 
-impl_abi_type!(bytes, bytes, true);
+impl_abi_type!(Bytes, bytes, true);
 
-impl AbiRead for bytes {
-	fn abi_read(reader: &mut AbiReader) -> Result<bytes> {
-		Ok(bytes(reader.bytes()?))
+impl AbiRead for Bytes {
+	fn abi_read(reader: &mut AbiReader) -> Result<Bytes> {
+		Ok(Bytes(reader.bytes()?))
 	}
 }
 
-impl AbiWrite for bytes {
+impl AbiWrite for Bytes {
 	fn abi_write(&self, writer: &mut AbiWriter) {
 		writer.bytes(self.0.as_slice())
 	}
 }
 
-impl_abi_type!(bytes4, bytes4, false);
-impl AbiRead for bytes4 {
-	fn abi_read(reader: &mut AbiReader) -> Result<bytes4> {
+impl_abi_type!(Bytes4, bytes4, false);
+impl AbiRead for Bytes4 {
+	fn abi_read(reader: &mut AbiReader) -> Result<Bytes4> {
 		reader.bytes4()
 	}
 }
modifiedcrates/evm-coder/src/abi/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/mod.rs
+++ b/crates/evm-coder/src/abi/mod.rs
@@ -54,7 +54,7 @@
 		}
 	}
 	/// Start reading RLP buffer, parsing first 4 bytes as selector
-	pub fn new_call(buf: &'i [u8]) -> Result<(bytes4, Self)> {
+	pub fn new_call(buf: &'i [u8]) -> Result<(Bytes4, Self)> {
 		if buf.len() < 4 {
 			return Err(Error::Error(ExitError::OutOfOffset));
 		}
@@ -148,8 +148,8 @@
 	}
 
 	/// Read [`string`] at current position, then advance
-	pub fn string(&mut self) -> Result<string> {
-		string::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))
+	pub fn string(&mut self) -> Result<String> {
+		String::from_utf8(self.bytes()?).map_err(|_| Error::Error(ExitError::InvalidRange))
 	}
 
 	/// Read [`u8`] at current position, then advance
modifiedcrates/evm-coder/src/abi/test.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/abi/test.rs
+++ b/crates/evm-coder/src/abi/test.rs
@@ -39,22 +39,22 @@
 
 #[test]
 fn encode_decode_uint8() {
-	test_impl_uint!(uint8);
+	test_impl_uint!(u8);
 }
 
 #[test]
 fn encode_decode_uint32() {
-	test_impl_uint!(uint32);
+	test_impl_uint!(u32);
 }
 
 #[test]
 fn encode_decode_uint128() {
-	test_impl_uint!(uint128);
+	test_impl_uint!(u128);
 }
 
 #[test]
 fn encode_decode_uint256() {
-	test_impl::<uint256>(
+	test_impl::<U256>(
 		0xdeadbeef,
 		U256([255, 0, 0, 0]),
 		&hex!(
@@ -101,7 +101,7 @@
 
 #[test]
 fn encode_decode_vec_tuple_address_uint256() {
-	test_impl::<Vec<(address, uint256)>>(
+	test_impl::<Vec<(Address, U256)>>(
         0x1ACF2D55,
         vec![
             (
@@ -138,7 +138,7 @@
 
 #[test]
 fn encode_decode_vec_tuple_uint256_string() {
-	test_impl::<Vec<(uint256, string)>>(
+	test_impl::<Vec<(U256, String)>>(
         0xdeadbeef,
         vec![
             (1.into(), "Test URI 0".to_string()),
@@ -261,7 +261,7 @@
 	let (call, mut decoder) = AbiReader::new_call(encoded_data).unwrap();
 	assert_eq!(call, u32::to_be_bytes(decoded_data.0));
 	let address = decoder.address().unwrap();
-	let data = <Vec<(uint256, string)>>::abi_read(&mut decoder).unwrap();
+	let data = <Vec<(U256, String)>>::abi_read(&mut decoder).unwrap();
 	assert_eq!(data, decoded_data.1);
 
 	let mut writer = AbiWriter::new_call(decoded_data.0);
@@ -273,12 +273,12 @@
 
 #[test]
 fn encode_decode_vec_tuple_string_bytes() {
-	test_impl::<Vec<(string, bytes)>>(
+	test_impl::<Vec<(String, Bytes)>>(
 		0xdeadbeef,
 		vec![
 			(
 				"Test URI 0".to_string(),
-				bytes(vec![
+				Bytes(vec![
 					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
 					0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
@@ -287,14 +287,14 @@
 			),
 			(
 				"Test URI 1".to_string(),
-				bytes(vec![
+				Bytes(vec![
 					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 					0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
 				]),
 			),
-			("Test URI 2".to_string(), bytes(vec![0x33, 0x33])),
+			("Test URI 2".to_string(), Bytes(vec![0x33, 0x33])),
 		],
 		&hex!(
 			"
@@ -337,10 +337,10 @@
 // #[ignore = "reason"]
 fn encode_decode_tuple0_tuple1_uint8_tuple1_string_bytes_tuple1_uint8_bytes() {
 	let int = 0xff;
-	let by = bytes(vec![0x11, 0x22, 0x33]);
+	let by = Bytes(vec![0x11, 0x22, 0x33]);
 	let string = "some string".to_string();
 
-	test_impl::<((u8,), (String, bytes), (u8, bytes))>(
+	test_impl::<((u8,), (String, Bytes), (u8, Bytes))>(
 		0xdeadbeef,
 		((int,), (string.clone(), by.clone()), (int, by)),
 		&hex!(
@@ -485,9 +485,9 @@
 
 #[test]
 fn encode_decode_tuple0_tuple1_string_bytes() {
-	test_impl::<((String, bytes),)>(
+	test_impl::<((String, Bytes),)>(
 		0xdeadbeef,
-		(("some string".to_string(), bytes(vec![1, 2, 3])),),
+		(("some string".to_string(), Bytes(vec![1, 2, 3])),),
 		&hex!(
 			"
                 deadbeef
modifiedcrates/evm-coder/src/events.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/events.rs
+++ b/crates/evm-coder/src/events.rs
@@ -15,7 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 use ethereum::Log;
-use primitive_types::{H160, H256};
+use primitive_types::{H160, H256, U256};
 
 use crate::types::*;
 
@@ -45,7 +45,7 @@
 	}
 }
 
-impl ToTopic for uint256 {
+impl ToTopic for U256 {
 	fn to_topic(&self) -> H256 {
 		let mut out = [0u8; 32];
 		self.to_big_endian(&mut out);
@@ -53,7 +53,7 @@
 	}
 }
 
-impl ToTopic for address {
+impl ToTopic for Address {
 	fn to_topic(&self) -> H256 {
 		let mut out = [0u8; 32];
 		out[12..32].copy_from_slice(&self.0);
@@ -61,7 +61,7 @@
 	}
 }
 
-impl ToTopic for uint32 {
+impl ToTopic for u32 {
 	fn to_topic(&self) -> H256 {
 		let mut out = [0u8; 32];
 		out[28..32].copy_from_slice(&self.to_be_bytes());
modifiedcrates/evm-coder/src/lib.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/lib.rs
+++ b/crates/evm-coder/src/lib.rs
@@ -131,33 +131,23 @@
 	use alloc::{vec::Vec};
 	use primitive_types::{U256, H160, H256};
 
-	pub type address = H160;
-	pub type uint8 = u8;
-	pub type uint16 = u16;
-	pub type uint32 = u32;
-	pub type uint64 = u64;
-	pub type uint128 = u128;
-	pub type uint256 = U256;
-	pub type bytes4 = [u8; 4];
-	pub type topic = H256;
+	pub type Address = H160;
+	pub type Bytes4 = [u8; 4];
+	pub type Topic = H256;
 
 	#[cfg(not(feature = "std"))]
-	pub type string = ::alloc::string::String;
+	pub type String = ::alloc::string::String;
 	#[cfg(feature = "std")]
-	pub type string = ::std::string::String;
+	pub type String = ::std::string::String;
 
 	#[derive(Default, Debug, PartialEq, Eq, Clone)]
-	pub struct bytes(pub Vec<u8>);
-
-	/// Solidity doesn't have `void` type, however we have special implementation
-	/// for empty tuple return type
-	pub type void = ();
+	pub struct Bytes(pub Vec<u8>);
 
 	//#region Special types
 	/// Makes function payable
-	pub type value = U256;
+	pub type Value = U256;
 	/// Makes function caller-sensitive
-	pub type caller = address;
+	pub type Caller = Address;
 	//#endregion
 
 	/// Ethereum typed call message, similar to solidity
@@ -172,20 +162,20 @@
 		pub value: U256,
 	}
 
-	impl From<Vec<u8>> for bytes {
+	impl From<Vec<u8>> for Bytes {
 		fn from(src: Vec<u8>) -> Self {
 			Self(src)
 		}
 	}
 
 	#[allow(clippy::from_over_into)]
-	impl Into<Vec<u8>> for bytes {
+	impl Into<Vec<u8>> for Bytes {
 		fn into(self) -> Vec<u8> {
 			self.0
 		}
 	}
 
-	impl bytes {
+	impl Bytes {
 		#[must_use]
 		pub fn len(&self) -> usize {
 			self.0.len()
@@ -201,7 +191,7 @@
 /// Parseable EVM call, this trait should be implemented with [`solidity_interface`] macro
 pub trait Call: Sized {
 	/// Parse call buffer into typed call enum
-	fn parse(selector: types::bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>>;
+	fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>>;
 }
 
 /// Intended to be used as `#[weight]` output type
@@ -237,22 +227,22 @@
 	/// implements specified interface
 	SupportsInterface {
 		/// Requested interface
-		interface_id: types::bytes4,
+		interface_id: types::Bytes4,
 	},
 }
 
 impl ERC165Call {
 	/// ERC165 selector is provided by standard
-	pub const INTERFACE_ID: types::bytes4 = u32::to_be_bytes(0x01ffc9a7);
+	pub const INTERFACE_ID: types::Bytes4 = u32::to_be_bytes(0x01ffc9a7);
 }
 
 impl Call for ERC165Call {
-	fn parse(selector: types::bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>> {
+	fn parse(selector: types::Bytes4, input: &mut AbiReader) -> execution::Result<Option<Self>> {
 		if selector != Self::INTERFACE_ID {
 			return Ok(None);
 		}
 		Ok(Some(Self::SupportsInterface {
-			interface_id: types::bytes4::abi_read(input)?,
+			interface_id: types::Bytes4::abi_read(input)?,
 		}))
 	}
 }
modifiedcrates/evm-coder/src/solidity/impls.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/impls.rs
+++ b/crates/evm-coder/src/solidity/impls.rs
@@ -27,14 +27,14 @@
 	u64 => "uint64" true = "0",
 	u128 => "uint128" true = "0",
 	U256 => "uint256" true = "0",
-	bytes4 => "bytes4" true = "bytes4(0)",
+	Bytes4 => "bytes4" true = "bytes4(0)",
 	H160 => "address" true = "0x0000000000000000000000000000000000000000",
-	string => "string" false = "\"\"",
-	bytes => "bytes" false = "hex\"\"",
+	String => "string" false = "\"\"",
+	Bytes => "bytes" false = "hex\"\"",
 	bool => "bool" true = "false",
 }
 
-impl SolidityTypeName for void {
+impl SolidityTypeName for () {
 	fn solidity_name(_writer: &mut impl fmt::Write, _tc: &TypeCollector) -> fmt::Result {
 		Ok(())
 	}
@@ -72,10 +72,10 @@
 macro_rules! impl_tuples {
 	($($ident:ident)+) => {
 		impl<$($ident: SolidityTypeName + 'static),+> SolidityTupleTy for ($($ident,)+) {
-			fn fields(tc: &TypeCollector) -> Vec<string> {
+			fn fields(tc: &TypeCollector) -> Vec<String> {
 				let mut collected = Vec::with_capacity(Self::len());
 				$({
-					let mut out = string::new();
+					let mut out = String::new();
 					$ident::solidity_name(&mut out, tc).expect("no fmt error");
 					collected.push(out);
 				})*;
modifiedcrates/evm-coder/src/solidity/mod.rsdiffbeforeafterboth
--- a/crates/evm-coder/src/solidity/mod.rs
+++ b/crates/evm-coder/src/solidity/mod.rs
@@ -26,7 +26,7 @@
 mod impls;
 
 #[cfg(not(feature = "std"))]
-use alloc::{string::String, vec::Vec, collections::BTreeMap, format};
+use alloc::{vec::Vec, collections::BTreeMap, format};
 #[cfg(feature = "std")]
 use std::collections::BTreeMap;
 use core::{
@@ -42,16 +42,16 @@
 pub struct TypeCollector {
 	/// Code => id
 	/// 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>>,
+	structs: RefCell<BTreeMap<String, usize>>,
+	anonymous: RefCell<BTreeMap<Vec<String>, usize>>,
+	// generic: RefCell<BTreeMap<String, usize>>,
 	id: Cell<usize>,
 }
 impl TypeCollector {
 	pub fn new() -> Self {
 		Self::default()
 	}
-	pub fn collect(&self, item: string) {
+	pub fn collect(&self, item: String) {
 		let id = self.next_id();
 		self.structs.borrow_mut().insert(item, id);
 	}
@@ -84,7 +84,7 @@
 	pub fn collect_enum<T: SolidityEnumTy>(&self) -> String {
 		T::generate_solidity_interface(self)
 	}
-	pub fn finish(self) -> Vec<string> {
+	pub fn finish(self) -> Vec<String> {
 		let mut data = self.structs.into_inner().into_iter().collect::<Vec<_>>();
 		data.sort_by_key(|(_, id)| Reverse(*id));
 		data.into_iter().map(|(code, _)| code).collect()
@@ -360,7 +360,7 @@
 
 pub struct SolidityInterface<F: SolidityFunctions> {
 	pub docs: &'static [&'static str],
-	pub selector: bytes4,
+	pub selector: Bytes4,
 	pub name: &'static str,
 	pub is: &'static [&'static str],
 	pub functions: F,
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,6 +1,6 @@
 mod test_struct {
 	use evm_coder_procedural::AbiCoder;
-	use evm_coder::types::bytes;
+	use evm_coder::types::Bytes;
 
 	#[test]
 	fn empty_struct() {
@@ -27,13 +27,13 @@
 	#[derive(AbiCoder, PartialEq, Debug)]
 	struct TypeStruct2DynamicParam {
 		_a: String,
-		_b: bytes,
+		_b: Bytes,
 	}
 
 	#[derive(AbiCoder, PartialEq, Debug)]
 	struct TypeStruct2MixedParam {
 		_a: u8,
-		_b: bytes,
+		_b: Bytes,
 	}
 
 	#[derive(AbiCoder, PartialEq, Debug)]
@@ -236,10 +236,10 @@
 	struct TupleStruct2SimpleParam(u8, u32);
 
 	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2DynamicParam(String, bytes);
+	struct TupleStruct2DynamicParam(String, Bytes);
 
 	#[derive(AbiCoder, PartialEq, Debug)]
-	struct TupleStruct2MixedParam(u8, bytes);
+	struct TupleStruct2MixedParam(u8, Bytes);
 
 	#[derive(AbiCoder, PartialEq, Debug)]
 	struct TupleStruct1DerivedSimpleParam(TupleStruct1SimpleParam);
@@ -562,8 +562,8 @@
 	#[test]
 	fn codec_struct_2_dynamic() {
 		let _a: String = "some string".into();
-		let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
-		test_impl::<(String, bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
+		let _b: Bytes = Bytes(vec![0x11, 0x22, 0x33]);
+		test_impl::<(String, Bytes), TupleStruct2DynamicParam, TypeStruct2DynamicParam>(
 			(_a.clone(), _b.clone()),
 			TupleStruct2DynamicParam(_a.clone(), _b.clone()),
 			TypeStruct2DynamicParam { _a, _b },
@@ -573,8 +573,8 @@
 	#[test]
 	fn codec_struct_2_mixed() {
 		let _a: u8 = 0xff;
-		let _b: bytes = bytes(vec![0x11, 0x22, 0x33]);
-		test_impl::<(u8, bytes), TupleStruct2MixedParam, TypeStruct2MixedParam>(
+		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 },
@@ -605,9 +605,9 @@
 	#[test]
 	fn codec_struct_2_derived_dynamic() {
 		let _a = "some string".to_string();
-		let _b = bytes(vec![0x11, 0x22, 0x33]);
+		let _b = Bytes(vec![0x11, 0x22, 0x33]);
 		test_impl::<
-			((String,), (String, bytes)),
+			((String,), (String, Bytes)),
 			TupleStruct2DerivedDynamicParam,
 			TypeStruct2DerivedDynamicParam,
 		>(
@@ -626,10 +626,10 @@
 	#[test]
 	fn codec_struct_3_derived_mixed() {
 		let int = 0xff;
-		let by = bytes(vec![0x11, 0x22, 0x33]);
+		let by = Bytes(vec![0x11, 0x22, 0x33]);
 		let string = "some string".to_string();
 		test_impl::<
-			((u8,), (String, bytes), (u8, bytes)),
+			((u8,), (String, Bytes), (u8, Bytes)),
 			TupleStruct3DerivedMixedParam,
 			TypeStruct3DerivedMixedParam,
 		>(
modifiedcrates/evm-coder/tests/conditional_is.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/conditional_is.rs
+++ b/crates/evm-coder/tests/conditional_is.rs
@@ -4,14 +4,14 @@
 
 #[solidity_interface(name = A)]
 impl Contract {
-	fn method_a() -> Result<void> {
+	fn method_a() -> Result<()> {
 		Ok(())
 	}
 }
 
 #[solidity_interface(name = B)]
 impl Contract {
-	fn method_b() -> Result<void> {
+	fn method_b() -> Result<()> {
 		Ok(())
 	}
 }
modifiedcrates/evm-coder/tests/generics.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/generics.rs
+++ b/crates/evm-coder/tests/generics.rs
@@ -16,19 +16,20 @@
 
 use std::marker::PhantomData;
 use evm_coder::{execution::Result, generate_stubgen, solidity_interface, types::*};
+use primitive_types::U256;
 
 pub struct Generic<T>(PhantomData<T>);
 
 #[solidity_interface(name = GenericIs)]
 impl<T> Generic<T> {
-	fn test_1(&self) -> Result<uint256> {
+	fn test_1(&self) -> Result<U256> {
 		unreachable!()
 	}
 }
 
 #[solidity_interface(name = Generic, is(GenericIs))]
 impl<T: Into<u32>> Generic<T> {
-	fn test_2(&self) -> Result<uint256> {
+	fn test_2(&self) -> Result<U256> {
 		unreachable!()
 	}
 }
@@ -40,7 +41,7 @@
 where
 	T: core::fmt::Debug,
 {
-	fn test_3(&self) -> Result<uint256> {
+	fn test_3(&self) -> Result<U256> {
 		unreachable!()
 	}
 }
modifiedcrates/evm-coder/tests/log.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/log.rs
+++ b/crates/evm-coder/tests/log.rs
@@ -17,19 +17,20 @@
 #![allow(dead_code)]
 
 use evm_coder::{ToLog, types::*};
+use primitive_types::U256;
 
 #[derive(ToLog)]
 enum ERC721Log {
 	Transfer {
 		#[indexed]
-		from: address,
+		from: Address,
 		#[indexed]
-		to: address,
-		value: uint256,
+		to: Address,
+		value: U256,
 	},
 	Eee {
 		#[indexed]
-		aaa: address,
-		bbb: uint256,
+		aaa: Address,
+		bbb: U256,
 	},
 }
modifiedcrates/evm-coder/tests/random.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/random.rs
+++ b/crates/evm-coder/tests/random.rs
@@ -19,19 +19,20 @@
 use evm_coder::{
 	abi::AbiType, ToLog, execution::Result, solidity_interface, types::*, solidity, weight,
 };
+use primitive_types::U256;
 
 pub struct Impls;
 
 #[solidity_interface(name = OurInterface)]
 impl Impls {
-	fn fn_a(&self, _input: uint256) -> Result<bool> {
+	fn fn_a(&self, _input: U256) -> Result<bool> {
 		unreachable!()
 	}
 }
 
 #[solidity_interface(name = OurInterface1)]
 impl Impls {
-	fn fn_b(&self, _input: uint128) -> Result<uint32> {
+	fn fn_b(&self, _input: u128) -> Result<u32> {
 		unreachable!()
 	}
 }
@@ -39,12 +40,12 @@
 #[derive(ToLog)]
 enum OurEvents {
 	Event1 {
-		field1: uint32,
+		field1: u32,
 	},
 	Event2 {
-		field1: uint32,
+		field1: u32,
 		#[indexed]
-		field2: uint32,
+		field2: u32,
 	},
 }
 
@@ -56,27 +57,27 @@
 )]
 impl Impls {
 	#[solidity(rename_selector = "fnK")]
-	fn fn_c(&self, _input: uint32) -> Result<uint8> {
+	fn fn_c(&self, _input: u32) -> Result<u8> {
 		unreachable!()
 	}
-	fn fn_d(&self, _value: uint32) -> Result<uint32> {
+	fn fn_d(&self, _value: u32) -> Result<u32> {
 		unreachable!()
 	}
 
-	fn caller_sensitive(&self, _caller: caller) -> Result<uint8> {
+	fn caller_sensitive(&self, _caller: Caller) -> Result<u8> {
 		unreachable!()
 	}
-	fn payable(&mut self, _value: value) -> Result<uint8> {
+	fn payable(&mut self, _value: Value) -> Result<u8> {
 		unreachable!()
 	}
 
 	#[weight(*_weight)]
-	fn with_weight(&self, _weight: uint64) -> Result<void> {
+	fn with_weight(&self, _weight: u64) -> Result<()> {
 		unreachable!()
 	}
 
 	/// Doccoment example
-	fn with_doc(&self) -> Result<void> {
+	fn with_doc(&self) -> Result<()> {
 		unreachable!()
 	}
 }
modifiedcrates/evm-coder/tests/solidity_generation.rsdiffbeforeafterboth
--- a/crates/evm-coder/tests/solidity_generation.rs
+++ b/crates/evm-coder/tests/solidity_generation.rs
@@ -15,34 +15,35 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 use evm_coder::{abi::AbiType, execution::Result, generate_stubgen, solidity_interface, types::*};
+use primitive_types::U256;
 
 pub struct ERC20;
 
 #[solidity_interface(name = ERC20)]
 impl ERC20 {
-	fn decimals(&self) -> Result<uint8> {
+	fn decimals(&self) -> Result<u8> {
 		unreachable!()
 	}
 	/// Get balance of specified owner
-	fn balance_of(&self, _owner: address) -> Result<uint256> {
+	fn balance_of(&self, _owner: Address) -> Result<U256> {
 		unreachable!()
 	}
-	fn transfer(&mut self, _caller: caller, _to: address, _value: uint256) -> Result<bool> {
+	fn transfer(&mut self, _caller: Caller, _to: Address, _value: U256) -> Result<bool> {
 		unreachable!()
 	}
 	fn transfer_from(
 		&mut self,
-		_caller: caller,
-		_from: address,
-		_to: address,
-		_value: uint256,
+		_caller: Caller,
+		_from: Address,
+		_to: Address,
+		_value: U256,
 	) -> Result<bool> {
 		unreachable!()
 	}
-	fn approve(&mut self, _caller: caller, _spender: address, _value: uint256) -> Result<bool> {
+	fn approve(&mut self, _caller: Caller, _spender: Address, _value: U256) -> Result<bool> {
 		unreachable!()
 	}
-	fn allowance(&self, _owner: address, _spender: address) -> Result<uint256> {
+	fn allowance(&self, _owner: Address, _spender: Address) -> Result<U256> {
 		unreachable!()
 	}
 }
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -26,6 +26,7 @@
 };
 use pallet_evm_coder_substrate::dispatch_to_evm;
 use sp_std::{vec, vec::Vec};
+use sp_core::U256;
 use up_data_structs::{
 	AccessMode, CollectionMode, CollectionPermissions, OwnerRestrictedSet, Property,
 	SponsoringRateLimit, SponsorshipState,
@@ -42,32 +43,32 @@
 	CollectionCreated {
 		/// Collection owner.
 		#[indexed]
-		owner: address,
+		owner: Address,
 
 		/// Collection ID.
 		#[indexed]
-		collection_id: address,
+		collection_id: Address,
 	},
 	/// The collection has been destroyed.
 	CollectionDestroyed {
 		/// Collection ID.
 		#[indexed]
-		collection_id: address,
+		collection_id: Address,
 	},
 	/// The collection has been changed.
 	CollectionChanged {
 		/// Collection ID.
 		#[indexed]
-		collection_id: address,
+		collection_id: Address,
 	},
 
 	/// The token has been changed.
 	TokenChanged {
 		/// Collection ID.
 		#[indexed]
-		collection_id: address,
+		collection_id: Address,
 		/// Token ID.
-		token_id: uint256,
+		token_id: U256,
 	},
 }
 
@@ -93,12 +94,7 @@
 	/// @param value Propery value.
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::set_collection_properties(1))]
-	fn set_collection_property(
-		&mut self,
-		caller: caller,
-		key: string,
-		value: bytes,
-	) -> Result<void> {
+	fn set_collection_property(&mut self, caller: Caller, key: String, value: Bytes) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let key = <Vec<u8>>::from(key)
 			.try_into()
@@ -115,9 +111,9 @@
 	#[weight(<SelfWeightOf<T>>::set_collection_properties(properties.len() as u32))]
 	fn set_collection_properties(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		properties: Vec<eth::Property>,
-	) -> Result<void> {
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 
 		let properties = properties
@@ -134,7 +130,7 @@
 	/// @param key Property key.
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::delete_collection_properties(1))]
-	fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> {
+	fn delete_collection_property(&mut self, caller: Caller, key: String) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let key = <Vec<u8>>::from(key)
 			.try_into()
@@ -147,7 +143,7 @@
 	///
 	/// @param keys Properties keys.
 	#[weight(<SelfWeightOf<T>>::delete_collection_properties(keys.len() as u32))]
-	fn delete_collection_properties(&mut self, caller: caller, keys: Vec<string>) -> Result<()> {
+	fn delete_collection_properties(&mut self, caller: Caller, keys: Vec<String>) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let keys = keys
 			.into_iter()
@@ -168,7 +164,7 @@
 	///
 	/// @param key Property key.
 	/// @return bytes The property corresponding to the key.
-	fn collection_property(&self, key: string) -> Result<bytes> {
+	fn collection_property(&self, key: String) -> Result<Bytes> {
 		let key = <Vec<u8>>::from(key)
 			.try_into()
 			.map_err(|_| "key too large")?;
@@ -176,14 +172,14 @@
 		let props = CollectionProperties::<T>::get(self.id);
 		let prop = props.get(&key).ok_or("key not found")?;
 
-		Ok(bytes(prop.to_vec()))
+		Ok(Bytes(prop.to_vec()))
 	}
 
 	/// Get collection properties.
 	///
 	/// @param keys Properties keys. Empty keys for all propertyes.
 	/// @return Vector of properties key/value pairs.
-	fn collection_properties(&self, keys: Vec<string>) -> Result<Vec<eth::Property>> {
+	fn collection_properties(&self, keys: Vec<String>) -> Result<Vec<eth::Property>> {
 		let keys = keys
 			.into_iter()
 			.map(|key| {
@@ -212,7 +208,7 @@
 	///
 	/// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract.
 	#[solidity(hide)]
-	fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result<void> {
+	fn set_collection_sponsor(&mut self, caller: Caller, sponsor: Address) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -229,9 +225,9 @@
 	/// @param sponsor Cross account address of the sponsor from whose account funds will be debited for operations with the contract.
 	fn set_collection_sponsor_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		sponsor: eth::CrossAddress,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -252,7 +248,7 @@
 	/// Collection sponsorship confirmation.
 	///
 	/// @dev After setting the sponsor for the collection, it must be confirmed with this function.
-	fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result<void> {
+	fn confirm_collection_sponsorship(&mut self, caller: Caller) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -261,7 +257,7 @@
 	}
 
 	/// Remove collection sponsor.
-	fn remove_collection_sponsor(&mut self, caller: caller) -> Result<void> {
+	fn remove_collection_sponsor(&mut self, caller: Caller) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 		let caller = T::CrossAccountId::from_eth(caller);
 		self.remove_sponsor(&caller).map_err(dispatch_to_evm::<T>)
@@ -343,11 +339,7 @@
 	/// @dev Throws error if limit not found.
 	/// @param limit Some limit.
 	#[solidity(rename_selector = "setCollectionLimit")]
-	fn set_collection_limit(
-		&mut self,
-		caller: caller,
-		limit: eth::CollectionLimit,
-	) -> Result<void> {
+	fn set_collection_limit(&mut self, caller: Caller, limit: eth::CollectionLimit) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		if !limit.has_value() {
@@ -359,7 +351,7 @@
 	}
 
 	/// Get contract address.
-	fn contract_address(&self) -> Result<address> {
+	fn contract_address(&self) -> Result<Address> {
 		Ok(crate::eth::collection_id_to_address(self.id))
 	}
 
@@ -367,9 +359,9 @@
 	/// @param newAdmin Cross account administrator address.
 	fn add_collection_admin_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		new_admin: eth::CrossAddress,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.consume_store_reads_and_writes(2, 2)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -382,9 +374,9 @@
 	/// @param admin Cross account administrator address.
 	fn remove_collection_admin_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		admin: eth::CrossAddress,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.consume_store_reads_and_writes(2, 2)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -396,7 +388,7 @@
 	/// Add collection admin.
 	/// @param newAdmin Address of the added administrator.
 	#[solidity(hide)]
-	fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result<void> {
+	fn add_collection_admin(&mut self, caller: Caller, new_admin: Address) -> Result<()> {
 		self.consume_store_reads_and_writes(2, 2)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -409,7 +401,7 @@
 	///
 	/// @param admin Address of the removed administrator.
 	#[solidity(hide)]
-	fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result<void> {
+	fn remove_collection_admin(&mut self, caller: Caller, admin: Address) -> Result<()> {
 		self.consume_store_reads_and_writes(2, 2)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -422,7 +414,7 @@
 	///
 	/// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled'
 	#[solidity(rename_selector = "setCollectionNesting")]
-	fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result<void> {
+	fn set_nesting_bool(&mut self, caller: Caller, enable: bool) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -443,10 +435,10 @@
 	#[solidity(rename_selector = "setCollectionNesting")]
 	fn set_nesting(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		enable: bool,
-		collections: Vec<address>,
-	) -> Result<void> {
+		collections: Vec<Address>,
+	) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		if collections.is_empty() {
@@ -511,18 +503,12 @@
 	}
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
-	fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result<void> {
+	fn set_collection_access(&mut self, caller: Caller, mode: eth::AccessMode) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
 		let permissions = CollectionPermissions {
-			access: Some(match mode {
-				0 => AccessMode::Normal,
-				1 => AccessMode::AllowList,
-				_ => return Err("not supported access mode".into()),
-			}),
+			access: Some(mode.into()),
 			..Default::default()
 		};
 		<Pallet<T>>::update_permissions(&caller, self, permissions).map_err(dispatch_to_evm::<T>)
@@ -540,7 +526,7 @@
 	///
 	/// @param user Address of a trusted user.
 	#[solidity(hide)]
-	fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
+	fn add_to_collection_allow_list(&mut self, caller: Caller, user: Address) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -554,9 +540,9 @@
 	/// @param user User cross account address.
 	fn add_to_collection_allow_list_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		user: eth::CrossAddress,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -569,7 +555,7 @@
 	///
 	/// @param user Address of a removed user.
 	#[solidity(hide)]
-	fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result<void> {
+	fn remove_from_collection_allow_list(&mut self, caller: Caller, user: Address) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -583,9 +569,9 @@
 	/// @param user User cross account address.
 	fn remove_from_collection_allow_list_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		user: eth::CrossAddress,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -597,7 +583,7 @@
 	/// Switch permission for minting.
 	///
 	/// @param mode Enable if "true".
-	fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result<void> {
+	fn set_collection_mint_mode(&mut self, caller: Caller, mode: bool) -> Result<()> {
 		self.consume_store_reads_and_writes(1, 1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -613,7 +599,7 @@
 	/// @param user account to verify
 	/// @return "true" if account is the owner or admin
 	#[solidity(hide, rename_selector = "isOwnerOrAdmin")]
-	fn is_owner_or_admin_eth(&self, user: address) -> Result<bool> {
+	fn is_owner_or_admin_eth(&self, user: Address) -> Result<bool> {
 		let user = T::CrossAccountId::from_eth(user);
 		Ok(self.is_owner_or_admin(&user))
 	}
@@ -630,7 +616,7 @@
 	/// Returns collection type
 	///
 	/// @return `Fungible` or `NFT` or `ReFungible`
-	fn unique_collection_type(&self) -> Result<string> {
+	fn unique_collection_type(&self) -> Result<String> {
 		let mode = match self.collection.mode {
 			CollectionMode::Fungible(_) => "Fungible",
 			CollectionMode::NFT => "NFT",
@@ -654,7 +640,7 @@
 	/// @dev Owner can be changed only by current owner
 	/// @param newOwner new owner account
 	#[solidity(hide, rename_selector = "changeCollectionOwner")]
-	fn set_owner(&mut self, caller: caller, new_owner: address) -> Result<void> {
+	fn set_owner(&mut self, caller: Caller, new_owner: Address) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -680,9 +666,9 @@
 	/// @param newOwner new owner cross account
 	fn change_collection_owner_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		new_owner: eth::CrossAddress,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.consume_store_writes(1)?;
 
 		let caller = T::CrossAccountId::from_eth(caller);
modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -18,12 +18,9 @@
 
 use alloc::format;
 use sp_std::{vec, vec::Vec};
-use evm_coder::{
-	AbiCoder,
-	types::{uint256, address},
-};
+use evm_coder::{AbiCoder, types::Address};
 pub use pallet_evm::{Config, account::CrossAccountId};
-use sp_core::H160;
+use sp_core::{H160, U256};
 use up_data_structs::CollectionId;
 
 // 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection 1
@@ -33,7 +30,7 @@
 ];
 
 /// Maps the ethereum address of the collection in substrate.
-pub fn map_eth_to_id(eth: &H160) -> Option<CollectionId> {
+pub fn map_eth_to_id(eth: &Address) -> Option<CollectionId> {
 	if eth[0..16] != ETH_COLLECTION_PREFIX {
 		return None;
 	}
@@ -43,7 +40,7 @@
 }
 
 /// Maps the substrate collection id in ethereum.
-pub fn collection_id_to_address(id: CollectionId) -> H160 {
+pub fn collection_id_to_address(id: CollectionId) -> Address {
 	let mut out = [0; 20];
 	out[0..16].copy_from_slice(&ETH_COLLECTION_PREFIX);
 	out[16..20].copy_from_slice(&u32::to_be_bytes(id.0));
@@ -51,12 +48,12 @@
 }
 
 /// Check if the ethereum address is a collection.
-pub fn is_collection(address: &H160) -> bool {
+pub fn is_collection(address: &Address) -> bool {
 	address[0..16] == ETH_COLLECTION_PREFIX
 }
 
-/// Convert `uint256` to `CrossAccountId`.
-pub fn convert_uint256_to_cross_account<T: Config>(from: uint256) -> T::CrossAccountId
+/// Convert `U256` to `CrossAccountId`.
+pub fn convert_uint256_to_cross_account<T: Config>(from: U256) -> T::CrossAccountId
 where
 	T::AccountId: From<[u8; 32]>,
 {
@@ -69,8 +66,8 @@
 /// Cross account struct
 #[derive(Debug, Default, AbiCoder)]
 pub struct CrossAddress {
-	pub(crate) eth: address,
-	pub(crate) sub: uint256,
+	pub(crate) eth: Address,
+	pub(crate) sub: U256,
 }
 
 impl CrossAddress {
@@ -97,7 +94,7 @@
 	{
 		Self {
 			eth: Default::default(),
-			sub: uint256::from_big_endian(account_id.as_ref()),
+			sub: U256::from_big_endian(account_id.as_ref()),
 		}
 	}
 	/// Converts [`CrossAddress`] to `CrossAccountId`.
@@ -121,17 +118,17 @@
 /// Ethereum representation of collection [`PropertyKey`](up_data_structs::PropertyKey) and [`PropertyValue`](up_data_structs::PropertyValue).
 #[derive(Debug, Default, AbiCoder)]
 pub struct Property {
-	key: evm_coder::types::string,
-	value: evm_coder::types::bytes,
+	key: evm_coder::types::String,
+	value: evm_coder::types::Bytes,
 }
 
 impl TryFrom<up_data_structs::Property> for Property {
 	type Error = evm_coder::execution::Error;
 
 	fn try_from(from: up_data_structs::Property) -> Result<Self, Self::Error> {
-		let key = evm_coder::types::string::from_utf8(from.key.into())
+		let key = evm_coder::types::String::from_utf8(from.key.into())
 			.map_err(|e| Self::Error::Revert(format!("utf8 conversion error: {}", e)))?;
-		let value = evm_coder::types::bytes(from.value.to_vec());
+		let value = evm_coder::types::Bytes(from.value.to_vec());
 		Ok(Property { key, value })
 	}
 }
@@ -187,7 +184,7 @@
 #[derive(Debug, Default, AbiCoder)]
 pub struct CollectionLimit {
 	field: CollectionLimitField,
-	value: Option<uint256>,
+	value: Option<U256>,
 }
 
 impl CollectionLimit {
@@ -345,7 +342,7 @@
 #[derive(Debug, Default, AbiCoder)]
 pub struct TokenPropertyPermission {
 	/// Token property key.
-	key: evm_coder::types::string,
+	key: evm_coder::types::String,
 	/// Token property permissions.
 	permissions: Vec<PropertyPermission>,
 }
@@ -363,7 +360,7 @@
 		),
 	) -> Self {
 		let (key, permission) = value;
-		let key = evm_coder::types::string::from_utf8(key.into_inner())
+		let key = evm_coder::types::String::from_utf8(key.into_inner())
 			.expect("Stored key must be valid");
 		let permissions = PropertyPermission::into_vec(permission);
 		Self { key, permissions }
@@ -393,12 +390,12 @@
 #[derive(Debug, Default, AbiCoder)]
 pub struct CollectionNesting {
 	token_owner: bool,
-	ids: Vec<uint256>,
+	ids: Vec<U256>,
 }
 
 impl CollectionNesting {
 	/// Create [`CollectionNesting`].
-	pub fn new(token_owner: bool, ids: Vec<uint256>) -> Self {
+	pub fn new(token_owner: bool, ids: Vec<U256>) -> Self {
 		Self { token_owner, ids }
 	}
 }
@@ -416,3 +413,32 @@
 		Self { field, value }
 	}
 }
+
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+#[derive(AbiCoder, Copy, Clone, Default, Debug)]
+#[repr(u8)]
+pub enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	#[default]
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList,
+}
+
+impl From<up_data_structs::AccessMode> for AccessMode {
+	fn from(value: up_data_structs::AccessMode) -> Self {
+		match value {
+			up_data_structs::AccessMode::Normal => AccessMode::Normal,
+			up_data_structs::AccessMode::AllowList => AccessMode::AllowList,
+		}
+	}
+}
+
+impl Into<up_data_structs::AccessMode> for AccessMode {
+	fn into(self) -> up_data_structs::AccessMode {
+		match self {
+			AccessMode::Normal => up_data_structs::AccessMode::Normal,
+			AccessMode::AllowList => up_data_structs::AccessMode::AllowList,
+		}
+	}
+}
modifiedpallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-coder-substrate/src/lib.rs
+++ b/pallets/evm-coder-substrate/src/lib.rs
@@ -41,7 +41,7 @@
 use evm_coder::{
 	abi::{AbiReader, AbiWrite, AbiWriter},
 	execution,
-	types::{Msg, value},
+	types::{Msg, Value},
 };
 
 pub use pallet::*;
@@ -256,7 +256,7 @@
 >(
 	caller: H160,
 	e: &mut E,
-	value: value,
+	value: Value,
 	input: &[u8],
 ) -> execution::Result<Option<AbiWriter>> {
 	let (selector, mut reader) = AbiReader::new_call(input)?;
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -49,25 +49,25 @@
 	ContractSponsorSet {
 		/// Contract address of the affected collection.
 		#[indexed]
-		contract_address: address,
+		contract_address: Address,
 		/// New sponsor address.
-		sponsor: address,
+		sponsor: Address,
 	},
 
 	/// New sponsor was confirm.
 	ContractSponsorshipConfirmed {
 		/// Contract address of the affected collection.
 		#[indexed]
-		contract_address: address,
+		contract_address: Address,
 		/// New sponsor address.
-		sponsor: address,
+		sponsor: Address,
 	},
 
 	/// Collection sponsor was removed.
 	ContractSponsorRemoved {
 		/// Contract address of the affected collection.
 		#[indexed]
-		contract_address: address,
+		contract_address: Address,
 	},
 }
 
@@ -96,7 +96,7 @@
 	/// @dev Returns zero address if contract does not exists
 	/// @param contractAddress Contract to get owner of
 	/// @return address Owner of contract
-	fn contract_owner(&self, contract_address: address) -> Result<address> {
+	fn contract_owner(&self, contract_address: Address) -> Result<Address> {
 		Ok(<Owner<T>>::get(contract_address))
 	}
 
@@ -105,10 +105,10 @@
 	/// @param sponsor User address who set as pending sponsor.
 	fn set_sponsor(
 		&mut self,
-		caller: caller,
-		contract_address: address,
-		sponsor: address,
-	) -> Result<void> {
+		caller: Caller,
+		contract_address: Address,
+		sponsor: Address,
+	) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -125,7 +125,7 @@
 	/// Set contract as self sponsored.
 	///
 	/// @param contractAddress Contract for which a self sponsoring is being enabled.
-	fn self_sponsored_enable(&mut self, caller: caller, contract_address: address) -> Result<void> {
+	fn self_sponsored_enable(&mut self, caller: Caller, contract_address: Address) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -146,7 +146,7 @@
 	/// Remove sponsor.
 	///
 	/// @param contractAddress Contract for which a sponsorship is being removed.
-	fn remove_sponsor(&mut self, caller: caller, contract_address: address) -> Result<void> {
+	fn remove_sponsor(&mut self, caller: Caller, contract_address: Address) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -161,7 +161,7 @@
 	/// @dev Caller must be same that set via [`setSponsor`].
 	///
 	/// @param contractAddress Сontract for which need to confirm sponsorship.
-	fn confirm_sponsorship(&mut self, caller: caller, contract_address: address) -> Result<void> {
+	fn confirm_sponsorship(&mut self, caller: Caller, contract_address: Address) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -175,7 +175,7 @@
 	///
 	/// @param contractAddress The contract for which a sponsor is requested.
 	/// @return Tuble with sponsor address and his substrate mirror. If there is no confirmed sponsor error "Contract has no sponsor" throw.
-	fn sponsor(&self, contract_address: address) -> Result<Option<eth::CrossAddress>> {
+	fn sponsor(&self, contract_address: Address) -> Result<Option<eth::CrossAddress>> {
 		Ok(match Pallet::<T>::get_sponsor(contract_address) {
 			Some(ref value) => Some(eth::CrossAddress::from_sub_cross_account::<T>(value)),
 			None => None,
@@ -186,7 +186,7 @@
 	///
 	/// @param contractAddress The contract for which the presence of a confirmed sponsor is checked.
 	/// @return **true** if contract has confirmed sponsor.
-	fn has_sponsor(&self, contract_address: address) -> Result<bool> {
+	fn has_sponsor(&self, contract_address: Address) -> Result<bool> {
 		Ok(Pallet::<T>::get_sponsor(contract_address).is_some())
 	}
 
@@ -194,23 +194,23 @@
 	///
 	/// @param contractAddress The contract for which the presence of a pending sponsor is checked.
 	/// @return **true** if contract has pending sponsor.
-	fn has_pending_sponsor(&self, contract_address: address) -> Result<bool> {
+	fn has_pending_sponsor(&self, contract_address: Address) -> Result<bool> {
 		Ok(match Sponsoring::<T>::get(contract_address) {
 			SponsorshipState::Disabled | SponsorshipState::Confirmed(_) => false,
 			SponsorshipState::Unconfirmed(_) => true,
 		})
 	}
 
-	fn sponsoring_enabled(&self, contract_address: address) -> Result<bool> {
+	fn sponsoring_enabled(&self, contract_address: Address) -> Result<bool> {
 		Ok(<Pallet<T>>::sponsoring_mode(contract_address) != SponsoringModeT::Disabled)
 	}
 
 	fn set_sponsoring_mode(
 		&mut self,
-		caller: caller,
-		contract_address: address,
+		caller: Caller,
+		contract_address: Address,
 		mode: SponsoringModeT,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -223,7 +223,7 @@
 	/// Get current contract sponsoring rate limit
 	/// @param contractAddress Contract to get sponsoring rate limit of
 	/// @return uint32 Amount of blocks between two sponsored transactions
-	fn sponsoring_rate_limit(&self, contract_address: address) -> Result<uint32> {
+	fn sponsoring_rate_limit(&self, contract_address: Address) -> Result<u32> {
 		self.recorder().consume_sload()?;
 
 		Ok(<SponsoringRateLimit<T>>::get(contract_address)
@@ -239,10 +239,10 @@
 	/// @dev Only contract owner can change this setting
 	fn set_sponsoring_rate_limit(
 		&mut self,
-		caller: caller,
-		contract_address: address,
-		rate_limit: uint32,
-	) -> Result<void> {
+		caller: Caller,
+		contract_address: Address,
+		rate_limit: u32,
+	) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -259,10 +259,10 @@
 	/// @dev Only contract owner can change this setting
 	fn set_sponsoring_fee_limit(
 		&mut self,
-		caller: caller,
-		contract_address: address,
-		fee_limit: uint256,
-	) -> Result<void> {
+		caller: Caller,
+		contract_address: Address,
+		fee_limit: U256,
+	) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -276,7 +276,7 @@
 	/// @param contractAddress Contract to get sponsoring fee limit of
 	/// @return uint256 Maximum amount of fee that could be spent by single
 	///  transaction
-	fn sponsoring_fee_limit(&self, contract_address: address) -> Result<uint256> {
+	fn sponsoring_fee_limit(&self, contract_address: Address) -> Result<U256> {
 		self.recorder().consume_sload()?;
 
 		Ok(get_sponsoring_fee_limit::<T>(contract_address))
@@ -287,7 +287,7 @@
 	/// @param contractAddress Contract to check allowlist of
 	/// @param user User to check
 	/// @return bool Is specified users exists in contract allowlist
-	fn allowed(&self, contract_address: address, user: address) -> Result<bool> {
+	fn allowed(&self, contract_address: Address, user: Address) -> Result<bool> {
 		self.0.consume_sload()?;
 		Ok(<Pallet<T>>::allowed(contract_address, user))
 	}
@@ -300,11 +300,11 @@
 	/// @dev Only contract owner can change this setting
 	fn toggle_allowed(
 		&mut self,
-		caller: caller,
-		contract_address: address,
-		user: address,
+		caller: Caller,
+		contract_address: Address,
+		user: Address,
 		is_allowed: bool,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -320,7 +320,7 @@
 	///  in case of allowlist access enabled, only users from allowlist may call this contract
 	/// @param contractAddress Contract to get allowlist access of
 	/// @return bool Is specified contract has allowlist access enabled
-	fn allowlist_enabled(&self, contract_address: address) -> Result<bool> {
+	fn allowlist_enabled(&self, contract_address: Address) -> Result<bool> {
 		Ok(<AllowlistEnabled<T>>::get(contract_address))
 	}
 
@@ -329,10 +329,10 @@
 	/// @param enabled Should allowlist access to be enabled?
 	fn toggle_allowlist(
 		&mut self,
-		caller: caller,
-		contract_address: address,
+		caller: Caller,
+		contract_address: Address,
 		enabled: bool,
-	) -> Result<void> {
+	) -> Result<()> {
 		self.recorder().consume_sload()?;
 		self.recorder().consume_sstore()?;
 
@@ -441,7 +441,7 @@
 	}
 }
 
-fn get_sponsoring_fee_limit<T: Config>(contract_address: address) -> uint256 {
+fn get_sponsoring_fee_limit<T: Config>(contract_address: Address) -> U256 {
 	<SponsoringFeeLimit<T>>::get(contract_address)
 		.get(&0xffffffff)
 		.cloned()
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -32,7 +32,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::{call, dispatch_to_evm};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
-use sp_core::Get;
+use sp_core::{U256, Get};
 
 use crate::{
 	Allowance, Balance, Config, FungibleHandle, Pallet, SelfWeightOf, TotalSupply,
@@ -43,50 +43,50 @@
 pub enum ERC20Events {
 	Transfer {
 		#[indexed]
-		from: address,
+		from: Address,
 		#[indexed]
-		to: address,
-		value: uint256,
+		to: Address,
+		value: U256,
 	},
 	Approval {
 		#[indexed]
-		owner: address,
+		owner: Address,
 		#[indexed]
-		spender: address,
-		value: uint256,
+		spender: Address,
+		value: U256,
 	},
 }
 
 #[solidity_interface(name = ERC20, events(ERC20Events))]
 impl<T: Config> FungibleHandle<T> {
-	fn name(&self) -> Result<string> {
+	fn name(&self) -> Result<String> {
 		Ok(decode_utf16(self.name.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
-	fn symbol(&self) -> Result<string> {
-		Ok(string::from_utf8_lossy(&self.token_prefix).into())
+	fn symbol(&self) -> Result<String> {
+		Ok(String::from_utf8_lossy(&self.token_prefix).into())
 	}
-	fn total_supply(&self) -> Result<uint256> {
+	fn total_supply(&self) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		Ok(<TotalSupply<T>>::get(self.id).into())
 	}
 
-	fn decimals(&self) -> Result<uint8> {
+	fn decimals(&self) -> Result<u8> {
 		Ok(if let CollectionMode::Fungible(decimals) = &self.mode {
 			*decimals
 		} else {
 			unreachable!()
 		})
 	}
-	fn balance_of(&self, owner: address) -> Result<uint256> {
+	fn balance_of(&self, owner: Address) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		let owner = T::CrossAccountId::from_eth(owner);
 		let balance = <Balance<T>>::get((self.id, owner));
 		Ok(balance.into())
 	}
 	#[weight(<SelfWeightOf<T>>::transfer())]
-	fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
+	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -101,10 +101,10 @@
 	#[weight(<SelfWeightOf<T>>::transfer_from())]
 	fn transfer_from(
 		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		amount: uint256,
+		caller: Caller,
+		from: Address,
+		to: Address,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
@@ -119,7 +119,7 @@
 		Ok(true)
 	}
 	#[weight(<SelfWeightOf<T>>::approve())]
-	fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result<bool> {
+	fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let spender = T::CrossAccountId::from_eth(spender);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -128,7 +128,7 @@
 			.map_err(dispatch_to_evm::<T>)?;
 		Ok(true)
 	}
-	fn allowance(&self, owner: address, spender: address) -> Result<uint256> {
+	fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		let owner = T::CrossAccountId::from_eth(owner);
 		let spender = T::CrossAccountId::from_eth(spender);
@@ -137,7 +137,7 @@
 	}
 
 	/// @notice Returns collection helper contract address
-	fn collection_helper_address(&self) -> Result<address> {
+	fn collection_helper_address(&self) -> Result<Address> {
 		Ok(T::ContractAddress::get())
 	}
 }
@@ -148,7 +148,7 @@
 	/// @param to account that will receive minted tokens
 	/// @param amount amount of tokens to mint
 	#[weight(<SelfWeightOf<T>>::create_item())]
-	fn mint(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
+	fn mint(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -167,18 +167,18 @@
 	T::AccountId: From<[u8; 32]>,
 {
 	/// @notice A description for the collection.
-	fn description(&self) -> Result<string> {
+	fn description(&self) -> Result<String> {
 		Ok(decode_utf16(self.description.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
 
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = to.into_sub_cross_account::<T>()?;
@@ -194,9 +194,9 @@
 	#[weight(<SelfWeightOf<T>>::approve())]
 	fn approve_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		spender: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let spender = spender.into_sub_cross_account::<T>()?;
@@ -214,7 +214,7 @@
 	/// @param amount The amount that will be burnt.
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::burn_from())]
-	fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result<bool> {
+	fn burn_from(&mut self, caller: Caller, from: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -235,9 +235,9 @@
 	#[weight(<SelfWeightOf<T>>::burn_from())]
 	fn burn_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
@@ -254,7 +254,7 @@
 	/// Mint tokens for multiple accounts.
 	/// @param amounts array of pairs of account address and amount
 	#[weight(<SelfWeightOf<T>>::create_multiple_items_ex(amounts.len() as u32))]
-	fn mint_bulk(&mut self, caller: caller, amounts: Vec<(address, uint256)>) -> Result<bool> {
+	fn mint_bulk(&mut self, caller: Caller, amounts: Vec<(Address, U256)>) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let budget = self
 			.recorder
@@ -277,9 +277,9 @@
 	#[weight(<SelfWeightOf<T>>::transfer())]
 	fn transfer_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = to.into_sub_cross_account::<T>()?;
@@ -295,10 +295,10 @@
 	#[weight(<SelfWeightOf<T>>::transfer_from())]
 	fn transfer_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: pallet_common::eth::CrossAddress,
 		to: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
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
@@ -274,11 +274,9 @@
 
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
 	/// @dev EVM selector for this function is: 0x41835d4c,
 	///  or in textual repr: setCollectionAccess(uint8)
-	function setCollectionAccess(uint8 mode) public {
+	function setCollectionAccess(AccessMode mode) public {
 		require(false, stub_error);
 		mode;
 		dummy = 0;
@@ -443,6 +441,14 @@
 	uint256 sub;
 }
 
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList
+}
+
 /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -43,7 +43,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::call;
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
-use sp_core::Get;
+use sp_core::{U256, Get};
 
 use crate::{
 	AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,
@@ -63,8 +63,8 @@
 	#[solidity(hide)]
 	fn set_token_property_permission(
 		&mut self,
-		caller: caller,
-		key: string,
+		caller: Caller,
+		key: String,
 		is_mutable: bool,
 		collection_admin: bool,
 		token_owner: bool,
@@ -93,7 +93,7 @@
 	#[weight(<SelfWeightOf<T>>::set_token_property_permissions(permissions.len() as u32))]
 	fn set_token_property_permissions(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		permissions: Vec<eth::TokenPropertyPermission>,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -121,10 +121,10 @@
 	#[weight(<SelfWeightOf<T>>::set_token_properties(1))]
 	fn set_property(
 		&mut self,
-		caller: caller,
-		token_id: uint256,
-		key: string,
-		value: bytes,
+		caller: Caller,
+		token_id: U256,
+		key: String,
+		value: Bytes,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
@@ -154,8 +154,8 @@
 	#[weight(<SelfWeightOf<T>>::set_token_properties(properties.len() as u32))]
 	fn set_properties(
 		&mut self,
-		caller: caller,
-		token_id: uint256,
+		caller: Caller,
+		token_id: U256,
 		properties: Vec<eth::Property>,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -187,7 +187,7 @@
 	/// @param key Property key.
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::delete_token_properties(1))]
-	fn delete_property(&mut self, token_id: uint256, caller: caller, key: string) -> Result<()> {
+	fn delete_property(&mut self, token_id: U256, caller: Caller, key: String) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
 		let key = <Vec<u8>>::from(key)
@@ -209,9 +209,9 @@
 	#[weight(<SelfWeightOf<T>>::delete_token_properties(keys.len() as u32))]
 	fn delete_properties(
 		&mut self,
-		token_id: uint256,
-		caller: caller,
-		keys: Vec<string>,
+		token_id: U256,
+		caller: Caller,
+		keys: Vec<String>,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
@@ -239,7 +239,7 @@
 	/// @param tokenId ID of the token.
 	/// @param key Property key.
 	/// @return Property value bytes
-	fn property(&self, token_id: uint256, key: string) -> Result<bytes> {
+	fn property(&self, token_id: U256, key: String) -> Result<Bytes> {
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
 		let key = <Vec<u8>>::from(key)
 			.try_into()
@@ -261,11 +261,11 @@
 	///  any transfer, the approved address for that NFT (if any) is reset to none.
 	Transfer {
 		#[indexed]
-		from: address,
+		from: Address,
 		#[indexed]
-		to: address,
+		to: Address,
 		#[indexed]
-		token_id: uint256,
+		token_id: U256,
 	},
 	/// @dev This emits when the approved address for an NFT is changed or
 	///  reaffirmed. The zero address indicates there is no approved address.
@@ -273,20 +273,20 @@
 	///  address for that NFT (if any) is reset to none.
 	Approval {
 		#[indexed]
-		owner: address,
+		owner: Address,
 		#[indexed]
-		approved: address,
+		approved: Address,
 		#[indexed]
-		token_id: uint256,
+		token_id: U256,
 	},
 	/// @dev This emits when an operator is enabled or disabled for an owner.
 	///  The operator can manage all NFTs of the owner.
 	#[allow(dead_code)]
 	ApprovalForAll {
 		#[indexed]
-		owner: address,
+		owner: Address,
 		#[indexed]
-		operator: address,
+		operator: Address,
 		approved: bool,
 	},
 }
@@ -301,14 +301,14 @@
 	/// @notice A descriptive name for a collection of NFTs in this contract
 	/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
 	#[solidity(hide, rename_selector = "name")]
-	fn name_proxy(&self) -> Result<string> {
+	fn name_proxy(&self) -> Result<String> {
 		self.name()
 	}
 
 	/// @notice An abbreviated name for NFTs in this contract
 	/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
 	#[solidity(hide, rename_selector = "symbol")]
-	fn symbol_proxy(&self) -> Result<string> {
+	fn symbol_proxy(&self) -> Result<String> {
 		self.symbol()
 	}
 
@@ -322,7 +322,7 @@
 	///
 	/// @return token's const_metadata
 	#[solidity(rename_selector = "tokenURI")]
-	fn token_uri(&self, token_id: uint256) -> Result<string> {
+	fn token_uri(&self, token_id: U256) -> Result<String> {
 		let token_id_u32: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
 
 		match get_token_property(self, token_id_u32, &key::url()).as_deref() {
@@ -335,7 +335,7 @@
 		let base_uri =
 			pallet_common::Pallet::<T>::get_collection_property(self.id, &key::base_uri())
 				.map(BoundedVec::into_inner)
-				.map(string::from_utf8)
+				.map(String::from_utf8)
 				.transpose()
 				.map_err(|e| {
 					Error::Revert(alloc::format!(
@@ -368,12 +368,12 @@
 	/// @param index A counter less than `totalSupply()`
 	/// @return The token identifier for the `index`th NFT,
 	///  (sort order not specified)
-	fn token_by_index(&self, index: uint256) -> Result<uint256> {
+	fn token_by_index(&self, index: U256) -> Result<U256> {
 		Ok(index)
 	}
 
 	/// @dev Not implemented
-	fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {
+	fn token_of_owner_by_index(&self, _owner: Address, _index: U256) -> Result<U256> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
@@ -381,7 +381,7 @@
 	/// @notice Count NFTs tracked by this contract
 	/// @return A count of valid NFTs tracked by this contract, where each one of
 	///  them has an assigned and queryable owner not equal to the zero address
-	fn total_supply(&self) -> Result<uint256> {
+	fn total_supply(&self) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		Ok(<Pallet<T>>::total_supply(self).into())
 	}
@@ -396,7 +396,7 @@
 	///  function throws for queries about the zero address.
 	/// @param owner An address for whom to query the balance
 	/// @return The number of NFTs owned by `owner`, possibly zero
-	fn balance_of(&self, owner: address) -> Result<uint256> {
+	fn balance_of(&self, owner: Address) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		let owner = T::CrossAccountId::from_eth(owner);
 		let balance = <AccountBalance<T>>::get((self.id, owner));
@@ -407,7 +407,7 @@
 	///  about them do throw.
 	/// @param tokenId The identifier for an NFT
 	/// @return The address of the owner of the NFT
-	fn owner_of(&self, token_id: uint256) -> Result<address> {
+	fn owner_of(&self, token_id: U256) -> Result<Address> {
 		self.consume_store_reads(1)?;
 		let token: TokenId = token_id.try_into()?;
 		Ok(*<TokenData<T>>::get((self.id, token))
@@ -419,21 +419,16 @@
 	#[solidity(rename_selector = "safeTransferFrom")]
 	fn safe_transfer_from_with_data(
 		&mut self,
-		_from: address,
-		_to: address,
-		_token_id: uint256,
-		_data: bytes,
-	) -> Result<void> {
+		_from: Address,
+		_to: Address,
+		_token_id: U256,
+		_data: Bytes,
+	) -> Result<()> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
 	/// @dev Not implemented
-	fn safe_transfer_from(
-		&mut self,
-		_from: address,
-		_to: address,
-		_token_id: uint256,
-	) -> Result<void> {
+	fn safe_transfer_from(&mut self, _from: Address, _to: Address, _token_id: U256) -> Result<()> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
@@ -450,11 +445,11 @@
 	#[weight(<SelfWeightOf<T>>::transfer_from())]
 	fn transfer_from(
 		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		token_id: uint256,
-	) -> Result<void> {
+		caller: Caller,
+		from: Address,
+		to: Address,
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
 		let to = T::CrossAccountId::from_eth(to);
@@ -475,7 +470,7 @@
 	/// @param approved The new approved NFT controller
 	/// @param tokenId The NFT to approve
 	#[weight(<SelfWeightOf<T>>::approve())]
-	fn approve(&mut self, caller: caller, approved: address, token_id: uint256) -> Result<void> {
+	fn approve(&mut self, caller: Caller, approved: Address, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let approved = T::CrossAccountId::from_eth(approved);
 		let token = token_id.try_into()?;
@@ -492,10 +487,10 @@
 	#[weight(<SelfWeightOf<T>>::set_allowance_for_all())]
 	fn set_approval_for_all(
 		&mut self,
-		caller: caller,
-		operator: address,
+		caller: Caller,
+		operator: Address,
 		approved: bool,
-	) -> Result<void> {
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let operator = T::CrossAccountId::from_eth(operator);
 
@@ -505,14 +500,14 @@
 	}
 
 	/// @dev Not implemented
-	fn get_approved(&self, _token_id: uint256) -> Result<address> {
+	fn get_approved(&self, _token_id: U256) -> Result<Address> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
 
 	/// @notice Tells whether the given `owner` approves the `operator`.
 	#[weight(<SelfWeightOf<T>>::allowance_for_all())]
-	fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {
+	fn is_approved_for_all(&self, owner: Address, operator: Address) -> Result<bool> {
 		let owner = T::CrossAccountId::from_eth(owner);
 		let operator = T::CrossAccountId::from_eth(operator);
 
@@ -528,7 +523,7 @@
 	///  operator of the current owner.
 	/// @param tokenId The NFT to approve
 	#[weight(<SelfWeightOf<T>>::burn_item())]
-	fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {
+	fn burn(&mut self, caller: Caller, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token = token_id.try_into()?;
 
@@ -544,8 +539,8 @@
 	/// @param to The new owner
 	/// @return uint256 The id of the newly minted token
 	#[weight(<SelfWeightOf<T>>::create_item())]
-	fn mint(&mut self, caller: caller, to: address) -> Result<uint256> {
-		let token_id: uint256 = <TokensMinted<T>>::get(self.id)
+	fn mint(&mut self, caller: Caller, to: Address) -> Result<U256> {
+		let token_id: U256 = <TokensMinted<T>>::get(self.id)
 			.checked_add(1)
 			.ok_or("item id overflow")?
 			.into();
@@ -560,7 +555,7 @@
 	/// @param tokenId ID of the minted NFT
 	#[solidity(hide, rename_selector = "mint")]
 	#[weight(<SelfWeightOf<T>>::create_item())]
-	fn mint_check_id(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {
+	fn mint_check_id(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let token_id: u32 = token_id.try_into()?;
@@ -598,11 +593,11 @@
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_with_token_uri(
 		&mut self,
-		caller: caller,
-		to: address,
-		token_uri: string,
-	) -> Result<uint256> {
-		let token_id: uint256 = <TokensMinted<T>>::get(self.id)
+		caller: Caller,
+		to: Address,
+		token_uri: String,
+	) -> Result<U256> {
+		let token_id: U256 = <TokensMinted<T>>::get(self.id)
 			.checked_add(1)
 			.ok_or("item id overflow")?
 			.into();
@@ -620,10 +615,10 @@
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_with_token_uri_check_id(
 		&mut self,
-		caller: caller,
-		to: address,
-		token_id: uint256,
-		token_uri: string,
+		caller: Caller,
+		to: Address,
+		token_id: U256,
+		token_uri: String,
 	) -> Result<bool> {
 		let key = key::url();
 		let permission = get_token_permission::<T>(self.id, &key)?;
@@ -675,12 +670,12 @@
 	collection: &CollectionHandle<T>,
 	token_id: u32,
 	key: &up_data_structs::PropertyKey,
-) -> Result<string> {
+) -> Result<String> {
 	collection.consume_store_reads(1)?;
 	let properties = <TokenProperties<T>>::try_get((collection.id, token_id))
 		.map_err(|_| Error::Revert("Token properties not found".into()))?;
 	if let Some(property) = properties.get(key) {
-		return Ok(string::from_utf8_lossy(property).into());
+		return Ok(String::from_utf8_lossy(property).into());
 	}
 
 	Err("Property tokenURI not found".into())
@@ -696,7 +691,7 @@
 		.get(key)
 		.map(Clone::clone)
 		.ok_or_else(|| {
-			let key = string::from_utf8(key.clone().into_inner()).unwrap_or_default();
+			let key = String::from_utf8(key.clone().into_inner()).unwrap_or_default();
 			Error::Revert(alloc::format!("No permission for key {}", key))
 		})?;
 	Ok(a)
@@ -709,28 +704,28 @@
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
 {
 	/// @notice A descriptive name for a collection of NFTs in this contract
-	fn name(&self) -> Result<string> {
+	fn name(&self) -> Result<String> {
 		Ok(decode_utf16(self.name.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
 
 	/// @notice An abbreviated name for NFTs in this contract
-	fn symbol(&self) -> Result<string> {
-		Ok(string::from_utf8_lossy(&self.token_prefix).into())
+	fn symbol(&self) -> Result<String> {
+		Ok(String::from_utf8_lossy(&self.token_prefix).into())
 	}
 
 	/// @notice A description for the collection.
-	fn description(&self) -> Result<string> {
+	fn description(&self) -> Result<String> {
 		Ok(decode_utf16(self.description.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
 
 	/// Returns the owner (in cross format) of the token.
 	///
 	/// @param tokenId Id for the token.
-	fn cross_owner_of(&self, token_id: uint256) -> Result<eth::CrossAddress> {
+	fn cross_owner_of(&self, token_id: U256) -> Result<eth::CrossAddress> {
 		Self::token_owner(&self, token_id.try_into()?)
 			.map(|o| eth::CrossAddress::from_sub_cross_account::<T>(&o))
 			.ok_or(Error::Revert("key too large".into()))
@@ -741,7 +736,7 @@
 	/// @param tokenId Id for the token.
 	/// @param keys Properties keys. Empty keys for all propertyes.
 	/// @return Vector of properties key/value pairs.
-	fn properties(&self, token_id: uint256, keys: Vec<string>) -> Result<Vec<eth::Property>> {
+	fn properties(&self, token_id: U256, keys: Vec<String>) -> Result<Vec<eth::Property>> {
 		let keys = keys
 			.into_iter()
 			.map(|key| {
@@ -770,10 +765,10 @@
 	#[weight(<SelfWeightOf<T>>::approve())]
 	fn approve_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		approved: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let approved = approved.into_sub_cross_account::<T>()?;
 		let token = token_id.try_into()?;
@@ -789,7 +784,7 @@
 	/// @param to The new owner
 	/// @param tokenId The NFT to transfer
 	#[weight(<SelfWeightOf<T>>::transfer())]
-	fn transfer(&mut self, caller: caller, to: address, token_id: uint256) -> Result<void> {
+	fn transfer(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let token = token_id.try_into()?;
@@ -809,10 +804,10 @@
 	#[weight(<SelfWeightOf<T>>::transfer())]
 	fn transfer_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = to.into_sub_cross_account::<T>()?;
 		let token = token_id.try_into()?;
@@ -833,11 +828,11 @@
 	#[weight(<SelfWeightOf<T>>::transfer())]
 	fn transfer_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: eth::CrossAddress,
 		to: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
 		let to = to.into_sub_cross_account::<T>()?;
@@ -858,7 +853,7 @@
 	/// @param tokenId The NFT to transfer
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::burn_from())]
-	fn burn_from(&mut self, caller: caller, from: address, token_id: uint256) -> Result<void> {
+	fn burn_from(&mut self, caller: Caller, from: Address, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
 		let token = token_id.try_into()?;
@@ -880,10 +875,10 @@
 	#[weight(<SelfWeightOf<T>>::burn_from())]
 	fn burn_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
 		let token = token_id.try_into()?;
@@ -897,7 +892,7 @@
 	}
 
 	/// @notice Returns next free NFT ID.
-	fn next_token_id(&self) -> Result<uint256> {
+	fn next_token_id(&self) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		Ok(<TokensMinted<T>>::get(self.id)
 			.checked_add(1)
@@ -912,7 +907,7 @@
 	/// @param tokenIds IDs of the minted NFTs
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::create_multiple_items(token_ids.len() as u32))]
-	fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec<uint256>) -> Result<bool> {
+	fn mint_bulk(&mut self, caller: Caller, to: Address, token_ids: Vec<U256>) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let mut expected_index = <TokensMinted<T>>::get(self.id)
@@ -951,9 +946,9 @@
 	#[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32))]
 	fn mint_bulk_with_token_uri(
 		&mut self,
-		caller: caller,
-		to: address,
-		tokens: Vec<(uint256, string)>,
+		caller: Caller,
+		to: Address,
+		tokens: Vec<(U256, String)>,
 	) -> Result<bool> {
 		let key = key::url();
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -1002,10 +997,10 @@
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: eth::CrossAddress,
 		properties: Vec<eth::Property>,
-	) -> Result<uint256> {
+	) -> Result<U256> {
 		let token_id = <TokensMinted<T>>::get(self.id)
 			.checked_add(1)
 			.ok_or("item id overflow")?;
@@ -1040,7 +1035,7 @@
 	}
 
 	/// @notice Returns collection helper contract address
-	fn collection_helper_address(&self) -> Result<address> {
+	fn collection_helper_address(&self) -> Result<Address> {
 		Ok(T::ContractAddress::get())
 	}
 }
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
@@ -416,11 +416,9 @@
 
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
 	/// @dev EVM selector for this function is: 0x41835d4c,
 	///  or in textual repr: setCollectionAccess(uint8)
-	function setCollectionAccess(uint8 mode) public {
+	function setCollectionAccess(AccessMode mode) public {
 		require(false, stub_error);
 		mode;
 		dummy = 0;
@@ -585,6 +583,14 @@
 	uint256 sub;
 }
 
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList
+}
+
 /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -39,7 +39,7 @@
 use pallet_evm::{account::CrossAccountId, PrecompileHandle};
 use pallet_evm_coder_substrate::{call, dispatch_to_evm};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
-use sp_core::{H160, Get};
+use sp_core::{H160, U256, Get};
 use sp_std::{collections::btree_map::BTreeMap, vec::Vec, vec};
 use up_data_structs::{
 	CollectionId, CollectionPropertiesVec, mapping::TokenAddressMapping, Property, PropertyKey,
@@ -66,8 +66,8 @@
 	#[solidity(hide)]
 	fn set_token_property_permission(
 		&mut self,
-		caller: caller,
-		key: string,
+		caller: Caller,
+		key: String,
 		is_mutable: bool,
 		collection_admin: bool,
 		token_owner: bool,
@@ -96,7 +96,7 @@
 	#[weight(<SelfWeightOf<T>>::set_token_property_permissions(permissions.len() as u32))]
 	fn set_token_property_permissions(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		permissions: Vec<eth::TokenPropertyPermission>,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -124,10 +124,10 @@
 	#[weight(<SelfWeightOf<T>>::set_token_properties(1))]
 	fn set_property(
 		&mut self,
-		caller: caller,
-		token_id: uint256,
-		key: string,
-		value: bytes,
+		caller: Caller,
+		token_id: U256,
+		key: String,
+		value: Bytes,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
@@ -157,8 +157,8 @@
 	#[weight(<SelfWeightOf<T>>::set_token_properties(properties.len() as u32))]
 	fn set_properties(
 		&mut self,
-		caller: caller,
-		token_id: uint256,
+		caller: Caller,
+		token_id: U256,
 		properties: Vec<eth::Property>,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -190,7 +190,7 @@
 	/// @param key Property key.
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::delete_token_properties(1))]
-	fn delete_property(&mut self, token_id: uint256, caller: caller, key: string) -> Result<()> {
+	fn delete_property(&mut self, token_id: U256, caller: Caller, key: String) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
 		let key = <Vec<u8>>::from(key)
@@ -212,9 +212,9 @@
 	#[weight(<SelfWeightOf<T>>::delete_token_properties(keys.len() as u32))]
 	fn delete_properties(
 		&mut self,
-		token_id: uint256,
-		caller: caller,
-		keys: Vec<string>,
+		token_id: U256,
+		caller: Caller,
+		keys: Vec<String>,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
@@ -242,7 +242,7 @@
 	/// @param tokenId ID of the token.
 	/// @param key Property key.
 	/// @return Property value bytes
-	fn property(&self, token_id: uint256, key: string) -> Result<bytes> {
+	fn property(&self, token_id: U256, key: String) -> Result<Bytes> {
 		let token_id: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
 		let key = <Vec<u8>>::from(key)
 			.try_into()
@@ -262,28 +262,28 @@
 	///  may be created and assigned without emitting Transfer.
 	Transfer {
 		#[indexed]
-		from: address,
+		from: Address,
 		#[indexed]
-		to: address,
+		to: Address,
 		#[indexed]
-		token_id: uint256,
+		token_id: U256,
 	},
 	/// @dev Not supported
 	Approval {
 		#[indexed]
-		owner: address,
+		owner: Address,
 		#[indexed]
-		approved: address,
+		approved: Address,
 		#[indexed]
-		token_id: uint256,
+		token_id: U256,
 	},
 	/// @dev Not supported
 	#[allow(dead_code)]
 	ApprovalForAll {
 		#[indexed]
-		owner: address,
+		owner: Address,
 		#[indexed]
-		operator: address,
+		operator: Address,
 		approved: bool,
 	},
 }
@@ -298,14 +298,14 @@
 	/// @notice A descriptive name for a collection of NFTs in this contract
 	/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
 	#[solidity(hide, rename_selector = "name")]
-	fn name_proxy(&self) -> Result<string> {
+	fn name_proxy(&self) -> Result<String> {
 		self.name()
 	}
 
 	/// @notice An abbreviated name for NFTs in this contract
 	/// @dev real implementation of this function lies in `ERC721UniqueExtensions`
 	#[solidity(hide, rename_selector = "symbol")]
-	fn symbol_proxy(&self) -> Result<string> {
+	fn symbol_proxy(&self) -> Result<String> {
 		self.symbol()
 	}
 
@@ -319,7 +319,7 @@
 	///
 	/// @return token's const_metadata
 	#[solidity(rename_selector = "tokenURI")]
-	fn token_uri(&self, token_id: uint256) -> Result<string> {
+	fn token_uri(&self, token_id: U256) -> Result<String> {
 		let token_id_u32: u32 = token_id.try_into().map_err(|_| "token id overflow")?;
 
 		match get_token_property(self, token_id_u32, &key::url()).as_deref() {
@@ -332,7 +332,7 @@
 		let base_uri =
 			pallet_common::Pallet::<T>::get_collection_property(self.id, &key::base_uri())
 				.map(BoundedVec::into_inner)
-				.map(string::from_utf8)
+				.map(String::from_utf8)
 				.transpose()
 				.map_err(|e| {
 					Error::Revert(alloc::format!(
@@ -365,12 +365,12 @@
 	/// @param index A counter less than `totalSupply()`
 	/// @return The token identifier for the `index`th NFT,
 	///  (sort order not specified)
-	fn token_by_index(&self, index: uint256) -> Result<uint256> {
+	fn token_by_index(&self, index: U256) -> Result<U256> {
 		Ok(index)
 	}
 
 	/// Not implemented
-	fn token_of_owner_by_index(&self, _owner: address, _index: uint256) -> Result<uint256> {
+	fn token_of_owner_by_index(&self, _owner: Address, _index: U256) -> Result<U256> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
@@ -378,7 +378,7 @@
 	/// @notice Count RFTs tracked by this contract
 	/// @return A count of valid RFTs tracked by this contract, where each one of
 	///  them has an assigned and queryable owner not equal to the zero address
-	fn total_supply(&self) -> Result<uint256> {
+	fn total_supply(&self) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		Ok(<Pallet<T>>::total_supply(self).into())
 	}
@@ -393,7 +393,7 @@
 	///  function throws for queries about the zero address.
 	/// @param owner An address for whom to query the balance
 	/// @return The number of RFTs owned by `owner`, possibly zero
-	fn balance_of(&self, owner: address) -> Result<uint256> {
+	fn balance_of(&self, owner: Address) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		let owner = T::CrossAccountId::from_eth(owner);
 		let balance = <AccountBalance<T>>::get((self.id, owner));
@@ -407,7 +407,7 @@
 	///  the tokens that are partially owned.
 	/// @param tokenId The identifier for an RFT
 	/// @return The address of the owner of the RFT
-	fn owner_of(&self, token_id: uint256) -> Result<address> {
+	fn owner_of(&self, token_id: U256) -> Result<Address> {
 		self.consume_store_reads(2)?;
 		let token = token_id.try_into()?;
 		let owner = <Pallet<T>>::token_owner(self.id, token);
@@ -420,23 +420,18 @@
 	#[solidity(rename_selector = "safeTransferFrom")]
 	fn safe_transfer_from_with_data(
 		&mut self,
-		_from: address,
-		_to: address,
-		_token_id: uint256,
-		_data: bytes,
-	) -> Result<void> {
+		_from: Address,
+		_to: Address,
+		_token_id: U256,
+		_data: Bytes,
+	) -> Result<()> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
 
 	/// @dev Not implemented
 	#[solidity(rename_selector = "safeTransferFrom")]
-	fn safe_transfer_from(
-		&mut self,
-		_from: address,
-		_to: address,
-		_token_id: uint256,
-	) -> Result<void> {
+	fn safe_transfer_from(&mut self, _from: Address, _to: Address, _token_id: U256) -> Result<()> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
@@ -454,11 +449,11 @@
 	#[weight(<SelfWeightOf<T>>::transfer_from_creating_removing())]
 	fn transfer_from(
 		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		token_id: uint256,
-	) -> Result<void> {
+		caller: Caller,
+		from: Address,
+		to: Address,
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
 		let to = T::CrossAccountId::from_eth(to);
@@ -477,7 +472,7 @@
 	}
 
 	/// @dev Not implemented
-	fn approve(&mut self, _caller: caller, _approved: address, _token_id: uint256) -> Result<void> {
+	fn approve(&mut self, _caller: Caller, _approved: Address, _token_id: U256) -> Result<()> {
 		Err("not implemented".into())
 	}
 
@@ -488,10 +483,10 @@
 	#[weight(<SelfWeightOf<T>>::set_allowance_for_all())]
 	fn set_approval_for_all(
 		&mut self,
-		caller: caller,
-		operator: address,
+		caller: Caller,
+		operator: Address,
 		approved: bool,
-	) -> Result<void> {
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let operator = T::CrossAccountId::from_eth(operator);
 
@@ -501,14 +496,14 @@
 	}
 
 	/// @dev Not implemented
-	fn get_approved(&self, _token_id: uint256) -> Result<address> {
+	fn get_approved(&self, _token_id: U256) -> Result<Address> {
 		// TODO: Not implemetable
 		Err("not implemented".into())
 	}
 
 	/// @notice Tells whether the given `owner` approves the `operator`.
 	#[weight(<SelfWeightOf<T>>::allowance_for_all())]
-	fn is_approved_for_all(&self, owner: address, operator: address) -> Result<bool> {
+	fn is_approved_for_all(&self, owner: Address, operator: Address) -> Result<bool> {
 		let owner = T::CrossAccountId::from_eth(owner);
 		let operator = T::CrossAccountId::from_eth(operator);
 
@@ -556,7 +551,7 @@
 	///  operator of the current owner.
 	/// @param tokenId The RFT to approve
 	#[weight(<SelfWeightOf<T>>::burn_item_fully())]
-	fn burn(&mut self, caller: caller, token_id: uint256) -> Result<void> {
+	fn burn(&mut self, caller: Caller, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let token = token_id.try_into()?;
 
@@ -575,8 +570,8 @@
 	/// @param to The new owner
 	/// @return uint256 The id of the newly minted token
 	#[weight(<SelfWeightOf<T>>::create_item())]
-	fn mint(&mut self, caller: caller, to: address) -> Result<uint256> {
-		let token_id: uint256 = <TokensMinted<T>>::get(self.id)
+	fn mint(&mut self, caller: Caller, to: Address) -> Result<U256> {
+		let token_id: U256 = <TokensMinted<T>>::get(self.id)
 			.checked_add(1)
 			.ok_or("item id overflow")?
 			.into();
@@ -591,7 +586,7 @@
 	/// @param tokenId ID of the minted RFT
 	#[solidity(hide, rename_selector = "mint")]
 	#[weight(<SelfWeightOf<T>>::create_item())]
-	fn mint_check_id(&mut self, caller: caller, to: address, token_id: uint256) -> Result<bool> {
+	fn mint_check_id(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let token_id: u32 = token_id.try_into()?;
@@ -634,11 +629,11 @@
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_with_token_uri(
 		&mut self,
-		caller: caller,
-		to: address,
-		token_uri: string,
-	) -> Result<uint256> {
-		let token_id: uint256 = <TokensMinted<T>>::get(self.id)
+		caller: Caller,
+		to: Address,
+		token_uri: String,
+	) -> Result<U256> {
+		let token_id: U256 = <TokensMinted<T>>::get(self.id)
 			.checked_add(1)
 			.ok_or("item id overflow")?
 			.into();
@@ -656,10 +651,10 @@
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_with_token_uri_check_id(
 		&mut self,
-		caller: caller,
-		to: address,
-		token_id: uint256,
-		token_uri: string,
+		caller: Caller,
+		to: Address,
+		token_id: U256,
+		token_uri: String,
 	) -> Result<bool> {
 		let key = key::url();
 		let permission = get_token_permission::<T>(self.id, &key)?;
@@ -713,12 +708,12 @@
 	collection: &CollectionHandle<T>,
 	token_id: u32,
 	key: &up_data_structs::PropertyKey,
-) -> Result<string> {
+) -> Result<String> {
 	collection.consume_store_reads(1)?;
 	let properties = <TokenProperties<T>>::try_get((collection.id, token_id))
 		.map_err(|_| Error::Revert("Token properties not found".into()))?;
 	if let Some(property) = properties.get(key) {
-		return Ok(string::from_utf8_lossy(property).into());
+		return Ok(String::from_utf8_lossy(property).into());
 	}
 
 	Err("Property tokenURI not found".into())
@@ -734,7 +729,7 @@
 		.get(key)
 		.map(Clone::clone)
 		.ok_or_else(|| {
-			let key = string::from_utf8(key.clone().into_inner()).unwrap_or_default();
+			let key = String::from_utf8(key.clone().into_inner()).unwrap_or_default();
 			Error::Revert(alloc::format!("No permission for key {}", key))
 		})?;
 	Ok(a)
@@ -747,28 +742,28 @@
 	T::AccountId: From<[u8; 32]> + AsRef<[u8; 32]>,
 {
 	/// @notice A descriptive name for a collection of NFTs in this contract
-	fn name(&self) -> Result<string> {
+	fn name(&self) -> Result<String> {
 		Ok(decode_utf16(self.name.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
 
 	/// @notice An abbreviated name for NFTs in this contract
-	fn symbol(&self) -> Result<string> {
-		Ok(string::from_utf8_lossy(&self.token_prefix).into())
+	fn symbol(&self) -> Result<String> {
+		Ok(String::from_utf8_lossy(&self.token_prefix).into())
 	}
 
 	/// @notice A description for the collection.
-	fn description(&self) -> Result<string> {
+	fn description(&self) -> Result<String> {
 		Ok(decode_utf16(self.description.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
 
 	/// Returns the owner (in cross format) of the token.
 	///
 	/// @param tokenId Id for the token.
-	fn cross_owner_of(&self, token_id: uint256) -> Result<eth::CrossAddress> {
+	fn cross_owner_of(&self, token_id: U256) -> Result<eth::CrossAddress> {
 		Self::token_owner(&self, token_id.try_into()?)
 			.map(|o| eth::CrossAddress::from_sub_cross_account::<T>(&o))
 			.ok_or(Error::Revert("key too large".into()))
@@ -779,7 +774,7 @@
 	/// @param tokenId Id for the token.
 	/// @param keys Properties keys. Empty keys for all propertyes.
 	/// @return Vector of properties key/value pairs.
-	fn properties(&self, token_id: uint256, keys: Vec<string>) -> Result<Vec<eth::Property>> {
+	fn properties(&self, token_id: U256, keys: Vec<String>) -> Result<Vec<eth::Property>> {
 		let keys = keys
 			.into_iter()
 			.map(|key| {
@@ -805,7 +800,7 @@
 	/// @param to The new owner
 	/// @param tokenId The RFT to transfer
 	#[weight(<SelfWeightOf<T>>::transfer_creating_removing())]
-	fn transfer(&mut self, caller: caller, to: address, token_id: uint256) -> Result<void> {
+	fn transfer(&mut self, caller: Caller, to: Address, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let token = token_id.try_into()?;
@@ -830,10 +825,10 @@
 	#[weight(<SelfWeightOf<T>>::transfer_creating_removing())]
 	fn transfer_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = to.into_sub_cross_account::<T>()?;
 		let token = token_id.try_into()?;
@@ -858,11 +853,11 @@
 	#[weight(<SelfWeightOf<T>>::transfer_creating_removing())]
 	fn transfer_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: eth::CrossAddress,
 		to: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
 		let to = to.into_sub_cross_account::<T>()?;
@@ -888,7 +883,7 @@
 	/// @param tokenId The RFT to transfer
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::burn_from())]
-	fn burn_from(&mut self, caller: caller, from: address, token_id: uint256) -> Result<void> {
+	fn burn_from(&mut self, caller: Caller, from: Address, token_id: U256) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
 		let token = token_id.try_into()?;
@@ -914,10 +909,10 @@
 	#[weight(<SelfWeightOf<T>>::burn_from())]
 	fn burn_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: eth::CrossAddress,
-		token_id: uint256,
-	) -> Result<void> {
+		token_id: U256,
+	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
 		let token = token_id.try_into()?;
@@ -934,7 +929,7 @@
 	}
 
 	/// @notice Returns next free RFT ID.
-	fn next_token_id(&self) -> Result<uint256> {
+	fn next_token_id(&self) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		Ok(<TokensMinted<T>>::get(self.id)
 			.checked_add(1)
@@ -949,7 +944,7 @@
 	/// @param tokenIds IDs of the minted RFTs
 	#[solidity(hide)]
 	#[weight(<SelfWeightOf<T>>::create_multiple_items(token_ids.len() as u32))]
-	fn mint_bulk(&mut self, caller: caller, to: address, token_ids: Vec<uint256>) -> Result<bool> {
+	fn mint_bulk(&mut self, caller: Caller, to: Address, token_ids: Vec<U256>) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let mut expected_index = <TokensMinted<T>>::get(self.id)
@@ -994,9 +989,9 @@
 	#[weight(<SelfWeightOf<T>>::create_multiple_items(tokens.len() as u32))]
 	fn mint_bulk_with_token_uri(
 		&mut self,
-		caller: caller,
-		to: address,
-		tokens: Vec<(uint256, string)>,
+		caller: Caller,
+		to: Address,
+		tokens: Vec<(U256, String)>,
 	) -> Result<bool> {
 		let key = key::url();
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -1051,10 +1046,10 @@
 	#[weight(<SelfWeightOf<T>>::create_item())]
 	fn mint_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: eth::CrossAddress,
 		properties: Vec<eth::Property>,
-	) -> Result<uint256> {
+	) -> Result<U256> {
 		let token_id = <TokensMinted<T>>::get(self.id)
 			.checked_add(1)
 			.ok_or("item id overflow")?;
@@ -1093,7 +1088,7 @@
 	/// Returns EVM address for refungible token
 	///
 	/// @param token ID of the token
-	fn token_contract_address(&self, token: uint256) -> Result<address> {
+	fn token_contract_address(&self, token: U256) -> Result<Address> {
 		Ok(T::EvmTokenAddressMapping::token_to_address(
 			self.id,
 			token.try_into().map_err(|_| "token id overflow")?,
@@ -1101,7 +1096,7 @@
 	}
 
 	/// @notice Returns collection helper contract address
-	fn collection_helper_address(&self) -> Result<address> {
+	fn collection_helper_address(&self) -> Result<Address> {
 		Ok(T::ContractAddress::get())
 	}
 }
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -37,6 +37,7 @@
 use pallet_evm_coder_substrate::{call, dispatch_to_evm, WithRecorder};
 use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _};
 use sp_std::vec::Vec;
+use sp_core::U256;
 use up_data_structs::TokenId;
 
 use crate::{
@@ -51,11 +52,11 @@
 
 #[solidity_interface(name = ERC1633)]
 impl<T: Config> RefungibleTokenHandle<T> {
-	fn parent_token(&self) -> Result<address> {
+	fn parent_token(&self) -> Result<Address> {
 		Ok(collection_id_to_address(self.id))
 	}
 
-	fn parent_token_id(&self) -> Result<uint256> {
+	fn parent_token_id(&self) -> Result<U256> {
 		Ok(self.1.into())
 	}
 }
@@ -68,19 +69,19 @@
 	/// of burning tokens the transfer is to 0.
 	Transfer {
 		#[indexed]
-		from: address,
+		from: Address,
 		#[indexed]
-		to: address,
-		value: uint256,
+		to: Address,
+		value: U256,
 	},
 	/// @dev This event is emitted when the amount of tokens (value) is approved
 	/// by the owner to be used by the spender.
 	Approval {
 		#[indexed]
-		owner: address,
+		owner: Address,
 		#[indexed]
-		spender: address,
-		value: uint256,
+		spender: Address,
+		value: U256,
 	},
 }
 
@@ -91,25 +92,25 @@
 #[solidity_interface(name = ERC20, events(ERC20Events))]
 impl<T: Config> RefungibleTokenHandle<T> {
 	/// @return the name of the token.
-	fn name(&self) -> Result<string> {
+	fn name(&self) -> Result<String> {
 		Ok(decode_utf16(self.name.iter().copied())
 			.map(|r| r.unwrap_or(REPLACEMENT_CHARACTER))
-			.collect::<string>())
+			.collect::<String>())
 	}
 
 	/// @return the symbol of the token.
-	fn symbol(&self) -> Result<string> {
-		Ok(string::from_utf8_lossy(&self.token_prefix).into())
+	fn symbol(&self) -> Result<String> {
+		Ok(String::from_utf8_lossy(&self.token_prefix).into())
 	}
 
 	/// @dev Total number of tokens in existence
-	fn total_supply(&self) -> Result<uint256> {
+	fn total_supply(&self) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		Ok(<TotalSupply<T>>::get((self.id, self.1)).into())
 	}
 
 	/// @dev Not supported
-	fn decimals(&self) -> Result<uint8> {
+	fn decimals(&self) -> Result<u8> {
 		// Decimals aren't supported for refungible tokens
 		Ok(0)
 	}
@@ -117,7 +118,7 @@
 	/// @dev Gets the balance of the specified address.
 	/// @param owner The address to query the balance of.
 	/// @return An uint256 representing the amount owned by the passed address.
-	fn balance_of(&self, owner: address) -> Result<uint256> {
+	fn balance_of(&self, owner: Address) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		let owner = T::CrossAccountId::from_eth(owner);
 		let balance = <Balance<T>>::get((self.id, self.1, owner));
@@ -128,7 +129,7 @@
 	/// @param to The address to transfer to.
 	/// @param amount The amount to be transferred.
 	#[weight(<CommonWeights<T>>::transfer())]
-	fn transfer(&mut self, caller: caller, to: address, amount: uint256) -> Result<bool> {
+	fn transfer(&mut self, caller: Caller, to: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = T::CrossAccountId::from_eth(to);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -148,10 +149,10 @@
 	#[weight(<CommonWeights<T>>::transfer_from())]
 	fn transfer_from(
 		&mut self,
-		caller: caller,
-		from: address,
-		to: address,
-		amount: uint256,
+		caller: Caller,
+		from: Address,
+		to: Address,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
@@ -174,7 +175,7 @@
 	/// @param spender The address which will spend the funds.
 	/// @param amount The amount of tokens to be spent.
 	#[weight(<SelfWeightOf<T>>::approve())]
-	fn approve(&mut self, caller: caller, spender: address, amount: uint256) -> Result<bool> {
+	fn approve(&mut self, caller: Caller, spender: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let spender = T::CrossAccountId::from_eth(spender);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -188,7 +189,7 @@
 	/// @param owner address The address which owns the funds.
 	/// @param spender address The address which will spend the funds.
 	/// @return A uint256 specifying the amount of tokens still available for the spender.
-	fn allowance(&self, owner: address, spender: address) -> Result<uint256> {
+	fn allowance(&self, owner: Address, spender: Address) -> Result<U256> {
 		self.consume_store_reads(1)?;
 		let owner = T::CrossAccountId::from_eth(owner);
 		let spender = T::CrossAccountId::from_eth(spender);
@@ -208,7 +209,7 @@
 	/// @param amount The amount that will be burnt.
 	#[weight(<SelfWeightOf<T>>::burn_from())]
 	#[solidity(hide)]
-	fn burn_from(&mut self, caller: caller, from: address, amount: uint256) -> Result<bool> {
+	fn burn_from(&mut self, caller: Caller, from: Address, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = T::CrossAccountId::from_eth(from);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
@@ -228,9 +229,9 @@
 	#[weight(<SelfWeightOf<T>>::burn_from())]
 	fn burn_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
@@ -254,9 +255,9 @@
 	#[weight(<SelfWeightOf<T>>::approve())]
 	fn approve_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		spender: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let spender = spender.into_sub_cross_account::<T>()?;
@@ -270,7 +271,7 @@
 	///  Throws if `msg.sender` doesn't owns all of the tokens.
 	/// @param amount New total amount of the tokens.
 	#[weight(<SelfWeightOf<T>>::repartition_item())]
-	fn repartition(&mut self, caller: caller, amount: uint256) -> Result<bool> {
+	fn repartition(&mut self, caller: Caller, amount: U256) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let amount = amount.try_into().map_err(|_| "amount overflow")?;
 
@@ -284,9 +285,9 @@
 	#[weight(<CommonWeights<T>>::transfer())]
 	fn transfer_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		to: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let to = to.into_sub_cross_account::<T>()?;
@@ -307,10 +308,10 @@
 	#[weight(<CommonWeights<T>>::transfer_from())]
 	fn transfer_from_cross(
 		&mut self,
-		caller: caller,
+		caller: Caller,
 		from: pallet_common::eth::CrossAddress,
 		to: pallet_common::eth::CrossAddress,
-		amount: uint256,
+		amount: U256,
 	) -> Result<bool> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let from = from.into_sub_cross_account::<T>()?;
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
@@ -416,11 +416,9 @@
 
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
 	/// @dev EVM selector for this function is: 0x41835d4c,
 	///  or in textual repr: setCollectionAccess(uint8)
-	function setCollectionAccess(uint8 mode) public {
+	function setCollectionAccess(AccessMode mode) public {
 		require(false, stub_error);
 		mode;
 		dummy = 0;
@@ -585,6 +583,14 @@
 	uint256 sub;
 }
 
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList
+}
+
 /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
modifiedpallets/unique/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/unique/src/eth/mod.rs
+++ b/pallets/unique/src/eth/mod.rs
@@ -56,10 +56,10 @@
 }
 
 fn convert_data<T: Config>(
-	caller: caller,
-	name: string,
-	description: string,
-	token_prefix: string,
+	caller: Caller,
+	name: String,
+	description: String,
+	token_prefix: String,
 ) -> Result<(
 	T::CrossAccountId,
 	CollectionName,
@@ -87,13 +87,13 @@
 
 #[inline(always)]
 fn create_collection_internal<T: Config>(
-	caller: caller,
-	value: value,
-	name: string,
+	caller: Caller,
+	value: Value,
+	name: String,
 	collection_mode: CollectionMode,
-	description: string,
-	token_prefix: string,
-) -> Result<address> {
+	description: String,
+	token_prefix: String,
+) -> Result<Address> {
 	let (caller, name, description, token_prefix) =
 		convert_data::<T>(caller, name, description, token_prefix)?;
 	let data = CreateCollectionData {
@@ -118,7 +118,7 @@
 	Ok(address)
 }
 
-fn check_sent_amount_equals_collection_creation_price<T: Config>(value: value) -> Result<()> {
+fn check_sent_amount_equals_collection_creation_price<T: Config>(value: Value) -> Result<()> {
 	let value = value.as_u128();
 	let creation_price: u128 = T::CollectionCreationPrice::get()
 		.try_into()
@@ -149,12 +149,12 @@
 	#[solidity(rename_selector = "createNFTCollection")]
 	fn create_nft_collection(
 		&mut self,
-		caller: caller,
-		value: value,
-		name: string,
-		description: string,
-		token_prefix: string,
-	) -> Result<address> {
+		caller: Caller,
+		value: Value,
+		name: String,
+		description: String,
+		token_prefix: String,
+	) -> Result<Address> {
 		let (caller, name, description, token_prefix) =
 			convert_data::<T>(caller, name, description, token_prefix)?;
 		let data = CreateCollectionData {
@@ -188,12 +188,12 @@
 	#[solidity(hide)]
 	fn create_nonfungible_collection(
 		&mut self,
-		caller: caller,
-		value: value,
-		name: string,
-		description: string,
-		token_prefix: string,
-	) -> Result<address> {
+		caller: Caller,
+		value: Value,
+		name: String,
+		description: String,
+		token_prefix: String,
+	) -> Result<Address> {
 		create_collection_internal::<T>(
 			caller,
 			value,
@@ -208,12 +208,12 @@
 	#[solidity(rename_selector = "createRFTCollection")]
 	fn create_rft_collection(
 		&mut self,
-		caller: caller,
-		value: value,
-		name: string,
-		description: string,
-		token_prefix: string,
-	) -> Result<address> {
+		caller: Caller,
+		value: Value,
+		name: String,
+		description: String,
+		token_prefix: String,
+	) -> Result<Address> {
 		create_collection_internal::<T>(
 			caller,
 			value,
@@ -228,13 +228,13 @@
 	#[solidity(rename_selector = "createFTCollection")]
 	fn create_fungible_collection(
 		&mut self,
-		caller: caller,
-		value: value,
-		name: string,
-		decimals: uint8,
-		description: string,
-		token_prefix: string,
-	) -> Result<address> {
+		caller: Caller,
+		value: Value,
+		name: String,
+		decimals: u8,
+		description: String,
+		token_prefix: String,
+	) -> Result<Address> {
 		create_collection_internal::<T>(
 			caller,
 			value,
@@ -248,9 +248,9 @@
 	#[solidity(rename_selector = "makeCollectionERC721MetadataCompatible")]
 	fn make_collection_metadata_compatible(
 		&mut self,
-		caller: caller,
-		collection: address,
-		base_uri: string,
+		caller: Caller,
+		collection: Address,
+		base_uri: String,
 	) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 		let collection =
@@ -334,7 +334,7 @@
 	}
 
 	#[weight(<SelfWeightOf<T>>::destroy_collection())]
-	fn destroy_collection(&mut self, caller: caller, collection_address: address) -> Result<void> {
+	fn destroy_collection(&mut self, caller: Caller, collection_address: Address) -> Result<()> {
 		let caller = T::CrossAccountId::from_eth(caller);
 
 		let collection_id = pallet_common::eth::map_eth_to_id(&collection_address)
@@ -346,7 +346,7 @@
 	/// Check if a collection exists
 	/// @param collectionAddress Address of the collection in question
 	/// @return bool Does the collection exist?
-	fn is_collection_exist(&self, _caller: caller, collection_address: address) -> Result<bool> {
+	fn is_collection_exist(&self, _caller: Caller, collection_address: Address) -> Result<bool> {
 		if let Some(id) = pallet_common::eth::map_eth_to_id(&collection_address) {
 			let collection_id = id;
 			return Ok(<CollectionById<T>>::contains_key(collection_id));
@@ -355,7 +355,7 @@
 		Ok(false)
 	}
 
-	fn collection_creation_fee(&self) -> Result<value> {
+	fn collection_creation_fee(&self) -> Result<Value> {
 		let price: u128 = T::CollectionCreationPrice::get()
 			.try_into()
 			.map_err(|_| ()) // workaround for `expect` requiring `Debug` trait
@@ -366,14 +366,14 @@
 	/// Returns address of a collection.
 	/// @param collectionId  - CollectionId  of the collection
 	/// @return eth mirror address of the collection
-	fn collection_address(&self, collection_id: uint32) -> Result<address> {
+	fn collection_address(&self, collection_id: u32) -> Result<Address> {
 		Ok(collection_id_to_address(collection_id.into()))
 	}
 
 	/// Returns collectionId of a collection.
 	/// @param collectionAddress  - Eth address of the collection
 	/// @return collectionId of the collection
-	fn collection_id(&self, collection_address: address) -> Result<uint32> {
+	fn collection_id(&self, collection_address: Address) -> Result<u32> {
 		map_eth_to_id(&collection_address)
 			.map(|id| id.0)
 			.ok_or(Error::Revert(format!(
modifiedruntime/tests/src/tests.rsdiffbeforeafterboth
--- a/runtime/tests/src/tests.rs
+++ b/runtime/tests/src/tests.rs
@@ -323,7 +323,7 @@
 				.map(|d| { d.into() })
 				.collect()
 		));
-		for (index, data) in items_data.into_iter().enumerate() {
+		for (index, _data) in items_data.into_iter().enumerate() {
 			let balance = <pallet_refungible::Balance<Test>>::get((
 				CollectionId(1),
 				TokenId((index + 1) as u32),
modifiedtests/src/eth/abi/fungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/fungible.json
+++ b/tests/src/eth/abi/fungible.json
@@ -488,7 +488,9 @@
     "type": "function"
   },
   {
-    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
+    "inputs": [
+      { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" }
+    ],
     "name": "setCollectionAccess",
     "outputs": [],
     "stateMutability": "nonpayable",
modifiedtests/src/eth/abi/nonFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/nonFungible.json
+++ b/tests/src/eth/abi/nonFungible.json
@@ -630,7 +630,9 @@
     "type": "function"
   },
   {
-    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
+    "inputs": [
+      { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" }
+    ],
     "name": "setCollectionAccess",
     "outputs": [],
     "stateMutability": "nonpayable",
modifiedtests/src/eth/abi/reFungible.jsondiffbeforeafterboth
--- a/tests/src/eth/abi/reFungible.json
+++ b/tests/src/eth/abi/reFungible.json
@@ -612,7 +612,9 @@
     "type": "function"
   },
   {
-    "inputs": [{ "internalType": "uint8", "name": "mode", "type": "uint8" }],
+    "inputs": [
+      { "internalType": "enum AccessMode", "name": "mode", "type": "uint8" }
+    ],
     "name": "setCollectionAccess",
     "outputs": [],
     "stateMutability": "nonpayable",
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -175,11 +175,9 @@
 
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
 	/// @dev EVM selector for this function is: 0x41835d4c,
 	///  or in textual repr: setCollectionAccess(uint8)
-	function setCollectionAccess(uint8 mode) external;
+	function setCollectionAccess(AccessMode mode) external;
 
 	/// Checks that user allowed to operate with collection.
 	///
@@ -285,6 +283,14 @@
 	uint256 sub;
 }
 
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList
+}
+
 /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -275,11 +275,9 @@
 
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
 	/// @dev EVM selector for this function is: 0x41835d4c,
 	///  or in textual repr: setCollectionAccess(uint8)
-	function setCollectionAccess(uint8 mode) external;
+	function setCollectionAccess(AccessMode mode) external;
 
 	/// Checks that user allowed to operate with collection.
 	///
@@ -385,6 +383,14 @@
 	uint256 sub;
 }
 
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList
+}
+
 /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;
modifiedtests/src/eth/api/UniqueRefungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueRefungible.sol
+++ b/tests/src/eth/api/UniqueRefungible.sol
@@ -275,11 +275,9 @@
 
 	/// Set the collection access method.
 	/// @param mode Access mode
-	/// 	0 for Normal
-	/// 	1 for AllowList
 	/// @dev EVM selector for this function is: 0x41835d4c,
 	///  or in textual repr: setCollectionAccess(uint8)
-	function setCollectionAccess(uint8 mode) external;
+	function setCollectionAccess(AccessMode mode) external;
 
 	/// Checks that user allowed to operate with collection.
 	///
@@ -385,6 +383,14 @@
 	uint256 sub;
 }
 
+/// Ethereum representation of `AccessMode` (see [`up_data_structs::AccessMode`]).
+enum AccessMode {
+	/// Access grant for owner and admins. Used as default.
+	Normal,
+	/// Like a [`Normal`](AccessMode::Normal) but also users in allow list.
+	AllowList
+}
+
 /// Ethereum representation of `NestingPermissions` (see [`up_data_structs::NestingPermissions`]) field.
 struct CollectionNestingPermission {
 	CollectionPermissionField field;