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
--- a/crates/evm-coder/procedural/src/solidity_interface.rs
+++ b/crates/evm-coder/procedural/src/solidity_interface.rs
@@ -347,14 +347,14 @@
 
 	fn is_value(&self) -> bool {
 		if let Ok(ident) = self.plain() {
-			return ident == "value";
+			return ident == "Value";
 		}
 		false
 	}
 
 	fn is_caller(&self) -> bool {
 		if let Ok(ident) = self.plain() {
-			return ident == "caller";
+			return ident == "Caller";
 		}
 		false
 	}
@@ -610,7 +610,7 @@
 		let custom_signature = self.expand_custom_signature();
 		quote! {
 			const #screaming_name_signature: ::evm_coder::custom_signature::SignatureUnit = #custom_signature;
-			const #screaming_name: ::evm_coder::types::bytes4 = {
+			const #screaming_name: ::evm_coder::types::Bytes4 = {
 				let mut sum = ::evm_coder::sha3_const::Keccak256::new();
 				let mut pos = 0;
 				while pos < Self::#screaming_name_signature.len {
@@ -974,7 +974,7 @@
 					#consts
 				)*
 				/// Return this call ERC165 selector
-				pub const fn interface_id() -> ::evm_coder::types::bytes4 {
+				pub const fn interface_id() -> ::evm_coder::types::Bytes4 {
 					let mut interface_id = 0;
 					#(#interface_id)*
 					#(#inline_interface_id)*
@@ -999,7 +999,7 @@
 						)*),
 					};
 
-					let mut out = ::evm_coder::types::string::new();
+					let mut out = ::evm_coder::types::String::new();
 					if #solidity_name.starts_with("Inline") {
 						out.push_str("/// @dev inlined interface\n");
 					}
@@ -1019,7 +1019,7 @@
 				}
 			}
 			impl #gen_ref ::evm_coder::Call for #call_name #gen_ref {
-				fn parse(method_id: ::evm_coder::types::bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
+				fn parse(method_id: ::evm_coder::types::Bytes4, reader: &mut ::evm_coder::abi::AbiReader) -> ::evm_coder::execution::Result<Option<Self>> {
 					use ::evm_coder::abi::AbiRead;
 					match method_id {
 						::evm_coder::ERC165Call::INTERFACE_ID => return Ok(
@@ -1041,7 +1041,7 @@
 			#gen_where
 			{
 				/// Is this contract implements specified ERC165 selector
-				pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::bytes4) -> bool {
+				pub fn supports_interface(this: &#name, interface_id: ::evm_coder::types::Bytes4) -> bool {
 					interface_id != u32::to_be_bytes(0xffffff) && (
 						interface_id == ::evm_coder::ERC165Call::INTERFACE_ID ||
 						interface_id == Self::interface_id()
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
before · runtime/tests/src/tests.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// Tests to be written here18use crate::{Test, TestCrossAccountId, CollectionCreationPrice, RuntimeOrigin, Unique, new_test_ext};19use up_data_structs::{20	COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,21	CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, TokenId,22	MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionMode, AccessMode, CollectionPermissions,23	PropertyKeyPermission, PropertyPermission, Property, CollectionPropertiesVec,24	CollectionPropertiesPermissionsVec,25};26use frame_support::{assert_noop, assert_ok, assert_err};27use sp_std::convert::TryInto;28use pallet_evm::account::CrossAccountId;29use pallet_common::Error as CommonError;30use pallet_unique::Error as UniqueError;3132fn add_balance(user: u64, value: u64) {33	const DONOR_USER: u64 = 999;34	assert_ok!(<pallet_balances::Pallet<Test>>::set_balance(35		RuntimeOrigin::root(),36		DONOR_USER,37		value,38		039	));40	assert_ok!(<pallet_balances::Pallet<Test>>::force_transfer(41		RuntimeOrigin::root(),42		DONOR_USER,43		user,44		value45	));46}4748fn default_nft_data() -> CreateNftData {49	CreateNftData {50		properties: vec![Property {51			key: b"test-prop".to_vec().try_into().unwrap(),52			value: b"test-nft-prop".to_vec().try_into().unwrap(),53		}]54		.try_into()55		.unwrap(),56	}57}5859fn default_fungible_data() -> CreateFungibleData {60	CreateFungibleData { value: 5 }61}6263fn default_re_fungible_data() -> CreateReFungibleData {64	CreateReFungibleData {65		pieces: 1023,66		properties: vec![Property {67			key: b"test-prop".to_vec().try_into().unwrap(),68			value: b"test-nft-prop".to_vec().try_into().unwrap(),69		}]70		.try_into()71		.unwrap(),72	}73}7475fn create_test_collection_for_owner(76	mode: &CollectionMode,77	owner: u64,78	id: CollectionId,79) -> CollectionId {80	add_balance(owner, CollectionCreationPrice::get() as u64 + 1);8182	let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();83	let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();84	let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();85	let token_property_permissions: CollectionPropertiesPermissionsVec =86		vec![PropertyKeyPermission {87			key: b"test-prop".to_vec().try_into().unwrap(),88			permission: PropertyPermission {89				mutable: true,90				collection_admin: false,91				token_owner: true,92			},93		}]94		.try_into()95		.unwrap();96	let properties: CollectionPropertiesVec = vec![Property {97		key: b"test-collection-prop".to_vec().try_into().unwrap(),98		value: b"test-collection-value".to_vec().try_into().unwrap(),99	}]100	.try_into()101	.unwrap();102103	let data: CreateCollectionData<u64> = CreateCollectionData {104		name: col_name1.try_into().unwrap(),105		description: col_desc1.try_into().unwrap(),106		token_prefix: token_prefix1.try_into().unwrap(),107		mode: mode.clone(),108		token_property_permissions: token_property_permissions.clone(),109		properties: properties.clone(),110		..Default::default()111	};112113	let origin1 = RuntimeOrigin::signed(owner);114	assert_ok!(Unique::create_collection_ex(origin1, data));115116	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();117	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();118	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();119	assert_eq!(120		<pallet_common::CollectionById<Test>>::get(id)121			.unwrap()122			.owner,123		owner124	);125	assert_eq!(126		<pallet_common::CollectionById<Test>>::get(id).unwrap().name,127		saved_col_name128	);129	assert_eq!(130		<pallet_common::CollectionById<Test>>::get(id).unwrap().mode,131		*mode132	);133	assert_eq!(134		<pallet_common::CollectionById<Test>>::get(id)135			.unwrap()136			.description,137		saved_description138	);139	assert_eq!(140		<pallet_common::CollectionById<Test>>::get(id)141			.unwrap()142			.token_prefix,143		saved_prefix144	);145	assert_eq!(146		get_collection_property_permissions(id).as_slice(),147		token_property_permissions.as_slice()148	);149	assert_eq!(150		get_collection_properties(id).as_slice(),151		properties.as_slice()152	);153	id154}155156fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {157	<pallet_common::Pallet<Test>>::property_permissions(collection_id)158		.into_iter()159		.map(|(key, permission)| PropertyKeyPermission { key, permission })160		.collect()161}162163fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {164	<pallet_common::Pallet<Test>>::collection_properties(collection_id)165		.into_iter()166		.map(|(key, value)| Property { key, value })167		.collect()168}169170fn get_token_properties(collection_id: CollectionId, token_id: TokenId) -> Vec<Property> {171	<pallet_nonfungible::Pallet<Test>>::token_properties((collection_id, token_id))172		.into_iter()173		.map(|(key, value)| Property { key, value })174		.collect()175}176177fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {178	create_test_collection_for_owner(&mode, 1, id)179}180181fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {182	let origin1 = RuntimeOrigin::signed(1);183	assert_ok!(Unique::create_item(184		origin1,185		collection_id,186		account(1),187		data.clone()188	));189}190191fn account(sub: u64) -> TestCrossAccountId {192	TestCrossAccountId::from_sub(sub)193}194195// Use cases tests region196// #region197198#[test]199fn check_not_sufficient_founds() {200	new_test_ext().execute_with(|| {201		let acc: u64 = 1;202		<pallet_balances::Pallet<Test>>::set_balance(RuntimeOrigin::root(), acc, 0, 0).unwrap();203204		let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();205		let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();206		let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();207208		let data: CreateCollectionData<<Test as frame_system::Config>::AccountId> =209			CreateCollectionData {210				name: name.try_into().unwrap(),211				description: description.try_into().unwrap(),212				token_prefix: token_prefix.try_into().unwrap(),213				mode: CollectionMode::NFT,214				..Default::default()215			};216217		let result = Unique::create_collection_ex(RuntimeOrigin::signed(acc), data);218		assert_err!(result, <CommonError<Test>>::NotSufficientFounds);219	});220}221222#[test]223fn create_fungible_collection_fails_with_large_decimal_numbers() {224	new_test_ext().execute_with(|| {225		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();226		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();227		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();228229		let data: CreateCollectionData<u64> = CreateCollectionData {230			name: col_name1.try_into().unwrap(),231			description: col_desc1.try_into().unwrap(),232			token_prefix: token_prefix1.try_into().unwrap(),233			mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),234			..Default::default()235		};236237		let origin1 = RuntimeOrigin::signed(1);238		assert_noop!(239			Unique::create_collection_ex(origin1, data),240			UniqueError::<Test>::CollectionDecimalPointLimitExceeded241		);242	});243}244245#[test]246fn create_nft_item() {247	new_test_ext().execute_with(|| {248		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));249250		let data = default_nft_data();251		create_test_item(collection_id, &data.clone().into());252253		assert_eq!(254			get_token_properties(collection_id, TokenId(1)).as_slice(),255			data.properties.as_slice(),256		);257	});258}259260// Use cases tests region261// #region262#[test]263fn create_nft_multiple_items() {264	new_test_ext().execute_with(|| {265		create_test_collection(&CollectionMode::NFT, CollectionId(1));266267		let origin1 = RuntimeOrigin::signed(1);268269		let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];270271		assert_ok!(Unique::create_multiple_items(272			origin1,273			CollectionId(1),274			account(1),275			items_data276				.clone()277				.into_iter()278				.map(|d| { d.into() })279				.collect()280		));281		for (index, data) in items_data.into_iter().enumerate() {282			assert_eq!(283				get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),284				data.properties.as_slice()285			);286		}287	});288}289290#[test]291fn create_refungible_item() {292	new_test_ext().execute_with(|| {293		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));294295		let data = default_re_fungible_data();296		create_test_item(collection_id, &data.clone().into());297		let balance =298			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));299		assert_eq!(balance, 1023);300	});301}302303#[test]304fn create_multiple_refungible_items() {305	new_test_ext().execute_with(|| {306		create_test_collection(&CollectionMode::ReFungible, CollectionId(1));307308		let origin1 = RuntimeOrigin::signed(1);309310		let items_data = vec![311			default_re_fungible_data(),312			default_re_fungible_data(),313			default_re_fungible_data(),314		];315316		assert_ok!(Unique::create_multiple_items(317			origin1,318			CollectionId(1),319			account(1),320			items_data321				.clone()322				.into_iter()323				.map(|d| { d.into() })324				.collect()325		));326		for (index, data) in items_data.into_iter().enumerate() {327			let balance = <pallet_refungible::Balance<Test>>::get((328				CollectionId(1),329				TokenId((index + 1) as u32),330				account(1),331			));332			assert_eq!(balance, 1023);333		}334	});335}336337#[test]338fn create_fungible_item() {339	new_test_ext().execute_with(|| {340		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));341342		let data = default_fungible_data();343		create_test_item(collection_id, &data.into());344345		assert_eq!(346			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),347			5348		);349	});350}351352//#[test]353// fn create_multiple_fungible_items() {354//     new_test_ext().execute_with(|| {355//         default_limits();356357//         create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));358359//         let origin1 = RuntimeOrigin::signed(1);360361//         let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];362363//         assert_ok!(Unique::create_multiple_items(364//             origin1.clone(),365//             1,366//             1,367//             items_data.clone().into_iter().map(|d| { d.into() }).collect()368//         ));369370//         for (index, _) in items_data.iter().enumerate() {371//             assert_eq!(Unique::fungible_item_id(1, (index + 1) as TokenId).value, 5);372//         }373//         assert_eq!(Unique::balance_count(1, 1), 3000);374//         assert_eq!(Unique::address_tokens(1, 1), [1, 2, 3]);375//     });376// }377378#[test]379fn transfer_fungible_item() {380	new_test_ext().execute_with(|| {381		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));382383		let origin1 = RuntimeOrigin::signed(1);384		let origin2 = RuntimeOrigin::signed(2);385386		let data = default_fungible_data();387		create_test_item(collection_id, &data.into());388389		assert_eq!(390			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),391			5392		);393394		// change owner scenario395		assert_ok!(Unique::transfer(396			origin1,397			account(2),398			CollectionId(1),399			TokenId(0),400			5401		));402		assert_eq!(403			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),404			0405		);406407		// split item scenario408		assert_ok!(Unique::transfer(409			origin2.clone(),410			account(3),411			CollectionId(1),412			TokenId(0),413			3414		));415416		// split item and new owner has account scenario417		assert_ok!(Unique::transfer(418			origin2,419			account(3),420			CollectionId(1),421			TokenId(0),422			1423		));424		assert_eq!(425			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),426			1427		);428		assert_eq!(429			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),430			4431		);432	});433}434435#[test]436fn transfer_refungible_item() {437	new_test_ext().execute_with(|| {438		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));439440		// Create RFT 1 in 1023 pieces for account 1441		let data = default_re_fungible_data();442		create_test_item(collection_id, &data.clone().into());443		assert_eq!(444			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),445			1446		);447		assert_eq!(448			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),449			1023450		);451		assert_eq!(452			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),453			true454		);455456		// Account 1 transfers all 1023 pieces of RFT 1 to account 2457		let origin1 = RuntimeOrigin::signed(1);458		let origin2 = RuntimeOrigin::signed(2);459		assert_ok!(Unique::transfer(460			origin1,461			account(2),462			CollectionId(1),463			TokenId(1),464			1023465		));466		assert_eq!(467			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),468			1023469		);470		assert_eq!(471			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),472			0473		);474		assert_eq!(475			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),476			1477		);478		assert_eq!(479			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),480			false481		);482		assert_eq!(483			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),484			true485		);486487		// Account 2 transfers 500 pieces of RFT 1 to account 3488		assert_ok!(Unique::transfer(489			origin2.clone(),490			account(3),491			CollectionId(1),492			TokenId(1),493			500494		));495		assert_eq!(496			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),497			523498		);499		assert_eq!(500			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),501			500502		);503		assert_eq!(504			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),505			1506		);507		assert_eq!(508			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),509			1510		);511		assert_eq!(512			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),513			true514		);515		assert_eq!(516			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),517			true518		);519520		// Account 2 transfers 200 more pieces of RFT 1 to account 3 with pre-existing balance521		assert_ok!(Unique::transfer(522			origin2,523			account(3),524			CollectionId(1),525			TokenId(1),526			200527		));528		assert_eq!(529			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),530			323531		);532		assert_eq!(533			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),534			700535		);536		assert_eq!(537			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),538			1539		);540		assert_eq!(541			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),542			1543		);544		assert_eq!(545			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),546			true547		);548		assert_eq!(549			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),550			true551		);552	});553}554555#[test]556fn transfer_nft_item() {557	new_test_ext().execute_with(|| {558		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));559560		let data = default_nft_data();561		create_test_item(collection_id, &data.into());562		assert_eq!(563			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),564			1565		);566		assert_eq!(567			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),568			true569		);570571		let origin1 = RuntimeOrigin::signed(1);572		// default scenario573		assert_ok!(Unique::transfer(574			origin1,575			account(2),576			CollectionId(1),577			TokenId(1),578			1579		));580		assert_eq!(581			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),582			0583		);584		assert_eq!(585			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),586			1587		);588		assert_eq!(589			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),590			false591		);592		assert_eq!(593			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),594			true595		);596	});597}598599#[test]600fn transfer_nft_item_wrong_value() {601	new_test_ext().execute_with(|| {602		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));603604		let data = default_nft_data();605		create_test_item(collection_id, &data.into());606		assert_eq!(607			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),608			1609		);610		assert_eq!(611			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),612			true613		);614615		let origin1 = RuntimeOrigin::signed(1);616617		assert_noop!(618			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)619				.map_err(|e| e.error),620			<pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount621		);622	});623}624625#[test]626fn transfer_nft_item_zero_value() {627	new_test_ext().execute_with(|| {628		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));629630		let data = default_nft_data();631		create_test_item(collection_id, &data.into());632		assert_eq!(633			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),634			1635		);636		assert_eq!(637			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),638			true639		);640641		let origin1 = RuntimeOrigin::signed(1);642643		// Transferring 0 amount works on NFT...644		assert_ok!(Unique::transfer(645			origin1,646			account(2),647			CollectionId(1),648			TokenId(1),649			0650		));651		// ... and results in no transfer652		assert_eq!(653			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),654			1655		);656		assert_eq!(657			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),658			true659		);660	});661}662663#[test]664fn nft_approve_and_transfer_from() {665	new_test_ext().execute_with(|| {666		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));667668		let data = default_nft_data();669		create_test_item(collection_id, &data.into());670671		let origin1 = RuntimeOrigin::signed(1);672		let origin2 = RuntimeOrigin::signed(2);673674		assert_eq!(675			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),676			1677		);678		assert_eq!(679			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),680			true681		);682683		// neg transfer_from684		assert_noop!(685			Unique::transfer_from(686				origin2.clone(),687				account(1),688				account(2),689				CollectionId(1),690				TokenId(1),691				1692			)693			.map_err(|e| e.error),694			CommonError::<Test>::ApprovedValueTooLow695		);696697		// do approve698		assert_ok!(Unique::approve(699			origin1,700			account(2),701			CollectionId(1),702			TokenId(1),703			1704		));705		assert_eq!(706			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),707			account(2)708		);709710		assert_ok!(Unique::transfer_from(711			origin2,712			account(1),713			account(3),714			CollectionId(1),715			TokenId(1),716			1717		));718		assert!(719			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()720		);721	});722}723724#[test]725fn nft_approve_and_transfer_from_allow_list() {726	new_test_ext().execute_with(|| {727		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));728729		let origin1 = RuntimeOrigin::signed(1);730		let origin2 = RuntimeOrigin::signed(2);731732		// Create NFT 1 for account 1733		let data = default_nft_data();734		create_test_item(collection_id, &data.clone().into());735		assert_eq!(736			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),737			1738		);739		assert_eq!(740			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),741			true742		);743744		// Allow allow-list users to mint and add accounts 1, 2, and 3 to allow-list745		assert_ok!(Unique::set_collection_permissions(746			origin1.clone(),747			CollectionId(1),748			CollectionPermissions {749				mint_mode: Some(true),750				access: Some(AccessMode::AllowList),751				nesting: None,752			}753		));754		assert_ok!(Unique::add_to_allow_list(755			origin1.clone(),756			CollectionId(1),757			account(1)758		));759		assert_ok!(Unique::add_to_allow_list(760			origin1.clone(),761			CollectionId(1),762			account(2)763		));764		assert_ok!(Unique::add_to_allow_list(765			origin1.clone(),766			CollectionId(1),767			account(3)768		));769770		// Account 1 approves account 2 for NFT 1771		assert_ok!(Unique::approve(772			origin1.clone(),773			account(2),774			CollectionId(1),775			TokenId(1),776			1777		));778		assert_eq!(779			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),780			account(2)781		);782783		// Account 2 transfers NFT 1 from account 1 to account 3784		assert_ok!(Unique::transfer_from(785			origin2,786			account(1),787			account(3),788			CollectionId(1),789			TokenId(1),790			1791		));792		assert!(793			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()794		);795	});796}797798#[test]799fn refungible_approve_and_transfer_from() {800	new_test_ext().execute_with(|| {801		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));802803		let origin1 = RuntimeOrigin::signed(1);804		let origin2 = RuntimeOrigin::signed(2);805806		// Create RFT 1 in 1023 pieces for account 1807		let data = default_re_fungible_data();808		create_test_item(collection_id, &data.into());809810		assert_eq!(811			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),812			1813		);814		assert_eq!(815			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),816			1023817		);818		assert_eq!(819			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),820			true821		);822823		// Allow public minting, enable allow-list and add accounts 1, 2, 3 to allow-list824		assert_ok!(Unique::set_collection_permissions(825			origin1.clone(),826			CollectionId(1),827			CollectionPermissions {828				mint_mode: Some(true),829				access: Some(AccessMode::AllowList),830				nesting: None,831			}832		));833		assert_ok!(Unique::add_to_allow_list(834			origin1.clone(),835			CollectionId(1),836			account(1)837		));838		assert_ok!(Unique::add_to_allow_list(839			origin1.clone(),840			CollectionId(1),841			account(2)842		));843		assert_ok!(Unique::add_to_allow_list(844			origin1.clone(),845			CollectionId(1),846			account(3)847		));848849		// Account 1 approves account 2 for 1023 pieces of RFT 1850		assert_ok!(Unique::approve(851			origin1,852			account(2),853			CollectionId(1),854			TokenId(1),855			1023856		));857		assert_eq!(858			<pallet_refungible::Allowance<Test>>::get((859				CollectionId(1),860				TokenId(1),861				account(1),862				account(2)863			)),864			1023865		);866867		// Account 2 transfers 100 pieces of RFT 1 from account 1 to account 3868		assert_ok!(Unique::transfer_from(869			origin2,870			account(1),871			account(3),872			CollectionId(1),873			TokenId(1),874			100875		));876		assert_eq!(877			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),878			1879		);880		assert_eq!(881			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),882			1883		);884		assert_eq!(885			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),886			923887		);888		assert_eq!(889			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),890			100891		);892		assert_eq!(893			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),894			true895		);896		assert_eq!(897			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),898			true899		);900		assert_eq!(901			<pallet_refungible::Allowance<Test>>::get((902				CollectionId(1),903				TokenId(1),904				account(1),905				account(2)906			)),907			923908		);909	});910}911912#[test]913fn fungible_approve_and_transfer_from() {914	new_test_ext().execute_with(|| {915		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));916917		let data = default_fungible_data();918		create_test_item(collection_id, &data.into());919920		let origin1 = RuntimeOrigin::signed(1);921		let origin2 = RuntimeOrigin::signed(2);922923		assert_ok!(Unique::set_collection_permissions(924			origin1.clone(),925			CollectionId(1),926			CollectionPermissions {927				mint_mode: Some(true),928				access: Some(AccessMode::AllowList),929				nesting: None,930			}931		));932		assert_ok!(Unique::add_to_allow_list(933			origin1.clone(),934			CollectionId(1),935			account(1)936		));937		assert_ok!(Unique::add_to_allow_list(938			origin1.clone(),939			CollectionId(1),940			account(2)941		));942		assert_ok!(Unique::add_to_allow_list(943			origin1.clone(),944			CollectionId(1),945			account(3)946		));947948		// do approve949		assert_ok!(Unique::approve(950			origin1.clone(),951			account(2),952			CollectionId(1),953			TokenId(0),954			5955		));956		assert_eq!(957			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),958			5959		);960		assert_ok!(Unique::approve(961			origin1,962			account(3),963			CollectionId(1),964			TokenId(0),965			5966		));967		assert_eq!(968			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),969			5970		);971		assert_eq!(972			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),973			5974		);975976		assert_ok!(Unique::transfer_from(977			origin2.clone(),978			account(1),979			account(3),980			CollectionId(1),981			TokenId(0),982			4983		));984985		assert_eq!(986			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),987			1988		);989990		assert_noop!(991			Unique::transfer_from(992				origin2,993				account(1),994				account(3),995				CollectionId(1),996				TokenId(0),997				4998			)999			.map_err(|e| e.error),1000			CommonError::<Test>::ApprovedValueTooLow1001		);1002	});1003}10041005#[test]1006fn change_collection_owner() {1007	new_test_ext().execute_with(|| {1008		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10091010		let origin1 = RuntimeOrigin::signed(1);1011		assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1012		assert_eq!(1013			<pallet_common::CollectionById<Test>>::get(collection_id)1014				.unwrap()1015				.owner,1016			21017		);1018	});1019}10201021#[test]1022fn destroy_collection() {1023	new_test_ext().execute_with(|| {1024		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10251026		let origin1 = RuntimeOrigin::signed(1);1027		assert_ok!(Unique::destroy_collection(origin1, collection_id));1028	});1029}10301031#[test]1032fn burn_nft_item() {1033	new_test_ext().execute_with(|| {1034		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10351036		let origin1 = RuntimeOrigin::signed(1);10371038		let data = default_nft_data();1039		create_test_item(collection_id, &data.into());10401041		// check balance (collection with id = 1, user id = 1)1042		assert_eq!(1043			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1044			11045		);10461047		// burn item1048		assert_ok!(Unique::burn_item(1049			origin1.clone(),1050			collection_id,1051			TokenId(1),1052			11053		));1054		assert_eq!(1055			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1056			01057		);1058	});1059}10601061#[test]1062fn burn_same_nft_item_twice() {1063	new_test_ext().execute_with(|| {1064		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10651066		let origin1 = RuntimeOrigin::signed(1);10671068		let data = default_nft_data();1069		create_test_item(collection_id, &data.into());10701071		// check balance (collection with id = 1, user id = 1)1072		assert_eq!(1073			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1074			11075		);10761077		// burn item1078		assert_ok!(Unique::burn_item(1079			origin1.clone(),1080			collection_id,1081			TokenId(1),1082			11083		));10841085		// burn item again1086		assert_noop!(1087			Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1088			CommonError::<Test>::TokenNotFound1089		);10901091		assert_eq!(1092			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1093			01094		);1095	});1096}10971098#[test]1099fn burn_fungible_item() {1100	new_test_ext().execute_with(|| {1101		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11021103		let origin1 = RuntimeOrigin::signed(1);1104		assert_ok!(Unique::add_collection_admin(1105			origin1.clone(),1106			collection_id,1107			account(2)1108		));11091110		let data = default_fungible_data();1111		create_test_item(collection_id, &data.into());11121113		// check balance (collection with id = 1, user id = 1)1114		assert_eq!(1115			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1116			51117		);11181119		// burn item1120		assert_ok!(Unique::burn_item(1121			origin1.clone(),1122			CollectionId(1),1123			TokenId(0),1124			51125		));1126		assert_noop!(1127			Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1128			CommonError::<Test>::TokenValueTooLow1129		);11301131		assert_eq!(1132			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1133			01134		);1135	});1136}11371138#[test]1139fn burn_fungible_item_with_token_id() {1140	new_test_ext().execute_with(|| {1141		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11421143		let origin1 = RuntimeOrigin::signed(1);1144		assert_ok!(Unique::add_collection_admin(1145			origin1.clone(),1146			collection_id,1147			account(2)1148		));11491150		let data = default_fungible_data();1151		create_test_item(collection_id, &data.into());11521153		// check balance (collection with id = 1, user id = 1)1154		assert_eq!(1155			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1156			51157		);11581159		// Try to burn item using Token ID1160		assert_noop!(1161			Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1162			<pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1163		);1164	});1165}1166#[test]1167fn burn_refungible_item() {1168	new_test_ext().execute_with(|| {1169		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1170		let origin1 = RuntimeOrigin::signed(1);11711172		assert_ok!(Unique::set_collection_permissions(1173			origin1.clone(),1174			collection_id,1175			CollectionPermissions {1176				mint_mode: Some(true),1177				access: Some(AccessMode::AllowList),1178				nesting: None,1179			}1180		));1181		assert_ok!(Unique::add_to_allow_list(1182			origin1.clone(),1183			collection_id,1184			account(1)1185		));11861187		assert_ok!(Unique::add_collection_admin(1188			origin1.clone(),1189			collection_id,1190			account(2)1191		));11921193		let data = default_re_fungible_data();1194		create_test_item(collection_id, &data.into());11951196		// check balance (collection with id = 1, user id = 2)1197		assert_eq!(1198			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1199			11200		);1201		assert_eq!(1202			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1203			10231204		);12051206		// burn item1207		assert_ok!(Unique::burn_item(1208			origin1.clone(),1209			collection_id,1210			TokenId(1),1211			10231212		));1213		assert_noop!(1214			Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1215			CommonError::<Test>::TokenValueTooLow1216		);12171218		assert_eq!(1219			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1220			01221		);1222	});1223}12241225#[test]1226fn add_collection_admin() {1227	new_test_ext().execute_with(|| {1228		let collection1_id =1229			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1230		let origin1 = RuntimeOrigin::signed(1);12311232		// Add collection admins1233		assert_ok!(Unique::add_collection_admin(1234			origin1.clone(),1235			collection1_id,1236			account(2)1237		));1238		assert_ok!(Unique::add_collection_admin(1239			origin1,1240			collection1_id,1241			account(3)1242		));12431244		// Owner is not an admin by default1245		assert_eq!(1246			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1247			false1248		);1249		assert!(<pallet_common::IsAdmin<Test>>::get((1250			CollectionId(1),1251			account(2)1252		)));1253		assert!(<pallet_common::IsAdmin<Test>>::get((1254			CollectionId(1),1255			account(3)1256		)));1257	});1258}12591260#[test]1261fn remove_collection_admin() {1262	new_test_ext().execute_with(|| {1263		let collection1_id =1264			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1265		let origin1 = RuntimeOrigin::signed(1);12661267		// Add collection admins 2 and 31268		assert_ok!(Unique::add_collection_admin(1269			origin1.clone(),1270			collection1_id,1271			account(2)1272		));1273		assert_ok!(Unique::add_collection_admin(1274			origin1.clone(),1275			collection1_id,1276			account(3)1277		));12781279		assert!(<pallet_common::IsAdmin<Test>>::get((1280			CollectionId(1),1281			account(2)1282		)));1283		assert!(<pallet_common::IsAdmin<Test>>::get((1284			CollectionId(1),1285			account(3)1286		)));12871288		// remove admin 31289		assert_ok!(Unique::remove_collection_admin(1290			origin1,1291			CollectionId(1),1292			account(3)1293		));12941295		// 2 is still admin, 3 is not an admin anymore1296		assert!(<pallet_common::IsAdmin<Test>>::get((1297			CollectionId(1),1298			account(2)1299		)));1300		assert_eq!(1301			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1302			false1303		);1304	});1305}13061307#[test]1308fn balance_of() {1309	new_test_ext().execute_with(|| {1310		let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1311		let fungible_collection_id =1312			create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1313		let re_fungible_collection_id =1314			create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13151316		// check balance before1317		assert_eq!(1318			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1319			01320		);1321		assert_eq!(1322			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1323			01324		);1325		assert_eq!(1326			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1327			01328		);13291330		let nft_data = default_nft_data();1331		create_test_item(nft_collection_id, &nft_data.into());13321333		let fungible_data = default_fungible_data();1334		create_test_item(fungible_collection_id, &fungible_data.into());13351336		let re_fungible_data = default_re_fungible_data();1337		create_test_item(re_fungible_collection_id, &re_fungible_data.into());13381339		// check balance (collection with id = 1, user id = 1)1340		assert_eq!(1341			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1342			11343		);1344		assert_eq!(1345			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1346			51347		);1348		assert_eq!(1349			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1350			11351		);13521353		assert_eq!(1354			<pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1355			true1356		);1357		assert_eq!(1358			<pallet_refungible::Owned<Test>>::get((1359				re_fungible_collection_id,1360				account(1),1361				TokenId(1)1362			)),1363			true1364		);1365	});1366}13671368#[test]1369fn approve() {1370	new_test_ext().execute_with(|| {1371		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13721373		let data = default_nft_data();1374		create_test_item(collection_id, &data.into());13751376		let origin1 = RuntimeOrigin::signed(1);13771378		// approve1379		assert_ok!(Unique::approve(1380			origin1,1381			account(2),1382			CollectionId(1),1383			TokenId(1),1384			11385		));1386		assert_eq!(1387			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1388			account(2)1389		);1390	});1391}13921393#[test]1394fn transfer_from() {1395	new_test_ext().execute_with(|| {1396		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1397		let origin1 = RuntimeOrigin::signed(1);1398		let origin2 = RuntimeOrigin::signed(2);13991400		let data = default_nft_data();1401		create_test_item(collection_id, &data.into());14021403		// approve1404		assert_ok!(Unique::approve(1405			origin1.clone(),1406			account(2),1407			CollectionId(1),1408			TokenId(1),1409			11410		));1411		assert_eq!(1412			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1413			account(2)1414		);14151416		assert_ok!(Unique::set_collection_permissions(1417			origin1.clone(),1418			CollectionId(1),1419			CollectionPermissions {1420				mint_mode: Some(true),1421				access: Some(AccessMode::AllowList),1422				nesting: None,1423			}1424		));1425		assert_ok!(Unique::add_to_allow_list(1426			origin1.clone(),1427			CollectionId(1),1428			account(1)1429		));1430		assert_ok!(Unique::add_to_allow_list(1431			origin1.clone(),1432			CollectionId(1),1433			account(2)1434		));1435		assert_ok!(Unique::add_to_allow_list(1436			origin1,1437			CollectionId(1),1438			account(3)1439		));14401441		assert_ok!(Unique::transfer_from(1442			origin2,1443			account(1),1444			account(2),1445			CollectionId(1),1446			TokenId(1),1447			11448		));14491450		// after transfer1451		assert_eq!(1452			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1453			01454		);1455		assert_eq!(1456			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1457			11458		);1459	});1460}14611462// #endregion14631464// Coverage tests region1465// #region14661467#[test]1468fn owner_can_add_address_to_allow_list() {1469	new_test_ext().execute_with(|| {1470		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14711472		let origin1 = RuntimeOrigin::signed(1);1473		assert_ok!(Unique::add_to_allow_list(1474			origin1,1475			collection_id,1476			account(2)1477		));1478		assert!(<pallet_common::Allowlist<Test>>::get((1479			collection_id,1480			account(2)1481		)));1482	});1483}14841485#[test]1486fn admin_can_add_address_to_allow_list() {1487	new_test_ext().execute_with(|| {1488		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1489		let origin1 = RuntimeOrigin::signed(1);1490		let origin2 = RuntimeOrigin::signed(2);14911492		assert_ok!(Unique::add_collection_admin(1493			origin1,1494			collection_id,1495			account(2)1496		));1497		assert_ok!(Unique::add_to_allow_list(1498			origin2,1499			collection_id,1500			account(3)1501		));1502		assert!(<pallet_common::Allowlist<Test>>::get((1503			collection_id,1504			account(3)1505		)));1506	});1507}15081509#[test]1510fn nonprivileged_user_cannot_add_address_to_allow_list() {1511	new_test_ext().execute_with(|| {1512		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15131514		let origin2 = RuntimeOrigin::signed(2);1515		assert_noop!(1516			Unique::add_to_allow_list(origin2, collection_id, account(3)),1517			CommonError::<Test>::NoPermission1518		);1519	});1520}15211522#[test]1523fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1524	new_test_ext().execute_with(|| {1525		let origin1 = RuntimeOrigin::signed(1);15261527		assert_noop!(1528			Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1529			CommonError::<Test>::CollectionNotFound1530		);1531	});1532}15331534#[test]1535fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1536	new_test_ext().execute_with(|| {1537		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15381539		let origin1 = RuntimeOrigin::signed(1);1540		assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1541		assert_noop!(1542			Unique::add_to_allow_list(origin1, collection_id, account(2)),1543			CommonError::<Test>::CollectionNotFound1544		);1545	});1546}15471548// If address is already added to allow list, nothing happens1549#[test]1550fn address_is_already_added_to_allow_list() {1551	new_test_ext().execute_with(|| {1552		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1553		let origin1 = RuntimeOrigin::signed(1);15541555		assert_ok!(Unique::add_to_allow_list(1556			origin1.clone(),1557			collection_id,1558			account(2)1559		));1560		assert_ok!(Unique::add_to_allow_list(1561			origin1,1562			collection_id,1563			account(2)1564		));1565		assert!(<pallet_common::Allowlist<Test>>::get((1566			collection_id,1567			account(2)1568		)));1569	});1570}15711572#[test]1573fn owner_can_remove_address_from_allow_list() {1574	new_test_ext().execute_with(|| {1575		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15761577		let origin1 = RuntimeOrigin::signed(1);1578		assert_ok!(Unique::add_to_allow_list(1579			origin1.clone(),1580			collection_id,1581			account(2)1582		));1583		assert_ok!(Unique::remove_from_allow_list(1584			origin1,1585			collection_id,1586			account(2)1587		));1588		assert_eq!(1589			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1590			false1591		);1592	});1593}15941595#[test]1596fn admin_can_remove_address_from_allow_list() {1597	new_test_ext().execute_with(|| {1598		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1599		let origin1 = RuntimeOrigin::signed(1);1600		let origin2 = RuntimeOrigin::signed(2);16011602		// Owner adds admin1603		assert_ok!(Unique::add_collection_admin(1604			origin1.clone(),1605			collection_id,1606			account(2)1607		));16081609		// Owner adds address 3 to allow list1610		assert_ok!(Unique::add_to_allow_list(1611			origin1,1612			collection_id,1613			account(3)1614		));16151616		// Admin removes address 3 from allow list1617		assert_ok!(Unique::remove_from_allow_list(1618			origin2,1619			collection_id,1620			account(3)1621		));1622		assert_eq!(1623			<pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1624			false1625		);1626	});1627}16281629#[test]1630fn nonprivileged_user_cannot_remove_address_from_allow_list() {1631	new_test_ext().execute_with(|| {1632		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1633		let origin1 = RuntimeOrigin::signed(1);1634		let origin2 = RuntimeOrigin::signed(2);16351636		assert_ok!(Unique::add_to_allow_list(1637			origin1,1638			collection_id,1639			account(2)1640		));1641		assert_noop!(1642			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1643			CommonError::<Test>::NoPermission1644		);1645		assert!(<pallet_common::Allowlist<Test>>::get((1646			collection_id,1647			account(2)1648		)));1649	});1650}16511652#[test]1653fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1654	new_test_ext().execute_with(|| {1655		let origin1 = RuntimeOrigin::signed(1);16561657		assert_noop!(1658			Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1659			CommonError::<Test>::CollectionNotFound1660		);1661	});1662}16631664#[test]1665fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1666	new_test_ext().execute_with(|| {1667		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1668		let origin1 = RuntimeOrigin::signed(1);1669		let origin2 = RuntimeOrigin::signed(2);16701671		// Add account 2 to allow list1672		assert_ok!(Unique::add_to_allow_list(1673			origin1.clone(),1674			collection_id,1675			account(2)1676		));16771678		// Account 2 is in collection allow-list1679		assert!(<pallet_common::Allowlist<Test>>::get((1680			collection_id,1681			account(2)1682		)));16831684		// Destroy collection1685		assert_ok!(Unique::destroy_collection(origin1, collection_id));16861687		// Attempt to remove account 2 from collection allow-list => error1688		assert_noop!(1689			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1690			CommonError::<Test>::CollectionNotFound1691		);16921693		// Account 2 is not found in collection allow-list anyway1694		assert_eq!(1695			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1696			false1697		);1698	});1699}17001701// If address is already removed from allow list, nothing happens1702#[test]1703fn address_is_already_removed_from_allow_list() {1704	new_test_ext().execute_with(|| {1705		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1706		let origin1 = RuntimeOrigin::signed(1);17071708		assert_ok!(Unique::add_to_allow_list(1709			origin1.clone(),1710			collection_id,1711			account(2)1712		));1713		assert_ok!(Unique::remove_from_allow_list(1714			origin1.clone(),1715			collection_id,1716			account(2)1717		));1718		assert_eq!(1719			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1720			false1721		);1722		assert_ok!(Unique::remove_from_allow_list(1723			origin1,1724			collection_id,1725			account(2)1726		));1727		assert_eq!(1728			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1729			false1730		);1731	});1732}17331734// If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom (2 tests)1735#[test]1736fn allow_list_test_1() {1737	new_test_ext().execute_with(|| {1738		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17391740		let origin1 = RuntimeOrigin::signed(1);17411742		let data = default_nft_data();1743		create_test_item(collection_id, &data.into());17441745		assert_ok!(Unique::set_collection_permissions(1746			origin1.clone(),1747			collection_id,1748			CollectionPermissions {1749				mint_mode: None,1750				access: Some(AccessMode::AllowList),1751				nesting: None,1752			}1753		));1754		assert_ok!(Unique::add_to_allow_list(1755			origin1.clone(),1756			collection_id,1757			account(2)1758		));17591760		assert_noop!(1761			Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1762				.map_err(|e| e.error),1763			CommonError::<Test>::AddressNotInAllowlist1764		);1765	});1766}17671768#[test]1769fn allow_list_test_2() {1770	new_test_ext().execute_with(|| {1771		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1772		let origin1 = RuntimeOrigin::signed(1);17731774		let data = default_nft_data();1775		create_test_item(collection_id, &data.into());17761777		assert_ok!(Unique::set_collection_permissions(1778			origin1.clone(),1779			collection_id,1780			CollectionPermissions {1781				mint_mode: None,1782				access: Some(AccessMode::AllowList),1783				nesting: None,1784			}1785		));1786		assert_ok!(Unique::add_to_allow_list(1787			origin1.clone(),1788			collection_id,1789			account(1)1790		));1791		assert_ok!(Unique::add_to_allow_list(1792			origin1.clone(),1793			collection_id,1794			account(2)1795		));17961797		// do approve1798		assert_ok!(Unique::approve(1799			origin1.clone(),1800			account(1),1801			collection_id,1802			TokenId(1),1803			11804		));1805		assert_eq!(1806			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1807			account(1)1808		);18091810		assert_ok!(Unique::remove_from_allow_list(1811			origin1.clone(),1812			collection_id,1813			account(1)1814		));18151816		assert_noop!(1817			Unique::transfer_from(1818				origin1,1819				account(1),1820				account(3),1821				CollectionId(1),1822				TokenId(1),1823				11824			)1825			.map_err(|e| e.error),1826			CommonError::<Test>::AddressNotInAllowlist1827		);1828	});1829}18301831// If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom (2 tests)1832#[test]1833fn allow_list_test_3() {1834	new_test_ext().execute_with(|| {1835		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18361837		let origin1 = RuntimeOrigin::signed(1);18381839		let data = default_nft_data();1840		create_test_item(collection_id, &data.into());18411842		assert_ok!(Unique::set_collection_permissions(1843			origin1.clone(),1844			collection_id,1845			CollectionPermissions {1846				mint_mode: None,1847				access: Some(AccessMode::AllowList),1848				nesting: None,1849			}1850		));1851		assert_ok!(Unique::add_to_allow_list(1852			origin1.clone(),1853			collection_id,1854			account(1)1855		));18561857		assert_noop!(1858			Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1859				.map_err(|e| e.error),1860			CommonError::<Test>::AddressNotInAllowlist1861		);1862	});1863}18641865#[test]1866fn allow_list_test_4() {1867	new_test_ext().execute_with(|| {1868		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18691870		let origin1 = RuntimeOrigin::signed(1);18711872		let data = default_nft_data();1873		create_test_item(collection_id, &data.into());18741875		assert_ok!(Unique::set_collection_permissions(1876			origin1.clone(),1877			collection_id,1878			CollectionPermissions {1879				mint_mode: None,1880				access: Some(AccessMode::AllowList),1881				nesting: None,1882			}1883		));1884		assert_ok!(Unique::add_to_allow_list(1885			origin1.clone(),1886			collection_id,1887			account(1)1888		));1889		assert_ok!(Unique::add_to_allow_list(1890			origin1.clone(),1891			collection_id,1892			account(2)1893		));18941895		// do approve1896		assert_ok!(Unique::approve(1897			origin1.clone(),1898			account(1),1899			collection_id,1900			TokenId(1),1901			11902		));1903		assert_eq!(1904			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1905			account(1)1906		);19071908		assert_ok!(Unique::remove_from_allow_list(1909			origin1.clone(),1910			collection_id,1911			account(2)1912		));19131914		assert_noop!(1915			Unique::transfer_from(1916				origin1,1917				account(1),1918				account(3),1919				collection_id,1920				TokenId(1),1921				11922			)1923			.map_err(|e| e.error),1924			CommonError::<Test>::AddressNotInAllowlist1925		);1926	});1927}19281929// If Public Access mode is set to AllowList, tokens can’t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)1930#[test]1931fn allow_list_test_5() {1932	new_test_ext().execute_with(|| {1933		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19341935		let origin1 = RuntimeOrigin::signed(1);19361937		let data = default_nft_data();1938		create_test_item(collection_id, &data.into());19391940		assert_ok!(Unique::set_collection_permissions(1941			origin1.clone(),1942			collection_id,1943			CollectionPermissions {1944				mint_mode: None,1945				access: Some(AccessMode::AllowList),1946				nesting: None,1947			}1948		));1949		assert_noop!(1950			Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1951			CommonError::<Test>::AddressNotInAllowlist1952		);1953	});1954}19551956// If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method).1957#[test]1958fn allow_list_test_6() {1959	new_test_ext().execute_with(|| {1960		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19611962		let origin1 = RuntimeOrigin::signed(1);19631964		let data = default_nft_data();1965		create_test_item(collection_id, &data.into());19661967		assert_ok!(Unique::set_collection_permissions(1968			origin1.clone(),1969			collection_id,1970			CollectionPermissions {1971				mint_mode: None,1972				access: Some(AccessMode::AllowList),1973				nesting: None,1974			}1975		));19761977		// do approve1978		assert_noop!(1979			Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1980				.map_err(|e| e.error),1981			CommonError::<Test>::AddressNotInAllowlist1982		);1983	});1984}19851986// If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests) and1987//          tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests)1988#[test]1989fn allow_list_test_7() {1990	new_test_ext().execute_with(|| {1991		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19921993		let data = default_nft_data();1994		create_test_item(collection_id, &data.into());19951996		let origin1 = RuntimeOrigin::signed(1);19971998		assert_ok!(Unique::set_collection_permissions(1999			origin1.clone(),2000			collection_id,2001			CollectionPermissions {2002				mint_mode: None,2003				access: Some(AccessMode::AllowList),2004				nesting: None,2005			}2006		));2007		assert_ok!(Unique::add_to_allow_list(2008			origin1.clone(),2009			collection_id,2010			account(1)2011		));2012		assert_ok!(Unique::add_to_allow_list(2013			origin1.clone(),2014			collection_id,2015			account(2)2016		));20172018		assert_ok!(Unique::transfer(2019			origin1,2020			account(2),2021			CollectionId(1),2022			TokenId(1),2023			12024		));2025	});2026}20272028#[test]2029fn allow_list_test_8() {2030	new_test_ext().execute_with(|| {2031		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20322033		// Create NFT for account 12034		let data = default_nft_data();2035		create_test_item(collection_id, &data.into());20362037		let origin1 = RuntimeOrigin::signed(1);20382039		// Toggle Allow List mode and add accounts 1 and 22040		assert_ok!(Unique::set_collection_permissions(2041			origin1.clone(),2042			collection_id,2043			CollectionPermissions {2044				mint_mode: None,2045				access: Some(AccessMode::AllowList),2046				nesting: None,2047			}2048		));2049		assert_ok!(Unique::add_to_allow_list(2050			origin1.clone(),2051			collection_id,2052			account(1)2053		));2054		assert_ok!(Unique::add_to_allow_list(2055			origin1.clone(),2056			collection_id,2057			account(2)2058		));20592060		// Sself-approve account 1 for NFT 12061		assert_ok!(Unique::approve(2062			origin1.clone(),2063			account(1),2064			CollectionId(1),2065			TokenId(1),2066			12067		));2068		assert_eq!(2069			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2070			account(1)2071		);20722073		// Transfer from 1 to 22074		assert_ok!(Unique::transfer_from(2075			origin1,2076			account(1),2077			account(2),2078			CollectionId(1),2079			TokenId(1),2080			12081		));2082	});2083}20842085// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner.2086#[test]2087fn allow_list_test_9() {2088	new_test_ext().execute_with(|| {2089		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2090		let origin1 = RuntimeOrigin::signed(1);20912092		assert_ok!(Unique::set_collection_permissions(2093			origin1.clone(),2094			collection_id,2095			CollectionPermissions {2096				mint_mode: Some(false),2097				access: Some(AccessMode::AllowList),2098				nesting: None,2099			}2100		));21012102		let data = default_nft_data();2103		create_test_item(collection_id, &data.into());2104	});2105}21062107// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin.2108#[test]2109fn allow_list_test_10() {2110	new_test_ext().execute_with(|| {2111		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21122113		let origin1 = RuntimeOrigin::signed(1);2114		let origin2 = RuntimeOrigin::signed(2);21152116		assert_ok!(Unique::set_collection_permissions(2117			origin1.clone(),2118			collection_id,2119			CollectionPermissions {2120				mint_mode: Some(false),2121				access: Some(AccessMode::AllowList),2122				nesting: None,2123			}2124		));21252126		assert_ok!(Unique::add_collection_admin(2127			origin1,2128			collection_id,2129			account(2)2130		));21312132		assert_ok!(Unique::create_item(2133			origin2,2134			collection_id,2135			account(2),2136			default_nft_data().into()2137		));2138	});2139}21402141// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow listed address.2142#[test]2143fn allow_list_test_11() {2144	new_test_ext().execute_with(|| {2145		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21462147		let origin1 = RuntimeOrigin::signed(1);2148		let origin2 = RuntimeOrigin::signed(2);21492150		assert_ok!(Unique::set_collection_permissions(2151			origin1.clone(),2152			collection_id,2153			CollectionPermissions {2154				mint_mode: Some(false),2155				access: Some(AccessMode::AllowList),2156				nesting: None,2157			}2158		));2159		assert_ok!(Unique::add_to_allow_list(2160			origin1,2161			collection_id,2162			account(2)2163		));21642165		assert_noop!(2166			Unique::create_item(2167				origin2,2168				CollectionId(1),2169				account(2),2170				default_nft_data().into()2171			)2172			.map_err(|e| e.error),2173			CommonError::<Test>::PublicMintingNotAllowed2174		);2175	});2176}21772178// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address.2179#[test]2180fn allow_list_test_12() {2181	new_test_ext().execute_with(|| {2182		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21832184		let origin1 = RuntimeOrigin::signed(1);2185		let origin2 = RuntimeOrigin::signed(2);21862187		assert_ok!(Unique::set_collection_permissions(2188			origin1.clone(),2189			collection_id,2190			CollectionPermissions {2191				mint_mode: Some(false),2192				access: Some(AccessMode::AllowList),2193				nesting: None,2194			}2195		));21962197		assert_noop!(2198			Unique::create_item(2199				origin2,2200				CollectionId(1),2201				account(2),2202				default_nft_data().into()2203			)2204			.map_err(|e| e.error),2205			CommonError::<Test>::PublicMintingNotAllowed2206		);2207	});2208}22092210// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner.2211#[test]2212fn allow_list_test_13() {2213	new_test_ext().execute_with(|| {2214		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22152216		let origin1 = RuntimeOrigin::signed(1);22172218		assert_ok!(Unique::set_collection_permissions(2219			origin1.clone(),2220			collection_id,2221			CollectionPermissions {2222				mint_mode: Some(true),2223				access: Some(AccessMode::AllowList),2224				nesting: None,2225			}2226		));22272228		let data = default_nft_data();2229		create_test_item(collection_id, &data.into());2230	});2231}22322233// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin.2234#[test]2235fn allow_list_test_14() {2236	new_test_ext().execute_with(|| {2237		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22382239		let origin1 = RuntimeOrigin::signed(1);2240		let origin2 = RuntimeOrigin::signed(2);22412242		assert_ok!(Unique::set_collection_permissions(2243			origin1.clone(),2244			collection_id,2245			CollectionPermissions {2246				mint_mode: Some(true),2247				access: Some(AccessMode::AllowList),2248				nesting: None,2249			}2250		));22512252		assert_ok!(Unique::add_collection_admin(2253			origin1,2254			collection_id,2255			account(2)2256		));22572258		assert_ok!(Unique::create_item(2259			origin2,2260			collection_id,2261			account(2),2262			default_nft_data().into()2263		));2264	});2265}22662267// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address.2268#[test]2269fn allow_list_test_15() {2270	new_test_ext().execute_with(|| {2271		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22722273		let origin1 = RuntimeOrigin::signed(1);2274		let origin2 = RuntimeOrigin::signed(2);22752276		assert_ok!(Unique::set_collection_permissions(2277			origin1.clone(),2278			collection_id,2279			CollectionPermissions {2280				mint_mode: Some(true),2281				access: Some(AccessMode::AllowList),2282				nesting: None,2283			}2284		));22852286		assert_noop!(2287			Unique::create_item(2288				origin2,2289				collection_id,2290				account(2),2291				default_nft_data().into()2292			)2293			.map_err(|e| e.error),2294			CommonError::<Test>::AddressNotInAllowlist2295		);2296	});2297}22982299// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address.2300#[test]2301fn allow_list_test_16() {2302	new_test_ext().execute_with(|| {2303		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23042305		let origin1 = RuntimeOrigin::signed(1);2306		let origin2 = RuntimeOrigin::signed(2);23072308		assert_ok!(Unique::set_collection_permissions(2309			origin1.clone(),2310			collection_id,2311			CollectionPermissions {2312				mint_mode: Some(true),2313				access: Some(AccessMode::AllowList),2314				nesting: None,2315			}2316		));2317		assert_ok!(Unique::add_to_allow_list(2318			origin1,2319			collection_id,2320			account(2)2321		));23222323		assert_ok!(Unique::create_item(2324			origin2,2325			collection_id,2326			account(2),2327			default_nft_data().into()2328		));2329	});2330}23312332// Total number of collections. Positive test2333#[test]2334fn total_number_collections_bound() {2335	new_test_ext().execute_with(|| {2336		create_test_collection(&CollectionMode::NFT, CollectionId(1));2337	});2338}23392340#[test]2341fn create_max_collections() {2342	new_test_ext().execute_with(|| {2343		for i in 1..COLLECTION_NUMBER_LIMIT {2344			create_test_collection(&CollectionMode::NFT, CollectionId(i));2345		}2346	});2347}23482349// Total number of collections. Negative test2350#[test]2351fn total_number_collections_bound_neg() {2352	new_test_ext().execute_with(|| {2353		let origin1 = RuntimeOrigin::signed(1);23542355		for i in 1..=COLLECTION_NUMBER_LIMIT {2356			create_test_collection(&CollectionMode::NFT, CollectionId(i));2357		}23582359		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2360		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2361		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23622363		let data: CreateCollectionData<u64> = CreateCollectionData {2364			name: col_name1.try_into().unwrap(),2365			description: col_desc1.try_into().unwrap(),2366			token_prefix: token_prefix1.try_into().unwrap(),2367			mode: CollectionMode::NFT,2368			..Default::default()2369		};23702371		// 11-th collection in chain. Expects error2372		assert_noop!(2373			Unique::create_collection_ex(origin1, data),2374			CommonError::<Test>::TotalCollectionsLimitExceeded2375		);2376	});2377}23782379// Owned tokens by a single address. Positive test2380#[test]2381fn owned_tokens_bound() {2382	new_test_ext().execute_with(|| {2383		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23842385		let data = default_nft_data();2386		create_test_item(collection_id, &data.clone().into());2387		create_test_item(collection_id, &data.into());2388	});2389}23902391// Owned tokens by a single address. Negotive test2392#[test]2393fn owned_tokens_bound_neg() {2394	new_test_ext().execute_with(|| {2395		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23962397		let origin1 = RuntimeOrigin::signed(1);23982399		for _ in 1..=MAX_TOKEN_OWNERSHIP {2400			let data = default_nft_data();2401			create_test_item(collection_id, &data.clone().into());2402		}24032404		let data = default_nft_data();2405		assert_noop!(2406			Unique::create_item(origin1, CollectionId(1), account(1), data.into())2407				.map_err(|e| e.error),2408			CommonError::<Test>::AccountTokenLimitExceeded2409		);2410	});2411}24122413// Number of collection admins. Positive test2414#[test]2415fn collection_admins_bound() {2416	new_test_ext().execute_with(|| {2417		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24182419		let origin1 = RuntimeOrigin::signed(1);24202421		assert_ok!(Unique::add_collection_admin(2422			origin1.clone(),2423			collection_id,2424			account(2)2425		));2426		assert_ok!(Unique::add_collection_admin(2427			origin1,2428			collection_id,2429			account(3)2430		));2431	});2432}24332434// Number of collection admins. Negotive test2435#[test]2436fn collection_admins_bound_neg() {2437	new_test_ext().execute_with(|| {2438		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24392440		let origin1 = RuntimeOrigin::signed(1);24412442		for i in 0..COLLECTION_ADMINS_LIMIT {2443			assert_ok!(Unique::add_collection_admin(2444				origin1.clone(),2445				collection_id,2446				account((2 + i).into())2447			));2448		}2449		assert_noop!(2450			Unique::add_collection_admin(2451				origin1,2452				collection_id,2453				account((3 + COLLECTION_ADMINS_LIMIT).into())2454			),2455			CommonError::<Test>::CollectionAdminCountExceeded2456		);2457	});2458}2459// #endregion24602461#[test]2462fn collection_transfer_flag_works() {2463	new_test_ext().execute_with(|| {2464		let origin1 = RuntimeOrigin::signed(1);24652466		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2467		assert_ok!(Unique::set_transfers_enabled_flag(2468			origin1,2469			collection_id,2470			true2471		));24722473		let data = default_nft_data();2474		create_test_item(collection_id, &data.into());2475		assert_eq!(2476			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2477			12478		);2479		assert_eq!(2480			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2481			true2482		);24832484		let origin1 = RuntimeOrigin::signed(1);24852486		// default scenario2487		assert_ok!(Unique::transfer(2488			origin1,2489			account(2),2490			collection_id,2491			TokenId(1),2492			12493		));2494		assert_eq!(2495			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2496			false2497		);2498		assert_eq!(2499			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2500			true2501		);2502		assert_eq!(2503			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2504			02505		);2506		assert_eq!(2507			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2508			12509		);2510	});2511}25122513#[test]2514fn collection_transfer_flag_works_neg() {2515	new_test_ext().execute_with(|| {2516		let origin1 = RuntimeOrigin::signed(1);25172518		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2519		assert_ok!(Unique::set_transfers_enabled_flag(2520			origin1,2521			collection_id,2522			false2523		));25242525		let data = default_nft_data();2526		create_test_item(collection_id, &data.into());2527		assert_eq!(2528			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2529			12530		);2531		assert_eq!(2532			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2533			true2534		);25352536		let origin1 = RuntimeOrigin::signed(1);25372538		// default scenario2539		assert_noop!(2540			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2541				.map_err(|e| e.error),2542			CommonError::<Test>::TransferNotAllowed2543		);2544		assert_eq!(2545			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2546			12547		);2548		assert_eq!(2549			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2550			02551		);2552		assert_eq!(2553			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2554			true2555		);2556		assert_eq!(2557			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2558			false2559		);2560	});2561}25622563#[test]2564fn collection_sponsoring() {2565	new_test_ext().execute_with(|| {2566		// default_limits();2567		let user1 = 1_u64;2568		let user2 = 777_u64;2569		let origin1 = RuntimeOrigin::signed(user1);2570		let origin2 = RuntimeOrigin::signed(user2);2571		let account2 = account(user2);25722573		let collection_id =2574			create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2575		assert_ok!(Unique::set_collection_sponsor(2576			origin1.clone(),2577			collection_id,2578			user12579		));2580		assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25812582		// Expect error while have no permissions2583		assert!(Unique::create_item(2584			origin2.clone(),2585			collection_id,2586			account2.clone(),2587			default_nft_data().into()2588		)2589		.is_err());25902591		assert_ok!(Unique::set_collection_permissions(2592			origin1.clone(),2593			collection_id,2594			CollectionPermissions {2595				mint_mode: Some(true),2596				access: Some(AccessMode::AllowList),2597				nesting: None,2598			}2599		));2600		assert_ok!(Unique::add_to_allow_list(2601			origin1.clone(),2602			collection_id,2603			account2.clone()2604		));26052606		assert_ok!(Unique::create_item(2607			origin2,2608			collection_id,2609			account2,2610			default_nft_data().into()2611		));2612	});2613}
after · runtime/tests/src/tests.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// Tests to be written here18use crate::{Test, TestCrossAccountId, CollectionCreationPrice, RuntimeOrigin, Unique, new_test_ext};19use up_data_structs::{20	COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,21	CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, TokenId,22	MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionMode, AccessMode, CollectionPermissions,23	PropertyKeyPermission, PropertyPermission, Property, CollectionPropertiesVec,24	CollectionPropertiesPermissionsVec,25};26use frame_support::{assert_noop, assert_ok, assert_err};27use sp_std::convert::TryInto;28use pallet_evm::account::CrossAccountId;29use pallet_common::Error as CommonError;30use pallet_unique::Error as UniqueError;3132fn add_balance(user: u64, value: u64) {33	const DONOR_USER: u64 = 999;34	assert_ok!(<pallet_balances::Pallet<Test>>::set_balance(35		RuntimeOrigin::root(),36		DONOR_USER,37		value,38		039	));40	assert_ok!(<pallet_balances::Pallet<Test>>::force_transfer(41		RuntimeOrigin::root(),42		DONOR_USER,43		user,44		value45	));46}4748fn default_nft_data() -> CreateNftData {49	CreateNftData {50		properties: vec![Property {51			key: b"test-prop".to_vec().try_into().unwrap(),52			value: b"test-nft-prop".to_vec().try_into().unwrap(),53		}]54		.try_into()55		.unwrap(),56	}57}5859fn default_fungible_data() -> CreateFungibleData {60	CreateFungibleData { value: 5 }61}6263fn default_re_fungible_data() -> CreateReFungibleData {64	CreateReFungibleData {65		pieces: 1023,66		properties: vec![Property {67			key: b"test-prop".to_vec().try_into().unwrap(),68			value: b"test-nft-prop".to_vec().try_into().unwrap(),69		}]70		.try_into()71		.unwrap(),72	}73}7475fn create_test_collection_for_owner(76	mode: &CollectionMode,77	owner: u64,78	id: CollectionId,79) -> CollectionId {80	add_balance(owner, CollectionCreationPrice::get() as u64 + 1);8182	let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();83	let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();84	let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();85	let token_property_permissions: CollectionPropertiesPermissionsVec =86		vec![PropertyKeyPermission {87			key: b"test-prop".to_vec().try_into().unwrap(),88			permission: PropertyPermission {89				mutable: true,90				collection_admin: false,91				token_owner: true,92			},93		}]94		.try_into()95		.unwrap();96	let properties: CollectionPropertiesVec = vec![Property {97		key: b"test-collection-prop".to_vec().try_into().unwrap(),98		value: b"test-collection-value".to_vec().try_into().unwrap(),99	}]100	.try_into()101	.unwrap();102103	let data: CreateCollectionData<u64> = CreateCollectionData {104		name: col_name1.try_into().unwrap(),105		description: col_desc1.try_into().unwrap(),106		token_prefix: token_prefix1.try_into().unwrap(),107		mode: mode.clone(),108		token_property_permissions: token_property_permissions.clone(),109		properties: properties.clone(),110		..Default::default()111	};112113	let origin1 = RuntimeOrigin::signed(owner);114	assert_ok!(Unique::create_collection_ex(origin1, data));115116	let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();117	let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();118	let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();119	assert_eq!(120		<pallet_common::CollectionById<Test>>::get(id)121			.unwrap()122			.owner,123		owner124	);125	assert_eq!(126		<pallet_common::CollectionById<Test>>::get(id).unwrap().name,127		saved_col_name128	);129	assert_eq!(130		<pallet_common::CollectionById<Test>>::get(id).unwrap().mode,131		*mode132	);133	assert_eq!(134		<pallet_common::CollectionById<Test>>::get(id)135			.unwrap()136			.description,137		saved_description138	);139	assert_eq!(140		<pallet_common::CollectionById<Test>>::get(id)141			.unwrap()142			.token_prefix,143		saved_prefix144	);145	assert_eq!(146		get_collection_property_permissions(id).as_slice(),147		token_property_permissions.as_slice()148	);149	assert_eq!(150		get_collection_properties(id).as_slice(),151		properties.as_slice()152	);153	id154}155156fn get_collection_property_permissions(collection_id: CollectionId) -> Vec<PropertyKeyPermission> {157	<pallet_common::Pallet<Test>>::property_permissions(collection_id)158		.into_iter()159		.map(|(key, permission)| PropertyKeyPermission { key, permission })160		.collect()161}162163fn get_collection_properties(collection_id: CollectionId) -> Vec<Property> {164	<pallet_common::Pallet<Test>>::collection_properties(collection_id)165		.into_iter()166		.map(|(key, value)| Property { key, value })167		.collect()168}169170fn get_token_properties(collection_id: CollectionId, token_id: TokenId) -> Vec<Property> {171	<pallet_nonfungible::Pallet<Test>>::token_properties((collection_id, token_id))172		.into_iter()173		.map(|(key, value)| Property { key, value })174		.collect()175}176177fn create_test_collection(mode: &CollectionMode, id: CollectionId) -> CollectionId {178	create_test_collection_for_owner(&mode, 1, id)179}180181fn create_test_item(collection_id: CollectionId, data: &CreateItemData) {182	let origin1 = RuntimeOrigin::signed(1);183	assert_ok!(Unique::create_item(184		origin1,185		collection_id,186		account(1),187		data.clone()188	));189}190191fn account(sub: u64) -> TestCrossAccountId {192	TestCrossAccountId::from_sub(sub)193}194195// Use cases tests region196// #region197198#[test]199fn check_not_sufficient_founds() {200	new_test_ext().execute_with(|| {201		let acc: u64 = 1;202		<pallet_balances::Pallet<Test>>::set_balance(RuntimeOrigin::root(), acc, 0, 0).unwrap();203204		let name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();205		let description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();206		let token_prefix: Vec<u8> = b"token_prefix1\0".to_vec();207208		let data: CreateCollectionData<<Test as frame_system::Config>::AccountId> =209			CreateCollectionData {210				name: name.try_into().unwrap(),211				description: description.try_into().unwrap(),212				token_prefix: token_prefix.try_into().unwrap(),213				mode: CollectionMode::NFT,214				..Default::default()215			};216217		let result = Unique::create_collection_ex(RuntimeOrigin::signed(acc), data);218		assert_err!(result, <CommonError<Test>>::NotSufficientFounds);219	});220}221222#[test]223fn create_fungible_collection_fails_with_large_decimal_numbers() {224	new_test_ext().execute_with(|| {225		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();226		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();227		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();228229		let data: CreateCollectionData<u64> = CreateCollectionData {230			name: col_name1.try_into().unwrap(),231			description: col_desc1.try_into().unwrap(),232			token_prefix: token_prefix1.try_into().unwrap(),233			mode: CollectionMode::Fungible(MAX_DECIMAL_POINTS + 1),234			..Default::default()235		};236237		let origin1 = RuntimeOrigin::signed(1);238		assert_noop!(239			Unique::create_collection_ex(origin1, data),240			UniqueError::<Test>::CollectionDecimalPointLimitExceeded241		);242	});243}244245#[test]246fn create_nft_item() {247	new_test_ext().execute_with(|| {248		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));249250		let data = default_nft_data();251		create_test_item(collection_id, &data.clone().into());252253		assert_eq!(254			get_token_properties(collection_id, TokenId(1)).as_slice(),255			data.properties.as_slice(),256		);257	});258}259260// Use cases tests region261// #region262#[test]263fn create_nft_multiple_items() {264	new_test_ext().execute_with(|| {265		create_test_collection(&CollectionMode::NFT, CollectionId(1));266267		let origin1 = RuntimeOrigin::signed(1);268269		let items_data = vec![default_nft_data(), default_nft_data(), default_nft_data()];270271		assert_ok!(Unique::create_multiple_items(272			origin1,273			CollectionId(1),274			account(1),275			items_data276				.clone()277				.into_iter()278				.map(|d| { d.into() })279				.collect()280		));281		for (index, data) in items_data.into_iter().enumerate() {282			assert_eq!(283				get_token_properties(CollectionId(1), TokenId(index as u32 + 1)).as_slice(),284				data.properties.as_slice()285			);286		}287	});288}289290#[test]291fn create_refungible_item() {292	new_test_ext().execute_with(|| {293		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));294295		let data = default_re_fungible_data();296		create_test_item(collection_id, &data.clone().into());297		let balance =298			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));299		assert_eq!(balance, 1023);300	});301}302303#[test]304fn create_multiple_refungible_items() {305	new_test_ext().execute_with(|| {306		create_test_collection(&CollectionMode::ReFungible, CollectionId(1));307308		let origin1 = RuntimeOrigin::signed(1);309310		let items_data = vec![311			default_re_fungible_data(),312			default_re_fungible_data(),313			default_re_fungible_data(),314		];315316		assert_ok!(Unique::create_multiple_items(317			origin1,318			CollectionId(1),319			account(1),320			items_data321				.clone()322				.into_iter()323				.map(|d| { d.into() })324				.collect()325		));326		for (index, _data) in items_data.into_iter().enumerate() {327			let balance = <pallet_refungible::Balance<Test>>::get((328				CollectionId(1),329				TokenId((index + 1) as u32),330				account(1),331			));332			assert_eq!(balance, 1023);333		}334	});335}336337#[test]338fn create_fungible_item() {339	new_test_ext().execute_with(|| {340		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));341342		let data = default_fungible_data();343		create_test_item(collection_id, &data.into());344345		assert_eq!(346			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),347			5348		);349	});350}351352//#[test]353// fn create_multiple_fungible_items() {354//     new_test_ext().execute_with(|| {355//         default_limits();356357//         create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));358359//         let origin1 = RuntimeOrigin::signed(1);360361//         let items_data = vec![default_fungible_data(), default_fungible_data(), default_fungible_data()];362363//         assert_ok!(Unique::create_multiple_items(364//             origin1.clone(),365//             1,366//             1,367//             items_data.clone().into_iter().map(|d| { d.into() }).collect()368//         ));369370//         for (index, _) in items_data.iter().enumerate() {371//             assert_eq!(Unique::fungible_item_id(1, (index + 1) as TokenId).value, 5);372//         }373//         assert_eq!(Unique::balance_count(1, 1), 3000);374//         assert_eq!(Unique::address_tokens(1, 1), [1, 2, 3]);375//     });376// }377378#[test]379fn transfer_fungible_item() {380	new_test_ext().execute_with(|| {381		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));382383		let origin1 = RuntimeOrigin::signed(1);384		let origin2 = RuntimeOrigin::signed(2);385386		let data = default_fungible_data();387		create_test_item(collection_id, &data.into());388389		assert_eq!(390			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),391			5392		);393394		// change owner scenario395		assert_ok!(Unique::transfer(396			origin1,397			account(2),398			CollectionId(1),399			TokenId(0),400			5401		));402		assert_eq!(403			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))),404			0405		);406407		// split item scenario408		assert_ok!(Unique::transfer(409			origin2.clone(),410			account(3),411			CollectionId(1),412			TokenId(0),413			3414		));415416		// split item and new owner has account scenario417		assert_ok!(Unique::transfer(418			origin2,419			account(3),420			CollectionId(1),421			TokenId(0),422			1423		));424		assert_eq!(425			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))),426			1427		);428		assert_eq!(429			<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))),430			4431		);432	});433}434435#[test]436fn transfer_refungible_item() {437	new_test_ext().execute_with(|| {438		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));439440		// Create RFT 1 in 1023 pieces for account 1441		let data = default_re_fungible_data();442		create_test_item(collection_id, &data.clone().into());443		assert_eq!(444			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),445			1446		);447		assert_eq!(448			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),449			1023450		);451		assert_eq!(452			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),453			true454		);455456		// Account 1 transfers all 1023 pieces of RFT 1 to account 2457		let origin1 = RuntimeOrigin::signed(1);458		let origin2 = RuntimeOrigin::signed(2);459		assert_ok!(Unique::transfer(460			origin1,461			account(2),462			CollectionId(1),463			TokenId(1),464			1023465		));466		assert_eq!(467			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),468			1023469		);470		assert_eq!(471			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),472			0473		);474		assert_eq!(475			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),476			1477		);478		assert_eq!(479			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),480			false481		);482		assert_eq!(483			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),484			true485		);486487		// Account 2 transfers 500 pieces of RFT 1 to account 3488		assert_ok!(Unique::transfer(489			origin2.clone(),490			account(3),491			CollectionId(1),492			TokenId(1),493			500494		));495		assert_eq!(496			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),497			523498		);499		assert_eq!(500			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),501			500502		);503		assert_eq!(504			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),505			1506		);507		assert_eq!(508			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),509			1510		);511		assert_eq!(512			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),513			true514		);515		assert_eq!(516			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),517			true518		);519520		// Account 2 transfers 200 more pieces of RFT 1 to account 3 with pre-existing balance521		assert_ok!(Unique::transfer(522			origin2,523			account(3),524			CollectionId(1),525			TokenId(1),526			200527		));528		assert_eq!(529			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2))),530			323531		);532		assert_eq!(533			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),534			700535		);536		assert_eq!(537			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))),538			1539		);540		assert_eq!(541			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),542			1543		);544		assert_eq!(545			<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),546			true547		);548		assert_eq!(549			<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))),550			true551		);552	});553}554555#[test]556fn transfer_nft_item() {557	new_test_ext().execute_with(|| {558		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));559560		let data = default_nft_data();561		create_test_item(collection_id, &data.into());562		assert_eq!(563			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),564			1565		);566		assert_eq!(567			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),568			true569		);570571		let origin1 = RuntimeOrigin::signed(1);572		// default scenario573		assert_ok!(Unique::transfer(574			origin1,575			account(2),576			CollectionId(1),577			TokenId(1),578			1579		));580		assert_eq!(581			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),582			0583		);584		assert_eq!(585			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),586			1587		);588		assert_eq!(589			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),590			false591		);592		assert_eq!(593			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),594			true595		);596	});597}598599#[test]600fn transfer_nft_item_wrong_value() {601	new_test_ext().execute_with(|| {602		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));603604		let data = default_nft_data();605		create_test_item(collection_id, &data.into());606		assert_eq!(607			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),608			1609		);610		assert_eq!(611			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),612			true613		);614615		let origin1 = RuntimeOrigin::signed(1);616617		assert_noop!(618			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 2)619				.map_err(|e| e.error),620			<pallet_nonfungible::Error::<Test>>::NonfungibleItemsHaveNoAmount621		);622	});623}624625#[test]626fn transfer_nft_item_zero_value() {627	new_test_ext().execute_with(|| {628		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));629630		let data = default_nft_data();631		create_test_item(collection_id, &data.into());632		assert_eq!(633			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),634			1635		);636		assert_eq!(637			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),638			true639		);640641		let origin1 = RuntimeOrigin::signed(1);642643		// Transferring 0 amount works on NFT...644		assert_ok!(Unique::transfer(645			origin1,646			account(2),647			CollectionId(1),648			TokenId(1),649			0650		));651		// ... and results in no transfer652		assert_eq!(653			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),654			1655		);656		assert_eq!(657			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),658			true659		);660	});661}662663#[test]664fn nft_approve_and_transfer_from() {665	new_test_ext().execute_with(|| {666		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));667668		let data = default_nft_data();669		create_test_item(collection_id, &data.into());670671		let origin1 = RuntimeOrigin::signed(1);672		let origin2 = RuntimeOrigin::signed(2);673674		assert_eq!(675			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),676			1677		);678		assert_eq!(679			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),680			true681		);682683		// neg transfer_from684		assert_noop!(685			Unique::transfer_from(686				origin2.clone(),687				account(1),688				account(2),689				CollectionId(1),690				TokenId(1),691				1692			)693			.map_err(|e| e.error),694			CommonError::<Test>::ApprovedValueTooLow695		);696697		// do approve698		assert_ok!(Unique::approve(699			origin1,700			account(2),701			CollectionId(1),702			TokenId(1),703			1704		));705		assert_eq!(706			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),707			account(2)708		);709710		assert_ok!(Unique::transfer_from(711			origin2,712			account(1),713			account(3),714			CollectionId(1),715			TokenId(1),716			1717		));718		assert!(719			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()720		);721	});722}723724#[test]725fn nft_approve_and_transfer_from_allow_list() {726	new_test_ext().execute_with(|| {727		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));728729		let origin1 = RuntimeOrigin::signed(1);730		let origin2 = RuntimeOrigin::signed(2);731732		// Create NFT 1 for account 1733		let data = default_nft_data();734		create_test_item(collection_id, &data.clone().into());735		assert_eq!(736			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),737			1738		);739		assert_eq!(740			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),741			true742		);743744		// Allow allow-list users to mint and add accounts 1, 2, and 3 to allow-list745		assert_ok!(Unique::set_collection_permissions(746			origin1.clone(),747			CollectionId(1),748			CollectionPermissions {749				mint_mode: Some(true),750				access: Some(AccessMode::AllowList),751				nesting: None,752			}753		));754		assert_ok!(Unique::add_to_allow_list(755			origin1.clone(),756			CollectionId(1),757			account(1)758		));759		assert_ok!(Unique::add_to_allow_list(760			origin1.clone(),761			CollectionId(1),762			account(2)763		));764		assert_ok!(Unique::add_to_allow_list(765			origin1.clone(),766			CollectionId(1),767			account(3)768		));769770		// Account 1 approves account 2 for NFT 1771		assert_ok!(Unique::approve(772			origin1.clone(),773			account(2),774			CollectionId(1),775			TokenId(1),776			1777		));778		assert_eq!(779			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),780			account(2)781		);782783		// Account 2 transfers NFT 1 from account 1 to account 3784		assert_ok!(Unique::transfer_from(785			origin2,786			account(1),787			account(3),788			CollectionId(1),789			TokenId(1),790			1791		));792		assert!(793			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none()794		);795	});796}797798#[test]799fn refungible_approve_and_transfer_from() {800	new_test_ext().execute_with(|| {801		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));802803		let origin1 = RuntimeOrigin::signed(1);804		let origin2 = RuntimeOrigin::signed(2);805806		// Create RFT 1 in 1023 pieces for account 1807		let data = default_re_fungible_data();808		create_test_item(collection_id, &data.into());809810		assert_eq!(811			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),812			1813		);814		assert_eq!(815			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),816			1023817		);818		assert_eq!(819			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),820			true821		);822823		// Allow public minting, enable allow-list and add accounts 1, 2, 3 to allow-list824		assert_ok!(Unique::set_collection_permissions(825			origin1.clone(),826			CollectionId(1),827			CollectionPermissions {828				mint_mode: Some(true),829				access: Some(AccessMode::AllowList),830				nesting: None,831			}832		));833		assert_ok!(Unique::add_to_allow_list(834			origin1.clone(),835			CollectionId(1),836			account(1)837		));838		assert_ok!(Unique::add_to_allow_list(839			origin1.clone(),840			CollectionId(1),841			account(2)842		));843		assert_ok!(Unique::add_to_allow_list(844			origin1.clone(),845			CollectionId(1),846			account(3)847		));848849		// Account 1 approves account 2 for 1023 pieces of RFT 1850		assert_ok!(Unique::approve(851			origin1,852			account(2),853			CollectionId(1),854			TokenId(1),855			1023856		));857		assert_eq!(858			<pallet_refungible::Allowance<Test>>::get((859				CollectionId(1),860				TokenId(1),861				account(1),862				account(2)863			)),864			1023865		);866867		// Account 2 transfers 100 pieces of RFT 1 from account 1 to account 3868		assert_ok!(Unique::transfer_from(869			origin2,870			account(1),871			account(3),872			CollectionId(1),873			TokenId(1),874			100875		));876		assert_eq!(877			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),878			1879		);880		assert_eq!(881			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))),882			1883		);884		assert_eq!(885			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),886			923887		);888		assert_eq!(889			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3))),890			100891		);892		assert_eq!(893			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),894			true895		);896		assert_eq!(897			<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),898			true899		);900		assert_eq!(901			<pallet_refungible::Allowance<Test>>::get((902				CollectionId(1),903				TokenId(1),904				account(1),905				account(2)906			)),907			923908		);909	});910}911912#[test]913fn fungible_approve_and_transfer_from() {914	new_test_ext().execute_with(|| {915		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));916917		let data = default_fungible_data();918		create_test_item(collection_id, &data.into());919920		let origin1 = RuntimeOrigin::signed(1);921		let origin2 = RuntimeOrigin::signed(2);922923		assert_ok!(Unique::set_collection_permissions(924			origin1.clone(),925			CollectionId(1),926			CollectionPermissions {927				mint_mode: Some(true),928				access: Some(AccessMode::AllowList),929				nesting: None,930			}931		));932		assert_ok!(Unique::add_to_allow_list(933			origin1.clone(),934			CollectionId(1),935			account(1)936		));937		assert_ok!(Unique::add_to_allow_list(938			origin1.clone(),939			CollectionId(1),940			account(2)941		));942		assert_ok!(Unique::add_to_allow_list(943			origin1.clone(),944			CollectionId(1),945			account(3)946		));947948		// do approve949		assert_ok!(Unique::approve(950			origin1.clone(),951			account(2),952			CollectionId(1),953			TokenId(0),954			5955		));956		assert_eq!(957			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),958			5959		);960		assert_ok!(Unique::approve(961			origin1,962			account(3),963			CollectionId(1),964			TokenId(0),965			5966		));967		assert_eq!(968			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),969			5970		);971		assert_eq!(972			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))),973			5974		);975976		assert_ok!(Unique::transfer_from(977			origin2.clone(),978			account(1),979			account(3),980			CollectionId(1),981			TokenId(0),982			4983		));984985		assert_eq!(986			<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))),987			1988		);989990		assert_noop!(991			Unique::transfer_from(992				origin2,993				account(1),994				account(3),995				CollectionId(1),996				TokenId(0),997				4998			)999			.map_err(|e| e.error),1000			CommonError::<Test>::ApprovedValueTooLow1001		);1002	});1003}10041005#[test]1006fn change_collection_owner() {1007	new_test_ext().execute_with(|| {1008		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10091010		let origin1 = RuntimeOrigin::signed(1);1011		assert_ok!(Unique::change_collection_owner(origin1, collection_id, 2));1012		assert_eq!(1013			<pallet_common::CollectionById<Test>>::get(collection_id)1014				.unwrap()1015				.owner,1016			21017		);1018	});1019}10201021#[test]1022fn destroy_collection() {1023	new_test_ext().execute_with(|| {1024		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10251026		let origin1 = RuntimeOrigin::signed(1);1027		assert_ok!(Unique::destroy_collection(origin1, collection_id));1028	});1029}10301031#[test]1032fn burn_nft_item() {1033	new_test_ext().execute_with(|| {1034		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10351036		let origin1 = RuntimeOrigin::signed(1);10371038		let data = default_nft_data();1039		create_test_item(collection_id, &data.into());10401041		// check balance (collection with id = 1, user id = 1)1042		assert_eq!(1043			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1044			11045		);10461047		// burn item1048		assert_ok!(Unique::burn_item(1049			origin1.clone(),1050			collection_id,1051			TokenId(1),1052			11053		));1054		assert_eq!(1055			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1056			01057		);1058	});1059}10601061#[test]1062fn burn_same_nft_item_twice() {1063	new_test_ext().execute_with(|| {1064		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));10651066		let origin1 = RuntimeOrigin::signed(1);10671068		let data = default_nft_data();1069		create_test_item(collection_id, &data.into());10701071		// check balance (collection with id = 1, user id = 1)1072		assert_eq!(1073			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1074			11075		);10761077		// burn item1078		assert_ok!(Unique::burn_item(1079			origin1.clone(),1080			collection_id,1081			TokenId(1),1082			11083		));10841085		// burn item again1086		assert_noop!(1087			Unique::burn_item(origin1, collection_id, TokenId(1), 1).map_err(|e| e.error),1088			CommonError::<Test>::TokenNotFound1089		);10901091		assert_eq!(1092			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),1093			01094		);1095	});1096}10971098#[test]1099fn burn_fungible_item() {1100	new_test_ext().execute_with(|| {1101		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11021103		let origin1 = RuntimeOrigin::signed(1);1104		assert_ok!(Unique::add_collection_admin(1105			origin1.clone(),1106			collection_id,1107			account(2)1108		));11091110		let data = default_fungible_data();1111		create_test_item(collection_id, &data.into());11121113		// check balance (collection with id = 1, user id = 1)1114		assert_eq!(1115			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1116			51117		);11181119		// burn item1120		assert_ok!(Unique::burn_item(1121			origin1.clone(),1122			CollectionId(1),1123			TokenId(0),1124			51125		));1126		assert_noop!(1127			Unique::burn_item(origin1, CollectionId(1), TokenId(0), 5).map_err(|e| e.error),1128			CommonError::<Test>::TokenValueTooLow1129		);11301131		assert_eq!(1132			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1133			01134		);1135	});1136}11371138#[test]1139fn burn_fungible_item_with_token_id() {1140	new_test_ext().execute_with(|| {1141		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));11421143		let origin1 = RuntimeOrigin::signed(1);1144		assert_ok!(Unique::add_collection_admin(1145			origin1.clone(),1146			collection_id,1147			account(2)1148		));11491150		let data = default_fungible_data();1151		create_test_item(collection_id, &data.into());11521153		// check balance (collection with id = 1, user id = 1)1154		assert_eq!(1155			<pallet_fungible::Balance<Test>>::get((collection_id, account(1))),1156			51157		);11581159		// Try to burn item using Token ID1160		assert_noop!(1161			Unique::burn_item(origin1, CollectionId(1), TokenId(1), 5).map_err(|e| e.error),1162			<pallet_fungible::Error::<Test>>::FungibleItemsHaveNoId1163		);1164	});1165}1166#[test]1167fn burn_refungible_item() {1168	new_test_ext().execute_with(|| {1169		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));1170		let origin1 = RuntimeOrigin::signed(1);11711172		assert_ok!(Unique::set_collection_permissions(1173			origin1.clone(),1174			collection_id,1175			CollectionPermissions {1176				mint_mode: Some(true),1177				access: Some(AccessMode::AllowList),1178				nesting: None,1179			}1180		));1181		assert_ok!(Unique::add_to_allow_list(1182			origin1.clone(),1183			collection_id,1184			account(1)1185		));11861187		assert_ok!(Unique::add_collection_admin(1188			origin1.clone(),1189			collection_id,1190			account(2)1191		));11921193		let data = default_re_fungible_data();1194		create_test_item(collection_id, &data.into());11951196		// check balance (collection with id = 1, user id = 2)1197		assert_eq!(1198			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),1199			11200		);1201		assert_eq!(1202			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1203			10231204		);12051206		// burn item1207		assert_ok!(Unique::burn_item(1208			origin1.clone(),1209			collection_id,1210			TokenId(1),1211			10231212		));1213		assert_noop!(1214			Unique::burn_item(origin1, collection_id, TokenId(1), 1023).map_err(|e| e.error),1215			CommonError::<Test>::TokenValueTooLow1216		);12171218		assert_eq!(1219			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))),1220			01221		);1222	});1223}12241225#[test]1226fn add_collection_admin() {1227	new_test_ext().execute_with(|| {1228		let collection1_id =1229			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1230		let origin1 = RuntimeOrigin::signed(1);12311232		// Add collection admins1233		assert_ok!(Unique::add_collection_admin(1234			origin1.clone(),1235			collection1_id,1236			account(2)1237		));1238		assert_ok!(Unique::add_collection_admin(1239			origin1,1240			collection1_id,1241			account(3)1242		));12431244		// Owner is not an admin by default1245		assert_eq!(1246			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))),1247			false1248		);1249		assert!(<pallet_common::IsAdmin<Test>>::get((1250			CollectionId(1),1251			account(2)1252		)));1253		assert!(<pallet_common::IsAdmin<Test>>::get((1254			CollectionId(1),1255			account(3)1256		)));1257	});1258}12591260#[test]1261fn remove_collection_admin() {1262	new_test_ext().execute_with(|| {1263		let collection1_id =1264			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));1265		let origin1 = RuntimeOrigin::signed(1);12661267		// Add collection admins 2 and 31268		assert_ok!(Unique::add_collection_admin(1269			origin1.clone(),1270			collection1_id,1271			account(2)1272		));1273		assert_ok!(Unique::add_collection_admin(1274			origin1.clone(),1275			collection1_id,1276			account(3)1277		));12781279		assert!(<pallet_common::IsAdmin<Test>>::get((1280			CollectionId(1),1281			account(2)1282		)));1283		assert!(<pallet_common::IsAdmin<Test>>::get((1284			CollectionId(1),1285			account(3)1286		)));12871288		// remove admin 31289		assert_ok!(Unique::remove_collection_admin(1290			origin1,1291			CollectionId(1),1292			account(3)1293		));12941295		// 2 is still admin, 3 is not an admin anymore1296		assert!(<pallet_common::IsAdmin<Test>>::get((1297			CollectionId(1),1298			account(2)1299		)));1300		assert_eq!(1301			<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))),1302			false1303		);1304	});1305}13061307#[test]1308fn balance_of() {1309	new_test_ext().execute_with(|| {1310		let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1311		let fungible_collection_id =1312			create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));1313		let re_fungible_collection_id =1314			create_test_collection(&CollectionMode::ReFungible, CollectionId(3));13151316		// check balance before1317		assert_eq!(1318			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1319			01320		);1321		assert_eq!(1322			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1323			01324		);1325		assert_eq!(1326			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1327			01328		);13291330		let nft_data = default_nft_data();1331		create_test_item(nft_collection_id, &nft_data.into());13321333		let fungible_data = default_fungible_data();1334		create_test_item(fungible_collection_id, &fungible_data.into());13351336		let re_fungible_data = default_re_fungible_data();1337		create_test_item(re_fungible_collection_id, &re_fungible_data.into());13381339		// check balance (collection with id = 1, user id = 1)1340		assert_eq!(1341			<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))),1342			11343		);1344		assert_eq!(1345			<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))),1346			51347		);1348		assert_eq!(1349			<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))),1350			11351		);13521353		assert_eq!(1354			<pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))),1355			true1356		);1357		assert_eq!(1358			<pallet_refungible::Owned<Test>>::get((1359				re_fungible_collection_id,1360				account(1),1361				TokenId(1)1362			)),1363			true1364		);1365	});1366}13671368#[test]1369fn approve() {1370	new_test_ext().execute_with(|| {1371		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));13721373		let data = default_nft_data();1374		create_test_item(collection_id, &data.into());13751376		let origin1 = RuntimeOrigin::signed(1);13771378		// approve1379		assert_ok!(Unique::approve(1380			origin1,1381			account(2),1382			CollectionId(1),1383			TokenId(1),1384			11385		));1386		assert_eq!(1387			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1388			account(2)1389		);1390	});1391}13921393#[test]1394fn transfer_from() {1395	new_test_ext().execute_with(|| {1396		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1397		let origin1 = RuntimeOrigin::signed(1);1398		let origin2 = RuntimeOrigin::signed(2);13991400		let data = default_nft_data();1401		create_test_item(collection_id, &data.into());14021403		// approve1404		assert_ok!(Unique::approve(1405			origin1.clone(),1406			account(2),1407			CollectionId(1),1408			TokenId(1),1409			11410		));1411		assert_eq!(1412			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1413			account(2)1414		);14151416		assert_ok!(Unique::set_collection_permissions(1417			origin1.clone(),1418			CollectionId(1),1419			CollectionPermissions {1420				mint_mode: Some(true),1421				access: Some(AccessMode::AllowList),1422				nesting: None,1423			}1424		));1425		assert_ok!(Unique::add_to_allow_list(1426			origin1.clone(),1427			CollectionId(1),1428			account(1)1429		));1430		assert_ok!(Unique::add_to_allow_list(1431			origin1.clone(),1432			CollectionId(1),1433			account(2)1434		));1435		assert_ok!(Unique::add_to_allow_list(1436			origin1,1437			CollectionId(1),1438			account(3)1439		));14401441		assert_ok!(Unique::transfer_from(1442			origin2,1443			account(1),1444			account(2),1445			CollectionId(1),1446			TokenId(1),1447			11448		));14491450		// after transfer1451		assert_eq!(1452			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))),1453			01454		);1455		assert_eq!(1456			<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))),1457			11458		);1459	});1460}14611462// #endregion14631464// Coverage tests region1465// #region14661467#[test]1468fn owner_can_add_address_to_allow_list() {1469	new_test_ext().execute_with(|| {1470		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));14711472		let origin1 = RuntimeOrigin::signed(1);1473		assert_ok!(Unique::add_to_allow_list(1474			origin1,1475			collection_id,1476			account(2)1477		));1478		assert!(<pallet_common::Allowlist<Test>>::get((1479			collection_id,1480			account(2)1481		)));1482	});1483}14841485#[test]1486fn admin_can_add_address_to_allow_list() {1487	new_test_ext().execute_with(|| {1488		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1489		let origin1 = RuntimeOrigin::signed(1);1490		let origin2 = RuntimeOrigin::signed(2);14911492		assert_ok!(Unique::add_collection_admin(1493			origin1,1494			collection_id,1495			account(2)1496		));1497		assert_ok!(Unique::add_to_allow_list(1498			origin2,1499			collection_id,1500			account(3)1501		));1502		assert!(<pallet_common::Allowlist<Test>>::get((1503			collection_id,1504			account(3)1505		)));1506	});1507}15081509#[test]1510fn nonprivileged_user_cannot_add_address_to_allow_list() {1511	new_test_ext().execute_with(|| {1512		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15131514		let origin2 = RuntimeOrigin::signed(2);1515		assert_noop!(1516			Unique::add_to_allow_list(origin2, collection_id, account(3)),1517			CommonError::<Test>::NoPermission1518		);1519	});1520}15211522#[test]1523fn nobody_can_add_address_to_allow_list_of_nonexisting_collection() {1524	new_test_ext().execute_with(|| {1525		let origin1 = RuntimeOrigin::signed(1);15261527		assert_noop!(1528			Unique::add_to_allow_list(origin1, CollectionId(1), account(2)),1529			CommonError::<Test>::CollectionNotFound1530		);1531	});1532}15331534#[test]1535fn nobody_can_add_address_to_allow_list_of_deleted_collection() {1536	new_test_ext().execute_with(|| {1537		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15381539		let origin1 = RuntimeOrigin::signed(1);1540		assert_ok!(Unique::destroy_collection(origin1.clone(), collection_id));1541		assert_noop!(1542			Unique::add_to_allow_list(origin1, collection_id, account(2)),1543			CommonError::<Test>::CollectionNotFound1544		);1545	});1546}15471548// If address is already added to allow list, nothing happens1549#[test]1550fn address_is_already_added_to_allow_list() {1551	new_test_ext().execute_with(|| {1552		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1553		let origin1 = RuntimeOrigin::signed(1);15541555		assert_ok!(Unique::add_to_allow_list(1556			origin1.clone(),1557			collection_id,1558			account(2)1559		));1560		assert_ok!(Unique::add_to_allow_list(1561			origin1,1562			collection_id,1563			account(2)1564		));1565		assert!(<pallet_common::Allowlist<Test>>::get((1566			collection_id,1567			account(2)1568		)));1569	});1570}15711572#[test]1573fn owner_can_remove_address_from_allow_list() {1574	new_test_ext().execute_with(|| {1575		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));15761577		let origin1 = RuntimeOrigin::signed(1);1578		assert_ok!(Unique::add_to_allow_list(1579			origin1.clone(),1580			collection_id,1581			account(2)1582		));1583		assert_ok!(Unique::remove_from_allow_list(1584			origin1,1585			collection_id,1586			account(2)1587		));1588		assert_eq!(1589			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1590			false1591		);1592	});1593}15941595#[test]1596fn admin_can_remove_address_from_allow_list() {1597	new_test_ext().execute_with(|| {1598		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1599		let origin1 = RuntimeOrigin::signed(1);1600		let origin2 = RuntimeOrigin::signed(2);16011602		// Owner adds admin1603		assert_ok!(Unique::add_collection_admin(1604			origin1.clone(),1605			collection_id,1606			account(2)1607		));16081609		// Owner adds address 3 to allow list1610		assert_ok!(Unique::add_to_allow_list(1611			origin1,1612			collection_id,1613			account(3)1614		));16151616		// Admin removes address 3 from allow list1617		assert_ok!(Unique::remove_from_allow_list(1618			origin2,1619			collection_id,1620			account(3)1621		));1622		assert_eq!(1623			<pallet_common::Allowlist<Test>>::get((collection_id, account(3))),1624			false1625		);1626	});1627}16281629#[test]1630fn nonprivileged_user_cannot_remove_address_from_allow_list() {1631	new_test_ext().execute_with(|| {1632		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1633		let origin1 = RuntimeOrigin::signed(1);1634		let origin2 = RuntimeOrigin::signed(2);16351636		assert_ok!(Unique::add_to_allow_list(1637			origin1,1638			collection_id,1639			account(2)1640		));1641		assert_noop!(1642			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1643			CommonError::<Test>::NoPermission1644		);1645		assert!(<pallet_common::Allowlist<Test>>::get((1646			collection_id,1647			account(2)1648		)));1649	});1650}16511652#[test]1653fn nobody_can_remove_address_from_allow_list_of_nonexisting_collection() {1654	new_test_ext().execute_with(|| {1655		let origin1 = RuntimeOrigin::signed(1);16561657		assert_noop!(1658			Unique::remove_from_allow_list(origin1, CollectionId(1), account(2)),1659			CommonError::<Test>::CollectionNotFound1660		);1661	});1662}16631664#[test]1665fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {1666	new_test_ext().execute_with(|| {1667		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1668		let origin1 = RuntimeOrigin::signed(1);1669		let origin2 = RuntimeOrigin::signed(2);16701671		// Add account 2 to allow list1672		assert_ok!(Unique::add_to_allow_list(1673			origin1.clone(),1674			collection_id,1675			account(2)1676		));16771678		// Account 2 is in collection allow-list1679		assert!(<pallet_common::Allowlist<Test>>::get((1680			collection_id,1681			account(2)1682		)));16831684		// Destroy collection1685		assert_ok!(Unique::destroy_collection(origin1, collection_id));16861687		// Attempt to remove account 2 from collection allow-list => error1688		assert_noop!(1689			Unique::remove_from_allow_list(origin2, collection_id, account(2)),1690			CommonError::<Test>::CollectionNotFound1691		);16921693		// Account 2 is not found in collection allow-list anyway1694		assert_eq!(1695			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1696			false1697		);1698	});1699}17001701// If address is already removed from allow list, nothing happens1702#[test]1703fn address_is_already_removed_from_allow_list() {1704	new_test_ext().execute_with(|| {1705		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1706		let origin1 = RuntimeOrigin::signed(1);17071708		assert_ok!(Unique::add_to_allow_list(1709			origin1.clone(),1710			collection_id,1711			account(2)1712		));1713		assert_ok!(Unique::remove_from_allow_list(1714			origin1.clone(),1715			collection_id,1716			account(2)1717		));1718		assert_eq!(1719			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1720			false1721		);1722		assert_ok!(Unique::remove_from_allow_list(1723			origin1,1724			collection_id,1725			account(2)1726		));1727		assert_eq!(1728			<pallet_common::Allowlist<Test>>::get((collection_id, account(2))),1729			false1730		);1731	});1732}17331734// If Public Access mode is set to AllowList, tokens can’t be transferred from a non-allowlisted address with transfer or transferFrom (2 tests)1735#[test]1736fn allow_list_test_1() {1737	new_test_ext().execute_with(|| {1738		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));17391740		let origin1 = RuntimeOrigin::signed(1);17411742		let data = default_nft_data();1743		create_test_item(collection_id, &data.into());17441745		assert_ok!(Unique::set_collection_permissions(1746			origin1.clone(),1747			collection_id,1748			CollectionPermissions {1749				mint_mode: None,1750				access: Some(AccessMode::AllowList),1751				nesting: None,1752			}1753		));1754		assert_ok!(Unique::add_to_allow_list(1755			origin1.clone(),1756			collection_id,1757			account(2)1758		));17591760		assert_noop!(1761			Unique::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1)1762				.map_err(|e| e.error),1763			CommonError::<Test>::AddressNotInAllowlist1764		);1765	});1766}17671768#[test]1769fn allow_list_test_2() {1770	new_test_ext().execute_with(|| {1771		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));1772		let origin1 = RuntimeOrigin::signed(1);17731774		let data = default_nft_data();1775		create_test_item(collection_id, &data.into());17761777		assert_ok!(Unique::set_collection_permissions(1778			origin1.clone(),1779			collection_id,1780			CollectionPermissions {1781				mint_mode: None,1782				access: Some(AccessMode::AllowList),1783				nesting: None,1784			}1785		));1786		assert_ok!(Unique::add_to_allow_list(1787			origin1.clone(),1788			collection_id,1789			account(1)1790		));1791		assert_ok!(Unique::add_to_allow_list(1792			origin1.clone(),1793			collection_id,1794			account(2)1795		));17961797		// do approve1798		assert_ok!(Unique::approve(1799			origin1.clone(),1800			account(1),1801			collection_id,1802			TokenId(1),1803			11804		));1805		assert_eq!(1806			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1807			account(1)1808		);18091810		assert_ok!(Unique::remove_from_allow_list(1811			origin1.clone(),1812			collection_id,1813			account(1)1814		));18151816		assert_noop!(1817			Unique::transfer_from(1818				origin1,1819				account(1),1820				account(3),1821				CollectionId(1),1822				TokenId(1),1823				11824			)1825			.map_err(|e| e.error),1826			CommonError::<Test>::AddressNotInAllowlist1827		);1828	});1829}18301831// If Public Access mode is set to AllowList, tokens can’t be transferred to a non-allowlisted address with transfer or transferFrom (2 tests)1832#[test]1833fn allow_list_test_3() {1834	new_test_ext().execute_with(|| {1835		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18361837		let origin1 = RuntimeOrigin::signed(1);18381839		let data = default_nft_data();1840		create_test_item(collection_id, &data.into());18411842		assert_ok!(Unique::set_collection_permissions(1843			origin1.clone(),1844			collection_id,1845			CollectionPermissions {1846				mint_mode: None,1847				access: Some(AccessMode::AllowList),1848				nesting: None,1849			}1850		));1851		assert_ok!(Unique::add_to_allow_list(1852			origin1.clone(),1853			collection_id,1854			account(1)1855		));18561857		assert_noop!(1858			Unique::transfer(origin1, account(3), collection_id, TokenId(1), 1)1859				.map_err(|e| e.error),1860			CommonError::<Test>::AddressNotInAllowlist1861		);1862	});1863}18641865#[test]1866fn allow_list_test_4() {1867	new_test_ext().execute_with(|| {1868		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));18691870		let origin1 = RuntimeOrigin::signed(1);18711872		let data = default_nft_data();1873		create_test_item(collection_id, &data.into());18741875		assert_ok!(Unique::set_collection_permissions(1876			origin1.clone(),1877			collection_id,1878			CollectionPermissions {1879				mint_mode: None,1880				access: Some(AccessMode::AllowList),1881				nesting: None,1882			}1883		));1884		assert_ok!(Unique::add_to_allow_list(1885			origin1.clone(),1886			collection_id,1887			account(1)1888		));1889		assert_ok!(Unique::add_to_allow_list(1890			origin1.clone(),1891			collection_id,1892			account(2)1893		));18941895		// do approve1896		assert_ok!(Unique::approve(1897			origin1.clone(),1898			account(1),1899			collection_id,1900			TokenId(1),1901			11902		));1903		assert_eq!(1904			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),1905			account(1)1906		);19071908		assert_ok!(Unique::remove_from_allow_list(1909			origin1.clone(),1910			collection_id,1911			account(2)1912		));19131914		assert_noop!(1915			Unique::transfer_from(1916				origin1,1917				account(1),1918				account(3),1919				collection_id,1920				TokenId(1),1921				11922			)1923			.map_err(|e| e.error),1924			CommonError::<Test>::AddressNotInAllowlist1925		);1926	});1927}19281929// If Public Access mode is set to AllowList, tokens can’t be destroyed by a non-allowlisted address (even if it owned them before enabling AllowList mode)1930#[test]1931fn allow_list_test_5() {1932	new_test_ext().execute_with(|| {1933		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19341935		let origin1 = RuntimeOrigin::signed(1);19361937		let data = default_nft_data();1938		create_test_item(collection_id, &data.into());19391940		assert_ok!(Unique::set_collection_permissions(1941			origin1.clone(),1942			collection_id,1943			CollectionPermissions {1944				mint_mode: None,1945				access: Some(AccessMode::AllowList),1946				nesting: None,1947			}1948		));1949		assert_noop!(1950			Unique::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 1).map_err(|e| e.error),1951			CommonError::<Test>::AddressNotInAllowlist1952		);1953	});1954}19551956// If Public Access mode is set to AllowList, token transfers can’t be Approved by a non-allowlisted address (see Approve method).1957#[test]1958fn allow_list_test_6() {1959	new_test_ext().execute_with(|| {1960		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19611962		let origin1 = RuntimeOrigin::signed(1);19631964		let data = default_nft_data();1965		create_test_item(collection_id, &data.into());19661967		assert_ok!(Unique::set_collection_permissions(1968			origin1.clone(),1969			collection_id,1970			CollectionPermissions {1971				mint_mode: None,1972				access: Some(AccessMode::AllowList),1973				nesting: None,1974			}1975		));19761977		// do approve1978		assert_noop!(1979			Unique::approve(origin1, account(1), CollectionId(1), TokenId(1), 1)1980				.map_err(|e| e.error),1981			CommonError::<Test>::AddressNotInAllowlist1982		);1983	});1984}19851986// If Public Access mode is set to AllowList, tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests) and1987//          tokens can be transferred from a allowlisted address with transfer or transferFrom (2 tests)1988#[test]1989fn allow_list_test_7() {1990	new_test_ext().execute_with(|| {1991		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));19921993		let data = default_nft_data();1994		create_test_item(collection_id, &data.into());19951996		let origin1 = RuntimeOrigin::signed(1);19971998		assert_ok!(Unique::set_collection_permissions(1999			origin1.clone(),2000			collection_id,2001			CollectionPermissions {2002				mint_mode: None,2003				access: Some(AccessMode::AllowList),2004				nesting: None,2005			}2006		));2007		assert_ok!(Unique::add_to_allow_list(2008			origin1.clone(),2009			collection_id,2010			account(1)2011		));2012		assert_ok!(Unique::add_to_allow_list(2013			origin1.clone(),2014			collection_id,2015			account(2)2016		));20172018		assert_ok!(Unique::transfer(2019			origin1,2020			account(2),2021			CollectionId(1),2022			TokenId(1),2023			12024		));2025	});2026}20272028#[test]2029fn allow_list_test_8() {2030	new_test_ext().execute_with(|| {2031		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));20322033		// Create NFT for account 12034		let data = default_nft_data();2035		create_test_item(collection_id, &data.into());20362037		let origin1 = RuntimeOrigin::signed(1);20382039		// Toggle Allow List mode and add accounts 1 and 22040		assert_ok!(Unique::set_collection_permissions(2041			origin1.clone(),2042			collection_id,2043			CollectionPermissions {2044				mint_mode: None,2045				access: Some(AccessMode::AllowList),2046				nesting: None,2047			}2048		));2049		assert_ok!(Unique::add_to_allow_list(2050			origin1.clone(),2051			collection_id,2052			account(1)2053		));2054		assert_ok!(Unique::add_to_allow_list(2055			origin1.clone(),2056			collection_id,2057			account(2)2058		));20592060		// Sself-approve account 1 for NFT 12061		assert_ok!(Unique::approve(2062			origin1.clone(),2063			account(1),2064			CollectionId(1),2065			TokenId(1),2066			12067		));2068		assert_eq!(2069			<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(),2070			account(1)2071		);20722073		// Transfer from 1 to 22074		assert_ok!(Unique::transfer_from(2075			origin1,2076			account(1),2077			account(2),2078			CollectionId(1),2079			TokenId(1),2080			12081		));2082	});2083}20842085// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by owner.2086#[test]2087fn allow_list_test_9() {2088	new_test_ext().execute_with(|| {2089		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2090		let origin1 = RuntimeOrigin::signed(1);20912092		assert_ok!(Unique::set_collection_permissions(2093			origin1.clone(),2094			collection_id,2095			CollectionPermissions {2096				mint_mode: Some(false),2097				access: Some(AccessMode::AllowList),2098				nesting: None,2099			}2100		));21012102		let data = default_nft_data();2103		create_test_item(collection_id, &data.into());2104	});2105}21062107// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens can be created by admin.2108#[test]2109fn allow_list_test_10() {2110	new_test_ext().execute_with(|| {2111		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21122113		let origin1 = RuntimeOrigin::signed(1);2114		let origin2 = RuntimeOrigin::signed(2);21152116		assert_ok!(Unique::set_collection_permissions(2117			origin1.clone(),2118			collection_id,2119			CollectionPermissions {2120				mint_mode: Some(false),2121				access: Some(AccessMode::AllowList),2122				nesting: None,2123			}2124		));21252126		assert_ok!(Unique::add_collection_admin(2127			origin1,2128			collection_id,2129			account(2)2130		));21312132		assert_ok!(Unique::create_item(2133			origin2,2134			collection_id,2135			account(2),2136			default_nft_data().into()2137		));2138	});2139}21402141// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and allow listed address.2142#[test]2143fn allow_list_test_11() {2144	new_test_ext().execute_with(|| {2145		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21462147		let origin1 = RuntimeOrigin::signed(1);2148		let origin2 = RuntimeOrigin::signed(2);21492150		assert_ok!(Unique::set_collection_permissions(2151			origin1.clone(),2152			collection_id,2153			CollectionPermissions {2154				mint_mode: Some(false),2155				access: Some(AccessMode::AllowList),2156				nesting: None,2157			}2158		));2159		assert_ok!(Unique::add_to_allow_list(2160			origin1,2161			collection_id,2162			account(2)2163		));21642165		assert_noop!(2166			Unique::create_item(2167				origin2,2168				CollectionId(1),2169				account(2),2170				default_nft_data().into()2171			)2172			.map_err(|e| e.error),2173			CommonError::<Test>::PublicMintingNotAllowed2174		);2175	});2176}21772178// If Public Access mode is set to AllowList, and Mint Permission is set to false, tokens cannot be created by non-privileged and non-allow listed address.2179#[test]2180fn allow_list_test_12() {2181	new_test_ext().execute_with(|| {2182		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));21832184		let origin1 = RuntimeOrigin::signed(1);2185		let origin2 = RuntimeOrigin::signed(2);21862187		assert_ok!(Unique::set_collection_permissions(2188			origin1.clone(),2189			collection_id,2190			CollectionPermissions {2191				mint_mode: Some(false),2192				access: Some(AccessMode::AllowList),2193				nesting: None,2194			}2195		));21962197		assert_noop!(2198			Unique::create_item(2199				origin2,2200				CollectionId(1),2201				account(2),2202				default_nft_data().into()2203			)2204			.map_err(|e| e.error),2205			CommonError::<Test>::PublicMintingNotAllowed2206		);2207	});2208}22092210// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by owner.2211#[test]2212fn allow_list_test_13() {2213	new_test_ext().execute_with(|| {2214		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22152216		let origin1 = RuntimeOrigin::signed(1);22172218		assert_ok!(Unique::set_collection_permissions(2219			origin1.clone(),2220			collection_id,2221			CollectionPermissions {2222				mint_mode: Some(true),2223				access: Some(AccessMode::AllowList),2224				nesting: None,2225			}2226		));22272228		let data = default_nft_data();2229		create_test_item(collection_id, &data.into());2230	});2231}22322233// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by admin.2234#[test]2235fn allow_list_test_14() {2236	new_test_ext().execute_with(|| {2237		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22382239		let origin1 = RuntimeOrigin::signed(1);2240		let origin2 = RuntimeOrigin::signed(2);22412242		assert_ok!(Unique::set_collection_permissions(2243			origin1.clone(),2244			collection_id,2245			CollectionPermissions {2246				mint_mode: Some(true),2247				access: Some(AccessMode::AllowList),2248				nesting: None,2249			}2250		));22512252		assert_ok!(Unique::add_collection_admin(2253			origin1,2254			collection_id,2255			account(2)2256		));22572258		assert_ok!(Unique::create_item(2259			origin2,2260			collection_id,2261			account(2),2262			default_nft_data().into()2263		));2264	});2265}22662267// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens cannot be created by non-privileged and non-allow listed address.2268#[test]2269fn allow_list_test_15() {2270	new_test_ext().execute_with(|| {2271		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));22722273		let origin1 = RuntimeOrigin::signed(1);2274		let origin2 = RuntimeOrigin::signed(2);22752276		assert_ok!(Unique::set_collection_permissions(2277			origin1.clone(),2278			collection_id,2279			CollectionPermissions {2280				mint_mode: Some(true),2281				access: Some(AccessMode::AllowList),2282				nesting: None,2283			}2284		));22852286		assert_noop!(2287			Unique::create_item(2288				origin2,2289				collection_id,2290				account(2),2291				default_nft_data().into()2292			)2293			.map_err(|e| e.error),2294			CommonError::<Test>::AddressNotInAllowlist2295		);2296	});2297}22982299// If Public Access mode is set to AllowList, and Mint Permission is set to true, tokens can be created by non-privileged and allow listed address.2300#[test]2301fn allow_list_test_16() {2302	new_test_ext().execute_with(|| {2303		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23042305		let origin1 = RuntimeOrigin::signed(1);2306		let origin2 = RuntimeOrigin::signed(2);23072308		assert_ok!(Unique::set_collection_permissions(2309			origin1.clone(),2310			collection_id,2311			CollectionPermissions {2312				mint_mode: Some(true),2313				access: Some(AccessMode::AllowList),2314				nesting: None,2315			}2316		));2317		assert_ok!(Unique::add_to_allow_list(2318			origin1,2319			collection_id,2320			account(2)2321		));23222323		assert_ok!(Unique::create_item(2324			origin2,2325			collection_id,2326			account(2),2327			default_nft_data().into()2328		));2329	});2330}23312332// Total number of collections. Positive test2333#[test]2334fn total_number_collections_bound() {2335	new_test_ext().execute_with(|| {2336		create_test_collection(&CollectionMode::NFT, CollectionId(1));2337	});2338}23392340#[test]2341fn create_max_collections() {2342	new_test_ext().execute_with(|| {2343		for i in 1..COLLECTION_NUMBER_LIMIT {2344			create_test_collection(&CollectionMode::NFT, CollectionId(i));2345		}2346	});2347}23482349// Total number of collections. Negative test2350#[test]2351fn total_number_collections_bound_neg() {2352	new_test_ext().execute_with(|| {2353		let origin1 = RuntimeOrigin::signed(1);23542355		for i in 1..=COLLECTION_NUMBER_LIMIT {2356			create_test_collection(&CollectionMode::NFT, CollectionId(i));2357		}23582359		let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();2360		let col_desc1: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();2361		let token_prefix1: Vec<u8> = b"token_prefix1\0".to_vec();23622363		let data: CreateCollectionData<u64> = CreateCollectionData {2364			name: col_name1.try_into().unwrap(),2365			description: col_desc1.try_into().unwrap(),2366			token_prefix: token_prefix1.try_into().unwrap(),2367			mode: CollectionMode::NFT,2368			..Default::default()2369		};23702371		// 11-th collection in chain. Expects error2372		assert_noop!(2373			Unique::create_collection_ex(origin1, data),2374			CommonError::<Test>::TotalCollectionsLimitExceeded2375		);2376	});2377}23782379// Owned tokens by a single address. Positive test2380#[test]2381fn owned_tokens_bound() {2382	new_test_ext().execute_with(|| {2383		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23842385		let data = default_nft_data();2386		create_test_item(collection_id, &data.clone().into());2387		create_test_item(collection_id, &data.into());2388	});2389}23902391// Owned tokens by a single address. Negotive test2392#[test]2393fn owned_tokens_bound_neg() {2394	new_test_ext().execute_with(|| {2395		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));23962397		let origin1 = RuntimeOrigin::signed(1);23982399		for _ in 1..=MAX_TOKEN_OWNERSHIP {2400			let data = default_nft_data();2401			create_test_item(collection_id, &data.clone().into());2402		}24032404		let data = default_nft_data();2405		assert_noop!(2406			Unique::create_item(origin1, CollectionId(1), account(1), data.into())2407				.map_err(|e| e.error),2408			CommonError::<Test>::AccountTokenLimitExceeded2409		);2410	});2411}24122413// Number of collection admins. Positive test2414#[test]2415fn collection_admins_bound() {2416	new_test_ext().execute_with(|| {2417		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24182419		let origin1 = RuntimeOrigin::signed(1);24202421		assert_ok!(Unique::add_collection_admin(2422			origin1.clone(),2423			collection_id,2424			account(2)2425		));2426		assert_ok!(Unique::add_collection_admin(2427			origin1,2428			collection_id,2429			account(3)2430		));2431	});2432}24332434// Number of collection admins. Negotive test2435#[test]2436fn collection_admins_bound_neg() {2437	new_test_ext().execute_with(|| {2438		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));24392440		let origin1 = RuntimeOrigin::signed(1);24412442		for i in 0..COLLECTION_ADMINS_LIMIT {2443			assert_ok!(Unique::add_collection_admin(2444				origin1.clone(),2445				collection_id,2446				account((2 + i).into())2447			));2448		}2449		assert_noop!(2450			Unique::add_collection_admin(2451				origin1,2452				collection_id,2453				account((3 + COLLECTION_ADMINS_LIMIT).into())2454			),2455			CommonError::<Test>::CollectionAdminCountExceeded2456		);2457	});2458}2459// #endregion24602461#[test]2462fn collection_transfer_flag_works() {2463	new_test_ext().execute_with(|| {2464		let origin1 = RuntimeOrigin::signed(1);24652466		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2467		assert_ok!(Unique::set_transfers_enabled_flag(2468			origin1,2469			collection_id,2470			true2471		));24722473		let data = default_nft_data();2474		create_test_item(collection_id, &data.into());2475		assert_eq!(2476			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2477			12478		);2479		assert_eq!(2480			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2481			true2482		);24832484		let origin1 = RuntimeOrigin::signed(1);24852486		// default scenario2487		assert_ok!(Unique::transfer(2488			origin1,2489			account(2),2490			collection_id,2491			TokenId(1),2492			12493		));2494		assert_eq!(2495			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2496			false2497		);2498		assert_eq!(2499			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2500			true2501		);2502		assert_eq!(2503			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2504			02505		);2506		assert_eq!(2507			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2508			12509		);2510	});2511}25122513#[test]2514fn collection_transfer_flag_works_neg() {2515	new_test_ext().execute_with(|| {2516		let origin1 = RuntimeOrigin::signed(1);25172518		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));2519		assert_ok!(Unique::set_transfers_enabled_flag(2520			origin1,2521			collection_id,2522			false2523		));25242525		let data = default_nft_data();2526		create_test_item(collection_id, &data.into());2527		assert_eq!(2528			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2529			12530		);2531		assert_eq!(2532			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2533			true2534		);25352536		let origin1 = RuntimeOrigin::signed(1);25372538		// default scenario2539		assert_noop!(2540			Unique::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1)2541				.map_err(|e| e.error),2542			CommonError::<Test>::TransferNotAllowed2543		);2544		assert_eq!(2545			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))),2546			12547		);2548		assert_eq!(2549			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),2550			02551		);2552		assert_eq!(2553			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))),2554			true2555		);2556		assert_eq!(2557			<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))),2558			false2559		);2560	});2561}25622563#[test]2564fn collection_sponsoring() {2565	new_test_ext().execute_with(|| {2566		// default_limits();2567		let user1 = 1_u64;2568		let user2 = 777_u64;2569		let origin1 = RuntimeOrigin::signed(user1);2570		let origin2 = RuntimeOrigin::signed(user2);2571		let account2 = account(user2);25722573		let collection_id =2574			create_test_collection_for_owner(&CollectionMode::NFT, user1, CollectionId(1));2575		assert_ok!(Unique::set_collection_sponsor(2576			origin1.clone(),2577			collection_id,2578			user12579		));2580		assert_ok!(Unique::confirm_sponsorship(origin1.clone(), collection_id));25812582		// Expect error while have no permissions2583		assert!(Unique::create_item(2584			origin2.clone(),2585			collection_id,2586			account2.clone(),2587			default_nft_data().into()2588		)2589		.is_err());25902591		assert_ok!(Unique::set_collection_permissions(2592			origin1.clone(),2593			collection_id,2594			CollectionPermissions {2595				mint_mode: Some(true),2596				access: Some(AccessMode::AllowList),2597				nesting: None,2598			}2599		));2600		assert_ok!(Unique::add_to_allow_list(2601			origin1.clone(),2602			collection_id,2603			account2.clone()2604		));26052606		assert_ok!(Unique::create_item(2607			origin2,2608			collection_id,2609			account2,2610			default_nft_data().into()2611		));2612	});2613}
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;