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

difftreelog

Merge branch 'feature/pallet-structure-rebased' of https://github.com/UniqueNetwork/unique-chain into feature/pallet-structure-rebased

Fahrrader2022-05-19parents: #547ee7a #aa4cd0e.patch.diff
in: master

68 files changed

modified.maintain/scripts/generate_api.shdiffbeforeafterboth
--- a/.maintain/scripts/generate_api.sh
+++ b/.maintain/scripts/generate_api.sh
@@ -7,6 +7,5 @@
 sed -n '/=== SNIP START ===/, /=== SNIP END ===/{ /=== SNIP START ===/! { /=== SNIP END ===/! p } }' $tmp > $raw
 formatted=$(mktemp)
 prettier --use-tabs $raw > $formatted
-solhint --fix $formatted
 
 mv $formatted $OUTPUT
modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6391,6 +6391,7 @@
  "sp-core",
  "sp-runtime",
  "sp-std",
+ "struct-versioning",
  "up-data-structs",
 ]
 
@@ -6508,6 +6509,7 @@
  "sp-core",
  "sp-runtime",
  "sp-std",
+ "struct-versioning",
  "up-data-structs",
 ]
 
modifiedclient/rpc/src/lib.rsdiffbeforeafterboth
--- a/client/rpc/src/lib.rs
+++ b/client/rpc/src/lib.rs
@@ -30,8 +30,8 @@
 // RMRK
 use rmrk_rpc::RmrkApi as RmrkRuntimeApi;
 use up_data_structs::{
-	RmrkCollectionId, RmrkNftId, RmrkBaseId, RmrkNftChild,
-	RmrkThemeName, RmrkPropertyKey, RmrkResourceId
+	RmrkCollectionId, RmrkNftId, RmrkBaseId, RmrkNftChild, RmrkThemeName, RmrkPropertyKey,
+	RmrkResourceId,
 };
 
 pub use rmrk_unique_rpc::RmrkApi;
@@ -75,13 +75,6 @@
 	) -> Result<Option<CrossAccountId>>;
 	#[rpc(name = "unique_constMetadata")]
 	fn const_metadata(
-		&self,
-		collection: CollectionId,
-		token: TokenId,
-		at: Option<BlockHash>,
-	) -> Result<Vec<u8>>;
-	#[rpc(name = "unique_variableMetadata")]
-	fn variable_metadata(
 		&self,
 		collection: CollectionId,
 		token: TokenId,
@@ -92,7 +85,7 @@
 	fn collection_properties(
 		&self,
 		collection: CollectionId,
-		keys: Vec<String>,
+		keys: Option<Vec<String>>,
 		at: Option<BlockHash>,
 	) -> Result<Vec<Property>>;
 
@@ -101,7 +94,7 @@
 		&self,
 		collection: CollectionId,
 		token_id: TokenId,
-		properties: Vec<String>,
+		keys: Option<Vec<String>>,
 		at: Option<BlockHash>,
 	) -> Result<Vec<Property>>;
 
@@ -109,7 +102,7 @@
 	fn property_permissions(
 		&self,
 		collection: CollectionId,
-		keys: Vec<String>,
+		keys: Option<Vec<String>>,
 		at: Option<BlockHash>,
 	) -> Result<Vec<PropertyKeyPermission>>;
 
@@ -118,7 +111,7 @@
 		&self,
 		collection: CollectionId,
 		token_id: TokenId,
-		keys: Vec<String>,
+		keys: Option<Vec<String>>,
 		at: Option<BlockHash>,
 	) -> Result<TokenData<CrossAccountId>>;
 
@@ -428,10 +421,6 @@
 	);
 	pass_method!(
 		const_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>, unique_api
-	);
-	pass_method!(
-		variable_metadata(collection: CollectionId, token: TokenId) -> Vec<u8>,
-		unique_api
 	);
 	pass_method!(total_supply(collection: CollectionId) -> u32, unique_api);
 	pass_method!(account_balance(collection: CollectionId, account: CrossAccountId) -> u32, unique_api);
@@ -445,7 +434,7 @@
 		collection: CollectionId,
 
 		#[map(|keys| string_keys_to_bytes_keys(keys))]
-		keys: Vec<String>
+		keys: Option<Vec<String>>
 	) -> Vec<Property>, unique_api);
 
 	pass_method!(token_properties(
@@ -453,14 +442,14 @@
 		token_id: TokenId,
 
 		#[map(|keys| string_keys_to_bytes_keys(keys))]
-		properties: Vec<String>
+		keys: Option<Vec<String>>
 	) -> Vec<Property>, unique_api);
 
 	pass_method!(property_permissions(
 		collection: CollectionId,
 
 		#[map(|keys| string_keys_to_bytes_keys(keys))]
-		keys: Vec<String>
+		keys: Option<Vec<String>>
 	) -> Vec<PropertyKeyPermission>, unique_api);
 
 	pass_method!(token_data(
@@ -468,7 +457,7 @@
 		token_id: TokenId,
 
 		#[map(|keys| string_keys_to_bytes_keys(keys))]
-		keys: Vec<String>,
+		keys: Option<Vec<String>>,
 	) -> TokenData<CrossAccountId>, unique_api);
 
 	pass_method!(adminlist(collection: CollectionId) -> Vec<CrossAccountId>, unique_api);
@@ -549,6 +538,6 @@
 	pass_method!(theme(base_id: RmrkBaseId, theme_name: RmrkThemeName, filter_keys: Option<Vec<RmrkPropertyKey>>) -> Option<Theme>, rmrk_api);
 }
 
-fn string_keys_to_bytes_keys(keys: Vec<String>) -> Vec<Vec<u8>> {
-	keys.into_iter().map(|key| key.into_bytes()).collect()
+fn string_keys_to_bytes_keys(keys: Option<Vec<String>>) -> Option<Vec<Vec<u8>>> {
+	keys.map(|keys| keys.into_iter().map(|key| key.into_bytes()).collect())
 }
modifiednode/cli/src/service.rsdiffbeforeafterboth
--- a/node/cli/src/service.rs
+++ b/node/cli/src/service.rs
@@ -65,25 +65,12 @@
 use fc_rpc_core::types::FilterPool;
 use fc_mapping_sync::{MappingSyncWorker, SyncStrategy};
 
-use unique_runtime_common::types::{
-	AuraId,
-	RuntimeInstance,
-	AccountId,
-	Balance,
-	Index,
-	Hash,
-	Block,
-};
+use unique_runtime_common::types::{AuraId, RuntimeInstance, AccountId, Balance, Index, Hash, Block};
 
 // RMRK
 use up_data_structs::{
-	RmrkCollectionInfo,
-	RmrkInstanceInfo,
-	RmrkResourceInfo,
-	RmrkPropertyInfo,
-	RmrkBaseInfo,
-	RmrkPartType,
-	RmrkTheme,
+	RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
+	RmrkPartType, RmrkTheme,
 };
 
 /// Unique native executor instance.
modifiednode/rpc/src/lib.rsdiffbeforeafterboth
--- a/node/rpc/src/lib.rs
+++ b/node/rpc/src/lib.rs
@@ -41,17 +41,12 @@
 use std::{collections::BTreeMap, sync::Arc};
 
 use unique_runtime_common::types::{
-	Hash,
-	AccountId,
-	RuntimeInstance,
-	Index,
-	Block,
-	BlockNumber,
-	Balance,
+	Hash, AccountId, RuntimeInstance, Index, Block, BlockNumber, Balance,
 };
 // RMRK
 use up_data_structs::{
-	RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo, RmrkPartType, RmrkTheme, 
+	RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo,
+	RmrkPartType, RmrkTheme,
 };
 
 /// Public io handler for exporting into other modules
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -21,7 +21,7 @@
 use sp_std::vec::Vec;
 use up_data_structs::Property;
 
-use crate::{Pallet, CollectionHandle, Config};
+use crate::{Pallet, CollectionHandle, Config, CollectionProperties};
 
 /// Does not always represent a full collection, for RFT it is either
 /// collection (Implementing ERC721), or specific collection token (Implementing ERC20)
@@ -33,24 +33,35 @@
 
 #[solidity_interface(name = "CollectionProperties")]
 impl<T: Config> CollectionHandle<T> {
-	fn set_property(&mut self, caller: caller, key: string, value: string) -> Result<()> {
-		<Pallet<T>>::set_collection_property(
-			self,
-			&T::CrossAccountId::from_eth(caller),
-			Property {
-				key: <Vec<u8>>::from(key)
-					.try_into()
-					.map_err(|_| "key too large")?,
-				value: <Vec<u8>>::from(value)
-					.try_into()
-					.map_err(|_| "value too large")?,
-			},
-		)
-		.map_err(dispatch_to_evm::<T>)?;
-		Ok(())
+	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()
+			.map_err(|_| "key too large")?;
+		let value = value.try_into().map_err(|_| "value too large")?;
+
+		<Pallet<T>>::set_collection_property(self, &caller, Property { key, value })
+			.map_err(dispatch_to_evm::<T>)
 	}
 
-	fn delete_property(&mut self, caller: caller, key: string) -> Result<()> {
-		self.set_property(caller, key, string::new())
+	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()
+			.map_err(|_| "key too large")?;
+
+		<Pallet<T>>::delete_collection_property(self, &caller, key).map_err(dispatch_to_evm::<T>)
+	}
+
+	/// Throws error if key not found
+	fn collection_property(&self, key: string) -> Result<bytes> {
+		let key = <Vec<u8>>::from(key)
+			.try_into()
+			.map_err(|_| "key too large")?;
+
+		let props = <CollectionProperties<T>>::get(self.id);
+		let prop = props.get(&key).ok_or("key not found")?;
+
+		Ok(prop.to_vec())
 	}
 }
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -22,23 +22,56 @@
 use pallet_evm::account::CrossAccountId;
 use frame_support::{
 	dispatch::{DispatchErrorWithPostInfo, DispatchResultWithPostInfo, Weight, PostDispatchInfo},
-	ensure, fail,
+	ensure,
 	traits::{Imbalance, Get, Currency, WithdrawReasons, ExistenceRequirement},
 	BoundedVec,
 	weights::Pays,
+	transactional,
 };
 use pallet_evm::GasWeightMapping;
 use up_data_structs::{
-	COLLECTION_NUMBER_LIMIT, Collection, RpcCollection, CollectionId, CreateItemData,
-	MAX_TOKEN_PREFIX_LENGTH, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission, TokenId,
-	CollectionStats, MAX_TOKEN_OWNERSHIP, CollectionMode, NFT_SPONSOR_TRANSFER_TIMEOUT,
-	FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MAX_SPONSOR_TIMEOUT,
-	CUSTOM_DATA_LIMIT, CollectionLimits, CustomDataLimit, CreateCollectionData, SponsorshipState,
-	CreateItemExData, SponsoringRateLimit, budget::Budget, COLLECTION_FIELD_LIMIT, CollectionField,
-	PhantomType, Property, Properties, PropertiesPermissionMap, PropertyKey, PropertyPermission,
-	PropertiesError, PropertyKeyPermission, TokenData, TrySet,
+	COLLECTION_NUMBER_LIMIT,
+	Collection,
+	RpcCollection,
+	CollectionId,
+	CreateItemData,
+	MAX_TOKEN_PREFIX_LENGTH,
+	COLLECTION_ADMINS_LIMIT,
+	TokenId,
+	CollectionStats,
+	MAX_TOKEN_OWNERSHIP,
+	CollectionMode,
+	NFT_SPONSOR_TRANSFER_TIMEOUT,
+	FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+	REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT,
+	MAX_SPONSOR_TIMEOUT,
+	CUSTOM_DATA_LIMIT,
+	CollectionLimits,
+	CreateCollectionData,
+	SponsorshipState,
+	CreateItemExData,
+	SponsoringRateLimit,
+	budget::Budget,
+	COLLECTION_FIELD_LIMIT,
+	CollectionField,
+	PhantomType,
+	Property,
+	Properties,
+	PropertiesPermissionMap,
+	PropertyKey,
+	PropertyPermission,
+	PropertiesError,
+	PropertyKeyPermission,
+	TokenData,
+	TrySetProperty,
 	// RMRK
-	RmrkCollectionInfo, RmrkInstanceInfo, RmrkResourceInfo, RmrkPropertyInfo, RmrkBaseInfo, RmrkPartType, RmrkTheme,
+	RmrkCollectionInfo,
+	RmrkInstanceInfo,
+	RmrkResourceInfo,
+	RmrkPropertyInfo,
+	RmrkBaseInfo,
+	RmrkPartType,
+	RmrkTheme,
 	RmrkNftChild,
 };
 
@@ -138,21 +171,6 @@
 			<Error<T>>::AddressNotInAllowlist
 		);
 		Ok(())
-	}
-
-	pub fn check_can_update_meta(
-		&self,
-		subject: &T::CrossAccountId,
-		item_owner: &T::CrossAccountId,
-	) -> DispatchResult {
-		match self.meta_update_permission {
-			MetaUpdatePermission::ItemOwner => {
-				ensure!(subject == item_owner, <Error<T>>::NoPermission);
-				Ok(())
-			}
-			MetaUpdatePermission::Admin => self.check_is_owner_or_admin(subject),
-			MetaUpdatePermission::None => fail!(<Error<T>>::NoPermission),
-		}
 	}
 }
 
@@ -316,8 +334,6 @@
 		CollectionTokenPrefixLimitExceeded,
 		/// Total collections bound exceeded.
 		TotalCollectionsLimitExceeded,
-		/// variable_data exceeded data limit.
-		TokenVariableDataLimitExceeded,
 		/// Exceeded max admin count
 		CollectionAdminCountExceeded,
 		/// Collection limit bounds per collection exceeded
@@ -366,8 +382,8 @@
 		/// Tried to store more property keys than allowed
 		PropertyLimitReached,
 
-		/// Unable to read array of unbounded keys
-		UnableToReadUnboundedKeys,
+		/// Property key is too long
+		PropertyKeyIsTooLong,
 
 		/// Only ASCII letters, digits, and '_', '-' are allowed
 		InvalidCharacterInPropertyKey,
@@ -580,7 +596,6 @@
 			schema_version,
 			sponsorship,
 			limits,
-			meta_update_permission,
 		} = <CollectionById<T>>::get(collection)?;
 
 		let token_property_permissions = <CollectionPropertyPermissions<T>>::get(collection)
@@ -610,7 +625,6 @@
 			schema_version,
 			sponsorship,
 			limits,
-			meta_update_permission,
 			offchain_schema: <CollectionData<T>>::get((
 				collection,
 				CollectionField::OffchainSchema,
@@ -671,7 +685,6 @@
 				.limits
 				.map(|limits| Self::clamp_limits(data.mode.clone(), &Default::default(), limits))
 				.unwrap_or_else(|| Ok(CollectionLimits::default()))?,
-			meta_update_permission: data.meta_update_permission.unwrap_or_default(),
 		};
 
 		let mut collection_properties = up_data_structs::CollectionProperties::get();
@@ -775,6 +788,7 @@
 		Ok(())
 	}
 
+	#[transactional]
 	pub fn set_collection_properties(
 		collection: &CollectionHandle<T>,
 		sender: &T::CrossAccountId,
@@ -807,6 +821,7 @@
 		Ok(())
 	}
 
+	#[transactional]
 	pub fn delete_collection_properties(
 		collection: &CollectionHandle<T>,
 		sender: &T::CrossAccountId,
@@ -849,6 +864,7 @@
 		Ok(())
 	}
 
+	#[transactional]
 	pub fn set_property_permissions(
 		collection: &CollectionHandle<T>,
 		sender: &T::CrossAccountId,
@@ -867,60 +883,69 @@
 		keys.into_iter()
 			.map(|key| -> Result<PropertyKey, DispatchError> {
 				key.try_into()
-					.map_err(|_| <Error<T>>::UnableToReadUnboundedKeys.into())
+					.map_err(|_| <Error<T>>::PropertyKeyIsTooLong.into())
 			})
 			.collect::<Result<Vec<PropertyKey>, DispatchError>>()
-	}
-
-	pub fn check_property_key(key: &PropertyKey) -> Result<(), DispatchError> {
-		let key_str = sp_std::str::from_utf8(key.as_slice())
-			.map_err(|_| <Error<T>>::InvalidCharacterInPropertyKey)?;
-
-		for ch in key_str.chars() {
-			if !ch.is_ascii_alphanumeric() && ch != '_' && ch != '-' {
-				return Err(<Error<T>>::InvalidCharacterInPropertyKey.into());
-			}
-		}
-
-		Ok(())
 	}
 
 	pub fn filter_collection_properties(
 		collection_id: CollectionId,
-		keys: Vec<PropertyKey>,
+		keys: Option<Vec<PropertyKey>>,
 	) -> Result<Vec<Property>, DispatchError> {
 		let properties = Self::collection_properties(collection_id);
 
 		let properties = keys
-			.into_iter()
-			.filter_map(|key| {
-				properties.get(&key).map(|value| Property {
-					key,
-					value: value.clone(),
-				})
+			.map(|keys| {
+				keys.into_iter()
+					.filter_map(|key| {
+						properties.get(&key).map(|value| Property {
+							key,
+							value: value.clone(),
+						})
+					})
+					.collect()
 			})
-			.collect();
+			.unwrap_or_else(|| {
+				properties
+					.iter()
+					.map(|(key, value)| Property {
+						key: key.clone(),
+						value: value.clone(),
+					})
+					.collect()
+			});
 
 		Ok(properties)
 	}
 
 	pub fn filter_property_permissions(
 		collection_id: CollectionId,
-		keys: Vec<PropertyKey>,
+		keys: Option<Vec<PropertyKey>>,
 	) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
 		let permissions = Self::property_permissions(collection_id);
 
 		let key_permissions = keys
-			.into_iter()
-			.filter_map(|key| {
+			.map(|keys| {
+				keys.into_iter()
+					.filter_map(|key| {
+						permissions
+							.get(&key)
+							.map(|permission| PropertyKeyPermission {
+								key,
+								permission: permission.clone(),
+							})
+					})
+					.collect()
+			})
+			.unwrap_or_else(|| {
 				permissions
-					.get(&key)
-					.map(|permission| PropertyKeyPermission {
-						key,
+					.iter()
+					.map(|(key, permission)| PropertyKeyPermission {
+						key: key.clone(),
 						permission: permission.clone(),
 					})
-			})
-			.collect();
+					.collect()
+			});
 
 		Ok(key_permissions)
 	}
@@ -1086,7 +1111,6 @@
 	fn approve() -> Weight;
 	fn transfer_from() -> Weight;
 	fn burn_from() -> Weight;
-	fn set_variable_metadata(bytes: u32) -> Weight;
 }
 
 pub trait CommonCollectionOperations<T: Config> {
@@ -1174,13 +1198,6 @@
 		token: TokenId,
 		amount: u128,
 		nesting_budget: &dyn Budget,
-	) -> DispatchResultWithPostInfo;
-
-	fn set_variable_metadata(
-		&self,
-		sender: T::CrossAccountId,
-		token: TokenId,
-		data: BoundedVec<u8, CustomDataLimit>,
 	) -> DispatchResultWithPostInfo;
 
 	fn check_nesting(
@@ -1198,8 +1215,7 @@
 
 	fn token_owner(&self, token: TokenId) -> Option<T::CrossAccountId>;
 	fn const_metadata(&self, token: TokenId) -> Vec<u8>;
-	fn variable_metadata(&self, token: TokenId) -> Vec<u8>;
-	fn token_properties(&self, token_id: TokenId, keys: Vec<PropertyKey>) -> Vec<Property>;
+	fn token_properties(&self, token_id: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property>;
 	/// Amount of unique collection tokens
 	fn total_supply(&self) -> u32;
 	/// Amount of different tokens account has (Applicable to nonfungible/refungible)
@@ -1232,6 +1248,7 @@
 			PropertiesError::NoSpaceForProperty => Self::NoSpaceForProperty,
 			PropertiesError::PropertyLimitReached => Self::PropertyLimitReached,
 			PropertiesError::InvalidCharacterInPropertyKey => Self::InvalidCharacterInPropertyKey,
+			PropertiesError::PropertyKeyIsTooLong => Self::PropertyKeyIsTooLong,
 			PropertiesError::EmptyPropertyKey => Self::EmptyPropertyKey,
 		}
 	}
modifiedpallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterboth

binary blob — no preview

modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -16,12 +16,12 @@
 
 use core::marker::PhantomData;
 
-use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};
+use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
 use up_data_structs::{TokenId, CollectionId, CreateItemExData, budget::Budget};
 use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
 use sp_runtime::ArithmeticError;
 use sp_std::{vec::Vec, vec};
-use up_data_structs::{CustomDataLimit, Property, PropertyKey, PropertyKeyPermission};
+use up_data_structs::{Property, PropertyKey, PropertyKeyPermission};
 
 use crate::{
 	Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf, weights::WeightInfo,
@@ -84,11 +84,6 @@
 
 	fn burn_from() -> Weight {
 		<SelfWeightOf<T>>::burn_from()
-	}
-
-	fn set_variable_metadata(_bytes: u32) -> Weight {
-		// Error
-		0
 	}
 }
 
@@ -287,15 +282,6 @@
 		fail!(<Error<T>>::SettingPropertiesNotAllowed)
 	}
 
-	fn set_variable_metadata(
-		&self,
-		_sender: T::CrossAccountId,
-		_token: TokenId,
-		_data: BoundedVec<u8, CustomDataLimit>,
-	) -> DispatchResultWithPostInfo {
-		fail!(<Error<T>>::FungibleItemsDontHaveData)
-	}
-
 	fn check_nesting(
 		&self,
 		_sender: <T>::CrossAccountId,
@@ -330,13 +316,14 @@
 		None
 	}
 	fn const_metadata(&self, _token: TokenId) -> Vec<u8> {
-		Vec::new()
-	}
-	fn variable_metadata(&self, _token: TokenId) -> Vec<u8> {
 		Vec::new()
 	}
 
-	fn token_properties(&self, _token_id: TokenId, _keys: Vec<PropertyKey>) -> Vec<Property> {
+	fn token_properties(
+		&self,
+		_token_id: TokenId,
+		_keys: Option<Vec<PropertyKey>>,
+	) -> Vec<Property> {
 		Vec::new()
 	}
 
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
@@ -8,8 +8,13 @@
 	uint8 dummy;
 	string stub_error = "this contract is implemented in native";
 }
+
 contract ERC165 is Dummy {
-	function supportsInterface(bytes4 interfaceID) external view returns (bool) {
+	function supportsInterface(bytes4 interfaceID)
+		external
+		view
+		returns (bool)
+	{
 		require(false, stub_error);
 		interfaceID;
 		return true;
@@ -19,24 +24,11 @@
 // Inline
 contract ERC20Events {
 	event Transfer(address indexed from, address indexed to, uint256 value);
-	event Approval(address indexed owner, address indexed spender, uint256 value);
-}
-
-// Selector: 56fd500b
-contract CollectionProperties is Dummy, ERC165 {
-	// Selector: setProperty(string,string) 62d9491f
-	function setProperty(string memory key, string memory value) public {
-		require(false, stub_error);
-		key;
-		value;
-		dummy = 0;
-	}
-	// Selector: deleteProperty(string) 34241914
-	function deleteProperty(string memory key) public {
-		require(false, stub_error);
-		key;
-		dummy = 0;
-	}
+	event Approval(
+		address indexed owner,
+		address indexed spender,
+		uint256 value
+	);
 }
 
 // Selector: 79cc6790
@@ -59,24 +51,28 @@
 		dummy;
 		return "";
 	}
+
 	// Selector: symbol() 95d89b41
 	function symbol() public view returns (string memory) {
 		require(false, stub_error);
 		dummy;
 		return "";
 	}
+
 	// Selector: totalSupply() 18160ddd
 	function totalSupply() public view returns (uint256) {
 		require(false, stub_error);
 		dummy;
 		return 0;
 	}
+
 	// Selector: decimals() 313ce567
 	function decimals() public view returns (uint8) {
 		require(false, stub_error);
 		dummy;
 		return 0;
 	}
+
 	// Selector: balanceOf(address) 70a08231
 	function balanceOf(address owner) public view returns (uint256) {
 		require(false, stub_error);
@@ -84,6 +80,7 @@
 		dummy;
 		return 0;
 	}
+
 	// Selector: transfer(address,uint256) a9059cbb
 	function transfer(address to, uint256 amount) public returns (bool) {
 		require(false, stub_error);
@@ -92,8 +89,13 @@
 		dummy = 0;
 		return false;
 	}
+
 	// Selector: transferFrom(address,address,uint256) 23b872dd
-	function transferFrom(address from, address to, uint256 amount) public returns (bool) {
+	function transferFrom(
+		address from,
+		address to,
+		uint256 amount
+	) public returns (bool) {
 		require(false, stub_error);
 		from;
 		to;
@@ -101,6 +103,7 @@
 		dummy = 0;
 		return false;
 	}
+
 	// Selector: approve(address,uint256) 095ea7b3
 	function approve(address spender, uint256 amount) public returns (bool) {
 		require(false, stub_error);
@@ -109,8 +112,13 @@
 		dummy = 0;
 		return false;
 	}
+
 	// Selector: allowance(address,address) dd62ed3e
-	function allowance(address owner, address spender) public view returns (uint256) {
+	function allowance(address owner, address spender)
+		public
+		view
+		returns (uint256)
+	{
 		require(false, stub_error);
 		owner;
 		spender;
@@ -119,6 +127,44 @@
 	}
 }
 
-contract UniqueFungible is Dummy, ERC165, ERC20, ERC20UniqueExtensions, CollectionProperties {
+// Selector: 9b5e29c5
+contract CollectionProperties is Dummy, ERC165 {
+	// Selector: setCollectionProperty(string,bytes) 2f073f66
+	function setCollectionProperty(string memory key, bytes memory value)
+		public
+	{
+		require(false, stub_error);
+		key;
+		value;
+		dummy = 0;
+	}
+
+	// Selector: deleteCollectionProperty(string) 7b7debce
+	function deleteCollectionProperty(string memory key) public {
+		require(false, stub_error);
+		key;
+		dummy = 0;
+	}
+
+	// Throws error if key not found
+	//
+	// Selector: collectionProperty(string) cf24fd6d
+	function collectionProperty(string memory key)
+		public
+		view
+		returns (bytes memory)
+	{
+		require(false, stub_error);
+		key;
+		dummy;
+		return hex"";
+	}
 }
 
+contract UniqueFungible is
+	Dummy,
+	ERC165,
+	ERC20,
+	ERC20UniqueExtensions,
+	CollectionProperties
+{}
modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/nonfungible/Cargo.toml
+++ b/pallets/nonfungible/Cargo.toml
@@ -27,6 +27,7 @@
 scale-info = { version = "2.0.1", default-features = false, features = [
     "derive",
 ] }
+struct-versioning = { path = "../../crates/struct-versioning" }
 
 [features]
 default = ["std"]
modifiedpallets/nonfungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/benchmarking.rs
+++ b/pallets/nonfungible/src/benchmarking.rs
@@ -28,12 +28,7 @@
 
 fn create_max_item_data<T: Config>(owner: T::CrossAccountId) -> CreateItemData<T> {
 	let const_data = create_data::<CUSTOM_DATA_LIMIT>();
-	let variable_data = create_data::<CUSTOM_DATA_LIMIT>();
-	CreateItemData::<T> {
-		const_data,
-		variable_data,
-		owner,
-	}
+	CreateItemData::<T> { const_data, owner }
 }
 fn create_max_item<T: Config>(
 	collection: &NonfungibleHandle<T>,
@@ -125,14 +120,4 @@
 		let item = create_max_item(&collection, &owner, sender.clone())?;
 		<Pallet<T>>::set_allowance(&collection, &sender, item, Some(&burner))?;
 	}: {<Pallet<T>>::burn_from(&collection, &burner, &sender, item, &Unlimited)?}
-
-	set_variable_metadata {
-		let b in 0..CUSTOM_DATA_LIMIT;
-		bench_init!{
-			owner: sub; collection: collection(owner);
-			owner: cross_from_sub; sender: cross_sub;
-		};
-		let item = create_max_item(&collection, &owner, sender.clone())?;
-		let data = create_var_data(b).try_into().unwrap();
-	}: {<Pallet<T>>::set_variable_metadata(&collection, &sender, item, data)?}
 }
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -16,10 +16,10 @@
 
 use core::marker::PhantomData;
 
-use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, BoundedVec};
+use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
 use up_data_structs::{
-	TokenId, CustomDataLimit, CreateItemExData, CollectionId, budget::Budget, Property,
-	PropertyKey, PropertyKeyPermission,
+	TokenId, CreateItemExData, CollectionId, budget::Budget, Property, PropertyKey,
+	PropertyKeyPermission,
 };
 use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
 use sp_runtime::DispatchError;
@@ -86,10 +86,6 @@
 	fn burn_from() -> Weight {
 		<SelfWeightOf<T>>::burn_from()
 	}
-
-	fn set_variable_metadata(bytes: u32) -> Weight {
-		<SelfWeightOf<T>>::set_variable_metadata(bytes)
-	}
 }
 
 fn map_create_data<T: Config>(
@@ -99,7 +95,6 @@
 	match data {
 		up_data_structs::CreateItemData::NFT(data) => Ok(CreateItemData::<T> {
 			const_data: data.const_data,
-			variable_data: data.variable_data,
 			properties: data.properties,
 			owner: to.clone(),
 		}),
@@ -184,7 +179,7 @@
 		let weight = <CommonWeights<T>>::delete_collection_properties(property_keys.len() as u32);
 
 		with_weight(
-			<Pallet<T>>::delete_collection_properties(self, &sender, property_keys),
+			<Pallet<T>>::delete_collection_properties(self, sender, property_keys),
 			weight,
 		)
 	}
@@ -327,19 +322,6 @@
 		}
 	}
 
-	fn set_variable_metadata(
-		&self,
-		sender: T::CrossAccountId,
-		token: TokenId,
-		data: BoundedVec<u8, CustomDataLimit>,
-	) -> DispatchResultWithPostInfo {
-		let len = data.len();
-		with_weight(
-			<Pallet<T>>::set_variable_metadata(self, &sender, token, data),
-			<CommonWeights<T>>::set_variable_metadata(len as u32),
-		)
-	}
-
 	fn check_nesting(
 		&self,
 		sender: T::CrossAccountId,
@@ -379,24 +361,29 @@
 			.unwrap_or_default()
 			.into_inner()
 	}
-	fn variable_metadata(&self, token: TokenId) -> Vec<u8> {
-		<TokenData<T>>::get((self.id, token))
-			.map(|t| t.variable_data)
-			.unwrap_or_default()
-			.into_inner()
-	}
 
-	fn token_properties(&self, token_id: TokenId, keys: Vec<PropertyKey>) -> Vec<Property> {
+	fn token_properties(&self, token_id: TokenId, keys: Option<Vec<PropertyKey>>) -> Vec<Property> {
 		let properties = <Pallet<T>>::token_properties((self.id, token_id));
 
-		keys.into_iter()
-			.filter_map(|key| {
-				properties.get(&key).map(|value| Property {
-					key,
+		keys.map(|keys| {
+			keys.into_iter()
+				.filter_map(|key| {
+					properties.get(&key).map(|value| Property {
+						key,
+						value: value.clone(),
+					})
+				})
+				.collect()
+		})
+		.unwrap_or_else(|| {
+			properties
+				.iter()
+				.map(|(key, value)| Property {
+					key: key.clone(),
 					value: value.clone(),
 				})
-			})
-			.collect()
+				.collect()
+		})
 	}
 
 	fn total_supply(&self) -> u32 {
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -21,10 +21,10 @@
 };
 use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight};
 use frame_support::BoundedVec;
-use up_data_structs::{TokenId, SchemaVersion};
+use up_data_structs::{TokenId, SchemaVersion, PropertyPermission, PropertyKeyPermission, Property};
 use pallet_evm_coder_substrate::dispatch_to_evm;
 use sp_core::{H160, U256};
-use sp_std::{vec::Vec, vec};
+use sp_std::vec::Vec;
 use pallet_common::{
 	erc::{CommonEvmHandler, PrecompileResult, CollectionPropertiesCall},
 	CollectionHandle,
@@ -35,9 +35,80 @@
 
 use crate::{
 	AccountBalance, Config, CreateItemData, NonfungibleHandle, Pallet, TokenData, TokensMinted,
-	SelfWeightOf, weights::WeightInfo,
+	SelfWeightOf, weights::WeightInfo, TokenProperties,
 };
 
+#[solidity_interface(name = "TokenProperties")]
+impl<T: Config> NonfungibleHandle<T> {
+	fn set_token_property_permission(
+		&mut self,
+		caller: caller,
+		key: string,
+		is_mutable: bool,
+		collection_admin: bool,
+		token_owner: bool,
+	) -> Result<()> {
+		let caller = T::CrossAccountId::from_eth(caller);
+		<Pallet<T>>::set_property_permission(
+			self,
+			&caller,
+			PropertyKeyPermission {
+				key: <Vec<u8>>::from(key)
+					.try_into()
+					.map_err(|_| "too long key")?,
+				permission: PropertyPermission {
+					mutable: is_mutable,
+					collection_admin,
+					token_owner,
+				},
+			},
+		)
+		.map_err(dispatch_to_evm::<T>)
+	}
+
+	fn set_property(
+		&mut self,
+		caller: caller,
+		token_id: uint256,
+		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")?;
+		let key = <Vec<u8>>::from(key)
+			.try_into()
+			.map_err(|_| "key too long")?;
+		let value = value.try_into().map_err(|_| "value too long")?;
+
+		<Pallet<T>>::set_token_property(self, &caller, TokenId(token_id), Property { key, value })
+			.map_err(dispatch_to_evm::<T>)
+	}
+
+	fn delete_property(&mut self, token_id: uint256, 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)
+			.try_into()
+			.map_err(|_| "key too long")?;
+
+		<Pallet<T>>::delete_token_property(self, &caller, TokenId(token_id), key)
+			.map_err(dispatch_to_evm::<T>)
+	}
+
+	/// Throws error if key not found
+	fn property(&self, token_id: uint256, 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()
+			.map_err(|_| "key too long")?;
+
+		let props = <TokenProperties<T>>::get((self.id, token_id));
+		let prop = props.get(&key).ok_or("key not found")?;
+
+		Ok(prop.to_vec())
+	}
+}
+
 fn error_unsupported_schema_version() -> Error {
 	alloc::format!(
 		"Unsupported schema version! Support only {:?}",
@@ -274,7 +345,6 @@
 			&caller,
 			CreateItemData::<T> {
 				const_data: BoundedVec::default(),
-				variable_data: BoundedVec::default(),
 				properties: BoundedVec::default(),
 				owner: to,
 			},
@@ -322,7 +392,6 @@
 				const_data: Vec::<u8>::from(token_uri)
 					.try_into()
 					.map_err(|_| "token uri is too long")?,
-				variable_data: BoundedVec::default(),
 				properties: BoundedVec::default(),
 				owner: to,
 			},
@@ -387,37 +456,6 @@
 			.into())
 	}
 
-	#[weight(<SelfWeightOf<T>>::set_variable_metadata(data.len() as u32))]
-	fn set_variable_metadata(
-		&mut self,
-		caller: caller,
-		token_id: uint256,
-		data: bytes,
-	) -> Result<void> {
-		let caller = T::CrossAccountId::from_eth(caller);
-		let token = token_id.try_into()?;
-
-		<Pallet<T>>::set_variable_metadata(
-			self,
-			&caller,
-			token,
-			data.try_into()
-				.map_err(|_| "metadata size exceeded limit")?,
-		)
-		.map_err(dispatch_to_evm::<T>)?;
-		Ok(())
-	}
-
-	fn get_variable_metadata(&self, token_id: uint256) -> Result<bytes> {
-		self.consume_store_reads(1)?;
-		let token: TokenId = token_id.try_into()?;
-
-		Ok(<TokenData<T>>::get((self.id, token))
-			.ok_or("token not found")?
-			.variable_data
-			.into_inner())
-	}
-
 	#[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> {
 		let caller = T::CrossAccountId::from_eth(caller);
@@ -440,7 +478,6 @@
 		let data = (0..total_tokens)
 			.map(|_| CreateItemData::<T> {
 				const_data: BoundedVec::default(),
-				variable_data: BoundedVec::default(),
 				properties: BoundedVec::default(),
 				owner: to.clone(),
 			})
@@ -484,7 +521,6 @@
 				const_data: Vec::<u8>::from(token_uri)
 					.try_into()
 					.map_err(|_| "token uri is too long")?,
-				variable_data: vec![].try_into().unwrap(),
 				properties: BoundedVec::default(),
 				owner: to.clone(),
 			});
@@ -505,7 +541,8 @@
 		ERC721UniqueExtensions,
 		ERC721Mintable,
 		ERC721Burnable,
-		via("CollectionHandle<T>", common_mut, CollectionProperties)
+		via("CollectionHandle<T>", common_mut, CollectionProperties),
+		TokenProperties,
 	)
 )]
 impl<T: Config> NonfungibleHandle<T> {}
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
before · pallets/nonfungible/src/lib.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#![cfg_attr(not(feature = "std"), no_std)]1819use erc::ERC721Events;20use evm_coder::ToLog;21use frame_support::{BoundedVec, ensure, fail};22use up_data_structs::{23	AccessMode, CollectionId, CustomDataLimit, TokenId, CreateCollectionData, CreateNftExData,24	mapping::TokenAddressMapping, NestingRule, budget::Budget, Property, PropertyPermission,25	PropertyKey, PropertyKeyPermission, Properties, TrySet,26};27use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};28use pallet_common::{29	Error as CommonError, Pallet as PalletCommon, Event as CommonEvent, CollectionHandle,30	dispatch::CollectionDispatch, eth::collection_id_to_address,31};32use pallet_structure::Pallet as PalletStructure;33use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};34use sp_core::H160;35use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};36use sp_std::{vec::Vec, vec};37use core::ops::Deref;38use sp_std::collections::btree_map::BTreeMap;39use codec::{Encode, Decode, MaxEncodedLen};40use scale_info::TypeInfo;4142pub use pallet::*;43#[cfg(feature = "runtime-benchmarks")]44pub mod benchmarking;45pub mod common;46pub mod erc;47pub mod weights;4849pub type CreateItemData<T> = CreateNftExData<<T as pallet_evm::account::Config>::CrossAccountId>;50pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;5152#[derive(Encode, Decode, TypeInfo, MaxEncodedLen)]53pub struct ItemData<CrossAccountId> {54	pub const_data: BoundedVec<u8, CustomDataLimit>,55	pub variable_data: BoundedVec<u8, CustomDataLimit>,56	pub owner: CrossAccountId,57}5859#[frame_support::pallet]60pub mod pallet {61	use super::*;62	use frame_support::{Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};63	use up_data_structs::{CollectionId, TokenId};64	use super::weights::WeightInfo;6566	#[pallet::error]67	pub enum Error<T> {68		/// Not Nonfungible item data used to mint in Nonfungible collection.69		NotNonfungibleDataUsedToMintFungibleCollectionToken,70		/// Used amount > 1 with NFT71		NonfungibleItemsHaveNoAmount,72	}7374	#[pallet::config]75	pub trait Config:76		frame_system::Config + pallet_common::Config + pallet_structure::Config + pallet_evm::Config77	{78		type WeightInfo: WeightInfo;79	}8081	#[pallet::pallet]82	#[pallet::generate_store(pub(super) trait Store)]83	pub struct Pallet<T>(_);8485	#[pallet::storage]86	pub type TokensMinted<T: Config> =87		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;88	#[pallet::storage]89	pub type TokensBurnt<T: Config> =90		StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;9192	#[pallet::storage]93	pub type TokenData<T: Config> = StorageNMap<94		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),95		Value = ItemData<T::CrossAccountId>,96		QueryKind = OptionQuery,97	>;9899	#[pallet::storage]100	#[pallet::getter(fn token_properties)]101	pub type TokenProperties<T: Config> = StorageNMap<102		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),103		Value = Properties,104		QueryKind = ValueQuery,105		OnEmpty = up_data_structs::TokenProperties,106	>;107108	/// Used to enumerate tokens owned by account109	#[pallet::storage]110	pub type Owned<T: Config> = StorageNMap<111		Key = (112			Key<Twox64Concat, CollectionId>,113			Key<Blake2_128Concat, T::CrossAccountId>,114			Key<Twox64Concat, TokenId>,115		),116		Value = bool,117		QueryKind = ValueQuery,118	>;119120	#[pallet::storage]121	pub type AccountBalance<T: Config> = StorageNMap<122		Key = (123			Key<Twox64Concat, CollectionId>,124			Key<Blake2_128Concat, T::CrossAccountId>,125		),126		Value = u32,127		QueryKind = ValueQuery,128	>;129130	#[pallet::storage]131	pub type Allowance<T: Config> = StorageNMap<132		Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),133		Value = T::CrossAccountId,134		QueryKind = OptionQuery,135	>;136}137138pub struct NonfungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);139impl<T: Config> NonfungibleHandle<T> {140	pub fn cast(inner: pallet_common::CollectionHandle<T>) -> Self {141		Self(inner)142	}143	pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {144		self.0145	}146	pub fn common_mut(&mut self) -> &mut pallet_common::CollectionHandle<T> {147		&mut self.0148	}149}150impl<T: Config> WithRecorder<T> for NonfungibleHandle<T> {151	fn recorder(&self) -> &SubstrateRecorder<T> {152		self.0.recorder()153	}154	fn into_recorder(self) -> SubstrateRecorder<T> {155		self.0.into_recorder()156	}157}158impl<T: Config> Deref for NonfungibleHandle<T> {159	type Target = pallet_common::CollectionHandle<T>;160161	fn deref(&self) -> &Self::Target {162		&self.0163	}164}165166impl<T: Config> Pallet<T> {167	pub fn total_supply(collection: &NonfungibleHandle<T>) -> u32 {168		<TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)169	}170	pub fn token_exists(collection: &NonfungibleHandle<T>, token: TokenId) -> bool {171		<TokenData<T>>::contains_key((collection.id, token))172	}173}174175// unchecked calls skips any permission checks176impl<T: Config> Pallet<T> {177	pub fn init_collection(178		owner: T::AccountId,179		data: CreateCollectionData<T::AccountId>,180	) -> Result<CollectionId, DispatchError> {181		<PalletCommon<T>>::init_collection(owner, data)182	}183	pub fn destroy_collection(184		collection: NonfungibleHandle<T>,185		sender: &T::CrossAccountId,186	) -> DispatchResult {187		let id = collection.id;188189		// =========190191		PalletCommon::destroy_collection(collection.0, sender)?;192193		<TokenData<T>>::remove_prefix((id,), None);194		<Owned<T>>::remove_prefix((id,), None);195		<TokensMinted<T>>::remove(id);196		<TokensBurnt<T>>::remove(id);197		<Allowance<T>>::remove_prefix((id,), None);198		<AccountBalance<T>>::remove_prefix((id,), None);199		Ok(())200	}201202	pub fn burn(203		collection: &NonfungibleHandle<T>,204		sender: &T::CrossAccountId,205		token: TokenId,206	) -> DispatchResult {207		let token_data =208			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;209		ensure!(210			&token_data.owner == sender211				|| (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(sender)),212			<CommonError<T>>::NoPermission213		);214215		if collection.access == AccessMode::AllowList {216			collection.check_allowlist(sender)?;217		}218219		let burnt = <TokensBurnt<T>>::get(collection.id)220			.checked_add(1)221			.ok_or(ArithmeticError::Overflow)?;222223		let balance = <AccountBalance<T>>::get((collection.id, token_data.owner.clone()))224			.checked_sub(1)225			.ok_or(ArithmeticError::Overflow)?;226227		if balance == 0 {228			<AccountBalance<T>>::remove((collection.id, token_data.owner.clone()));229		} else {230			<AccountBalance<T>>::insert((collection.id, token_data.owner.clone()), balance);231		}232		// =========233234		<Owned<T>>::remove((collection.id, &token_data.owner, token));235		<TokensBurnt<T>>::insert(collection.id, burnt);236		<TokenData<T>>::remove((collection.id, token));237		let old_spender = <Allowance<T>>::take((collection.id, token));238239		if let Some(old_spender) = old_spender {240			<PalletCommon<T>>::deposit_event(CommonEvent::Approved(241				collection.id,242				token,243				sender.clone(),244				old_spender,245				0,246			));247		}248249		<PalletEvm<T>>::deposit_log(250			ERC721Events::Transfer {251				from: *token_data.owner.as_eth(),252				to: H160::default(),253				token_id: token.into(),254			}255			.to_log(collection_id_to_address(collection.id)),256		);257		<PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(258			collection.id,259			token,260			token_data.owner,261			1,262		));263		Ok(())264	}265266	pub fn set_token_property(267		collection: &NonfungibleHandle<T>,268		sender: &T::CrossAccountId,269		token_id: TokenId,270		property: Property,271	) -> DispatchResult {272		Self::check_token_change_permission(collection, sender, token_id, &property.key)?;273274		<TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {275			let property = property.clone();276			properties.try_set(property.key, property.value)277		})278		.map_err(<CommonError<T>>::from)?;279280		<PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertySet(281			collection.id,282			token_id,283			property.key,284		));285286		Ok(())287	}288289	pub fn set_token_properties(290		collection: &NonfungibleHandle<T>,291		sender: &T::CrossAccountId,292		token_id: TokenId,293		properties: Vec<Property>,294	) -> DispatchResult {295		for property in properties {296			Self::set_token_property(collection, sender, token_id, property)?;297		}298299		Ok(())300	}301302	pub fn delete_token_property(303		collection: &NonfungibleHandle<T>,304		sender: &T::CrossAccountId,305		token_id: TokenId,306		property_key: PropertyKey,307	) -> DispatchResult {308		Self::check_token_change_permission(collection, sender, token_id, &property_key)?;309310		<TokenProperties<T>>::try_mutate((collection.id, token_id), |properties| {311			properties.remove(&property_key)312		})313		.map_err(<CommonError<T>>::from)?;314315		<PalletCommon<T>>::deposit_event(CommonEvent::TokenPropertyDeleted(316			collection.id,317			token_id,318			property_key,319		));320321		Ok(())322	}323324	fn check_token_change_permission(325		collection: &NonfungibleHandle<T>,326		sender: &T::CrossAccountId,327		token_id: TokenId,328		property_key: &PropertyKey,329	) -> DispatchResult {330		let permission = <PalletCommon<T>>::property_permissions(collection.id)331			.get(property_key)332			.map(|p| p.clone())333			.unwrap_or(PropertyPermission::none());334335		let token_data = <TokenData<T>>::get((collection.id, token_id))336			.ok_or(<CommonError<T>>::TokenNotFound)?;337338		let check_token_owner = || -> DispatchResult {339			ensure!(&token_data.owner == sender, <CommonError<T>>::NoPermission);340			Ok(())341		};342343		let is_property_exists = TokenProperties::<T>::get((collection.id, token_id))344			.get(property_key)345			.is_some();346347		match permission {348			PropertyPermission { mutable: false, .. } if is_property_exists => {349				Err(<CommonError<T>>::NoPermission.into())350			}351352			PropertyPermission {353				collection_admin,354				token_owner,355				..356			} => {357				let mut check_result = Err(<CommonError<T>>::NoPermission.into());358359				if collection_admin {360					check_result = collection.check_is_owner_or_admin(sender);361				}362363				if token_owner {364					check_result.or_else(|_| check_token_owner())365				} else {366					check_result367				}368			}369		}370	}371372	pub fn delete_token_properties(373		collection: &NonfungibleHandle<T>,374		sender: &T::CrossAccountId,375		token_id: TokenId,376		property_keys: Vec<PropertyKey>,377	) -> DispatchResult {378		for key in property_keys {379			Self::delete_token_property(collection, sender, token_id, key)?;380		}381382		Ok(())383	}384385	pub fn set_collection_properties(386		collection: &NonfungibleHandle<T>,387		sender: &T::CrossAccountId,388		properties: Vec<Property>,389	) -> DispatchResult {390		<PalletCommon<T>>::set_collection_properties(collection, sender, properties)391	}392393	pub fn delete_collection_properties(394		collection: &CollectionHandle<T>,395		sender: &T::CrossAccountId,396		property_keys: Vec<PropertyKey>,397	) -> DispatchResult {398		<PalletCommon<T>>::delete_collection_properties(collection, sender, property_keys)399	}400401	pub fn set_property_permissions(402		collection: &CollectionHandle<T>,403		sender: &T::CrossAccountId,404		property_permissions: Vec<PropertyKeyPermission>,405	) -> DispatchResult {406		<PalletCommon<T>>::set_property_permissions(collection, sender, property_permissions)407	}408409	pub fn transfer(410		collection: &NonfungibleHandle<T>,411		from: &T::CrossAccountId,412		to: &T::CrossAccountId,413		token: TokenId,414		nesting_budget: &dyn Budget,415	) -> DispatchResult {416		ensure!(417			collection.limits.transfers_enabled(),418			<CommonError<T>>::TransferNotAllowed419		);420421		let token_data =422			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;423		// TODO: require sender to be token, owner, require admins to go through transfer_from424		ensure!(425			&token_data.owner == from426				|| (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(from)),427			<CommonError<T>>::NoPermission428		);429430		if collection.access == AccessMode::AllowList {431			collection.check_allowlist(from)?;432			collection.check_allowlist(to)?;433		}434		<PalletCommon<T>>::ensure_correct_receiver(to)?;435436		let balance_from = <AccountBalance<T>>::get((collection.id, from))437			.checked_sub(1)438			.ok_or(<CommonError<T>>::TokenValueTooLow)?;439		let balance_to = if from != to {440			let balance_to = <AccountBalance<T>>::get((collection.id, to))441				.checked_add(1)442				.ok_or(ArithmeticError::Overflow)?;443444			ensure!(445				balance_to < collection.limits.account_token_ownership_limit(),446				<CommonError<T>>::AccountTokenLimitExceeded,447			);448449			Some(balance_to)450		} else {451			None452		};453454		if let Some(target) = T::CrossTokenAddressMapping::address_to_token(to) {455			let handle = <CollectionHandle<T>>::try_get(target.0)?;456			let dispatch = T::CollectionDispatch::dispatch(handle);457			let dispatch = dispatch.as_dyn();458459			dispatch.check_nesting(460				from.clone(),461				(collection.id, token),462				target.1,463				nesting_budget,464			)?;465		}466467		// =========468469		<TokenData<T>>::insert(470			(collection.id, token),471			ItemData {472				owner: to.clone(),473				..token_data474			},475		);476477		if let Some(balance_to) = balance_to {478			// from != to479			if balance_from == 0 {480				<AccountBalance<T>>::remove((collection.id, from));481			} else {482				<AccountBalance<T>>::insert((collection.id, from), balance_from);483			}484			<AccountBalance<T>>::insert((collection.id, to), balance_to);485			<Owned<T>>::remove((collection.id, from, token));486			<Owned<T>>::insert((collection.id, to, token), true);487		}488		Self::set_allowance_unchecked(collection, from, token, None, true);489490		<PalletEvm<T>>::deposit_log(491			ERC721Events::Transfer {492				from: *from.as_eth(),493				to: *to.as_eth(),494				token_id: token.into(),495			}496			.to_log(collection_id_to_address(collection.id)),497		);498		<PalletCommon<T>>::deposit_event(CommonEvent::Transfer(499			collection.id,500			token,501			from.clone(),502			to.clone(),503			1,504		));505		Ok(())506	}507508	pub fn create_multiple_items(509		collection: &NonfungibleHandle<T>,510		sender: &T::CrossAccountId,511		data: Vec<CreateItemData<T>>,512		nesting_budget: &dyn Budget,513	) -> DispatchResult {514		if !collection.is_owner_or_admin(sender) {515			ensure!(516				collection.mint_mode,517				<CommonError<T>>::PublicMintingNotAllowed518			);519			collection.check_allowlist(sender)?;520521			for item in data.iter() {522				collection.check_allowlist(&item.owner)?;523			}524		}525526		for data in data.iter() {527			<PalletCommon<T>>::ensure_correct_receiver(&data.owner)?;528		}529530		let first_token = <TokensMinted<T>>::get(collection.id);531		let tokens_minted = first_token532			.checked_add(data.len() as u32)533			.ok_or(ArithmeticError::Overflow)?;534		ensure!(535			tokens_minted <= collection.limits.token_limit(),536			<CommonError<T>>::CollectionTokenLimitExceeded537		);538539		let mut balances = BTreeMap::new();540		for data in &data {541			let balance = balances542				.entry(&data.owner)543				.or_insert_with(|| <AccountBalance<T>>::get((collection.id, &data.owner)));544			*balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;545546			ensure!(547				*balance <= collection.limits.account_token_ownership_limit(),548				<CommonError<T>>::AccountTokenLimitExceeded,549			);550		}551552		for (i, data) in data.iter().enumerate() {553			let token = TokenId(first_token + i as u32 + 1);554			if let Some(target) = T::CrossTokenAddressMapping::address_to_token(&data.owner) {555				let handle = <CollectionHandle<T>>::try_get(target.0)?;556				let dispatch = T::CollectionDispatch::dispatch(handle);557				let dispatch = dispatch.as_dyn();558				dispatch.check_nesting(559					sender.clone(),560					(collection.id, token),561					target.1,562					nesting_budget,563				)?;564			}565		}566567		// =========568569		<TokensMinted<T>>::insert(collection.id, tokens_minted);570		for (account, balance) in balances {571			<AccountBalance<T>>::insert((collection.id, account), balance);572		}573		for (i, data) in data.into_iter().enumerate() {574			let token = first_token + i as u32 + 1;575576			<TokenData<T>>::insert(577				(collection.id, token),578				ItemData {579					const_data: data.const_data,580					variable_data: data.variable_data,581					owner: data.owner.clone(),582				},583			);584			<Owned<T>>::insert((collection.id, &data.owner, token), true);585586			Self::set_token_properties(587				collection,588				sender,589				TokenId(token),590				data.properties.into_inner(),591			)?;592593			<PalletEvm<T>>::deposit_log(594				ERC721Events::Transfer {595					from: H160::default(),596					to: *data.owner.as_eth(),597					token_id: token.into(),598				}599				.to_log(collection_id_to_address(collection.id)),600			);601			<PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(602				collection.id,603				TokenId(token),604				data.owner.clone(),605				1,606			));607		}608		Ok(())609	}610611	pub fn set_allowance_unchecked(612		collection: &NonfungibleHandle<T>,613		sender: &T::CrossAccountId,614		token: TokenId,615		spender: Option<&T::CrossAccountId>,616		assume_implicit_eth: bool,617	) {618		if let Some(spender) = spender {619			let old_spender = <Allowance<T>>::get((collection.id, token));620			<Allowance<T>>::insert((collection.id, token), spender);621			// In ERC721 there is only one possible approved user of token, so we set622			// approved user to spender623			<PalletEvm<T>>::deposit_log(624				ERC721Events::Approval {625					owner: *sender.as_eth(),626					approved: *spender.as_eth(),627					token_id: token.into(),628				}629				.to_log(collection_id_to_address(collection.id)),630			);631			// In Unique chain, any token can have any amount of approved users, so we need to632			// set allowance of old owner to 0, and allowance of new owner to 1633			if old_spender.as_ref() != Some(spender) {634				if let Some(old_owner) = old_spender {635					<PalletCommon<T>>::deposit_event(CommonEvent::Approved(636						collection.id,637						token,638						sender.clone(),639						old_owner,640						0,641					));642				}643				<PalletCommon<T>>::deposit_event(CommonEvent::Approved(644					collection.id,645					token,646					sender.clone(),647					spender.clone(),648					1,649				));650			}651		} else {652			let old_spender = <Allowance<T>>::take((collection.id, token));653			if !assume_implicit_eth {654				// In ERC721 there is only one possible approved user of token, so we set655				// approved user to zero address656				<PalletEvm<T>>::deposit_log(657					ERC721Events::Approval {658						owner: *sender.as_eth(),659						approved: H160::default(),660						token_id: token.into(),661					}662					.to_log(collection_id_to_address(collection.id)),663				);664			}665			// In Unique chain, any token can have any amount of approved users, so we need to666			// set allowance of old owner to 0667			if let Some(old_spender) = old_spender {668				<PalletCommon<T>>::deposit_event(CommonEvent::Approved(669					collection.id,670					token,671					sender.clone(),672					old_spender,673					0,674				));675			}676		}677	}678679	pub fn set_allowance(680		collection: &NonfungibleHandle<T>,681		sender: &T::CrossAccountId,682		token: TokenId,683		spender: Option<&T::CrossAccountId>,684	) -> DispatchResult {685		if collection.access == AccessMode::AllowList {686			collection.check_allowlist(sender)?;687			if let Some(spender) = spender {688				collection.check_allowlist(spender)?;689			}690		}691692		if let Some(spender) = spender {693			<PalletCommon<T>>::ensure_correct_receiver(spender)?;694		}695		let token_data =696			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;697		if &token_data.owner != sender {698			ensure!(699				collection.ignores_owned_amount(sender),700				<CommonError<T>>::CantApproveMoreThanOwned701			);702		}703704		// =========705706		Self::set_allowance_unchecked(collection, sender, token, spender, false);707		Ok(())708	}709710	fn check_allowed(711		collection: &NonfungibleHandle<T>,712		spender: &T::CrossAccountId,713		from: &T::CrossAccountId,714		token: TokenId,715		nesting_budget: &dyn Budget,716	) -> DispatchResult {717		if spender.conv_eq(from) {718			return Ok(());719		}720		if collection.access == AccessMode::AllowList {721			// `from`, `to` checked in [`transfer`]722			collection.check_allowlist(spender)?;723		}724		if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {725			// TODO: should collection owner be allowed to perform this transfer?726			ensure!(727				<PalletStructure<T>>::check_indirectly_owned(728					spender.clone(),729					source.0,730					source.1,731					None,732					nesting_budget733				)?,734				<CommonError<T>>::ApprovedValueTooLow,735			);736			return Ok(());737		}738		if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {739			return Ok(());740		}741		ensure!(742			collection.ignores_allowance(spender),743			<CommonError<T>>::ApprovedValueTooLow744		);745		Ok(())746	}747748	pub fn transfer_from(749		collection: &NonfungibleHandle<T>,750		spender: &T::CrossAccountId,751		from: &T::CrossAccountId,752		to: &T::CrossAccountId,753		token: TokenId,754		nesting_budget: &dyn Budget,755	) -> DispatchResult {756		Self::check_allowed(collection, spender, from, token, nesting_budget)?;757758		// =========759760		// Allowance is reset in [`transfer`]761		Self::transfer(collection, from, to, token, nesting_budget)762	}763764	pub fn burn_from(765		collection: &NonfungibleHandle<T>,766		spender: &T::CrossAccountId,767		from: &T::CrossAccountId,768		token: TokenId,769		nesting_budget: &dyn Budget,770	) -> DispatchResult {771		Self::check_allowed(collection, spender, from, token, nesting_budget)?;772773		// =========774775		Self::burn(collection, from, token)776	}777778	pub fn set_variable_metadata(779		collection: &NonfungibleHandle<T>,780		sender: &T::CrossAccountId,781		token: TokenId,782		data: BoundedVec<u8, CustomDataLimit>,783	) -> DispatchResult {784		let token_data =785			<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;786		collection.check_can_update_meta(sender, &token_data.owner)?;787788		// =========789790		<TokenData<T>>::insert(791			(collection.id, token),792			ItemData {793				variable_data: data,794				..token_data795			},796		);797		Ok(())798	}799800	pub fn check_nesting(801		handle: &NonfungibleHandle<T>,802		sender: T::CrossAccountId,803		from: (CollectionId, TokenId),804		under: TokenId,805		nesting_budget: &dyn Budget,806	) -> DispatchResult {807		fn ensure_sender_allowed<T: Config>(808			collection: CollectionId,809			token: TokenId,810			for_nest: (CollectionId, TokenId),811			sender: T::CrossAccountId,812			budget: &dyn Budget,813		) -> DispatchResult {814			ensure!(815				<PalletStructure<T>>::check_indirectly_owned(816					sender,817					collection,818					token,819					Some(for_nest),820					budget821				)?,822				<CommonError<T>>::OnlyOwnerAllowedToNest,823			);824			Ok(())825		}826		match handle.limits.nesting_rule() {827			NestingRule::Disabled => fail!(<CommonError<T>>::NestingIsDisabled),828			NestingRule::Owner => {829				ensure_sender_allowed::<T>(handle.id, under, from, sender, nesting_budget)?830			}831			NestingRule::OwnerRestricted(whitelist) => {832				ensure!(833					whitelist.contains(&from.0),834					<CommonError<T>>::SourceCollectionIsNotAllowedToNest835				);836				ensure_sender_allowed::<T>(handle.id, under, from, sender, nesting_budget)?837			}838		}839		Ok(())840	}841842	/// Delegated to `create_multiple_items`843	pub fn create_item(844		collection: &NonfungibleHandle<T>,845		sender: &T::CrossAccountId,846		data: CreateItemData<T>,847		nesting_budget: &dyn Budget,848	) -> DispatchResult {849		Self::create_multiple_items(collection, sender, vec![data], nesting_budget)850	}851}
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
@@ -51,6 +51,60 @@
 	event MintingFinished();
 }
 
+// Selector: 41369377
+contract TokenProperties is Dummy, ERC165 {
+	// Selector: setTokenPropertyPermission(string,bool,bool,bool) 222d97fa
+	function setTokenPropertyPermission(
+		string memory key,
+		bool isMutable,
+		bool collectionAdmin,
+		bool tokenOwner
+	) public {
+		require(false, stub_error);
+		key;
+		isMutable;
+		collectionAdmin;
+		tokenOwner;
+		dummy = 0;
+	}
+
+	// Selector: setProperty(uint256,string,bytes) 1752d67b
+	function setProperty(
+		uint256 tokenId,
+		string memory key,
+		bytes memory value
+	) public {
+		require(false, stub_error);
+		tokenId;
+		key;
+		value;
+		dummy = 0;
+	}
+
+	// Selector: deleteProperty(uint256,string) 066111d1
+	function deleteProperty(uint256 tokenId, string memory key) public {
+		require(false, stub_error);
+		tokenId;
+		key;
+		dummy = 0;
+	}
+
+	// Throws error if key not found
+	//
+	// Selector: property(uint256,string) 7228c327
+	function property(uint256 tokenId, string memory key)
+		public
+		view
+		returns (bytes memory)
+	{
+		require(false, stub_error);
+		tokenId;
+		key;
+		dummy;
+		return hex"";
+	}
+}
+
 // Selector: 42966c68
 contract ERC721Burnable is Dummy, ERC165 {
 	// Selector: burn(uint256) 42966c68
@@ -276,7 +330,41 @@
 	}
 }
 
-// Selector: e562194d
+// Selector: 9b5e29c5
+contract CollectionProperties is Dummy, ERC165 {
+	// Selector: setCollectionProperty(string,bytes) 2f073f66
+	function setCollectionProperty(string memory key, bytes memory value)
+		public
+	{
+		require(false, stub_error);
+		key;
+		value;
+		dummy = 0;
+	}
+
+	// Selector: deleteCollectionProperty(string) 7b7debce
+	function deleteCollectionProperty(string memory key) public {
+		require(false, stub_error);
+		key;
+		dummy = 0;
+	}
+
+	// Throws error if key not found
+	//
+	// Selector: collectionProperty(string) cf24fd6d
+	function collectionProperty(string memory key)
+		public
+		view
+		returns (bytes memory)
+	{
+		require(false, stub_error);
+		key;
+		dummy;
+		return hex"";
+	}
+}
+
+// Selector: d74d154f
 contract ERC721UniqueExtensions is Dummy, ERC165 {
 	// Selector: transfer(address,uint256) a9059cbb
 	function transfer(address to, uint256 tokenId) public {
@@ -299,26 +387,6 @@
 		require(false, stub_error);
 		dummy;
 		return 0;
-	}
-
-	// Selector: setVariableMetadata(uint256,bytes) d4eac26d
-	function setVariableMetadata(uint256 tokenId, bytes memory data) public {
-		require(false, stub_error);
-		tokenId;
-		data;
-		dummy = 0;
-	}
-
-	// Selector: getVariableMetadata(uint256) e6c5ce6f
-	function getVariableMetadata(uint256 tokenId)
-		public
-		view
-		returns (bytes memory)
-	{
-		require(false, stub_error);
-		tokenId;
-		dummy;
-		return hex"";
 	}
 
 	// Selector: mintBulk(address,uint256[]) 44a9945e
@@ -354,5 +422,7 @@
 	ERC721Enumerable,
 	ERC721UniqueExtensions,
 	ERC721Mintable,
-	ERC721Burnable
+	ERC721Burnable,
+	CollectionProperties,
+	TokenProperties
 {}
modifiedpallets/nonfungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/weights.rs
+++ b/pallets/nonfungible/src/weights.rs
@@ -45,7 +45,6 @@
 	fn approve() -> Weight;
 	fn transfer_from() -> Weight;
 	fn burn_from() -> Weight;
-	fn set_variable_metadata(b: u32, ) -> Weight;
 }
 
 /// Weights for pallet_nonfungible using the Substrate node and recommended hardware.
@@ -155,12 +154,6 @@
 		(27_580_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(4 as Weight))
 			.saturating_add(T::DbWeight::get().writes(5 as Weight))
-	}
-	// Storage: Nonfungible TokenData (r:1 w:1)
-	fn set_variable_metadata(_b: u32, ) -> Weight {
-		(7_700_000 as Weight)
-			.saturating_add(T::DbWeight::get().reads(1 as Weight))
-			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 }
 
@@ -270,11 +263,5 @@
 		(27_580_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(4 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(5 as Weight))
-	}
-	// Storage: Nonfungible TokenData (r:1 w:1)
-	fn set_variable_metadata(_b: u32, ) -> Weight {
-		(7_700_000 as Weight)
-			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
-			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 }
modifiedpallets/refungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/refungible/Cargo.toml
+++ b/pallets/refungible/Cargo.toml
@@ -24,6 +24,7 @@
 scale-info = { version = "2.0.1", default-features = false, features = [
     "derive",
 ] }
+struct-versioning = { path = "../../crates/struct-versioning" }
 
 [features]
 default = ["std"]
modifiedpallets/refungible/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/refungible/src/benchmarking.rs
+++ b/pallets/refungible/src/benchmarking.rs
@@ -31,10 +31,8 @@
 	users: impl IntoIterator<Item = (CrossAccountId, u128)>,
 ) -> CreateRefungibleExData<CrossAccountId> {
 	let const_data = create_data::<CUSTOM_DATA_LIMIT>();
-	let variable_data = create_data::<CUSTOM_DATA_LIMIT>();
 	CreateRefungibleExData {
 		const_data,
-		variable_data,
 		users: users
 			.into_iter()
 			.collect::<BTreeMap<_, _>>()
@@ -203,14 +201,4 @@
 		let item = create_max_item(&collection, &owner, [(sender.clone(), 200)])?;
 		<Pallet<T>>::set_allowance(&collection, &sender, &burner, item, 200)?;
 	}: {<Pallet<T>>::burn_from(&collection, &burner, &sender, item, 200, &Unlimited)?}
-
-	set_variable_metadata {
-		let b in 0..CUSTOM_DATA_LIMIT;
-		bench_init!{
-			owner: sub; collection: collection(owner);
-			sender: cross_from_sub(owner);
-		};
-		let item = create_max_item(&collection, &sender, [(sender.clone(), 200)])?;
-		let data = create_var_data(b).try_into().unwrap();
-	}: {<Pallet<T>>::set_variable_metadata(&collection, &sender, item, data)?}
 }
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -17,10 +17,10 @@
 use core::marker::PhantomData;
 
 use sp_std::collections::btree_map::BTreeMap;
-use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight, BoundedVec};
+use frame_support::{dispatch::DispatchResultWithPostInfo, fail, weights::Weight};
 use up_data_structs::{
-	CollectionId, TokenId, CustomDataLimit, CreateItemExData, CreateRefungibleExData,
-	budget::Budget, Property, PropertyKey, PropertyKeyPermission,
+	CollectionId, TokenId, CreateItemExData, CreateRefungibleExData, budget::Budget, Property,
+	PropertyKey, PropertyKeyPermission,
 };
 use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};
 use sp_runtime::DispatchError;
@@ -110,10 +110,6 @@
 
 	fn burn_from() -> Weight {
 		<SelfWeightOf<T>>::burn_from()
-	}
-
-	fn set_variable_metadata(bytes: u32) -> Weight {
-		<SelfWeightOf<T>>::set_variable_metadata(bytes)
 	}
 }
 
@@ -124,7 +120,6 @@
 	match data {
 		up_data_structs::CreateItemData::ReFungible(data) => Ok(CreateRefungibleExData {
 			const_data: data.const_data,
-			variable_data: data.variable_data,
 			users: {
 				let mut out = BTreeMap::new();
 				out.insert(to.clone(), data.pieces);
@@ -306,19 +301,6 @@
 		fail!(<Error<T>>::SettingPropertiesNotAllowed)
 	}
 
-	fn set_variable_metadata(
-		&self,
-		sender: T::CrossAccountId,
-		token: TokenId,
-		data: BoundedVec<u8, CustomDataLimit>,
-	) -> DispatchResultWithPostInfo {
-		let len = data.len();
-		with_weight(
-			<Pallet<T>>::set_variable_metadata(self, &sender, token, data),
-			<CommonWeights<T>>::set_variable_metadata(len as u32),
-		)
-	}
-
 	fn check_nesting(
 		&self,
 		_sender: <T>::CrossAccountId,
@@ -357,13 +339,12 @@
 			.const_data
 			.into_inner()
 	}
-	fn variable_metadata(&self, token: TokenId) -> Vec<u8> {
-		<TokenData<T>>::get((self.id, token))
-			.variable_data
-			.into_inner()
-	}
 
-	fn token_properties(&self, _token_id: TokenId, _keys: Vec<PropertyKey>) -> Vec<Property> {
+	fn token_properties(
+		&self,
+		_token_id: TokenId,
+		_keys: Option<Vec<PropertyKey>>,
+	) -> Vec<Property> {
 		Vec::new()
 	}
 
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -41,16 +41,23 @@
 pub mod weights;
 pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;
 
+#[struct_versioning::versioned(version = 2, upper)]
 #[derive(Encode, Decode, Default, TypeInfo, MaxEncodedLen)]
 pub struct ItemData {
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
+
+	#[version(..2)]
 	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 }
 
 #[frame_support::pallet]
 pub mod pallet {
 	use super::*;
-	use frame_support::{Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};
+	use frame_support::{
+		Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key,
+		traits::StorageVersion,
+	};
+	use frame_system::pallet_prelude::*;
 	use up_data_structs::{CollectionId, TokenId};
 	use super::weights::WeightInfo;
 
@@ -73,7 +80,10 @@
 		type WeightInfo: WeightInfo;
 	}
 
+	const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
+
 	#[pallet::pallet]
+	#[pallet::storage_version(STORAGE_VERSION)]
 	#[pallet::generate_store(pub(super) trait Store)]
 	pub struct Pallet<T>(_);
 
@@ -146,6 +156,19 @@
 		Value = u128,
 		QueryKind = ValueQuery,
 	>;
+
+	#[pallet::hooks]
+	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+		fn on_runtime_upgrade() -> Weight {
+			if StorageVersion::get::<Pallet<T>>() < StorageVersion::new(1) {
+				<TokenData<T>>::translate_values::<ItemDataVersion1, _>(|v| {
+					Some(<ItemDataVersion2>::from(v))
+				})
+			}
+
+			0
+		}
+	}
 }
 
 pub struct RefungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);
@@ -494,7 +517,6 @@
 				(collection.id, token_id),
 				ItemData {
 					const_data: token.const_data,
-					variable_data: token.variable_data,
 				},
 			);
 			for (user, amount) in token.users.into_iter() {
@@ -643,31 +665,6 @@
 		if let Some(allowance) = allowance {
 			Self::set_allowance_unchecked(collection, from, spender, token, allowance);
 		}
-		Ok(())
-	}
-
-	pub fn set_variable_metadata(
-		collection: &RefungibleHandle<T>,
-		sender: &T::CrossAccountId,
-		token: TokenId,
-		data: BoundedVec<u8, CustomDataLimit>,
-	) -> DispatchResult {
-		collection.check_can_update_meta(
-			sender,
-			&T::CrossAccountId::from_sub(collection.owner.clone()),
-		)?;
-
-		let token_data = <TokenData<T>>::get((collection.id, token));
-
-		// =========
-
-		<TokenData<T>>::insert(
-			(collection.id, token),
-			ItemData {
-				variable_data: data,
-				..token_data
-			},
-		);
 		Ok(())
 	}
 
modifiedpallets/refungible/src/weights.rsdiffbeforeafterboth
--- a/pallets/refungible/src/weights.rs
+++ b/pallets/refungible/src/weights.rs
@@ -53,7 +53,6 @@
 	fn transfer_from_removing() -> Weight;
 	fn transfer_from_creating_removing() -> Weight;
 	fn burn_from() -> Weight;
-	fn set_variable_metadata(b: u32, ) -> Weight;
 }
 
 /// Weights for pallet_refungible using the Substrate node and recommended hardware.
@@ -242,12 +241,6 @@
 		(42_043_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(5 as Weight))
 			.saturating_add(T::DbWeight::get().writes(7 as Weight))
-	}
-	// Storage: Refungible TokenData (r:1 w:1)
-	fn set_variable_metadata(_b: u32, ) -> Weight {
-		(7_364_000 as Weight)
-			.saturating_add(T::DbWeight::get().reads(1 as Weight))
-			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
 }
 
@@ -436,11 +429,5 @@
 		(42_043_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(5 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(7 as Weight))
-	}
-	// Storage: Refungible TokenData (r:1 w:1)
-	fn set_variable_metadata(_b: u32, ) -> Weight {
-		(7_364_000 as Weight)
-			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
-			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
 }
modifiedpallets/unique/src/benchmarking.rsdiffbeforeafterboth
--- a/pallets/unique/src/benchmarking.rs
+++ b/pallets/unique/src/benchmarking.rs
@@ -168,9 +168,4 @@
 			nesting_rule: None,
 		};
 	}: set_collection_limits(RawOrigin::Signed(caller.clone()), collection, cl)
-
-	set_meta_update_permission_flag {
-		let caller: T::AccountId = account("caller", 0, SEED);
-		let collection = create_nft_collection::<T>(caller.clone())?;
-	}: _(RawOrigin::Signed(caller.clone()), collection, MetaUpdatePermission::Admin)
 }
modifiedpallets/unique/src/lib.rsdiffbeforeafterboth
--- a/pallets/unique/src/lib.rs
+++ b/pallets/unique/src/lib.rs
@@ -35,16 +35,16 @@
 use frame_system::{self as system, ensure_signed};
 use sp_runtime::{sp_std::prelude::Vec};
 use up_data_structs::{
-	CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT,
-	MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH,
-	AccessMode, CreateItemData, CollectionLimits, CollectionId, CollectionMode, TokenId,
-	SchemaVersion, SponsorshipState, MetaUpdatePermission, CreateCollectionData, CustomDataLimit,
-	CreateItemExData, budget, CollectionField, Property, PropertyKey, PropertyKeyPermission,
+	CONST_ON_CHAIN_SCHEMA_LIMIT, OFFCHAIN_SCHEMA_LIMIT, MAX_COLLECTION_NAME_LENGTH,
+	MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, AccessMode, CreateItemData,
+	CollectionLimits, CollectionId, CollectionMode, TokenId, SchemaVersion, SponsorshipState,
+	CreateCollectionData, CreateItemExData, budget, CollectionField, Property, PropertyKey,
+	PropertyKeyPermission,
 };
 use pallet_evm::account::CrossAccountId;
 use pallet_common::{
-	CollectionHandle, Pallet as PalletCommon, Error as CommonError, CommonWeightInfo,
-	dispatch::dispatch_call, dispatch::CollectionDispatch,
+	CollectionHandle, Pallet as PalletCommon, CommonWeightInfo, dispatch::dispatch_call,
+	dispatch::CollectionDispatch,
 };
 
 #[cfg(feature = "runtime-benchmarks")]
@@ -240,7 +240,9 @@
 
 		/// Variable metadata sponsoring
 		/// Collection id (controlled?2), token id (controlled?2)
+		#[deprecated]
 		pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
+
 		/// Approval sponsoring
 		pub NftApproveBasket get(fn nft_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber>;
 		pub FungibleApproveBasket get(fn fungible_approve_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(twox_64_concat) T::AccountId => Option<T::BlockNumber>;
@@ -261,6 +263,14 @@
 			0
 		}
 
+		fn on_runtime_upgrade() -> Weight {
+			let limit = None;
+
+			<VariableMetaDataBasket<T>>::remove_all(limit);
+
+			0
+		}
+
 		/// This method creates a Collection of NFTs. Each Token may have multiple properties encoded as an array of bytes of certain length. The initial owner of the collection is set to the address that signed the transaction and can be changed later.
 		///
 		/// # Permissions
@@ -333,7 +343,6 @@
 			<FungibleTransferBasket<T>>::remove_prefix(collection_id, None);
 			<ReFungibleTransferBasket<T>>::remove_prefix((collection_id,), None);
 
-			<VariableMetaDataBasket<T>>::remove_prefix(collection_id, None);
 			<NftApproveBasket<T>>::remove_prefix(collection_id, None);
 			<FungibleApproveBasket<T>>::remove_prefix(collection_id, None);
 			<RefungibleApproveBasket<T>>::remove_prefix((collection_id,), None);
@@ -929,59 +938,6 @@
 			let budget = budget::Value::new(2);
 
 			dispatch_call::<T, _>(collection_id, |d| d.transfer_from(sender, from, recipient, item_id, value, &budget))
-		}
-
-		/// Set off-chain data schema.
-		///
-		/// # Permissions
-		///
-		/// * Collection Owner
-		/// * Collection Admin
-		///
-		/// # Arguments
-		///
-		/// * collection_id.
-		///
-		/// * schema: String representing the offchain data schema.
-		#[weight = T::CommonWeightInfo::set_variable_metadata(data.len() as u32)]
-		#[transactional]
-		pub fn set_variable_meta_data (
-			origin,
-			collection_id: CollectionId,
-			item_id: TokenId,
-			data: BoundedVec<u8, CustomDataLimit>,
-		) -> DispatchResultWithPostInfo {
-			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
-
-			dispatch_call::<T, _>(collection_id, |d| d.set_variable_metadata(sender, item_id, data))
-		}
-
-		/// Set meta_update_permission value for particular collection
-		///
-		/// # Permissions
-		///
-		/// * Collection Owner.
-		///
-		/// # Arguments
-		///
-		/// * collection_id: ID of the collection.
-		///
-		/// * value: New flag value.
-		#[weight = <SelfWeightOf<T>>::set_meta_update_permission_flag()]
-		#[transactional]
-		pub fn set_meta_update_permission_flag(origin, collection_id: CollectionId, value: MetaUpdatePermission) -> DispatchResult {
-			let sender = T::CrossAccountId::from_sub(ensure_signed(origin)?);
-			let mut target_collection = <CollectionHandle<T>>::try_get(collection_id)?;
-
-			ensure!(
-				target_collection.meta_update_permission != MetaUpdatePermission::None,
-				<CommonError<T>>::MetadataFlagFrozen,
-			);
-			target_collection.check_is_owner(&sender)?;
-
-			target_collection.meta_update_permission = value;
-
-			target_collection.save()
 		}
 
 		/// Set schema standard
modifiedpallets/unique/src/weights.rsdiffbeforeafterboth
--- a/pallets/unique/src/weights.rs
+++ b/pallets/unique/src/weights.rs
@@ -49,7 +49,6 @@
 	fn set_const_on_chain_schema(b: u32, ) -> Weight;
 	fn set_schema_version() -> Weight;
 	fn set_collection_limits() -> Weight;
-	fn set_meta_update_permission_flag() -> Weight;
 }
 
 /// Weights for pallet_unique using the Substrate node and recommended hardware.
@@ -167,12 +166,6 @@
 	// Storage: Common CollectionById (r:1 w:1)
 	fn set_collection_limits() -> Weight {
 		(15_339_000 as Weight)
-			.saturating_add(T::DbWeight::get().reads(1 as Weight))
-			.saturating_add(T::DbWeight::get().writes(1 as Weight))
-	}
-	// Storage: Common CollectionById (r:1 w:1)
-	fn set_meta_update_permission_flag() -> Weight {
-		(7_214_000 as Weight)
 			.saturating_add(T::DbWeight::get().reads(1 as Weight))
 			.saturating_add(T::DbWeight::get().writes(1 as Weight))
 	}
@@ -292,12 +285,6 @@
 	// Storage: Common CollectionById (r:1 w:1)
 	fn set_collection_limits() -> Weight {
 		(15_339_000 as Weight)
-			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
-			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
-	}
-	// Storage: Common CollectionById (r:1 w:1)
-	fn set_meta_update_permission_flag() -> Weight {
-		(7_214_000 as Weight)
 			.saturating_add(RocksDbWeight::get().reads(1 as Weight))
 			.saturating_add(RocksDbWeight::get().writes(1 as Weight))
 	}
modifiedprimitives/data-structs/src/lib.rsdiffbeforeafterboth
--- a/primitives/data-structs/src/lib.rs
+++ b/primitives/data-structs/src/lib.rs
@@ -22,7 +22,8 @@
 };
 use frame_support::{
 	storage::{bounded_btree_map::BoundedBTreeMap, bounded_btree_set::BoundedBTreeSet},
-	traits::Get, parameter_types,
+	traits::Get,
+	parameter_types,
 };
 
 #[cfg(feature = "serde")]
@@ -40,7 +41,10 @@
 	CollectionInfo, NftInfo, ResourceInfo, PropertyInfo, BaseInfo, PartType, Theme, ThemeProperty,
 };
 pub use rmrk_types::{
-	primitives::{CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId, PartId as RmrkPartId, ResourceId as RmrkResourceId},
+	primitives::{
+		CollectionId as RmrkCollectionId, NftId as RmrkNftId, BaseId as RmrkBaseId,
+		PartId as RmrkPartId, ResourceId as RmrkResourceId,
+	},
 	NftChild as RmrkNftChild, AccountIdOrCollectionNftTuple as RmrkAccountIdOrCollectionNftTuple,
 };
 
@@ -85,6 +89,7 @@
 
 // Schema limits
 pub const OFFCHAIN_SCHEMA_LIMIT: u32 = 8192;
+pub const VARIABLE_ON_CHAIN_SCHEMA_LIMIT: u32 = 8192;
 pub const CONST_ON_CHAIN_SCHEMA_LIMIT: u32 = 32768;
 
 pub const COLLECTION_FIELD_LIMIT: u32 = CONST_ON_CHAIN_SCHEMA_LIMIT;
@@ -318,8 +323,12 @@
 	pub limits: CollectionLimitsVersion2,
 
 	#[version(..2)]
+	pub variable_on_chain_schema: BoundedVec<u8, ConstU32<VARIABLE_ON_CHAIN_SCHEMA_LIMIT>>,
+
+	#[version(..2)]
 	pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,
 
+	#[version(..2)]
 	pub meta_update_permission: MetaUpdatePermission,
 }
 
@@ -339,7 +348,6 @@
 	pub sponsorship: SponsorshipState<AccountId>,
 	pub limits: CollectionLimits,
 	pub const_on_chain_schema: Vec<u8>,
-	pub meta_update_permission: MetaUpdatePermission,
 	pub token_property_permissions: Vec<PropertyKeyPermission>,
 	pub properties: Vec<Property>,
 }
@@ -365,7 +373,6 @@
 	pub pending_sponsor: Option<AccountId>,
 	pub limits: Option<CollectionLimits>,
 	pub const_on_chain_schema: BoundedVec<u8, ConstU32<CONST_ON_CHAIN_SCHEMA_LIMIT>>,
-	pub meta_update_permission: Option<MetaUpdatePermission>,
 	pub token_property_permissions: CollectionPropertiesPermissionsVec,
 	pub properties: CollectionPropertiesVec,
 }
@@ -376,28 +383,6 @@
 pub type CollectionPropertiesVec =
 	BoundedVec<Property, ConstU32<MAX_COLLECTION_PROPERTIES_ENCODE_LEN>>;
 
-#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
-#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct NftItemType<AccountId> {
-	pub owner: AccountId,
-	pub const_data: Vec<u8>,
-	pub variable_data: Vec<u8>,
-}
-
-#[derive(Encode, Decode, Default, Debug, Clone, PartialEq, TypeInfo)]
-#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct FungibleItemType {
-	pub value: u128,
-}
-
-#[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo)]
-#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
-pub struct ReFungibleItemType<AccountId> {
-	pub owner: Vec<Ownership<AccountId>>,
-	pub const_data: Vec<u8>,
-	pub variable_data: Vec<u8>,
-}
-
 /// All fields are wrapped in `Option`s, where None means chain default
 #[struct_versioning::versioned(version = 2, upper)]
 #[derive(Encode, Decode, Debug, Default, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
@@ -405,6 +390,8 @@
 pub struct CollectionLimits {
 	pub account_token_ownership_limit: Option<u32>,
 	pub sponsored_data_size: Option<u32>,
+
+	/// FIXME should we delete this or repurpose it?
 	/// None - setVariableMetadata is not sponsored
 	/// Some(v) - setVariableMetadata is sponsored
 	///           if there is v block between txs
@@ -502,9 +489,6 @@
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
-	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
-	#[derivative(Debug(format_with = "bounded::vec_debug"))]
-	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
@@ -524,26 +508,16 @@
 	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
-	#[cfg_attr(feature = "serde1", serde(with = "bounded::vec_serde"))]
-	#[derivative(Debug(format_with = "bounded::vec_debug"))]
-	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 	pub pieces: u128,
 }
 
 #[derive(Encode, Decode, Debug, Clone, PartialEq, TypeInfo, MaxEncodedLen)]
-#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
 pub enum MetaUpdatePermission {
 	ItemOwner,
 	Admin,
 	None,
 }
 
-impl Default for MetaUpdatePermission {
-	fn default() -> Self {
-		Self::ItemOwner
-	}
-}
-
 #[derive(Encode, Decode, MaxEncodedLen, PartialEq, Clone, Debug, TypeInfo)]
 #[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
 pub enum CreateItemData {
@@ -557,8 +531,6 @@
 pub struct CreateNftExData<CrossAccountId> {
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
-	#[derivative(Debug(format_with = "bounded::vec_debug"))]
-	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub properties: CollectionPropertiesVec,
 	pub owner: CrossAccountId,
@@ -569,8 +541,6 @@
 pub struct CreateRefungibleExData<CrossAccountId> {
 	#[derivative(Debug(format_with = "bounded::vec_debug"))]
 	pub const_data: BoundedVec<u8, CustomDataLimit>,
-	#[derivative(Debug(format_with = "bounded::vec_debug"))]
-	pub variable_data: BoundedVec<u8, CustomDataLimit>,
 	#[derivative(Debug(format_with = "bounded::map_debug"))]
 	pub users: BoundedBTreeMap<CrossAccountId, u128, ConstU32<MAX_ITEMS_PER_BATCH>>,
 }
@@ -598,8 +568,8 @@
 impl CreateItemData {
 	pub fn data_size(&self) -> usize {
 		match self {
-			CreateItemData::NFT(data) => data.variable_data.len() + data.const_data.len(),
-			CreateItemData::ReFungible(data) => data.variable_data.len() + data.const_data.len(),
+			CreateItemData::NFT(data) => data.const_data.len(),
+			CreateItemData::ReFungible(data) => data.const_data.len(),
 			_ => 0,
 		}
 	}
@@ -700,24 +670,65 @@
 	NoSpaceForProperty,
 	PropertyLimitReached,
 	InvalidCharacterInPropertyKey,
+	PropertyKeyIsTooLong,
 	EmptyPropertyKey,
 }
 
-pub trait TrySet: Sized {
+#[derive(Clone, Copy)]
+pub enum PropertyScope {
+	None,
+	Rmrk,
+}
+
+impl PropertyScope {
+	fn apply(self, key: PropertyKey) -> Result<PropertyKey, PropertiesError> {
+		let scope_str: &[u8] = match self {
+			Self::None => return Ok(key),
+			Self::Rmrk => b"rmrk",
+		};
+
+		[scope_str, b":", key.as_slice()]
+			.concat()
+			.try_into()
+			.map_err(|_| PropertiesError::PropertyKeyIsTooLong)
+	}
+}
+
+pub trait TrySetProperty: Sized {
 	type Value;
 
-	fn try_set(&mut self, key: PropertyKey, value: Self::Value) -> Result<(), PropertiesError>;
+	fn try_scoped_set(
+		&mut self,
+		scope: PropertyScope,
+		key: PropertyKey,
+		value: Self::Value,
+	) -> Result<(), PropertiesError>;
 
-	fn try_set_from_iter<I>(&mut self, iter: I) -> Result<(), PropertiesError>
+	fn try_scoped_set_from_iter<I>(
+		&mut self,
+		scope: PropertyScope,
+		iter: I,
+	) -> Result<(), PropertiesError>
 	where
 		I: Iterator<Item = (PropertyKey, Self::Value)>,
 	{
 		for (key, value) in iter {
-			self.try_set(key, value)?;
+			self.try_scoped_set(scope, key, value)?;
 		}
 
 		Ok(())
 	}
+
+	fn try_set(&mut self, key: PropertyKey, value: Self::Value) -> Result<(), PropertiesError> {
+		self.try_scoped_set(PropertyScope::None, key, value)
+	}
+
+	fn try_set_from_iter<I>(&mut self, iter: I) -> Result<(), PropertiesError>
+	where
+		I: Iterator<Item = (PropertyKey, Self::Value)>,
+	{
+		self.try_scoped_set_from_iter(PropertyScope::None, iter)
+	}
 }
 
 #[derive(Encode, Decode, TypeInfo, Derivative, Clone, PartialEq, MaxEncodedLen)]
@@ -751,12 +762,10 @@
 		}
 
 		for byte in key.as_slice().iter() {
-			match char::from_u32(*byte as u32) {
-				Some(ch)
-					if ch.is_ascii_alphanumeric()
-					|| ch == '_'
-					|| ch == '-' => { /* OK */ },
-				_ => return Err(PropertiesError::InvalidCharacterInPropertyKey)
+			let byte = *byte;
+
+			if !byte.is_ascii_alphanumeric() && byte != b'_' && byte != b'-' {
+				return Err(PropertiesError::InvalidCharacterInPropertyKey);
 			}
 		}
 
@@ -764,12 +773,18 @@
 	}
 }
 
-impl<Value> TrySet for PropertiesMap<Value> {
+impl<Value> TrySetProperty for PropertiesMap<Value> {
 	type Value = Value;
 
-	fn try_set(&mut self, key: PropertyKey, value: Self::Value) -> Result<(), PropertiesError> {
+	fn try_scoped_set(
+		&mut self,
+		scope: PropertyScope,
+		key: PropertyKey,
+		value: Self::Value,
+	) -> Result<(), PropertiesError> {
 		Self::check_property_key(&key)?;
 
+		let key = scope.apply(key)?;
 		self.0
 			.try_insert(key, value)
 			.map_err(|_| PropertiesError::PropertyLimitReached)?;
@@ -816,17 +831,22 @@
 	}
 }
 
-impl TrySet for Properties {
+impl TrySetProperty for Properties {
 	type Value = PropertyValue;
 
-	fn try_set(&mut self, key: PropertyKey, value: Self::Value) -> Result<(), PropertiesError> {
+	fn try_scoped_set(
+		&mut self,
+		scope: PropertyScope,
+		key: PropertyKey,
+		value: Self::Value,
+	) -> Result<(), PropertiesError> {
 		let value_len = value.len();
 
 		if self.consumed_space as usize + value_len > self.space_limit as usize {
 			return Err(PropertiesError::NoSpaceForProperty);
 		}
 
-		self.map.try_set(key, value)?;
+		self.map.try_scoped_set(scope, key, value)?;
 
 		self.consumed_space += value_len as u32;
 
@@ -869,34 +889,23 @@
 	pub const RmrkPartsLimit: u32 = 3;
 }
 
-pub type RmrkCollectionInfo<AccountId> = CollectionInfo<
-	RmrkString,
-	BoundedVec<u8, RmrkCollectionSymbolLimit>,
-	AccountId
->;
-pub type RmrkInstanceInfo<AccountId> = NftInfo<
-	AccountId, 
-	Permill,
-	RmrkString
->;
-pub type RmrkResourceInfo = ResourceInfo::<
+pub type RmrkCollectionInfo<AccountId> =
+	CollectionInfo<RmrkString, BoundedVec<u8, RmrkCollectionSymbolLimit>, AccountId>;
+pub type RmrkInstanceInfo<AccountId> = NftInfo<AccountId, Permill, RmrkString>;
+pub type RmrkResourceInfo = ResourceInfo<
 	BoundedVec<u8, RmrkResourceSymbolLimit>,
 	RmrkString,
-	BoundedVec<RmrkPartId, RmrkPartsLimit>
->;
-pub type RmrkPropertyInfo = PropertyInfo<
-	BoundedVec<u8, RmrkKeyLimit>, 
-	BoundedVec<u8, RmrkValueLimit>
+	BoundedVec<RmrkPartId, RmrkPartsLimit>,
 >;
+pub type RmrkPropertyInfo =
+	PropertyInfo<BoundedVec<u8, RmrkKeyLimit>, BoundedVec<u8, RmrkValueLimit>>;
 pub type RmrkBaseInfo<AccountId> = BaseInfo<AccountId, RmrkString>;
-pub type RmrkPartType = PartType<
-	RmrkString,
-	BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>
->;
+pub type RmrkPartType =
+	PartType<RmrkString, BoundedVec<RmrkCollectionId, RmrkMaxCollectionsEquippablePerPart>>;
 pub type RmrkTheme = Theme<RmrkString, Vec<ThemeProperty<RmrkString>>>;
 
 pub type RmrkRpcString = Vec<u8>;
 pub type RmrkThemeName = RmrkRpcString;
 pub type RmrkPropertyKey = RmrkRpcString;
 
-type RmrkString = BoundedVec<u8, RmrkStringLimit>;
\ No newline at end of file
+type RmrkString = BoundedVec<u8, RmrkStringLimit>;
modifiedprimitives/rpc/src/lib.rsdiffbeforeafterboth
--- a/primitives/rpc/src/lib.rs
+++ b/primitives/rpc/src/lib.rs
@@ -42,22 +42,25 @@
 		fn token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;
 		fn topmost_token_owner(collection: CollectionId, token: TokenId) -> Result<Option<CrossAccountId>>;
 		fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;
-		fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>>;
 
-		fn collection_properties(collection: CollectionId, properties: Vec<Vec<u8>>) -> Result<Vec<Property>>;
+		fn collection_properties(collection: CollectionId, properties: Option<Vec<Vec<u8>>>) -> Result<Vec<Property>>;
 
 		fn token_properties(
 			collection: CollectionId,
 			token_id: TokenId,
-			properties: Vec<Vec<u8>>
+			properties: Option<Vec<Vec<u8>>>
 		) -> Result<Vec<Property>>;
 
 		fn property_permissions(
 			collection: CollectionId,
-			properties: Vec<Vec<u8>>
+			properties: Option<Vec<Vec<u8>>>
 		) -> Result<Vec<PropertyKeyPermission>>;
 
-		fn token_data(collection: CollectionId, token_id: TokenId, keys: Vec<Vec<u8>>) -> Result<TokenData<CrossAccountId>>;
+		fn token_data(
+			collection: CollectionId,
+			token_id: TokenId,
+			keys: Option<Vec<Vec<u8>>>
+		) -> Result<TokenData<CrossAccountId>>;
 
 		fn total_supply(collection: CollectionId) -> Result<u32>;
 		fn account_balance(collection: CollectionId, account: CrossAccountId) -> Result<u32>;
modifiedruntime/common/src/runtime_apis.rsdiffbeforeafterboth
--- a/runtime/common/src/runtime_apis.rs
+++ b/runtime/common/src/runtime_apis.rs
@@ -32,15 +32,14 @@
                 fn const_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {
                     dispatch_unique_runtime!(collection.const_metadata(token))
                 }
-                fn variable_metadata(collection: CollectionId, token: TokenId) -> Result<Vec<u8>, DispatchError> {
-                    dispatch_unique_runtime!(collection.variable_metadata(token))
-                }
 
                 fn collection_properties(
                     collection: CollectionId,
-                    keys: Vec<Vec<u8>>
+                    keys: Option<Vec<Vec<u8>>>
                 ) -> Result<Vec<Property>, DispatchError> {
-                    let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;
+                    let keys = keys.map(
+                        |keys| pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)
+                    ).transpose()?;
 
                     pallet_common::Pallet::<Runtime>::filter_collection_properties(collection, keys)
                 }
@@ -48,17 +47,22 @@
                 fn token_properties(
                     collection: CollectionId,
                     token_id: TokenId,
-                    keys: Vec<Vec<u8>>
+                    keys: Option<Vec<Vec<u8>>>
                 ) -> Result<Vec<Property>, DispatchError> {
-                    let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;
+                    let keys = keys.map(
+                        |keys| pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)
+                    ).transpose()?;
+
                     dispatch_unique_runtime!(collection.token_properties(token_id, keys))
                 }
 
                 fn property_permissions(
                     collection: CollectionId,
-                    keys: Vec<Vec<u8>>
+                    keys: Option<Vec<Vec<u8>>>
                 ) -> Result<Vec<PropertyKeyPermission>, DispatchError> {
-                    let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;
+                    let keys = keys.map(
+                        |keys| pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)
+                    ).transpose()?;
 
                     pallet_common::Pallet::<Runtime>::filter_property_permissions(collection, keys)
                 }
@@ -66,7 +70,7 @@
                 fn token_data(
                     collection: CollectionId,
                     token_id: TokenId,
-                    keys: Vec<Vec<u8>>
+                    keys: Option<Vec<Vec<u8>>>
                 ) -> Result<TokenData<CrossAccountId>, DispatchError> {
                     let token_data = TokenData {
                         const_data: Self::const_metadata(collection, token_id)?,
@@ -232,7 +236,7 @@
                                     })
                                 })
                                 .collect();
-        
+
                             properties
                         }
                         None => {
@@ -253,7 +257,7 @@
                     let token_id = TokenId(nft_id);
 
 		            let properties = pallet_nonfungible::Pallet::<Runtime>::token_properties((collection_id, token_id)); // todo look into usage of nonfungible
-                    
+
                     return Ok(match filter_keys {
                         Some(keys) => {
                             let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(keys)?;
@@ -266,7 +270,7 @@
                                     })
                                 })
                                 .collect();
-        
+
                             properties
                         }
                         None => {
@@ -300,7 +304,7 @@
                     let keys = pallet_common::Pallet::<Runtime>::bytes_keys_to_property_keys(
                         Vec::from([String::from("rmrk:base-type").into_bytes()])
                     )?;
-                    let properties = pallet_common::Pallet::<Runtime>::filter_collection_properties(collection_id, keys)?;
+                    let properties = pallet_common::Pallet::<Runtime>::filter_collection_properties(collection_id, Some(keys))?;
                     //ensure!(properties.len() == 1); // todo make sure it's fine to have ensure in place // no access to errors from here? displace?
 
                     Ok(Some( RmrkBaseInfo {
modifiedruntime/common/src/sponsoring.rsdiffbeforeafterboth
--- a/runtime/common/src/sponsoring.rs
+++ b/runtime/common/src/sponsoring.rs
@@ -21,17 +21,16 @@
 	storage::{StorageMap, StorageDoubleMap, StorageNMap},
 };
 use up_data_structs::{
-	CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, MetaUpdatePermission,
-	NFT_SPONSOR_TRANSFER_TIMEOUT, REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode,
-	CreateItemData,
+	CollectionId, FUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, NFT_SPONSOR_TRANSFER_TIMEOUT,
+	REFUNGIBLE_SPONSOR_TRANSFER_TIMEOUT, TokenId, CollectionMode, CreateItemData,
 };
 use sp_runtime::traits::Saturating;
 use pallet_common::{CollectionHandle};
 use pallet_evm::account::CrossAccountId;
 use pallet_unique::{
 	Call as UniqueCall, Config as UniqueConfig, FungibleApproveBasket, RefungibleApproveBasket,
-	NftApproveBasket, VariableMetaDataBasket, CreateItemBasket, ReFungibleTransferBasket,
-	FungibleTransferBasket, NftTransferBasket,
+	NftApproveBasket, CreateItemBasket, ReFungibleTransferBasket, FungibleTransferBasket,
+	NftTransferBasket,
 };
 use pallet_fungible::Config as FungibleConfig;
 use pallet_nonfungible::Config as NonfungibleConfig;
@@ -136,63 +135,6 @@
 	}
 
 	CreateItemBasket::<T>::insert((collection.id, who.as_sub()), block_number);
-
-	Some(())
-}
-
-pub fn withdraw_set_variable_meta_data<T: Config>(
-	who: &T::CrossAccountId,
-	collection: &CollectionHandle<T>,
-	item_id: &TokenId,
-	data: &[u8],
-) -> Option<()> {
-	// TODO: make it work for admins
-	if collection.meta_update_permission != MetaUpdatePermission::ItemOwner {
-		return None;
-	}
-	// preliminary sponsoring correctness check
-	match collection.mode {
-		CollectionMode::NFT => {
-			let owner = pallet_nonfungible::TokenData::<T>::get((collection.id, item_id))?.owner;
-			if !owner.conv_eq(who) {
-				return None;
-			}
-		}
-		CollectionMode::Fungible(_) => {
-			if item_id != &TokenId::default() {
-				return None;
-			}
-			if <pallet_fungible::Balance<T>>::get((collection.id, who)) == 0 {
-				return None;
-			}
-		}
-		CollectionMode::ReFungible => {
-			if !<pallet_refungible::Owned<T>>::get((collection.id, who, item_id)) {
-				return None;
-			}
-		}
-	}
-
-	// Can't sponsor fungible collection, this tx will be rejected
-	// as invalid
-	if matches!(collection.mode, CollectionMode::Fungible(_)) {
-		return None;
-	}
-	if data.len() > collection.limits.sponsored_data_size() as usize {
-		return None;
-	}
-
-	let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
-	let limit = collection.limits.sponsored_data_rate_limit()?;
-
-	if let Some(last_tx_block) = VariableMetaDataBasket::<T>::get(collection.id, item_id) {
-		let timeout = last_tx_block + limit.into();
-		if block_number < timeout {
-			return None;
-		}
-	}
-
-	<VariableMetaDataBasket<T>>::insert(collection.id, item_id, block_number);
 
 	Some(())
 }
@@ -290,20 +232,6 @@
 			} => {
 				let (sponsor, collection) = load(*collection_id)?;
 				withdraw_approve::<T>(&collection, who, item_id).map(|()| sponsor)
-			}
-			UniqueCall::set_variable_meta_data {
-				collection_id,
-				item_id,
-				data,
-			} => {
-				let (sponsor, collection) = load(*collection_id)?;
-				withdraw_set_variable_meta_data::<T>(
-					&T::CrossAccountId::from_sub(who.clone()),
-					&collection,
-					item_id,
-					data,
-				)
-				.map(|()| sponsor)
 			}
 			_ => None,
 		}
modifiedruntime/common/src/weights.rsdiffbeforeafterboth
--- a/runtime/common/src/weights.rs
+++ b/runtime/common/src/weights.rs
@@ -86,10 +86,6 @@
 		dispatch_weight::<T>() + max_weight_of!(transfer_from())
 	}
 
-	fn set_variable_metadata(bytes: u32) -> Weight {
-		dispatch_weight::<T>() + max_weight_of!(set_variable_metadata(bytes))
-	}
-
 	fn burn_from() -> Weight {
 		dispatch_weight::<T>() + max_weight_of!(burn_from())
 	}
modifiedruntime/tests/src/tests.rsdiffbeforeafterboth
--- a/runtime/tests/src/tests.rs
+++ b/runtime/tests/src/tests.rs
@@ -18,9 +18,9 @@
 use crate::{Test, TestCrossAccountId, CollectionCreationPrice, Origin, Unique, new_test_ext};
 use up_data_structs::{
 	COLLECTION_NUMBER_LIMIT, CollectionId, CreateItemData, CreateFungibleData, CreateNftData,
-	CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, MetaUpdatePermission,
-	TokenId, MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionField, SchemaVersion,
-	CollectionMode, AccessMode,
+	CreateReFungibleData, MAX_DECIMAL_POINTS, COLLECTION_ADMINS_LIMIT, TokenId,
+	MAX_TOKEN_OWNERSHIP, CreateCollectionData, CollectionField, SchemaVersion, CollectionMode,
+	AccessMode,
 };
 use frame_support::{assert_noop, assert_ok, assert_err};
 use sp_std::convert::TryInto;
@@ -47,7 +47,7 @@
 fn default_nft_data() -> CreateNftData {
 	CreateNftData {
 		const_data: vec![1, 2, 3].try_into().unwrap(),
-		variable_data: vec![3, 2, 1].try_into().unwrap(),
+		properties: vec![].try_into().unwrap(),
 	}
 }
 
@@ -58,7 +58,6 @@
 fn default_re_fungible_data() -> CreateReFungibleData {
 	CreateReFungibleData {
 		const_data: vec![1, 2, 3].try_into().unwrap(),
-		variable_data: vec![3, 2, 1].try_into().unwrap(),
 		pieces: 1023,
 	}
 }
@@ -215,7 +214,6 @@
 
 		let item = <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1)).unwrap();
 		assert_eq!(item.const_data, data.const_data.into_inner());
-		assert_eq!(item.variable_data, data.variable_data.into_inner());
 	});
 }
 
@@ -247,7 +245,6 @@
 			))
 			.unwrap();
 			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
-			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
 		}
 	});
 }
@@ -263,7 +260,6 @@
 		let balance =
 			<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));
 		assert_eq!(item.const_data, data.const_data.into_inner());
-		assert_eq!(item.variable_data, data.variable_data.into_inner());
 		assert_eq!(balance, 1023);
 	});
 }
@@ -299,7 +295,6 @@
 			let balance =
 				<pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));
 			assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
-			assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
 			assert_eq!(balance, 1023);
 		}
 	});
@@ -413,7 +408,6 @@
 		create_test_item(collection_id, &data.clone().into());
 		let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));
 		assert_eq!(item.const_data, data.const_data.into_inner());
-		assert_eq!(item.variable_data, data.variable_data.into_inner());
 		assert_eq!(
 			<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))),
 			1
@@ -2427,117 +2421,6 @@
 }
 
 #[test]
-fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {
-	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
-
-		let origin1 = Origin::signed(1);
-
-		let data = default_nft_data();
-		create_test_item(CollectionId(1), &data.into());
-
-		let variable_data = b"test data".to_vec();
-		assert_ok!(Unique::set_variable_meta_data(
-			origin1,
-			collection_id,
-			TokenId(1),
-			variable_data.clone().try_into().unwrap()
-		));
-
-		assert_eq!(
-			<pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
-				.unwrap()
-				.variable_data,
-			variable_data
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {
-	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
-
-		let origin1 = Origin::signed(1);
-
-		let data = default_re_fungible_data();
-		create_test_item(collection_id, &data.into());
-
-		let variable_data = b"test data".to_vec();
-		assert_ok!(Unique::set_variable_meta_data(
-			origin1,
-			collection_id,
-			TokenId(1),
-			variable_data.clone().try_into().unwrap()
-		));
-
-		assert_eq!(
-			<pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1))).variable_data,
-			variable_data
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_data_on_fungible_token_fails() {
-	new_test_ext().execute_with(|| {
-		let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
-
-		let origin1 = Origin::signed(1);
-
-		let data = default_fungible_data();
-		create_test_item(collection_id, &data.into());
-
-		let variable_data = b"test data".to_vec();
-		assert_noop!(
-			Unique::set_variable_meta_data(
-				origin1,
-				collection_id,
-				TokenId(0),
-				variable_data.try_into().unwrap()
-			)
-			.map_err(|e| e.error),
-			<pallet_fungible::Error<Test>>::FungibleItemsDontHaveData
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_item_owner_permission_flag() {
-	new_test_ext().execute_with(|| {
-		//default_limits();
-
-		let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
-
-		let origin1 = Origin::signed(1);
-
-		let data = default_nft_data();
-		create_test_item(collection_id, &data.into());
-
-		assert_ok!(Unique::set_meta_update_permission_flag(
-			origin1.clone(),
-			collection_id,
-			MetaUpdatePermission::ItemOwner,
-		));
-
-		let variable_data = b"ten chars.".to_vec();
-		assert_ok!(Unique::set_variable_meta_data(
-			origin1,
-			collection_id,
-			TokenId(1),
-			variable_data.clone().try_into().unwrap()
-		));
-
-		assert_eq!(
-			<pallet_nonfungible::TokenData<Test>>::get((collection_id, TokenId(1)))
-				.unwrap()
-				.variable_data,
-			variable_data
-		);
-	});
-}
-
-#[test]
 fn collection_transfer_flag_works() {
 	new_test_ext().execute_with(|| {
 		let origin1 = Origin::signed(1);
@@ -2585,163 +2468,6 @@
 		assert_eq!(
 			<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))),
 			1
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_admin_flag() {
-	new_test_ext().execute_with(|| {
-		// default_limits();
-
-		let collection_id =
-			create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
-
-		let origin1 = Origin::signed(1);
-		let origin2 = Origin::signed(2);
-
-		assert_ok!(Unique::set_mint_permission(
-			origin2.clone(),
-			collection_id,
-			true
-		));
-		assert_ok!(Unique::add_to_allow_list(
-			origin2.clone(),
-			collection_id,
-			account(1)
-		));
-
-		assert_ok!(Unique::add_collection_admin(
-			origin2.clone(),
-			collection_id,
-			account(1)
-		));
-
-		let data = default_nft_data();
-		create_test_item(collection_id, &data.into());
-
-		assert_ok!(Unique::set_meta_update_permission_flag(
-			origin2.clone(),
-			collection_id,
-			MetaUpdatePermission::Admin,
-		));
-
-		let variable_data = b"test.".to_vec();
-		assert_ok!(Unique::set_variable_meta_data(
-			origin1,
-			collection_id,
-			TokenId(1),
-			variable_data.clone().try_into().unwrap()
-		));
-
-		assert_eq!(
-			<pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
-				.unwrap()
-				.variable_data,
-			variable_data
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_admin_flag_neg() {
-	new_test_ext().execute_with(|| {
-		// default_limits();
-
-		let collection_id =
-			create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
-
-		let origin1 = Origin::signed(1);
-		let origin2 = Origin::signed(2);
-
-		assert_ok!(Unique::set_mint_permission(
-			origin2.clone(),
-			collection_id,
-			true
-		));
-		assert_ok!(Unique::add_to_allow_list(
-			origin2.clone(),
-			collection_id,
-			account(1)
-		));
-
-		let data = default_nft_data();
-		create_test_item(collection_id, &data.into());
-
-		assert_ok!(Unique::set_meta_update_permission_flag(
-			origin2.clone(),
-			collection_id,
-			MetaUpdatePermission::Admin,
-		));
-
-		let variable_data = b"test.".to_vec();
-		assert_noop!(
-			Unique::set_variable_meta_data(
-				origin1,
-				collection_id,
-				TokenId(1),
-				variable_data.try_into().unwrap()
-			)
-			.map_err(|e| e.error),
-			CommonError::<Test>::NoPermission
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_flag_after_freeze() {
-	new_test_ext().execute_with(|| {
-		// default_limits();
-
-		let collection_id =
-			create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
-
-		let origin2 = Origin::signed(2);
-
-		assert_ok!(Unique::set_meta_update_permission_flag(
-			origin2.clone(),
-			collection_id,
-			MetaUpdatePermission::None,
-		));
-		assert_noop!(
-			Unique::set_meta_update_permission_flag(
-				origin2.clone(),
-				collection_id,
-				MetaUpdatePermission::Admin
-			),
-			CommonError::<Test>::MetadataFlagFrozen
-		);
-	});
-}
-
-#[test]
-fn set_variable_meta_data_on_nft_with_none_flag_neg() {
-	new_test_ext().execute_with(|| {
-		// default_limits();
-
-		let collection_id =
-			create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
-		let origin1 = Origin::signed(1);
-
-		let data = default_nft_data();
-		create_test_item(collection_id, &data.into());
-
-		assert_ok!(Unique::set_meta_update_permission_flag(
-			origin1.clone(),
-			collection_id,
-			MetaUpdatePermission::None,
-		));
-
-		let variable_data = b"test.".to_vec();
-		assert_noop!(
-			Unique::set_variable_meta_data(
-				origin1.clone(),
-				collection_id,
-				TokenId(1),
-				variable_data.try_into().unwrap()
-			)
-			.map_err(|e| e.error),
-			CommonError::<Test>::NoPermission
 		);
 	});
 }
modifiedsmart_contracs/transfer/lib.rsdiffbeforeafterboth
--- a/smart_contracs/transfer/lib.rs
+++ b/smart_contracs/transfer/lib.rs
@@ -58,14 +58,12 @@
 pub enum CreateItemData {
     Nft {
         const_data: Vec<u8>,
-        variable_data: Vec<u8>,
     },
     Fungible {
         value: u128,
     },
     ReFungible {
         const_data: Vec<u8>,
-        variable_data: Vec<u8>,
         pieces: u128,
     },
 }
@@ -88,8 +86,6 @@
     fn approve(spender: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);
     #[ink(extension = 4, returns_result = false)]
     fn transfer_from(owner: DefaultAccountId, recipient: DefaultAccountId, collection_id: u32, item_id: u32, amount: u128);
-    #[ink(extension = 5, returns_result = false)]
-    fn set_variable_meta_data(collection_id: u32, item_id: u32, data: Vec<u8>);
     #[ink(extension = 6, returns_result = false)]
     fn toggle_allow_list(collection_id: u32, address: DefaultAccountId, allowlisted: bool);
 }
@@ -143,12 +139,6 @@
             let _ = self.env()
                 .extension()
                 .transfer_from(owner, recipient, collection_id, item_id, amount);
-        }
-        #[ink(message)]
-        pub fn set_variable_meta_data(&mut self, collection_id: u32, item_id: u32, data: Vec<u8>) {
-            let _ = self.env()
-                .extension()
-                .set_variable_meta_data(collection_id, item_id, data);
         }
         #[ink(message)]
         pub fn toggle_allow_list(&mut self, collection_id: u32, address: AccountId, allowlisted: bool) {
modifiedtests/package.jsondiffbeforeafterboth
--- a/tests/package.json
+++ b/tests/package.json
@@ -40,7 +40,6 @@
     "testMigrationStructure": "mocha --timeout 9999999 -r ts-node/register ./**/nesting/migration-check.test.ts",
     "testAddCollectionAdmin": "mocha --timeout 9999999 -r ts-node/register ./**/addCollectionAdmin.test.ts",
     "testSetSchemaVersion": "mocha --timeout 9999999 -r ts-node/register ./**/setSchemaVersion.test.ts",
-    "testSetVariableMetaData": "mocha --timeout 9999999 -r ts-node/register ./**/setVariableMetaData.test.ts",
     "testSetCollectionLimits": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionLimits.test.ts",
     "testSetCollectionSponsor": "mocha --timeout 9999999 -r ts-node/register ./**/setCollectionSponsor.test.ts",
     "testConfirmSponsorship": "mocha --timeout 9999999 -r ts-node/register ./**/confirmSponsorship.test.ts",
modifiedtests/src/contracts.test.tsdiffbeforeafterboth
--- a/tests/src/contracts.test.ts
+++ b/tests/src/contracts.test.ts
@@ -111,7 +111,7 @@
       await addToAllowListExpectSuccess(alice, collectionId, contract.address);
       await addToAllowListExpectSuccess(alice, collectionId, bob.address);
 
-      const transferTx = contract.tx.createItem(value, gasLimit, bob.address, collectionId, {Nft: {const_data: '0x010203', variable_data: '0x020304'}});
+      const transferTx = contract.tx.createItem(value, gasLimit, bob.address, collectionId, {Nft: {const_data: '0x010203'}});
       const events = await submitTransactionAsync(alice, transferTx);
       const result = getGenericResult(events);
       expect(result.success).to.be.true;
@@ -121,7 +121,6 @@
         {
           owner: bob.address,
           constData: '0x010203',
-          variableData: '0x020304',
         },
       ]);
     });
@@ -140,9 +139,9 @@
       await addToAllowListExpectSuccess(alice, collectionId, bob.address);
 
       const transferTx = contract.tx.createMultipleItems(value, gasLimit, bob.address, collectionId, [
-        {Nft: {const_data: '0x010203', variable_data: '0x020304'}},
-        {Nft: {const_data: '0x010204', variable_data: '0x020305'}},
-        {Nft: {const_data: '0x010205', variable_data: '0x020306'}},
+        {Nft: {const_data: '0x010203'}},
+        {Nft: {const_data: '0x010204'}},
+        {Nft: {const_data: '0x010205'}},
       ]);
       const events = await submitTransactionAsync(alice, transferTx);
       const result = getGenericResult(events);
@@ -155,17 +154,14 @@
         {
           Owner: bob.address,
           ConstData: '0x010203',
-          VariableData: '0x020304',
         },
         {
           Owner: bob.address,
           ConstData: '0x010204',
-          VariableData: '0x020305',
         },
         {
           Owner: bob.address,
           ConstData: '0x010205',
-          VariableData: '0x020306',
         },
       ]);
     });
@@ -208,24 +204,6 @@
 
       const token: any = (await api.query.unique.nftItemList(collectionId, tokenId) as any).unwrap();
       expect(token.owner.toString()).to.be.equal(charlie.address);
-    });
-  });
-
-  it('SetVariableMetaData CE', async () => {
-    await usingApi(async api => {
-      const alice = privateKey('//Alice');
-
-      const collectionId = await createCollectionExpectSuccess();
-      const [contract] = await deployTransferContract(api);
-      const tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT', contract.address.toString());
-
-      const transferTx = contract.tx.setVariableMetaData(value, gasLimit, collectionId, tokenId, '0x121314');
-      const events = await submitTransactionAsync(alice, transferTx);
-      const result = getGenericResult(events);
-      expect(result.success).to.be.true;
-
-      const token: any = (await api.query.unique.nftItemList(collectionId, tokenId) as any).unwrap();
-      expect(token.variableData.toString()).to.be.equal('0x121314');
     });
   });
 
modifiedtests/src/createCollection.test.tsdiffbeforeafterboth
--- a/tests/src/createCollection.test.ts
+++ b/tests/src/createCollection.test.ts
@@ -74,7 +74,6 @@
           accountTokenOwnershipLimit: 3,
         },
         constOnChainSchema: '0x333333',
-        metaUpdatePermission: 'Admin',
       });
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateCollectionResult(events);
@@ -91,7 +90,6 @@
       expect(collection.sponsorship.asUnconfirmed.toString()).to.equal(bob.address);
       expect(collection.limits.accountTokenOwnershipLimit.unwrap().toNumber()).to.equal(3);
       expect(collection.constOnChainSchema.toString()).to.equal('0x333333');
-      expect(collection.metaUpdatePermission.isAdmin).to.be.true;
     });
   });
 });
modifiedtests/src/createMultipleItems.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItems.test.ts
+++ b/tests/src/createMultipleItems.test.ts
@@ -30,7 +30,6 @@
   getBalance,
   getTokenOwner,
   getLastTokenId,
-  getVariableMetadata,
   getConstMetadata,
   getCreatedCollectionCount,
   createCollectionWithPropsExpectSuccess,
@@ -47,9 +46,9 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -63,10 +62,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 
@@ -97,9 +92,9 @@
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
       const args = [
-        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
-        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
-        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
+        {ReFungible: {const_data: [0x31], pieces: 1}},
+        {ReFungible: {const_data: [0x32], pieces: 1}},
+        {ReFungible: {const_data: [0x33], pieces: 1}},
       ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
@@ -114,10 +109,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 
@@ -130,8 +121,8 @@
         tokenLimit: 2,
       });
       const args = [
-        {NFT: {const_data: 'A', variable_data: 'A'}},
-        {NFT: {const_data: 'B', variable_data: 'B'}},
+        {NFT: {const_data: 'A'}},
+        {NFT: {const_data: 'B'}},
       ];
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -146,9 +137,10 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+      const bob = privateKey('//Bob');
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -156,9 +148,9 @@
       expect(itemsListIndexAfter).to.be.equal(3);
 
       await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]), 
+        api,
+        alice,
+        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]),
       )).to.not.be.rejected;
 
       expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
@@ -168,10 +160,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 
@@ -181,9 +169,10 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+      const bob = privateKey('//Bob');
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -191,9 +180,9 @@
       expect(itemsListIndexAfter).to.be.equal(3);
 
       await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]), 
+        api,
+        alice,
+        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]),
       )).to.not.be.rejected;
 
       expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
@@ -203,10 +192,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 
@@ -216,9 +201,10 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const alice = privateKey('//Alice');
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+      const bob = privateKey('//Bob');
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -226,9 +212,9 @@
       expect(itemsListIndexAfter).to.be.equal(3);
 
       await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]), 
+        api,
+        alice,
+        api.tx.unique.setPropertyPermissions(collectionId, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]),
       )).to.not.be.rejected;
 
       expect(await getTokenOwner(api, collectionId, 1)).to.be.deep.equal(normalizeAccountId(alice.address));
@@ -238,10 +224,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 });
@@ -264,9 +246,9 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
       await submitTransactionAsync(bob, createMultipleItemsTx);
@@ -280,10 +262,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 
@@ -314,9 +292,9 @@
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
       const args = [
-        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
-        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
-        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
+        {ReFungible: {const_data: [0x31], pieces: 1}},
+        {ReFungible: {const_data: [0x32], pieces: 1}},
+        {ReFungible: {const_data: [0x33], pieces: 1}},
       ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(bob.address), args);
@@ -331,10 +309,6 @@
       expect(await getConstMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
       expect(await getConstMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
       expect(await getConstMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
-
-      expect(await getVariableMetadata(api, collectionId, 1)).to.be.deep.equal([0x31]);
-      expect(await getVariableMetadata(api, collectionId, 2)).to.be.deep.equal([0x32]);
-      expect(await getVariableMetadata(api, collectionId, 3)).to.be.deep.equal([0x33]);
     });
   });
 });
@@ -356,9 +330,9 @@
       const collectionId = await createCollectionExpectSuccess();
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await expect(submitTransactionAsync(bob, createMultipleItemsTx)).to.be.rejected;
@@ -387,9 +361,9 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       const args = [
-        {ReFungible: {const_data: [0x31], variable_data: [0x31], pieces: 1}},
-        {ReFungible: {const_data: [0x32], variable_data: [0x32], pieces: 1}},
-        {ReFungible: {const_data: [0x33], variable_data: [0x33], pieces: 1}},
+        {ReFungible: {const_data: [0x31], pieces: 1}},
+        {ReFungible: {const_data: [0x32], pieces: 1}},
+        {ReFungible: {const_data: [0x33], pieces: 1}},
       ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
@@ -412,9 +386,9 @@
       const collectionId = await createCollectionExpectSuccess();
       const alice = privateKey('//Alice');
       const args = [
-        {NFT: {const_data: 'A'.repeat(2049), variable_data: 'A'.repeat(2049)}},
-        {NFT: {const_data: 'B'.repeat(2049), variable_data: 'B'.repeat(2049)}},
-        {NFT: {const_data: 'C'.repeat(2049), variable_data: 'C'.repeat(2049)}},
+        {NFT: {const_data: 'A'.repeat(2049)}},
+        {NFT: {const_data: 'B'.repeat(2049)}},
+        {NFT: {const_data: 'C'.repeat(2049)}},
       ];
       const createMultipleItemsTx = api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
@@ -424,9 +398,9 @@
       const collectionIdReFungible =
         await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
       const argsReFungible = [
-        {ReFungible: ['1'.repeat(2049), '1'.repeat(2049), 10]},
-        {ReFungible: ['2'.repeat(2049), '2'.repeat(2049), 10]},
-        {ReFungible: ['3'.repeat(2049), '3'.repeat(2049), 10]},
+        {ReFungible: ['1'.repeat(2049), 10]},
+        {ReFungible: ['2'.repeat(2049), 10]},
+        {ReFungible: ['3'.repeat(2049), 10]},
       ];
       const createMultipleItemsTxFungible = api.tx.unique
         .createMultipleItems(collectionIdReFungible, normalizeAccountId(alice.address), argsReFungible);
@@ -449,9 +423,8 @@
     await usingApi(async (api: ApiPromise) => {
       const collectionId = await createCollectionExpectSuccess();
       const args = [
-        {NFT: {const_data: 'A', variable_data: 'A'}},
-        {NFT: {const_data: 'B', variable_data: 'B'.repeat(2049)}},
-        {NFT: {const_data: 'C'.repeat(2049), variable_data: 'C'}},
+        {NFT: {const_data: 'A'}},
+        {NFT: {const_data: 'B'.repeat(2049)}},
       ];
       const createMultipleItemsTx = await api.tx.unique
         .createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
@@ -467,8 +440,8 @@
         tokenLimit: 1,
       });
       const args = [
-        {NFT: {const_data: 'A', variable_data: 'A'}},
-        {NFT: {const_data: 'B', variable_data: 'B'}},
+        {NFT: {const_data: 'A'}},
+        {NFT: {const_data: 'B'}},
       ];
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       await expect(submitTransactionExpectFailAsync(alice, createMultipleItemsTx)).to.be.rejected;
@@ -482,10 +455,10 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
-      
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
+
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
 
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -493,9 +466,9 @@
 
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
         )).to.be.rejected;
       }
 
@@ -510,10 +483,10 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
-      
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
+
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
 
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -521,9 +494,9 @@
 
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
         )).to.be.rejected;
       }
     });
@@ -535,10 +508,10 @@
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
       expect(itemsListIndexBefore).to.be.equal(0);
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
-      
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
+
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
 
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -546,9 +519,9 @@
 
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
         )).to.be.rejected;
       }
     });
@@ -562,28 +535,28 @@
       expect(itemsListIndexBefore).to.be.equal(0);
       await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
 
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
-      
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
+
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
 
       const result = getCreateItemsResult(events);
-      
+
       const prps = [];
-      
+
       for (let i = 0; i < 65; i++) {
         prps.push({key: `key${i}`, value: `value${i}`});
       }
 
       await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collectionId, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
-      
+
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
         )).to.be.rejected;
       }
     });
@@ -595,10 +568,10 @@
         propPerm:   [{key: 'key1', mutable: true, collectionAdmin: false, tokenOwner: false}]});
       const itemsListIndexBefore = await getLastTokenId(api, collectionId);
       expect(itemsListIndexBefore).to.be.equal(0);
-      const args = [{Nft: {const_data: '0x31', variable_data: '0x31'}},
-        {Nft: {const_data: '0x32', variable_data: '0x32'}},
-        {Nft: {const_data: '0x33', variable_data: '0x33'}}];
-      
+      const args = [{Nft: {const_data: '0x31'}},
+        {Nft: {const_data: '0x32'}},
+        {Nft: {const_data: '0x33'}}];
+
       const createMultipleItemsTx = api.tx.unique.createMultipleItems(collectionId, normalizeAccountId(alice.address), args);
 
       const events = await submitTransactionAsync(alice, createMultipleItemsTx);
@@ -609,9 +582,9 @@
 
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'k', value: 'vvvvvv'.repeat(5000)}, {key: 'k2', value: 'vvv'.repeat(5000)}]),
         )).to.be.rejected;
       }
     });
modifiedtests/src/createMultipleItemsEx.test.tsdiffbeforeafterboth
--- a/tests/src/createMultipleItemsEx.test.ts
+++ b/tests/src/createMultipleItemsEx.test.ts
@@ -30,15 +30,12 @@
         {
           owner: {substrate: alice.address},
           constData: '0x0000',
-          variableData: '0x1111',
         }, {
           owner: {substrate: bob.address},
           constData: '0x2222',
-          variableData: '0x3333',
         }, {
           owner: {substrate: charlie.address},
           constData: '0x4444',
-          variableData: '0x5555',
         },
       ];
 
@@ -61,22 +58,19 @@
         {
           owner: {substrate: alice.address},
           constData: '0x0000',
-          variableData: '0x1111',
         }, {
           owner: {substrate: bob.address},
           constData: '0x2222',
-          variableData: '0x3333',
         }, {
           owner: {substrate: charlie.address},
           constData: '0x4444',
-          variableData: '0x5555',
         },
       ];
 
       await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]), 
+        api,
+        alice,
+        api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: false}}]),
       )).to.not.be.rejected;
 
       await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
@@ -98,28 +92,25 @@
         {
           owner: {substrate: alice.address},
           constData: '0x0000',
-          variableData: '0x1111',
         }, {
           owner: {substrate: bob.address},
           constData: '0x2222',
-          variableData: '0x3333',
         }, {
           owner: {substrate: charlie.address},
           constData: '0x4444',
-          variableData: '0x5555',
         },
       ];
       await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]), 
+        api,
+        alice,
+        api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: false, collectionAdmin: true, tokenOwner: false}}]),
       )).to.not.be.rejected;
 
       await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
         NFT: data,
       }));
-      
 
+
       const tokens = await api.query.nonfungible.tokenData.entries(collection);
       const json = tokens.map(([, token]) => token.toJSON());
       expect(json).to.be.deep.equal(data);
@@ -136,28 +127,25 @@
         {
           owner: {substrate: alice.address},
           constData: '0x0000',
-          variableData: '0x1111',
         }, {
           owner: {substrate: bob.address},
           constData: '0x2222',
-          variableData: '0x3333',
         }, {
           owner: {substrate: charlie.address},
           constData: '0x4444',
-          variableData: '0x5555',
         },
       ];
       await expect(executeTransaction(
-        api, 
-        alice, 
-        api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]), 
+        api,
+        alice,
+        api.tx.unique.setPropertyPermissions(collection, [{key: 'k', permission: {mutable: true, collectionAdmin: true, tokenOwner: true}}]),
       )).to.not.be.rejected;
 
       await executeTransaction(api, alice, api.tx.unique.createMultipleItemsEx(collection, {
         NFT: data,
       }));
-      
 
+
       const tokens = await api.query.nonfungible.tokenData.entries(collection);
       const json = tokens.map(([, token]) => token.toJSON());
       expect(json).to.be.deep.equal(data);
@@ -184,15 +172,15 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       await executeTransaction(api, alice, tx);
-      
+
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateItemsResult(events);
-      
+
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
         )).to.be.rejected;
       }
     });
@@ -218,15 +206,15 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       await executeTransaction(api, alice, tx);
-      
+
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateItemsResult(events);
-      
+
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
         )).to.be.rejected;
       }
     });
@@ -251,15 +239,15 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       await executeTransaction(api, alice, tx);
-      
+
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateItemsResult(events);
-      
+
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, [{key: 'key1', value: 'v2'}]),
         )).to.be.rejected;
       }
     });
@@ -284,24 +272,24 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       await executeTransaction(api, alice, tx);
-      
+
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateItemsResult(events);
 
       const prps = [];
-      
+
       for (let i = 0; i < 65; i++) {
         prps.push({key: `key${i}`, value: `value${i}`});
       }
 
       await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.PropertyLimitReached/);
 
-      
+
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
         )).to.be.rejected;
       }
     });
@@ -326,7 +314,7 @@
 
       const tx = api.tx.unique.createMultipleItemsEx(collection, {NFT: data});
       await executeTransaction(api, alice, tx);
-      
+
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateItemsResult(events);
 
@@ -334,12 +322,12 @@
 
       await expect(executeTransaction(api, bob, api.tx.unique.setCollectionProperties(collection, prps))).to.be.rejectedWith(/common\.NoSpaceForProperty/);
 
-      
+
       for (const elem of result) {
         await expect(executeTransaction(
-          api, 
-          bob, 
-          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps), 
+          api,
+          bob,
+          api.tx.unique.setTokenProperties(elem.collectionId, elem.itemId, prps),
         )).to.be.rejected;
       }
     });
@@ -355,15 +343,12 @@
         {
           owner: {substrate: alice.address},
           constData: '0x0000',
-          variableData: '0x1111',
         }, {
           owner: {substrate: bob.address},
           constData: '0x2222',
-          variableData: '0x3333',
         }, {
           owner: {substrate: charlie.address},
           constData: '0x4444',
-          variableData: '0x5555',
         },
       ];
 
@@ -386,15 +371,12 @@
         {
           owner: {substrate: alice.address},
           constData: '0x0000',
-          variableData: '0x1111',
         }, {
           owner: {substrate: bob.address},
           constData: '0x2222',
-          variableData: '0x3333',
         }, {
           owner: {substrate: charlie.address},
           constData: '0x4444',
-          variableData: '0x5555',
         },
       ];
 
modifiedtests/src/eth/api/UniqueFungible.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueFungible.sol
+++ b/tests/src/eth/api/UniqueFungible.sol
@@ -22,6 +22,12 @@
 	);
 }
 
+// Selector: 79cc6790
+interface ERC20UniqueExtensions is Dummy, ERC165 {
+	// Selector: burnFrom(address,uint256) 79cc6790
+	function burnFrom(address from, uint256 amount) external returns (bool);
+}
+
 // Selector: 942e8b22
 interface ERC20 is Dummy, ERC165, ERC20Events {
 	// Selector: name() 06fdde03
@@ -59,4 +65,28 @@
 		returns (uint256);
 }
 
-interface UniqueFungible is Dummy, ERC165, ERC20 {}
+// Selector: 9b5e29c5
+interface CollectionProperties is Dummy, ERC165 {
+	// Selector: setCollectionProperty(string,bytes) 2f073f66
+	function setCollectionProperty(string memory key, bytes memory value)
+		external;
+
+	// Selector: deleteCollectionProperty(string) 7b7debce
+	function deleteCollectionProperty(string memory key) external;
+
+	// Throws error if key not found
+	//
+	// Selector: collectionProperty(string) cf24fd6d
+	function collectionProperty(string memory key)
+		external
+		view
+		returns (bytes memory);
+}
+
+interface UniqueFungible is
+	Dummy,
+	ERC165,
+	ERC20,
+	ERC20UniqueExtensions,
+	CollectionProperties
+{}
modifiedtests/src/eth/api/UniqueNFT.soldiffbeforeafterboth
--- a/tests/src/eth/api/UniqueNFT.sol
+++ b/tests/src/eth/api/UniqueNFT.sol
@@ -42,6 +42,35 @@
 	event MintingFinished();
 }
 
+// Selector: 41369377
+interface TokenProperties is Dummy, ERC165 {
+	// Selector: setTokenPropertyPermission(string,bool,bool,bool) 222d97fa
+	function setTokenPropertyPermission(
+		string memory key,
+		bool isMutable,
+		bool collectionAdmin,
+		bool tokenOwner
+	) external;
+
+	// Selector: setProperty(uint256,string,bytes) 1752d67b
+	function setProperty(
+		uint256 tokenId,
+		string memory key,
+		bytes memory value
+	) external;
+
+	// Selector: deleteProperty(uint256,string) 066111d1
+	function deleteProperty(uint256 tokenId, string memory key) external;
+
+	// Throws error if key not found
+	//
+	// Selector: property(uint256,string) 7228c327
+	function property(uint256 tokenId, string memory key)
+		external
+		view
+		returns (bytes memory);
+}
+
 // Selector: 42966c68
 interface ERC721Burnable is Dummy, ERC165 {
 	// Selector: burn(uint256) 42966c68
@@ -162,7 +191,25 @@
 	function totalSupply() external view returns (uint256);
 }
 
-// Selector: e562194d
+// Selector: 9b5e29c5
+interface CollectionProperties is Dummy, ERC165 {
+	// Selector: setCollectionProperty(string,bytes) 2f073f66
+	function setCollectionProperty(string memory key, bytes memory value)
+		external;
+
+	// Selector: deleteCollectionProperty(string) 7b7debce
+	function deleteCollectionProperty(string memory key) external;
+
+	// Throws error if key not found
+	//
+	// Selector: collectionProperty(string) cf24fd6d
+	function collectionProperty(string memory key)
+		external
+		view
+		returns (bytes memory);
+}
+
+// Selector: d74d154f
 interface ERC721UniqueExtensions is Dummy, ERC165 {
 	// Selector: transfer(address,uint256) a9059cbb
 	function transfer(address to, uint256 tokenId) external;
@@ -172,16 +219,7 @@
 
 	// Selector: nextTokenId() 75794a3c
 	function nextTokenId() external view returns (uint256);
-
-	// Selector: setVariableMetadata(uint256,bytes) d4eac26d
-	function setVariableMetadata(uint256 tokenId, bytes memory data) external;
 
-	// Selector: getVariableMetadata(uint256) e6c5ce6f
-	function getVariableMetadata(uint256 tokenId)
-		external
-		view
-		returns (bytes memory);
-
 	// Selector: mintBulk(address,uint256[]) 44a9945e
 	function mintBulk(address to, uint256[] memory tokenIds)
 		external
@@ -201,5 +239,7 @@
 	ERC721Enumerable,
 	ERC721UniqueExtensions,
 	ERC721Mintable,
-	ERC721Burnable
+	ERC721Burnable,
+	CollectionProperties,
+	TokenProperties
 {}
modifiedtests/src/eth/base.test.tsdiffbeforeafterboth
--- a/tests/src/eth/base.test.ts
+++ b/tests/src/eth/base.test.ts
@@ -79,7 +79,7 @@
       minter = createEthAccount(web3);
     });
   });
-  
+
   itWeb3('interfaceID == 0xffffffff always false', async ({web3}) => {
     expect(await contract(web3).methods.supportsInterface('0xffffffff').call()).to.be.false;
   });
@@ -101,7 +101,7 @@
   });
 
   itWeb3('ERC721UniqueExtensions support', async ({web3}) => {
-    expect(await contract(web3).methods.supportsInterface('0xe562194d').call()).to.be.true;
+    expect(await contract(web3).methods.supportsInterface('0xd74d154f').call()).to.be.true;
   });
 
   itWeb3('ERC721Burnable support', async ({web3}) => {
addedtests/src/eth/collectionProperties.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/collectionProperties.test.ts
@@ -0,0 +1,54 @@
+import privateKey from '../substrate/privateKey';
+import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess} from '../util/helpers';
+import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3} from './util/helpers';
+import nonFungibleAbi from './nonFungibleAbi.json';
+import {expect} from 'chai';
+import {executeTransaction} from '../substrate/substrate-api';
+
+describe('EVM collection properties', () => {
+  itWeb3('Can be set', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+
+    await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    await contract.methods.setCollectionProperty('testKey', Buffer.from('testValue')).send({from: caller});
+
+    const [{value}] = (await api.rpc.unique.collectionProperties(collection, ['testKey'])).toHuman()! as any;
+    expect(value).to.equal('testValue');
+  });
+  itWeb3('Can be deleted', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+
+    await executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collection, [{key: 'testKey', value: 'testValue'}]));
+
+    await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    await contract.methods.deleteCollectionProperty('testKey').send({from: caller});
+
+    const result = (await api.rpc.unique.collectionProperties(collection, ['testKey'])).toJSON()! as any;
+    expect(result.length).to.equal(0);
+  });
+  itWeb3('Can be read', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = createEthAccount(web3);
+    const collection = await createCollectionExpectSuccess({mode: {type:'NFT'}});
+
+    await executeTransaction(api, alice, api.tx.unique.setCollectionProperties(collection, [{key: 'testKey', value: 'testValue'}]));
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    const value = await contract.methods.collectionProperty('testKey').call();
+    expect(value).to.equal(web3.utils.toHex('testValue'));
+  });
+});
modifiedtests/src/eth/nonFungible.test.tsdiffbeforeafterboth
--- a/tests/src/eth/nonFungible.test.ts
+++ b/tests/src/eth/nonFungible.test.ts
@@ -15,7 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import privateKey from '../substrate/privateKey';
-import {approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, setVariableMetaDataExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE, setMetadataUpdatePermissionFlagExpectSuccess} from '../util/helpers';
+import {approveExpectSuccess, burnItemExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess, transferExpectSuccess, transferFromExpectSuccess, UNIQUE} from '../util/helpers';
 import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents, recordEthFee, recordEvents, subToEth, transferBalanceToEth} from './util/helpers';
 import nonFungibleAbi from './nonFungibleAbi.json';
 import {expect} from 'chai';
@@ -331,41 +331,6 @@
       const balance = await contract.methods.balanceOf(receiver).call();
       expect(+balance).to.equal(1);
     }
-  });
-
-  itWeb3('Can perform getVariableMetadata', async ({web3, api}) => {
-    const collection = await createCollectionExpectSuccess({
-      mode: {type: 'NFT'},
-    });
-    const alice = privateKey('//Alice');
-
-    const owner = await createEthAccountWithBalance(api, web3);
-
-    const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
-    await setMetadataUpdatePermissionFlagExpectSuccess(alice, collection, 'Admin');
-    await setVariableMetaDataExpectSuccess(alice, collection, item, [1, 2, 3]);
-
-    const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
-
-    expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');
-  });
-
-  itWeb3('Can perform setVariableMetadata', async ({web3, api}) => {
-    const collection = await createCollectionExpectSuccess({
-      mode: {type: 'NFT'},
-    });
-    const alice = privateKey('//Alice');
-
-    const owner = await createEthAccountWithBalance(api, web3);
-
-    const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: owner});
-
-    const address = collectionIdToAddress(collection);
-    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: owner, ...GAS_ARGS});
-
-    expect(await contract.methods.setVariableMetadata(item, '0x010203').send({from: owner}));
-    expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');
   });
 });
 
modifiedtests/src/eth/nonFungibleAbi.jsondiffbeforeafterboth
--- a/tests/src/eth/nonFungibleAbi.json
+++ b/tests/src/eth/nonFungibleAbi.json
@@ -1,614 +1,738 @@
 [
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "owner",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "approved",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "Approval",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "owner",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "operator",
-                "type": "address"
-            },
-            {
-                "indexed": false,
-                "internalType": "bool",
-                "name": "approved",
-                "type": "bool"
-            }
-        ],
-        "name": "ApprovalForAll",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [],
-        "name": "MintingFinished",
-        "type": "event"
-    },
-    {
-        "anonymous": false,
-        "inputs": [
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "from",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "indexed": true,
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "Transfer",
-        "type": "event"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "approved",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "approve",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "owner",
-                "type": "address"
-            }
-        ],
-        "name": "balanceOf",
-        "outputs": [
-            {
-                "internalType": "uint256",
-                "name": "",
-                "type": "uint256"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "burn",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "finishMinting",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "getApproved",
-        "outputs": [
-            {
-                "internalType": "address",
-                "name": "",
-                "type": "address"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "getVariableMetadata",
-        "outputs": [
-            {
-                "internalType": "bytes",
-                "name": "",
-                "type": "bytes"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "owner",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "operator",
-                "type": "address"
-            }
-        ],
-        "name": "isApprovedForAll",
-        "outputs": [
-            {
-                "internalType": "address",
-                "name": "",
-                "type": "address"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "mint",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256[]",
-                "name": "tokenIds",
-                "type": "uint256[]"
-            }
-        ],
-        "name": "mintBulk",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "components": [
-                    {
-                        "internalType": "uint256",
-                        "name": "field_0",
-                        "type": "uint256"
-                    },
-                    {
-                        "internalType": "string",
-                        "name": "field_1",
-                        "type": "string"
-                    }
-                ],
-                "internalType": "struct Tuple0[]",
-                "name": "tokens",
-                "type": "tuple[]"
-            }
-        ],
-        "name": "mintBulkWithTokenURI",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            },
-            {
-                "internalType": "string",
-                "name": "tokenUri",
-                "type": "string"
-            }
-        ],
-        "name": "mintWithTokenURI",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "mintingFinished",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "name",
-        "outputs": [
-            {
-                "internalType": "string",
-                "name": "",
-                "type": "string"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "nextTokenId",
-        "outputs": [
-            {
-                "internalType": "uint256",
-                "name": "",
-                "type": "uint256"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "ownerOf",
-        "outputs": [
-            {
-                "internalType": "address",
-                "name": "",
-                "type": "address"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "from",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "safeTransferFrom",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "from",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            },
-            {
-                "internalType": "bytes",
-                "name": "data",
-                "type": "bytes"
-            }
-        ],
-        "name": "safeTransferFromWithData",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "operator",
-                "type": "address"
-            },
-            {
-                "internalType": "bool",
-                "name": "approved",
-                "type": "bool"
-            }
-        ],
-        "name": "setApprovalForAll",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            },
-            {
-                "internalType": "bytes",
-                "name": "data",
-                "type": "bytes"
-            }
-        ],
-        "name": "setVariableMetadata",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "bytes4",
-                "name": "interfaceId",
-                "type": "bytes4"
-            }
-        ],
-        "name": "supportsInterface",
-        "outputs": [
-            {
-                "internalType": "bool",
-                "name": "",
-                "type": "bool"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "symbol",
-        "outputs": [
-            {
-                "internalType": "string",
-                "name": "",
-                "type": "string"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "index",
-                "type": "uint256"
-            }
-        ],
-        "name": "tokenByIndex",
-        "outputs": [
-            {
-                "internalType": "uint256",
-                "name": "",
-                "type": "uint256"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "owner",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "index",
-                "type": "uint256"
-            }
-        ],
-        "name": "tokenOfOwnerByIndex",
-        "outputs": [
-            {
-                "internalType": "uint256",
-                "name": "",
-                "type": "uint256"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "tokenURI",
-        "outputs": [
-            {
-                "internalType": "string",
-                "name": "",
-                "type": "string"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [],
-        "name": "totalSupply",
-        "outputs": [
-            {
-                "internalType": "uint256",
-                "name": "",
-                "type": "uint256"
-            }
-        ],
-        "stateMutability": "view",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "transfer",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    },
-    {
-        "inputs": [
-            {
-                "internalType": "address",
-                "name": "from",
-                "type": "address"
-            },
-            {
-                "internalType": "address",
-                "name": "to",
-                "type": "address"
-            },
-            {
-                "internalType": "uint256",
-                "name": "tokenId",
-                "type": "uint256"
-            }
-        ],
-        "name": "transferFrom",
-        "outputs": [],
-        "stateMutability": "nonpayable",
-        "type": "function"
-    }
-]
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			},
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "approved",
+				"type": "address"
+			},
+			{
+				"indexed": true,
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "Approval",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			},
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "operator",
+				"type": "address"
+			},
+			{
+				"indexed": false,
+				"internalType": "bool",
+				"name": "approved",
+				"type": "bool"
+			}
+		],
+		"name": "ApprovalForAll",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [],
+		"name": "MintingFinished",
+		"type": "event"
+	},
+	{
+		"anonymous": false,
+		"inputs": [
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "from",
+				"type": "address"
+			},
+			{
+				"indexed": true,
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"indexed": true,
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "Transfer",
+		"type": "event"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "approved",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "approve",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			}
+		],
+		"name": "balanceOf",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "burn",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "from",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "burnFrom",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			}
+		],
+		"name": "collectionProperty",
+		"outputs": [
+			{
+				"internalType": "bytes",
+				"name": "",
+				"type": "bytes"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			}
+		],
+		"name": "deleteCollectionProperty",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			},
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			}
+		],
+		"name": "deleteProperty",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "finishMinting",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "getApproved",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "operator",
+				"type": "address"
+			}
+		],
+		"name": "isApprovedForAll",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "mint",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256[]",
+				"name": "tokenIds",
+				"type": "uint256[]"
+			}
+		],
+		"name": "mintBulk",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"components": [
+					{
+						"internalType": "uint256",
+						"name": "field_0",
+						"type": "uint256"
+					},
+					{
+						"internalType": "string",
+						"name": "field_1",
+						"type": "string"
+					}
+				],
+				"internalType": "struct Tuple0[]",
+				"name": "tokens",
+				"type": "tuple[]"
+			}
+		],
+		"name": "mintBulkWithTokenURI",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			},
+			{
+				"internalType": "string",
+				"name": "tokenUri",
+				"type": "string"
+			}
+		],
+		"name": "mintWithTokenURI",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "mintingFinished",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "name",
+		"outputs": [
+			{
+				"internalType": "string",
+				"name": "",
+				"type": "string"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "nextTokenId",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "ownerOf",
+		"outputs": [
+			{
+				"internalType": "address",
+				"name": "",
+				"type": "address"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			},
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			}
+		],
+		"name": "property",
+		"outputs": [
+			{
+				"internalType": "bytes",
+				"name": "",
+				"type": "bytes"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "from",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "safeTransferFrom",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "from",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			},
+			{
+				"internalType": "bytes",
+				"name": "data",
+				"type": "bytes"
+			}
+		],
+		"name": "safeTransferFromWithData",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "operator",
+				"type": "address"
+			},
+			{
+				"internalType": "bool",
+				"name": "approved",
+				"type": "bool"
+			}
+		],
+		"name": "setApprovalForAll",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			},
+			{
+				"internalType": "bytes",
+				"name": "value",
+				"type": "bytes"
+			}
+		],
+		"name": "setCollectionProperty",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			},
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			},
+			{
+				"internalType": "bytes",
+				"name": "value",
+				"type": "bytes"
+			}
+		],
+		"name": "setProperty",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "string",
+				"name": "key",
+				"type": "string"
+			},
+			{
+				"internalType": "bool",
+				"name": "isMutable",
+				"type": "bool"
+			},
+			{
+				"internalType": "bool",
+				"name": "collectionAdmin",
+				"type": "bool"
+			},
+			{
+				"internalType": "bool",
+				"name": "tokenOwner",
+				"type": "bool"
+			}
+		],
+		"name": "setTokenPropertyPermission",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "bytes4",
+				"name": "interfaceID",
+				"type": "bytes4"
+			}
+		],
+		"name": "supportsInterface",
+		"outputs": [
+			{
+				"internalType": "bool",
+				"name": "",
+				"type": "bool"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "symbol",
+		"outputs": [
+			{
+				"internalType": "string",
+				"name": "",
+				"type": "string"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "index",
+				"type": "uint256"
+			}
+		],
+		"name": "tokenByIndex",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "owner",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "index",
+				"type": "uint256"
+			}
+		],
+		"name": "tokenOfOwnerByIndex",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "tokenURI",
+		"outputs": [
+			{
+				"internalType": "string",
+				"name": "",
+				"type": "string"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [],
+		"name": "totalSupply",
+		"outputs": [
+			{
+				"internalType": "uint256",
+				"name": "",
+				"type": "uint256"
+			}
+		],
+		"stateMutability": "view",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "transfer",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	},
+	{
+		"inputs": [
+			{
+				"internalType": "address",
+				"name": "from",
+				"type": "address"
+			},
+			{
+				"internalType": "address",
+				"name": "to",
+				"type": "address"
+			},
+			{
+				"internalType": "uint256",
+				"name": "tokenId",
+				"type": "uint256"
+			}
+		],
+		"name": "transferFrom",
+		"outputs": [],
+		"stateMutability": "nonpayable",
+		"type": "function"
+	}
+]
\ No newline at end of file
modifiedtests/src/eth/proxy/UniqueNFTProxy.abidiffbeforeafterboth
--- a/tests/src/eth/proxy/UniqueNFTProxy.abi
+++ b/tests/src/eth/proxy/UniqueNFTProxy.abi
@@ -1 +1 @@
-[{"inputs":[{"internalType":"address","name":"_proxied","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[],"name":"MintingFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"approved","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getVariableMetadata","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"mintBulk","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint256","name":"field_0","type":"uint256"},{"internalType":"string","name":"field_1","type":"string"}],"internalType":"struct Tuple0[]","name":"tokens","type":"tuple[]"}],"name":"mintBulkWithTokenURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenUri","type":"string"}],"name":"mintWithTokenURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintingFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFromWithData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"setVariableMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"interfaceId","type":"uint32"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
+[{"inputs":[{"internalType":"address","name":"_proxied","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[],"name":"MintingFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"approved","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"key","type":"string"}],"name":"deleteProperty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finishMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"mintBulk","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"components":[{"internalType":"uint256","name":"field_0","type":"uint256"},{"internalType":"string","name":"field_1","type":"string"}],"internalType":"struct Tuple0[]","name":"tokens","type":"tuple[]"}],"name":"mintBulkWithTokenURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"tokenUri","type":"string"}],"name":"mintWithTokenURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintingFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFromWithData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"key","type":"string"},{"internalType":"string","name":"value","type":"string"}],"name":"setProperty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]
\ No newline at end of file
modifiedtests/src/eth/proxy/UniqueNFTProxy.bindiffbeforeafterboth
--- a/tests/src/eth/proxy/UniqueNFTProxy.bin
+++ b/tests/src/eth/proxy/UniqueNFTProxy.bin
@@ -1 +1 @@
-608060405234801561001057600080fd5b5060405161168d38038061168d83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6115fa806100936000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c806350bb4e7f116100f9578063a22cb46511610097578063d4eac26d11610071578063d4eac26d1461036b578063e6c5ce6f1461037e578063e985e9c514610391578063f4f4b500146103a457600080fd5b8063a22cb46514610332578063a9059cbb14610345578063c87b56dd1461035857600080fd5b806370a08231116100d357806370a082311461030757806375794a3c1461031a5780637d64bcb41461032257806395d89b411461032a57600080fd5b806350bb4e7f146102ce57806360a11672146102e15780636352211e146102f457600080fd5b80632f745c591161016657806342842e0e1161014057806342842e0e1461028257806342966c681461029557806344a9945e146102a85780634f6ccce7146102bb57600080fd5b80632f745c5914610249578063365430061461025c57806340c10f191461026f57600080fd5b806305d2035b146101ae57806306fdde03146101cb578063081812fc146101e0578063095ea7b31461020b57806318160ddd1461022057806323b872dd14610236575b600080fd5b6101b66103b7565b60405190151581526020015b60405180910390f35b6101d3610443565b6040516101c2919061148a565b6101f36101ee366004611277565b6104c3565b6040516001600160a01b0390911681526020016101c2565b61021e61021936600461118c565b610547565b005b6102286105b2565b6040519081526020016101c2565b61021e610244366004610eff565b610639565b61022861025736600461118c565b6106ad565b6101b661026a366004610fac565b610739565b6101b661027d36600461118c565b6107be565b61021e610290366004610eff565b6107f8565b61021e6102a3366004611277565b610839565b6101b66102b63660046110b1565b61089a565b6102286102c9366004611277565b6108cd565b6101b66102dc3660046111b8565b61094b565b61021e6102ef366004610f40565b6109da565b6101f3610302366004611277565b610a49565b610228610315366004610e8c565b610a7b565b610228610aae565b6101b6610afd565b6101d3610b62565b61021e61034036600461115e565b610ba6565b61021e61035336600461118c565b610be0565b6101d3610366366004611277565b610c19565b61021e6103793660046112a9565b610c9b565b6101d361038c366004611277565b610ccd565b6101f361039f366004610ec6565b610cff565b6101b66103b23660046112f0565b610d85565b60008060009054906101000a90046001600160a01b03166001600160a01b03166305d2035b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561040657600080fd5b505afa15801561041a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190611211565b905090565b60008054604080516306fdde0360e01b815290516060936001600160a01b03909316926306fdde039260048082019391829003018186803b15801561048757600080fd5b505afa15801561049b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261043e919081019061122e565b6000805460405163020604bf60e21b8152600481018490526001600160a01b039091169063081812fc906024015b60206040518083038186803b15801561050957600080fd5b505afa15801561051d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105419190610ea9565b92915050565b60005460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044015b600060405180830381600087803b15801561059657600080fd5b505af11580156105aa573d6000803e3d6000fd5b505050505050565b60008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561060157600080fd5b505afa158015610615573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043e9190611290565b6000546040516323b872dd60e01b81526001600160a01b038581166004830152848116602483015260448201849052909116906323b872dd906064015b600060405180830381600087803b15801561069057600080fd5b505af11580156106a4573d6000803e3d6000fd5b50505050505050565b60008054604051632f745c5960e01b81526001600160a01b0385811660048301526024820185905290911690632f745c599060440160206040518083038186803b1580156106fa57600080fd5b505afa15801561070e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107329190611290565b9392505050565b60008054604051631b2a180360e11b81526001600160a01b039091169063365430069061076c908690869060040161137f565b602060405180830381600087803b15801561078657600080fd5b505af115801561079a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107329190611211565b600080546040516340c10f1960e01b81526001600160a01b03858116600483015260248201859052909116906340c10f199060440161076c565b600054604051632142170760e11b81526001600160a01b038581166004830152848116602483015260448201849052909116906342842e0e90606401610676565b600054604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c6890602401600060405180830381600087803b15801561087f57600080fd5b505af1158015610893573d6000803e3d6000fd5b5050505050565b60008054604051632254ca2f60e11b81526001600160a01b03909116906344a9945e9061076c9086908690600401611404565b60008054604051634f6ccce760e01b8152600481018490526001600160a01b0390911690634f6ccce7906024015b60206040518083038186803b15801561091357600080fd5b505afa158015610927573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105419190611290565b600080546040516350bb4e7f60e01b81526001600160a01b03909116906350bb4e7f906109809087908790879060040161145a565b602060405180830381600087803b15801561099a57600080fd5b505af11580156109ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d29190611211565b949350505050565b6000546040516330508b3960e11b81526001600160a01b03909116906360a1167290610a10908790879087908790600401611342565b600060405180830381600087803b158015610a2a57600080fd5b505af1158015610a3e573d6000803e3d6000fd5b505050505b50505050565b600080546040516331a9108f60e11b8152600481018490526001600160a01b0390911690636352211e906024016104f1565b600080546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a08231906024016108fb565b60008060009054906101000a90046001600160a01b03166001600160a01b03166375794a3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561060157600080fd5b60008060009054906101000a90046001600160a01b03166001600160a01b0316637d64bcb46040518163ffffffff1660e01b8152600401602060405180830381600087803b158015610b4e57600080fd5b505af115801561041a573d6000803e3d6000fd5b60008054604080516395d89b4160e01b815290516060936001600160a01b03909316926395d89b419260048082019391829003018186803b15801561048757600080fd5b60005460405163a22cb46560e01b81526001600160a01b03848116600483015283151560248301529091169063a22cb4659060440161057c565b60005460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb9060440161057c565b60005460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd906024015b60006040518083038186803b158015610c5f57600080fd5b505afa158015610c73573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610541919081019061122e565b60005460405163d4eac26d60e01b81526001600160a01b039091169063d4eac26d9061057c908590859060040161149d565b60005460405163e6c5ce6f60e01b8152600481018390526060916001600160a01b03169063e6c5ce6f90602401610c47565b6000805460405163e985e9c560e01b81526001600160a01b03858116600483015284811660248301529091169063e985e9c59060440160206040518083038186803b158015610d4d57600080fd5b505afa158015610d61573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107329190610ea9565b6000805460405162f4f4b560e81b815263ffffffff841660048201526001600160a01b039091169063f4f4b5009060240160206040518083038186803b158015610dce57600080fd5b505afa158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105419190611211565b6000610e19610e1484611534565b6114df565b9050828152838383011115610e2d57600080fd5b61073283602083018461155c565b600082601f830112610e4c57600080fd5b8135610e5a610e1482611534565b818152846020838601011115610e6f57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215610e9e57600080fd5b81356107328161159e565b600060208284031215610ebb57600080fd5b81516107328161159e565b60008060408385031215610ed957600080fd5b8235610ee48161159e565b91506020830135610ef48161159e565b809150509250929050565b600080600060608486031215610f1457600080fd5b8335610f1f8161159e565b92506020840135610f2f8161159e565b929592945050506040919091013590565b60008060008060808587031215610f5657600080fd5b8435610f618161159e565b93506020850135610f718161159e565b925060408501359150606085013567ffffffffffffffff811115610f9457600080fd5b610fa087828801610e3b565b91505092959194509250565b60008060408385031215610fbf57600080fd5b8235610fca8161159e565b915060208381013567ffffffffffffffff80821115610fe857600080fd5b818601915086601f830112610ffc57600080fd5b813561100a610e1482611510565b8082825285820191508585018a878560051b880101111561102a57600080fd5b60005b848110156110a05781358681111561104457600080fd5b87016040818e03601f1901121561105a57600080fd5b6110626114b6565b89820135815260408201358881111561107a57600080fd5b6110888f8c83860101610e3b565b828c015250855250928701929087019060010161102d565b50979a909950975050505050505050565b600080604083850312156110c457600080fd5b82356110cf8161159e565b915060208381013567ffffffffffffffff8111156110ec57600080fd5b8401601f810186136110fd57600080fd5b803561110b610e1482611510565b80828252848201915084840189868560051b870101111561112b57600080fd5b600094505b8385101561114e578035835260019490940193918501918501611130565b5080955050505050509250929050565b6000806040838503121561117157600080fd5b823561117c8161159e565b91506020830135610ef4816115b6565b6000806040838503121561119f57600080fd5b82356111aa8161159e565b946020939093013593505050565b6000806000606084860312156111cd57600080fd5b83356111d88161159e565b925060208401359150604084013567ffffffffffffffff8111156111fb57600080fd5b61120786828701610e3b565b9150509250925092565b60006020828403121561122357600080fd5b8151610732816115b6565b60006020828403121561124057600080fd5b815167ffffffffffffffff81111561125757600080fd5b8201601f8101841361126857600080fd5b6109d284825160208401610e06565b60006020828403121561128957600080fd5b5035919050565b6000602082840312156112a257600080fd5b5051919050565b600080604083850312156112bc57600080fd5b82359150602083013567ffffffffffffffff8111156112da57600080fd5b6112e685828601610e3b565b9150509250929050565b60006020828403121561130257600080fd5b813563ffffffff8116811461073257600080fd5b6000815180845261132e81602086016020860161155c565b601f01601f19169290920160200192915050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061137590830184611316565b9695505050505050565b6001600160a01b0383168152604060208083018290528351828401819052600092916060600583901b860181019290860190878301865b828110156113f557888603605f190184528151805187528501518587018890526113e288880182611316565b96505092840192908401906001016113b6565b50939998505050505050505050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b8181101561144d57845183529383019391830191600101611431565b5090979650505050505050565b60018060a01b03841681528260208201526060604082015260006114816060830184611316565b95945050505050565b6020815260006107326020830184611316565b8281526040602082015260006109d26040830184611316565b6040805190810167ffffffffffffffff811182821017156114d9576114d9611588565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561150857611508611588565b604052919050565b600067ffffffffffffffff82111561152a5761152a611588565b5060051b60200190565b600067ffffffffffffffff82111561154e5761154e611588565b50601f01601f191660200190565b60005b8381101561157757818101518382015260200161155f565b83811115610a435750506000910152565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146115b357600080fd5b50565b80151581146115b357600080fdfea2646970667358221220669a75a3efcdc6b60606caa5c7e41cab1d727e89a03fd231d1cda27f4de159a064736f6c63430008070033
\ No newline at end of file
+608060405234801561001057600080fd5b506040516116bb3803806116bb83398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b611628806100936000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80634f6ccce7116100f957806379cc679011610097578063a22cb46511610071578063a22cb46514610399578063a9059cbb146103ac578063c87b56dd146103bf578063e985e9c5146103d257600080fd5b806379cc6790146103765780637d64bcb41461038957806395d89b411461039157600080fd5b806362d9491f116100d357806362d9491f146103355780636352211e1461034857806370a082311461035b57806375794a3c1461036e57600080fd5b80634f6ccce7146102fc57806350bb4e7f1461030f57806360a116721461032257600080fd5b80632f745c591161016657806340c10f191161014057806340c10f19146102b057806342842e0e146102c357806342966c68146102d657806344a9945e146102e957600080fd5b80632f745c5914610277578063342419141461028a578063365430061461029d57600080fd5b8063081812fc116101a2578063081812fc1461020e578063095ea7b31461023957806318160ddd1461024e57806323b872dd1461026457600080fd5b806301ffc9a7146101c957806305d2035b146101f157806306fdde03146101f9575b600080fd5b6101dc6101d7366004610dca565b6103e5565b60405190151581526020015b60405180910390f35b6101dc610462565b6102016104df565b6040516101e89190610e4c565b61022161021c366004610e5f565b610550565b6040516001600160a01b0390911681526020016101e8565b61024c610247366004610e90565b6105bf565b005b61025661062a565b6040519081526020016101e8565b61024c610272366004610ebc565b6106a2565b610256610285366004610e90565b610716565b61024c610298366004610ff3565b610793565b6101dc6102ab36600461104c565b6107f8565b6101dc6102be366004610e90565b61086e565b61024c6102d1366004610ebc565b6108a8565b61024c6102e4366004610e5f565b6108e9565b6101dc6102f736600461114f565b61091a565b61025661030a366004610e5f565b61094d565b6101dc61031d3660046111f5565b6109bc565b61024c61033036600461124e565b610a3c565b61024c6103433660046112ce565b610aab565b610221610356366004610e5f565b610add565b610256610369366004611332565b610b0f565b610256610b42565b61024c610384366004610e90565b610b96565b6101dc610bcf565b610201610c25565b61024c6103a736600461135d565b610c6e565b61024c6103ba366004610e90565b610ca8565b6102016103cd366004610e5f565b610ce1565b6102216103e0366004611396565b610d53565b600080546040516301ffc9a760e01b81526001600160e01b0319841660048201526001600160a01b03909116906301ffc9a790602401602060405180830381865afa158015610438573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045c91906113c4565b92915050565b60008060009054906101000a90046001600160a01b03166001600160a01b03166305d2035b6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156104b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104da91906113c4565b905090565b60008054604080516306fdde0360e01b815290516060936001600160a01b03909316926306fdde0392600480820193918290030181865afa158015610528573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526104da91908101906113e1565b6000805460405163020604bf60e21b8152600481018490526001600160a01b039091169063081812fc906024015b602060405180830381865afa15801561059b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045c9190611458565b60005460405163095ea7b360e01b81526001600160a01b038481166004830152602482018490529091169063095ea7b3906044015b600060405180830381600087803b15801561060e57600080fd5b505af1158015610622573d6000803e3d6000fd5b505050505050565b60008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561067e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104da9190611475565b6000546040516323b872dd60e01b81526001600160a01b038581166004830152848116602483015260448201849052909116906323b872dd906064015b600060405180830381600087803b1580156106f957600080fd5b505af115801561070d573d6000803e3d6000fd5b50505050505050565b60008054604051632f745c5960e01b81526001600160a01b0385811660048301526024820185905290911690632f745c5990604401602060405180830381865afa158015610768573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078c9190611475565b9392505050565b600054604051630d09064560e21b81526001600160a01b03909116906334241914906107c3908490600401610e4c565b600060405180830381600087803b1580156107dd57600080fd5b505af11580156107f1573d6000803e3d6000fd5b5050505050565b60008054604051631b2a180360e11b81526001600160a01b039091169063365430069061082b908690869060040161148e565b6020604051808303816000875af115801561084a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078c91906113c4565b600080546040516340c10f1960e01b81526001600160a01b03858116600483015260248201859052909116906340c10f199060440161082b565b600054604051632142170760e11b81526001600160a01b038581166004830152848116602483015260448201849052909116906342842e0e906064016106df565b600054604051630852cd8d60e31b8152600481018390526001600160a01b03909116906342966c68906024016107c3565b60008054604051632254ca2f60e11b81526001600160a01b03909116906344a9945e9061082b9086908690600401611513565b60008054604051634f6ccce760e01b8152600481018490526001600160a01b0390911690634f6ccce7906024015b602060405180830381865afa158015610998573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061045c9190611475565b600080546040516350bb4e7f60e01b81526001600160a01b03909116906350bb4e7f906109f190879087908790600401611569565b6020604051808303816000875af1158015610a10573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a3491906113c4565b949350505050565b6000546040516330508b3960e11b81526001600160a01b03909116906360a1167290610a72908790879087908790600401611590565b600060405180830381600087803b158015610a8c57600080fd5b505af1158015610aa0573d6000803e3d6000fd5b505050505b50505050565b6000546040516362d9491f60e01b81526001600160a01b03909116906362d9491f906105f490859085906004016115cd565b600080546040516331a9108f60e11b8152600481018490526001600160a01b0390911690636352211e9060240161057e565b600080546040516370a0823160e01b81526001600160a01b038481166004830152909116906370a082319060240161097b565b60008060009054906101000a90046001600160a01b03166001600160a01b03166375794a3c6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561067e573d6000803e3d6000fd5b60005460405163079cc67960e41b81526001600160a01b03848116600483015260248201849052909116906379cc6790906044016105f4565b60008060009054906101000a90046001600160a01b03166001600160a01b0316637d64bcb46040518163ffffffff1660e01b81526004016020604051808303816000875af11580156104b6573d6000803e3d6000fd5b60008054604080516395d89b4160e01b815290516060936001600160a01b03909316926395d89b4192600480820193918290030181865afa158015610528573d6000803e3d6000fd5b60005460405163a22cb46560e01b81526001600160a01b03848116600483015283151560248301529091169063a22cb465906044016105f4565b60005460405163a9059cbb60e01b81526001600160a01b038481166004830152602482018490529091169063a9059cbb906044016105f4565b60005460405163c87b56dd60e01b8152600481018390526060916001600160a01b03169063c87b56dd90602401600060405180830381865afa158015610d2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261045c91908101906113e1565b6000805460405163e985e9c560e01b81526001600160a01b03858116600483015284811660248301529091169063e985e9c590604401602060405180830381865afa158015610da6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061078c9190611458565b600060208284031215610ddc57600080fd5b81356001600160e01b03198116811461078c57600080fd5b60005b83811015610e0f578181015183820152602001610df7565b83811115610aa55750506000910152565b60008151808452610e38816020860160208601610df4565b601f01601f19169290920160200192915050565b60208152600061078c6020830184610e20565b600060208284031215610e7157600080fd5b5035919050565b6001600160a01b0381168114610e8d57600080fd5b50565b60008060408385031215610ea357600080fd5b8235610eae81610e78565b946020939093013593505050565b600080600060608486031215610ed157600080fd5b8335610edc81610e78565b92506020840135610eec81610e78565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b6040805190810167ffffffffffffffff81118282101715610f3657610f36610efd565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610f6557610f65610efd565b604052919050565b600067ffffffffffffffff821115610f8757610f87610efd565b50601f01601f191660200190565b6000610fa8610fa384610f6d565b610f3c565b9050828152838383011115610fbc57600080fd5b828260208301376000602084830101529392505050565b600082601f830112610fe457600080fd5b61078c83833560208501610f95565b60006020828403121561100557600080fd5b813567ffffffffffffffff81111561101c57600080fd5b610a3484828501610fd3565b600067ffffffffffffffff82111561104257611042610efd565b5060051b60200190565b600080604080848603121561106057600080fd5b833561106b81610e78565b925060208481013567ffffffffffffffff8082111561108957600080fd5b818701915087601f83011261109d57600080fd5b81356110ab610fa382611028565b81815260059190911b8301840190848101908a8311156110ca57600080fd5b8585015b8381101561113d578035858111156110e65760008081fd5b8601808d03601f19018913156110fc5760008081fd5b611104610f13565b888201358152898201358781111561111c5760008081fd5b61112a8f8b83860101610fd3565b828b0152508452509186019186016110ce565b50809750505050505050509250929050565b6000806040838503121561116257600080fd5b823561116d81610e78565b915060208381013567ffffffffffffffff81111561118a57600080fd5b8401601f8101861361119b57600080fd5b80356111a9610fa382611028565b81815260059190911b820183019083810190888311156111c857600080fd5b928401925b828410156111e6578335825292840192908401906111cd565b80955050505050509250929050565b60008060006060848603121561120a57600080fd5b833561121581610e78565b925060208401359150604084013567ffffffffffffffff81111561123857600080fd5b61124486828701610fd3565b9150509250925092565b6000806000806080858703121561126457600080fd5b843561126f81610e78565b9350602085013561127f81610e78565b925060408501359150606085013567ffffffffffffffff8111156112a257600080fd5b8501601f810187136112b357600080fd5b6112c287823560208401610f95565b91505092959194509250565b600080604083850312156112e157600080fd5b823567ffffffffffffffff808211156112f957600080fd5b61130586838701610fd3565b9350602085013591508082111561131b57600080fd5b5061132885828601610fd3565b9150509250929050565b60006020828403121561134457600080fd5b813561078c81610e78565b8015158114610e8d57600080fd5b6000806040838503121561137057600080fd5b823561137b81610e78565b9150602083013561138b8161134f565b809150509250929050565b600080604083850312156113a957600080fd5b82356113b481610e78565b9150602083013561138b81610e78565b6000602082840312156113d657600080fd5b815161078c8161134f565b6000602082840312156113f357600080fd5b815167ffffffffffffffff81111561140a57600080fd5b8201601f8101841361141b57600080fd5b8051611429610fa382610f6d565b81815285602083850101111561143e57600080fd5b61144f826020830160208601610df4565b95945050505050565b60006020828403121561146a57600080fd5b815161078c81610e78565b60006020828403121561148757600080fd5b5051919050565b6001600160a01b0383168152604060208083018290528351828401819052600092916060600583901b860181019290860190878301865b8281101561150457888603605f190184528151805187528501518587018890526114f188880182610e20565b96505092840192908401906001016114c5565b50939998505050505050505050565b6001600160a01b038316815260406020808301829052835191830182905260009184820191906060850190845b8181101561155c57845183529383019391830191600101611540565b5090979650505050505050565b60018060a01b038416815282602082015260606040820152600061144f6060830184610e20565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906115c390830184610e20565b9695505050505050565b6040815260006115e06040830185610e20565b828103602084015261144f8185610e2056fea26469706673582212205bdf4275f4b714a1029ccfe77c0f9a0e20e121a932e1e5840cace97dfa886da964736f6c634300080d0033
\ No newline at end of file
modifiedtests/src/eth/proxy/UniqueNFTProxy.soldiffbeforeafterboth
--- a/tests/src/eth/proxy/UniqueNFTProxy.sol
+++ b/tests/src/eth/proxy/UniqueNFTProxy.sol
@@ -148,29 +148,17 @@
         return proxied.nextTokenId();
     }
 
-    function supportsInterface(uint32 interfaceId)
+    function burnFrom(address from, uint256 tokenId) external override {
+        return proxied.burnFrom(from, tokenId);
+    }
+
+    function supportsInterface(bytes4 interfaceId)
         external
         view
         override
         returns (bool)
     {
         return proxied.supportsInterface(interfaceId);
-    }
-
-    function setVariableMetadata(uint256 tokenId, bytes memory data)
-        external
-        override
-    {
-        return proxied.setVariableMetadata(tokenId, data);
-    }
-
-    function getVariableMetadata(uint256 tokenId)
-        external
-        view
-        override
-        returns (bytes memory)
-    {
-        return proxied.getVariableMetadata(tokenId);
     }
 
     function mintBulk(address to, uint256[] memory tokenIds)
@@ -188,4 +176,12 @@
     {
         return proxied.mintBulkWithTokenURI(to, tokens);
     }
+
+    function setProperty(string memory key, string memory value) external override {
+        return proxied.setProperty(key, value);
+    }
+
+	function deleteProperty(string memory key) external override {
+        return proxied.deleteProperty(key);
+    }
 }
modifiedtests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterboth
--- a/tests/src/eth/proxy/nonFungibleProxy.test.ts
+++ b/tests/src/eth/proxy/nonFungibleProxy.test.ts
@@ -15,7 +15,7 @@
 // along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
 
 import privateKey from '../../substrate/privateKey';
-import {createCollectionExpectSuccess, createItemExpectSuccess, setVariableMetaDataExpectSuccess, setMetadataUpdatePermissionFlagExpectSuccess} from '../../util/helpers';
+import {createCollectionExpectSuccess, createItemExpectSuccess} from '../../util/helpers';
 import {collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3, normalizeEvents} from '../util/helpers';
 import nonFungibleAbi from '../nonFungibleAbi.json';
 import {expect} from 'chai';
@@ -333,36 +333,5 @@
       const balance = await contract.methods.balanceOf(receiver).call();
       expect(+balance).to.equal(1);
     }
-  });
-
-  itWeb3('Can perform getVariableMetadata', async ({web3, api}) => {
-    const collection = await createCollectionExpectSuccess({
-      mode: {type: 'NFT'},
-    });
-    const alice = privateKey('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
-
-    const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
-    const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
-    await setMetadataUpdatePermissionFlagExpectSuccess(alice, collection, 'Admin');
-    await setVariableMetaDataExpectSuccess(alice, collection, item, [1, 2, 3]);
-
-    expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');
-  });
-
-  itWeb3('Can perform setVariableMetadata', async ({web3, api}) => {
-    const collection = await createCollectionExpectSuccess({
-      mode: {type: 'NFT'},
-    });
-    const alice = privateKey('//Alice');
-    const caller = await createEthAccountWithBalance(api, web3);
-
-    const address = collectionIdToAddress(collection);
-    const contract = await proxyWrap(api, web3, new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS}));
-    const item = await createItemExpectSuccess(alice, collection, 'NFT', {Ethereum: contract.options.address});
-
-    expect(await contract.methods.setVariableMetadata(item, '0x010203').send({from: caller}));
-    expect(await contract.methods.getVariableMetadata(item).call()).to.be.equal('0x010203');
   });
 });
addedtests/src/eth/tokenProperties.test.tsdiffbeforeafterboth
--- /dev/null
+++ b/tests/src/eth/tokenProperties.test.ts
@@ -0,0 +1,95 @@
+import privateKey from '../substrate/privateKey';
+import {addCollectionAdminExpectSuccess, createCollectionExpectSuccess, createItemExpectSuccess} from '../util/helpers';
+import {cartesian, collectionIdToAddress, createEthAccount, createEthAccountWithBalance, GAS_ARGS, itWeb3} from './util/helpers';
+import nonFungibleAbi from './nonFungibleAbi.json';
+import {expect} from 'chai';
+import {executeTransaction} from '../substrate/substrate-api';
+
+describe('EVM token properties', () => {
+  itWeb3('Can be reconfigured', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    for(const [mutable,collectionAdmin, tokenOwner] of cartesian([], [false, true], [false, true], [false, true])) {
+      const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+      await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
+      
+      const address = collectionIdToAddress(collection);
+      const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+  
+      await contract.methods.setTokenPropertyPermission('testKey', mutable, collectionAdmin, tokenOwner).send({from: caller});
+  
+      const state = (await api.query.common.collectionPropertyPermissions(collection)).toJSON();
+      expect(state).to.be.deep.equal({
+        [web3.utils.toHex('testKey')]: {mutable, collectionAdmin, tokenOwner},
+      });
+    }
+  });
+  itWeb3('Can be set', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const token = await createItemExpectSuccess(alice, collection, 'NFT');
+
+    await executeTransaction(api, alice, api.tx.unique.setPropertyPermissions(collection, [{
+      key: 'testKey',
+      permission: {
+        collectionAdmin: true,
+      },
+    }]));
+
+    await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    await contract.methods.setProperty(token, 'testKey', Buffer.from('testValue')).send({from: caller});
+
+    const [{value}] = (await api.rpc.unique.tokenProperties(collection, token, ['testKey'])).toHuman()! as any;
+    expect(value).to.equal('testValue');
+  });
+  itWeb3('Can be deleted', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = await createEthAccountWithBalance(api, web3);
+    const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
+    const token = await createItemExpectSuccess(alice, collection, 'NFT');
+
+    await executeTransaction(api, alice, api.tx.unique.setPropertyPermissions(collection, [{
+      key: 'testKey',
+      permission: {
+        mutable: true,
+        collectionAdmin: true,
+      },
+    }]));
+    await executeTransaction(api, alice, api.tx.unique.setTokenProperties(collection, token, [{key: 'testKey', value: 'testValue'}]));
+
+    await addCollectionAdminExpectSuccess(alice, collection, {Ethereum: caller});
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    await contract.methods.deleteProperty(token, 'testKey').send({from: caller});
+
+    const result = (await api.rpc.unique.tokenProperties(collection, token, ['testKey'])).toJSON()! as any;
+    expect(result.length).to.equal(0);
+  });
+  itWeb3('Can be read', async({web3, api}) => {
+    const alice = privateKey('//Alice');
+    const caller = createEthAccount(web3);
+    const collection = await createCollectionExpectSuccess({mode: {type:'NFT'}});
+    const token = await createItemExpectSuccess(alice, collection, 'NFT');
+
+    await executeTransaction(api, alice, api.tx.unique.setPropertyPermissions(collection, [{
+      key: 'testKey',
+      permission: {
+        collectionAdmin: true,
+      },
+    }]));
+    await executeTransaction(api, alice, api.tx.unique.setTokenProperties(collection, token, [{key: 'testKey', value: 'testValue'}]));
+
+    const address = collectionIdToAddress(collection);
+    const contract = new web3.eth.Contract(nonFungibleAbi as any, address, {from: caller, ...GAS_ARGS});
+
+    const value = await contract.methods.property(token, 'testKey').call();
+    expect(value).to.equal(web3.utils.toHex('testValue'));
+  });
+});
modifiedtests/src/eth/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/eth/util/helpers.ts
+++ b/tests/src/eth/util/helpers.ts
@@ -322,3 +322,15 @@
 
   return before - after;
 }
+
+type ElementOf<A> = A extends readonly (infer T)[] ? T : never;
+// I want a fancier api, not a memory efficiency
+export function* cartesian<T extends Array<Array<any>>, R extends Array<any>>(internalRest: [...R], ...args: [...T]): Generator<[...R, ...{[K in keyof T]: ElementOf<T[K]>}]> {
+  if(args.length === 0) {
+    yield internalRest as any;
+    return;
+  }
+  for(const value of args[0]) {
+    yield* cartesian([...internalRest, value], ...args.slice(1)) as any;
+  }
+}
\ No newline at end of file
modifiedtests/src/interfaces/augment-api-errors.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-errors.ts
+++ b/tests/src/interfaces/augment-api-errors.ts
@@ -137,6 +137,10 @@
        **/
       OwnerPermissionsCantBeReverted: AugmentedError<ApiType>;
       /**
+       * Property key is too long
+       **/
+      PropertyKeyIsTooLong: AugmentedError<ApiType>;
+      /**
        * Tried to store more property keys than allowed
        **/
       PropertyLimitReached: AugmentedError<ApiType>;
@@ -156,10 +160,6 @@
        * Item balance not enough.
        **/
       TokenValueTooLow: AugmentedError<ApiType>;
-      /**
-       * variable_data exceeded data limit.
-       **/
-      TokenVariableDataLimitExceeded: AugmentedError<ApiType>;
       /**
        * Total collections bound exceeded.
        **/
@@ -168,10 +168,6 @@
        * Collection settings not allowing items transferring
        **/
       TransferNotAllowed: AugmentedError<ApiType>;
-      /**
-       * Unable to read array of unbounded keys
-       **/
-      UnableToReadUnboundedKeys: AugmentedError<ApiType>;
       /**
        * Target collection doesn't supports this operation
        **/
modifiedtests/src/interfaces/augment-api-rpc.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-rpc.ts
+++ b/tests/src/interfaces/augment-api-rpc.ts
@@ -1,7 +1,7 @@
 // Auto-generated via `yarn polkadot-types-from-chain`, do not edit
 /* eslint-disable */
 
-import type { PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsCollectionLimits, UpDataStructsCollectionStats, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsRpcCollection, UpDataStructsTokenData } from './unique';
+import type { PalletEvmAccountBasicCrossAccountIdRepr, RmrkTypesBaseInfo, RmrkTypesCollectionInfo, RmrkTypesNftChild, RmrkTypesNftInfo, RmrkTypesPartType, RmrkTypesPropertyInfo, RmrkTypesResourceInfo, RmrkTypesTheme, UpDataStructsCollectionLimits, UpDataStructsCollectionStats, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsRpcCollection, UpDataStructsTokenData } from './unique';
 import type { AugmentedRpc } from '@polkadot/rpc-core/types';
 import type { Metadata, StorageKey } from '@polkadot/types';
 import type { Bytes, HashMap, Json, Null, Option, Text, U256, U64, Vec, bool, u128, u32, u64 } from '@polkadot/types-codec';
@@ -401,19 +401,19 @@
       /**
        * Get base info
        **/
-      base: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsBaseBaseInfo>>>;
+      base: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTypesBaseInfo>>>;
       /**
        * Get all Base's parts
        **/
-      baseParts: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsPartPartType>>>;
+      baseParts: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTypesPartType>>>;
       /**
        * Get collection by id
        **/
-      collectionById: AugmentedRpc<(id: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsCollectionCollectionInfo>>>;
+      collectionById: AugmentedRpc<(id: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTypesCollectionInfo>>>;
       /**
        * Get collection properties
        **/
-      collectionProperties: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsPropertyPropertyInfo>>>;
+      collectionProperties: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTypesPropertyInfo>>>;
       /**
        * Get the latest created collection id
        **/
@@ -421,15 +421,15 @@
       /**
        * Get NFT by collection id and NFT id
        **/
-      nftById: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsNftNftInfo>>>;
+      nftById: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTypesNftInfo>>>;
       /**
        * Get NFT children
        **/
-      nftChildren: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsNftNftChild>>>;
+      nftChildren: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTypesNftChild>>>;
       /**
        * Get NFT properties
        **/
-      nftProperties: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsPropertyPropertyInfo>>>;
+      nftProperties: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTypesPropertyInfo>>>;
       /**
        * Get NFT resource priorities
        **/
@@ -437,7 +437,7 @@
       /**
        * Get NFT resources
        **/
-      nftResources: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTraitsResourceResourceInfo>>>;
+      nftResources: AugmentedRpc<(collectionId: u32 | AnyNumber | Uint8Array, nftId: u32 | AnyNumber | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Vec<RmrkTypesResourceInfo>>>;
       /**
        * Get Base's theme names
        **/
@@ -445,7 +445,7 @@
       /**
        * Get Theme's keys values
        **/
-      themes: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, themeName: Text | string, keys: Option<Vec<Text>> | null | object | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTraitsTheme>>>;
+      themes: AugmentedRpc<(baseId: u32 | AnyNumber | Uint8Array, themeName: Text | string, keys: Option<Vec<Text>> | null | object | string | Uint8Array, at?: Hash | string | Uint8Array) => Observable<Option<RmrkTypesTheme>>>;
     };
     rpc: {
       /**
@@ -659,7 +659,7 @@
       /**
        * Get collection properties
        **/
-      collectionProperties: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, propertyKeys: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsProperty>>>;
+      collectionProperties: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsProperty>>>;
       /**
        * Get collection stats
        **/
@@ -687,11 +687,11 @@
       /**
        * Get property permissions
        **/
-      propertyPermissions: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, propertyKeys: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsPropertyKeyPermission>>>;
+      propertyPermissions: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsPropertyKeyPermission>>>;
       /**
        * Get token data
        **/
-      tokenData: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<UpDataStructsTokenData>>;
+      tokenData: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<UpDataStructsTokenData>>;
       /**
        * Check if token exists
        **/
@@ -703,7 +703,7 @@
       /**
        * Get token properties
        **/
-      tokenProperties: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsProperty>>>;
+      tokenProperties: AugmentedRpc<(collection: u32 | AnyNumber | Uint8Array, tokenId: u32 | AnyNumber | Uint8Array, propertyKeys?: Vec<Text> | (Text | string)[], at?: Hash | string | Uint8Array) => Observable<Vec<UpDataStructsProperty>>>;
       /**
        * Get token owner, in case of nested token - find parent recursive
        **/
modifiedtests/src/interfaces/augment-api-tx.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-api-tx.ts
+++ b/tests/src/interfaces/augment-api-tx.ts
@@ -5,7 +5,7 @@
 import type { Bytes, Compact, Option, U256, Vec, bool, u128, u16, u32, u64 } from '@polkadot/types-codec';
 import type { AnyNumber, IMethod, ITuple } from '@polkadot/types-codec/types';
 import type { AccountId32, Call, H160, H256, MultiAddress, Perbill } from '@polkadot/types/interfaces/runtime';
-import type { CumulusPrimitivesParachainInherentParachainInherentData, EthereumTransactionTransactionV2, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsMetaUpdatePermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsSchemaVersion, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
+import type { CumulusPrimitivesParachainInherentParachainInherentData, EthereumTransactionTransactionV2, OrmlVestingVestingSchedule, PalletEvmAccountBasicCrossAccountIdRepr, UpDataStructsAccessMode, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCreateCollectionData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsSchemaVersion, XcmV1MultiLocation, XcmV2WeightLimit, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
 
 declare module '@polkadot/api-base/types/submittable' {
   export interface AugmentedSubmittables<ApiType extends ApiTypes> {
@@ -679,7 +679,7 @@
        * 
        * Prefer it to deprecated [`created_collection`] method
        **/
-      createCollectionEx: AugmentedSubmittable<(data: UpDataStructsCreateCollectionData | { mode?: any; access?: any; name?: any; description?: any; tokenPrefix?: any; offchainSchema?: any; schemaVersion?: any; pendingSponsor?: any; limits?: any; constOnChainSchema?: any; metaUpdatePermission?: any; tokenPropertyPermissions?: any; properties?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [UpDataStructsCreateCollectionData]>;
+      createCollectionEx: AugmentedSubmittable<(data: UpDataStructsCreateCollectionData | { mode?: any; access?: any; name?: any; description?: any; tokenPrefix?: any; offchainSchema?: any; schemaVersion?: any; pendingSponsor?: any; limits?: any; constOnChainSchema?: any; tokenPropertyPermissions?: any; properties?: any } | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [UpDataStructsCreateCollectionData]>;
       /**
        * This method creates a concrete instance of NFT Collection created with CreateCollection method.
        * 
@@ -809,20 +809,6 @@
        **/
       setConstOnChainSchema: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, schema: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, Bytes]>;
       /**
-       * Set meta_update_permission value for particular collection
-       * 
-       * # Permissions
-       * 
-       * * Collection Owner.
-       * 
-       * # Arguments
-       * 
-       * * collection_id: ID of the collection.
-       * 
-       * * value: New flag value.
-       **/
-      setMetaUpdatePermissionFlag: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, value: UpDataStructsMetaUpdatePermission | 'ItemOwner' | 'Admin' | 'None' | number | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, UpDataStructsMetaUpdatePermission]>;
-      /**
        * Allows Anyone to create tokens if:
        * * Allow List is enabled, and
        * * Address is added to allow list, and
@@ -900,21 +886,6 @@
        * * value: New flag value.
        **/
       setTransfersEnabledFlag: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, value: bool | boolean | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, bool]>;
-      /**
-       * Set off-chain data schema.
-       * 
-       * # Permissions
-       * 
-       * * Collection Owner
-       * * Collection Admin
-       * 
-       * # Arguments
-       * 
-       * * collection_id.
-       * 
-       * * schema: String representing the offchain data schema.
-       **/
-      setVariableMetaData: AugmentedSubmittable<(collectionId: u32 | AnyNumber | Uint8Array, itemId: u32 | AnyNumber | Uint8Array, data: Bytes | string | Uint8Array) => SubmittableExtrinsic<ApiType>, [u32, u32, Bytes]>;
       /**
        * Change ownership of the token.
        * 
modifiedtests/src/interfaces/augment-types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/augment-types.ts
+++ b/tests/src/interfaces/augment-types.ts
@@ -1,7 +1,7 @@
 // Auto-generated via `yarn polkadot-types-from-defs`, do not edit
 /* eslint-disable */
 
-import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportPalletId, FrameSupportStorageBoundedBTreeSet, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PhantomTypeUpDataStructsBaseInfo, PhantomTypeUpDataStructsCollectionInfo, PhantomTypeUpDataStructsNftChild, PhantomTypeUpDataStructsNftInfo, PhantomTypeUpDataStructsPartType, PhantomTypeUpDataStructsPropertyInfo, PhantomTypeUpDataStructsResourceInfo, PhantomTypeUpDataStructsRpcCollection, PhantomTypeUpDataStructsTheme, PhantomTypeUpDataStructsTokenData, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, RmrkTypesAccountIdOrCollectionNftTuple, RmrkTypesBaseInfo, RmrkTypesCollectionInfo, RmrkTypesEquippableList, RmrkTypesFixedPart, RmrkTypesNftChild, RmrkTypesNftInfo, RmrkTypesPartType, RmrkTypesPropertyInfo, RmrkTypesResourceInfo, RmrkTypesRoyaltyInfo, RmrkTypesSlotPart, RmrkTypesTheme, RmrkTypesThemeProperty, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionField, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsMetaUpdatePermission, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRpcCollection, UpDataStructsSchemaVersion, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from './unique';
+import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportPalletId, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PhantomTypeUpDataStructsBaseInfo, PhantomTypeUpDataStructsCollectionInfo, PhantomTypeUpDataStructsNftChild, PhantomTypeUpDataStructsNftInfo, PhantomTypeUpDataStructsPartType, PhantomTypeUpDataStructsPropertyInfo, PhantomTypeUpDataStructsResourceInfo, PhantomTypeUpDataStructsRpcCollection, PhantomTypeUpDataStructsTheme, PhantomTypeUpDataStructsTokenData, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, RmrkTypesAccountIdOrCollectionNftTuple, RmrkTypesBaseInfo, RmrkTypesCollectionInfo, RmrkTypesEquippableList, RmrkTypesFixedPart, RmrkTypesNftChild, RmrkTypesNftInfo, RmrkTypesPartType, RmrkTypesPropertyInfo, RmrkTypesResourceInfo, RmrkTypesRoyaltyInfo, RmrkTypesSlotPart, RmrkTypesTheme, RmrkTypesThemeProperty, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionField, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRpcCollection, UpDataStructsSchemaVersion, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from './unique';
 import type { Data, StorageKey } from '@polkadot/types';
 import type { BitVec, Bool, Bytes, I128, I16, I256, I32, I64, I8, Json, Null, Raw, Text, Type, U128, U16, U256, U32, U64, U8, USize, bool, i128, i16, i256, i32, i64, i8, u128, u16, u256, u32, u64, u8, usize } from '@polkadot/types-codec';
 import type { AssetApproval, AssetApprovalKey, AssetBalance, AssetDestroyWitness, AssetDetails, AssetMetadata, TAssetBalance, TAssetDepositBalance } from '@polkadot/types/interfaces/assets';
@@ -478,7 +478,6 @@
     ForkTreePendingChangeNode: ForkTreePendingChangeNode;
     FpRpcTransactionStatus: FpRpcTransactionStatus;
     FrameSupportPalletId: FrameSupportPalletId;
-    FrameSupportStorageBoundedBTreeSet: FrameSupportStorageBoundedBTreeSet;
     FrameSupportTokensMiscBalanceStatus: FrameSupportTokensMiscBalanceStatus;
     FrameSupportWeightsDispatchClass: FrameSupportWeightsDispatchClass;
     FrameSupportWeightsDispatchInfo: FrameSupportWeightsDispatchInfo;
@@ -1204,7 +1203,6 @@
     UpDataStructsCreateNftExData: UpDataStructsCreateNftExData;
     UpDataStructsCreateReFungibleData: UpDataStructsCreateReFungibleData;
     UpDataStructsCreateRefungibleExData: UpDataStructsCreateRefungibleExData;
-    UpDataStructsMetaUpdatePermission: UpDataStructsMetaUpdatePermission;
     UpDataStructsNestingRule: UpDataStructsNestingRule;
     UpDataStructsProperties: UpDataStructsProperties;
     UpDataStructsPropertiesMapBoundedVec: UpDataStructsPropertiesMapBoundedVec;
modifiedtests/src/interfaces/lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/lookup.ts
+++ b/tests/src/interfaces/lookup.ts
@@ -1360,15 +1360,6 @@
         itemId: 'u32',
         value: 'u128',
       },
-      set_variable_meta_data: {
-        collectionId: 'u32',
-        itemId: 'u32',
-        data: 'Bytes',
-      },
-      set_meta_update_permission_flag: {
-        collectionId: 'u32',
-        value: 'UpDataStructsMetaUpdatePermission',
-      },
       set_schema_version: {
         collectionId: 'u32',
         version: 'UpDataStructsSchemaVersion',
@@ -1411,7 +1402,6 @@
     pendingSponsor: 'Option<AccountId32>',
     limits: 'Option<UpDataStructsCollectionLimits>',
     constOnChainSchema: 'Bytes',
-    metaUpdatePermission: 'Option<UpDataStructsMetaUpdatePermission>',
     tokenPropertyPermissions: 'Vec<UpDataStructsPropertyKeyPermission>',
     properties: 'Vec<UpDataStructsProperty>'
   },
@@ -1462,20 +1452,14 @@
     }
   },
   /**
-   * Lookup177: up_data_structs::MetaUpdatePermission
+   * Lookup177: up_data_structs::PropertyKeyPermission
    **/
-  UpDataStructsMetaUpdatePermission: {
-    _enum: ['ItemOwner', 'Admin', 'None']
-  },
-  /**
-   * Lookup179: up_data_structs::PropertyKeyPermission
-   **/
   UpDataStructsPropertyKeyPermission: {
     key: 'Bytes',
     permission: 'UpDataStructsPropertyPermission'
   },
   /**
-   * Lookup181: up_data_structs::PropertyPermission
+   * Lookup179: up_data_structs::PropertyPermission
    **/
   UpDataStructsPropertyPermission: {
     mutable: 'bool',
@@ -1483,14 +1467,14 @@
     tokenOwner: 'bool'
   },
   /**
-   * Lookup184: up_data_structs::Property
+   * Lookup182: up_data_structs::Property
    **/
   UpDataStructsProperty: {
     key: 'Bytes',
     value: 'Bytes'
   },
   /**
-   * Lookup186: pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>
+   * Lookup184: pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>
    **/
   PalletEvmAccountBasicCrossAccountIdRepr: {
     _enum: {
@@ -1499,7 +1483,7 @@
     }
   },
   /**
-   * Lookup188: up_data_structs::CreateItemData
+   * Lookup186: up_data_structs::CreateItemData
    **/
   UpDataStructsCreateItemData: {
     _enum: {
@@ -1509,29 +1493,27 @@
     }
   },
   /**
-   * Lookup189: up_data_structs::CreateNftData
+   * Lookup187: up_data_structs::CreateNftData
    **/
   UpDataStructsCreateNftData: {
     constData: 'Bytes',
-    variableData: 'Bytes',
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup191: up_data_structs::CreateFungibleData
+   * Lookup189: up_data_structs::CreateFungibleData
    **/
   UpDataStructsCreateFungibleData: {
     value: 'u128'
   },
   /**
-   * Lookup192: up_data_structs::CreateReFungibleData
+   * Lookup190: up_data_structs::CreateReFungibleData
    **/
   UpDataStructsCreateReFungibleData: {
     constData: 'Bytes',
-    variableData: 'Bytes',
     pieces: 'u128'
   },
   /**
-   * Lookup196: up_data_structs::CreateItemExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup194: up_data_structs::CreateItemExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateItemExData: {
     _enum: {
@@ -1542,32 +1524,30 @@
     }
   },
   /**
-   * Lookup198: up_data_structs::CreateNftExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup196: up_data_structs::CreateNftExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateNftExData: {
     constData: 'Bytes',
-    variableData: 'Bytes',
     properties: 'Vec<UpDataStructsProperty>',
     owner: 'PalletEvmAccountBasicCrossAccountIdRepr'
   },
   /**
-   * Lookup205: up_data_structs::CreateRefungibleExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup203: up_data_structs::CreateRefungibleExData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsCreateRefungibleExData: {
     constData: 'Bytes',
-    variableData: 'Bytes',
     users: 'BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>'
   },
   /**
-   * Lookup207: pallet_template_transaction_payment::Call<T>
+   * Lookup205: pallet_template_transaction_payment::Call<T>
    **/
   PalletTemplateTransactionPaymentCall: 'Null',
   /**
-   * Lookup208: pallet_structure::pallet::Call<T>
+   * Lookup206: pallet_structure::pallet::Call<T>
    **/
   PalletStructureCall: 'Null',
   /**
-   * Lookup209: pallet_evm::pallet::Call<T>
+   * Lookup207: pallet_evm::pallet::Call<T>
    **/
   PalletEvmCall: {
     _enum: {
@@ -1610,7 +1590,7 @@
     }
   },
   /**
-   * Lookup215: pallet_ethereum::pallet::Call<T>
+   * Lookup213: pallet_ethereum::pallet::Call<T>
    **/
   PalletEthereumCall: {
     _enum: {
@@ -1620,7 +1600,7 @@
     }
   },
   /**
-   * Lookup216: ethereum::transaction::TransactionV2
+   * Lookup214: ethereum::transaction::TransactionV2
    **/
   EthereumTransactionTransactionV2: {
     _enum: {
@@ -1630,7 +1610,7 @@
     }
   },
   /**
-   * Lookup217: ethereum::transaction::LegacyTransaction
+   * Lookup215: ethereum::transaction::LegacyTransaction
    **/
   EthereumTransactionLegacyTransaction: {
     nonce: 'U256',
@@ -1642,7 +1622,7 @@
     signature: 'EthereumTransactionTransactionSignature'
   },
   /**
-   * Lookup218: ethereum::transaction::TransactionAction
+   * Lookup216: ethereum::transaction::TransactionAction
    **/
   EthereumTransactionTransactionAction: {
     _enum: {
@@ -1651,7 +1631,7 @@
     }
   },
   /**
-   * Lookup219: ethereum::transaction::TransactionSignature
+   * Lookup217: ethereum::transaction::TransactionSignature
    **/
   EthereumTransactionTransactionSignature: {
     v: 'u64',
@@ -1659,7 +1639,7 @@
     s: 'H256'
   },
   /**
-   * Lookup221: ethereum::transaction::EIP2930Transaction
+   * Lookup219: ethereum::transaction::EIP2930Transaction
    **/
   EthereumTransactionEip2930Transaction: {
     chainId: 'u64',
@@ -1675,14 +1655,14 @@
     s: 'H256'
   },
   /**
-   * Lookup223: ethereum::transaction::AccessListItem
+   * Lookup221: ethereum::transaction::AccessListItem
    **/
   EthereumTransactionAccessListItem: {
     address: 'H160',
     storageKeys: 'Vec<H256>'
   },
   /**
-   * Lookup224: ethereum::transaction::EIP1559Transaction
+   * Lookup222: ethereum::transaction::EIP1559Transaction
    **/
   EthereumTransactionEip1559Transaction: {
     chainId: 'u64',
@@ -1699,7 +1679,7 @@
     s: 'H256'
   },
   /**
-   * Lookup225: pallet_evm_migration::pallet::Call<T>
+   * Lookup223: pallet_evm_migration::pallet::Call<T>
    **/
   PalletEvmMigrationCall: {
     _enum: {
@@ -1717,7 +1697,7 @@
     }
   },
   /**
-   * Lookup228: pallet_sudo::pallet::Event<T>
+   * Lookup226: pallet_sudo::pallet::Event<T>
    **/
   PalletSudoEvent: {
     _enum: {
@@ -1733,7 +1713,7 @@
     }
   },
   /**
-   * Lookup230: sp_runtime::DispatchError
+   * Lookup228: sp_runtime::DispatchError
    **/
   SpRuntimeDispatchError: {
     _enum: {
@@ -1750,38 +1730,38 @@
     }
   },
   /**
-   * Lookup231: sp_runtime::ModuleError
+   * Lookup229: sp_runtime::ModuleError
    **/
   SpRuntimeModuleError: {
     index: 'u8',
     error: '[u8;4]'
   },
   /**
-   * Lookup232: sp_runtime::TokenError
+   * Lookup230: sp_runtime::TokenError
    **/
   SpRuntimeTokenError: {
     _enum: ['NoFunds', 'WouldDie', 'BelowMinimum', 'CannotCreate', 'UnknownAsset', 'Frozen', 'Unsupported']
   },
   /**
-   * Lookup233: sp_runtime::ArithmeticError
+   * Lookup231: sp_runtime::ArithmeticError
    **/
   SpRuntimeArithmeticError: {
     _enum: ['Underflow', 'Overflow', 'DivisionByZero']
   },
   /**
-   * Lookup234: sp_runtime::TransactionalError
+   * Lookup232: sp_runtime::TransactionalError
    **/
   SpRuntimeTransactionalError: {
     _enum: ['LimitReached', 'NoLayer']
   },
   /**
-   * Lookup235: pallet_sudo::pallet::Error<T>
+   * Lookup233: pallet_sudo::pallet::Error<T>
    **/
   PalletSudoError: {
     _enum: ['RequireSudo']
   },
   /**
-   * Lookup236: frame_system::AccountInfo<Index, pallet_balances::AccountData<Balance>>
+   * Lookup234: frame_system::AccountInfo<Index, pallet_balances::AccountData<Balance>>
    **/
   FrameSystemAccountInfo: {
     nonce: 'u32',
@@ -1791,7 +1771,7 @@
     data: 'PalletBalancesAccountData'
   },
   /**
-   * Lookup237: frame_support::weights::PerDispatchClass<T>
+   * Lookup235: frame_support::weights::PerDispatchClass<T>
    **/
   FrameSupportWeightsPerDispatchClassU64: {
     normal: 'u64',
@@ -1799,13 +1779,13 @@
     mandatory: 'u64'
   },
   /**
-   * Lookup238: sp_runtime::generic::digest::Digest
+   * Lookup236: sp_runtime::generic::digest::Digest
    **/
   SpRuntimeDigest: {
     logs: 'Vec<SpRuntimeDigestDigestItem>'
   },
   /**
-   * Lookup240: sp_runtime::generic::digest::DigestItem
+   * Lookup238: sp_runtime::generic::digest::DigestItem
    **/
   SpRuntimeDigestDigestItem: {
     _enum: {
@@ -1821,7 +1801,7 @@
     }
   },
   /**
-   * Lookup242: frame_system::EventRecord<opal_runtime::Event, primitive_types::H256>
+   * Lookup240: frame_system::EventRecord<opal_runtime::Event, primitive_types::H256>
    **/
   FrameSystemEventRecord: {
     phase: 'FrameSystemPhase',
@@ -1829,7 +1809,7 @@
     topics: 'Vec<H256>'
   },
   /**
-   * Lookup244: frame_system::pallet::Event<T>
+   * Lookup242: frame_system::pallet::Event<T>
    **/
   FrameSystemEvent: {
     _enum: {
@@ -1857,7 +1837,7 @@
     }
   },
   /**
-   * Lookup245: frame_support::weights::DispatchInfo
+   * Lookup243: frame_support::weights::DispatchInfo
    **/
   FrameSupportWeightsDispatchInfo: {
     weight: 'u64',
@@ -1865,19 +1845,19 @@
     paysFee: 'FrameSupportWeightsPays'
   },
   /**
-   * Lookup246: frame_support::weights::DispatchClass
+   * Lookup244: frame_support::weights::DispatchClass
    **/
   FrameSupportWeightsDispatchClass: {
     _enum: ['Normal', 'Operational', 'Mandatory']
   },
   /**
-   * Lookup247: frame_support::weights::Pays
+   * Lookup245: frame_support::weights::Pays
    **/
   FrameSupportWeightsPays: {
     _enum: ['Yes', 'No']
   },
   /**
-   * Lookup248: orml_vesting::module::Event<T>
+   * Lookup246: orml_vesting::module::Event<T>
    **/
   OrmlVestingModuleEvent: {
     _enum: {
@@ -1896,7 +1876,7 @@
     }
   },
   /**
-   * Lookup249: cumulus_pallet_xcmp_queue::pallet::Event<T>
+   * Lookup247: cumulus_pallet_xcmp_queue::pallet::Event<T>
    **/
   CumulusPalletXcmpQueueEvent: {
     _enum: {
@@ -1911,7 +1891,7 @@
     }
   },
   /**
-   * Lookup250: pallet_xcm::pallet::Event<T>
+   * Lookup248: pallet_xcm::pallet::Event<T>
    **/
   PalletXcmEvent: {
     _enum: {
@@ -1934,7 +1914,7 @@
     }
   },
   /**
-   * Lookup251: xcm::v2::traits::Outcome
+   * Lookup249: xcm::v2::traits::Outcome
    **/
   XcmV2TraitsOutcome: {
     _enum: {
@@ -1944,7 +1924,7 @@
     }
   },
   /**
-   * Lookup253: cumulus_pallet_xcm::pallet::Event<T>
+   * Lookup251: cumulus_pallet_xcm::pallet::Event<T>
    **/
   CumulusPalletXcmEvent: {
     _enum: {
@@ -1954,7 +1934,7 @@
     }
   },
   /**
-   * Lookup254: cumulus_pallet_dmp_queue::pallet::Event<T>
+   * Lookup252: cumulus_pallet_dmp_queue::pallet::Event<T>
    **/
   CumulusPalletDmpQueueEvent: {
     _enum: {
@@ -1967,7 +1947,7 @@
     }
   },
   /**
-   * Lookup255: pallet_unique::RawEvent<sp_core::crypto::AccountId32, pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup253: pallet_unique::RawEvent<sp_core::crypto::AccountId32, pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   PalletUniqueRawEvent: {
     _enum: {
@@ -1988,7 +1968,7 @@
     }
   },
   /**
-   * Lookup256: pallet_common::pallet::Event<T>
+   * Lookup254: pallet_common::pallet::Event<T>
    **/
   PalletCommonEvent: {
     _enum: {
@@ -2006,7 +1986,7 @@
     }
   },
   /**
-   * Lookup257: pallet_structure::pallet::Event<T>
+   * Lookup255: pallet_structure::pallet::Event<T>
    **/
   PalletStructureEvent: {
     _enum: {
@@ -2014,7 +1994,7 @@
     }
   },
   /**
-   * Lookup258: pallet_evm::pallet::Event<T>
+   * Lookup256: pallet_evm::pallet::Event<T>
    **/
   PalletEvmEvent: {
     _enum: {
@@ -2028,7 +2008,7 @@
     }
   },
   /**
-   * Lookup259: ethereum::log::Log
+   * Lookup257: ethereum::log::Log
    **/
   EthereumLog: {
     address: 'H160',
@@ -2036,7 +2016,7 @@
     data: 'Bytes'
   },
   /**
-   * Lookup260: pallet_ethereum::pallet::Event
+   * Lookup258: pallet_ethereum::pallet::Event
    **/
   PalletEthereumEvent: {
     _enum: {
@@ -2044,7 +2024,7 @@
     }
   },
   /**
-   * Lookup261: evm_core::error::ExitReason
+   * Lookup259: evm_core::error::ExitReason
    **/
   EvmCoreErrorExitReason: {
     _enum: {
@@ -2055,13 +2035,13 @@
     }
   },
   /**
-   * Lookup262: evm_core::error::ExitSucceed
+   * Lookup260: evm_core::error::ExitSucceed
    **/
   EvmCoreErrorExitSucceed: {
     _enum: ['Stopped', 'Returned', 'Suicided']
   },
   /**
-   * Lookup263: evm_core::error::ExitError
+   * Lookup261: evm_core::error::ExitError
    **/
   EvmCoreErrorExitError: {
     _enum: {
@@ -2083,13 +2063,13 @@
     }
   },
   /**
-   * Lookup266: evm_core::error::ExitRevert
+   * Lookup264: evm_core::error::ExitRevert
    **/
   EvmCoreErrorExitRevert: {
     _enum: ['Reverted']
   },
   /**
-   * Lookup267: evm_core::error::ExitFatal
+   * Lookup265: evm_core::error::ExitFatal
    **/
   EvmCoreErrorExitFatal: {
     _enum: {
@@ -2100,7 +2080,7 @@
     }
   },
   /**
-   * Lookup268: frame_system::Phase
+   * Lookup266: frame_system::Phase
    **/
   FrameSystemPhase: {
     _enum: {
@@ -2110,14 +2090,14 @@
     }
   },
   /**
-   * Lookup270: frame_system::LastRuntimeUpgradeInfo
+   * Lookup268: frame_system::LastRuntimeUpgradeInfo
    **/
   FrameSystemLastRuntimeUpgradeInfo: {
     specVersion: 'Compact<u32>',
     specName: 'Text'
   },
   /**
-   * Lookup271: frame_system::limits::BlockWeights
+   * Lookup269: frame_system::limits::BlockWeights
    **/
   FrameSystemLimitsBlockWeights: {
     baseBlock: 'u64',
@@ -2125,7 +2105,7 @@
     perClass: 'FrameSupportWeightsPerDispatchClassWeightsPerClass'
   },
   /**
-   * Lookup272: frame_support::weights::PerDispatchClass<frame_system::limits::WeightsPerClass>
+   * Lookup270: frame_support::weights::PerDispatchClass<frame_system::limits::WeightsPerClass>
    **/
   FrameSupportWeightsPerDispatchClassWeightsPerClass: {
     normal: 'FrameSystemLimitsWeightsPerClass',
@@ -2133,7 +2113,7 @@
     mandatory: 'FrameSystemLimitsWeightsPerClass'
   },
   /**
-   * Lookup273: frame_system::limits::WeightsPerClass
+   * Lookup271: frame_system::limits::WeightsPerClass
    **/
   FrameSystemLimitsWeightsPerClass: {
     baseExtrinsic: 'u64',
@@ -2142,13 +2122,13 @@
     reserved: 'Option<u64>'
   },
   /**
-   * Lookup275: frame_system::limits::BlockLength
+   * Lookup273: frame_system::limits::BlockLength
    **/
   FrameSystemLimitsBlockLength: {
     max: 'FrameSupportWeightsPerDispatchClassU32'
   },
   /**
-   * Lookup276: frame_support::weights::PerDispatchClass<T>
+   * Lookup274: frame_support::weights::PerDispatchClass<T>
    **/
   FrameSupportWeightsPerDispatchClassU32: {
     normal: 'u32',
@@ -2156,14 +2136,14 @@
     mandatory: 'u32'
   },
   /**
-   * Lookup277: frame_support::weights::RuntimeDbWeight
+   * Lookup275: frame_support::weights::RuntimeDbWeight
    **/
   FrameSupportWeightsRuntimeDbWeight: {
     read: 'u64',
     write: 'u64'
   },
   /**
-   * Lookup278: sp_version::RuntimeVersion
+   * Lookup276: sp_version::RuntimeVersion
    **/
   SpVersionRuntimeVersion: {
     specName: 'Text',
@@ -2176,19 +2156,19 @@
     stateVersion: 'u8'
   },
   /**
-   * Lookup282: frame_system::pallet::Error<T>
+   * Lookup280: frame_system::pallet::Error<T>
    **/
   FrameSystemError: {
     _enum: ['InvalidSpecName', 'SpecVersionNeedsToIncrease', 'FailedToExtractRuntimeVersion', 'NonDefaultComposite', 'NonZeroRefCount', 'CallFiltered']
   },
   /**
-   * Lookup284: orml_vesting::module::Error<T>
+   * Lookup282: orml_vesting::module::Error<T>
    **/
   OrmlVestingModuleError: {
     _enum: ['ZeroVestingPeriod', 'ZeroVestingPeriodCount', 'InsufficientBalanceToLock', 'TooManyVestingSchedules', 'AmountLow', 'MaxVestingSchedulesExceeded']
   },
   /**
-   * Lookup286: cumulus_pallet_xcmp_queue::InboundChannelDetails
+   * Lookup284: cumulus_pallet_xcmp_queue::InboundChannelDetails
    **/
   CumulusPalletXcmpQueueInboundChannelDetails: {
     sender: 'u32',
@@ -2196,19 +2176,19 @@
     messageMetadata: 'Vec<(u32,PolkadotParachainPrimitivesXcmpMessageFormat)>'
   },
   /**
-   * Lookup287: cumulus_pallet_xcmp_queue::InboundState
+   * Lookup285: cumulus_pallet_xcmp_queue::InboundState
    **/
   CumulusPalletXcmpQueueInboundState: {
     _enum: ['Ok', 'Suspended']
   },
   /**
-   * Lookup290: polkadot_parachain::primitives::XcmpMessageFormat
+   * Lookup288: polkadot_parachain::primitives::XcmpMessageFormat
    **/
   PolkadotParachainPrimitivesXcmpMessageFormat: {
     _enum: ['ConcatenatedVersionedXcm', 'ConcatenatedEncodedBlob', 'Signals']
   },
   /**
-   * Lookup293: cumulus_pallet_xcmp_queue::OutboundChannelDetails
+   * Lookup291: cumulus_pallet_xcmp_queue::OutboundChannelDetails
    **/
   CumulusPalletXcmpQueueOutboundChannelDetails: {
     recipient: 'u32',
@@ -2218,13 +2198,13 @@
     lastIndex: 'u16'
   },
   /**
-   * Lookup294: cumulus_pallet_xcmp_queue::OutboundState
+   * Lookup292: cumulus_pallet_xcmp_queue::OutboundState
    **/
   CumulusPalletXcmpQueueOutboundState: {
     _enum: ['Ok', 'Suspended']
   },
   /**
-   * Lookup296: cumulus_pallet_xcmp_queue::QueueConfigData
+   * Lookup294: cumulus_pallet_xcmp_queue::QueueConfigData
    **/
   CumulusPalletXcmpQueueQueueConfigData: {
     suspendThreshold: 'u32',
@@ -2235,29 +2215,29 @@
     xcmpMaxIndividualWeight: 'u64'
   },
   /**
-   * Lookup298: cumulus_pallet_xcmp_queue::pallet::Error<T>
+   * Lookup296: cumulus_pallet_xcmp_queue::pallet::Error<T>
    **/
   CumulusPalletXcmpQueueError: {
     _enum: ['FailedToSend', 'BadXcmOrigin', 'BadXcm', 'BadOverweightIndex', 'WeightOverLimit']
   },
   /**
-   * Lookup299: pallet_xcm::pallet::Error<T>
+   * Lookup297: pallet_xcm::pallet::Error<T>
    **/
   PalletXcmError: {
     _enum: ['Unreachable', 'SendFailure', 'Filtered', 'UnweighableMessage', 'DestinationNotInvertible', 'Empty', 'CannotReanchor', 'TooManyAssets', 'InvalidOrigin', 'BadVersion', 'BadLocation', 'NoSubscription', 'AlreadySubscribed']
   },
   /**
-   * Lookup300: cumulus_pallet_xcm::pallet::Error<T>
+   * Lookup298: cumulus_pallet_xcm::pallet::Error<T>
    **/
   CumulusPalletXcmError: 'Null',
   /**
-   * Lookup301: cumulus_pallet_dmp_queue::ConfigData
+   * Lookup299: cumulus_pallet_dmp_queue::ConfigData
    **/
   CumulusPalletDmpQueueConfigData: {
     maxIndividual: 'u64'
   },
   /**
-   * Lookup302: cumulus_pallet_dmp_queue::PageIndexData
+   * Lookup300: cumulus_pallet_dmp_queue::PageIndexData
    **/
   CumulusPalletDmpQueuePageIndexData: {
     beginUsed: 'u32',
@@ -2265,19 +2245,19 @@
     overweightCount: 'u64'
   },
   /**
-   * Lookup305: cumulus_pallet_dmp_queue::pallet::Error<T>
+   * Lookup303: cumulus_pallet_dmp_queue::pallet::Error<T>
    **/
   CumulusPalletDmpQueueError: {
     _enum: ['Unknown', 'OverLimit']
   },
   /**
-   * Lookup309: pallet_unique::Error<T>
+   * Lookup307: pallet_unique::Error<T>
    **/
   PalletUniqueError: {
     _enum: ['CollectionDecimalPointLimitExceeded', 'ConfirmUnsetSponsorFail', 'EmptyArgument']
   },
   /**
-   * Lookup310: up_data_structs::Collection<sp_core::crypto::AccountId32>
+   * Lookup308: up_data_structs::Collection<sp_core::crypto::AccountId32>
    **/
   UpDataStructsCollection: {
     owner: 'AccountId32',
@@ -2289,11 +2269,10 @@
     mintMode: 'bool',
     schemaVersion: 'UpDataStructsSchemaVersion',
     sponsorship: 'UpDataStructsSponsorshipState',
-    limits: 'UpDataStructsCollectionLimits',
-    metaUpdatePermission: 'UpDataStructsMetaUpdatePermission'
+    limits: 'UpDataStructsCollectionLimits'
   },
   /**
-   * Lookup311: up_data_structs::SponsorshipState<sp_core::crypto::AccountId32>
+   * Lookup309: up_data_structs::SponsorshipState<sp_core::crypto::AccountId32>
    **/
   UpDataStructsSponsorshipState: {
     _enum: {
@@ -2303,7 +2282,7 @@
     }
   },
   /**
-   * Lookup312: up_data_structs::Properties
+   * Lookup310: up_data_structs::Properties
    **/
   UpDataStructsProperties: {
     map: 'UpDataStructsPropertiesMapBoundedVec',
@@ -2311,21 +2290,21 @@
     spaceLimit: 'u32'
   },
   /**
-   * Lookup313: up_data_structs::PropertiesMap<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup311: up_data_structs::PropertiesMap<frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   UpDataStructsPropertiesMapBoundedVec: 'BTreeMap<Bytes, Bytes>',
   /**
-   * Lookup318: up_data_structs::PropertiesMap<up_data_structs::PropertyPermission>
+   * Lookup316: up_data_structs::PropertiesMap<up_data_structs::PropertyPermission>
    **/
   UpDataStructsPropertiesMapPropertyPermission: 'BTreeMap<Bytes, UpDataStructsPropertyPermission>',
   /**
-   * Lookup324: up_data_structs::CollectionField
+   * Lookup322: up_data_structs::CollectionField
    **/
   UpDataStructsCollectionField: {
     _enum: ['ConstOnChainSchema', 'OffchainSchema']
   },
   /**
-   * Lookup327: up_data_structs::CollectionStats
+   * Lookup325: up_data_structs::CollectionStats
    **/
   UpDataStructsCollectionStats: {
     created: 'u32',
@@ -2333,11 +2312,11 @@
     alive: 'u32'
   },
   /**
-   * Lookup328: PhantomType::up_data_structs<up_data_structs::TokenData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>>
+   * Lookup326: PhantomType::up_data_structs<up_data_structs::TokenData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>>
    **/
-  PhantomTypeUpDataStructsTokenData: '[Lookup329;0]',
+  PhantomTypeUpDataStructsTokenData: '[Lookup327;0]',
   /**
-   * Lookup329: up_data_structs::TokenData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup327: up_data_structs::TokenData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   UpDataStructsTokenData: {
     constData: 'Bytes',
@@ -2345,11 +2324,11 @@
     owner: 'Option<PalletEvmAccountBasicCrossAccountIdRepr>'
   },
   /**
-   * Lookup332: PhantomType::up_data_structs<up_data_structs::RpcCollection<sp_core::crypto::AccountId32>>
+   * Lookup330: PhantomType::up_data_structs<up_data_structs::RpcCollection<sp_core::crypto::AccountId32>>
    **/
-  PhantomTypeUpDataStructsRpcCollection: '[Lookup333;0]',
+  PhantomTypeUpDataStructsRpcCollection: '[Lookup331;0]',
   /**
-   * Lookup333: up_data_structs::RpcCollection<sp_core::crypto::AccountId32>
+   * Lookup331: up_data_structs::RpcCollection<sp_core::crypto::AccountId32>
    **/
   UpDataStructsRpcCollection: {
     owner: 'AccountId32',
@@ -2364,16 +2343,15 @@
     sponsorship: 'UpDataStructsSponsorshipState',
     limits: 'UpDataStructsCollectionLimits',
     constOnChainSchema: 'Bytes',
-    metaUpdatePermission: 'UpDataStructsMetaUpdatePermission',
     tokenPropertyPermissions: 'Vec<UpDataStructsPropertyKeyPermission>',
     properties: 'Vec<UpDataStructsProperty>'
   },
   /**
-   * Lookup335: PhantomType::up_data_structs<rmrk_types::CollectionInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, sp_core::crypto::AccountId32>>
+   * Lookup333: PhantomType::up_data_structs<rmrk_types::CollectionInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, sp_core::crypto::AccountId32>>
    **/
-  PhantomTypeUpDataStructsCollectionInfo: '[Lookup336;0]',
+  PhantomTypeUpDataStructsCollectionInfo: '[Lookup334;0]',
   /**
-   * Lookup336: rmrk_types::CollectionInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, sp_core::crypto::AccountId32>
+   * Lookup334: rmrk_types::CollectionInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, sp_core::crypto::AccountId32>
    **/
   RmrkTypesCollectionInfo: {
     issuer: 'AccountId32',
@@ -2383,11 +2361,11 @@
     nftsCount: 'u32'
   },
   /**
-   * Lookup340: PhantomType::up_data_structs<rmrk_types::NftInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
+   * Lookup338: PhantomType::up_data_structs<rmrk_types::NftInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
    **/
-  PhantomTypeUpDataStructsNftInfo: '[Lookup341;0]',
+  PhantomTypeUpDataStructsNftInfo: '[Lookup339;0]',
   /**
-   * Lookup341: rmrk_types::NftInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup339: rmrk_types::NftInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesNftInfo: {
     owner: 'RmrkTypesAccountIdOrCollectionNftTuple',
@@ -2397,7 +2375,7 @@
     pending: 'bool'
   },
   /**
-   * Lookup342: rmrk_types::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
+   * Lookup340: rmrk_types::AccountIdOrCollectionNftTuple<sp_core::crypto::AccountId32>
    **/
   RmrkTypesAccountIdOrCollectionNftTuple: {
     _enum: {
@@ -2406,18 +2384,18 @@
     }
   },
   /**
-   * Lookup344: rmrk_types::RoyaltyInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill>
+   * Lookup342: rmrk_types::RoyaltyInfo<sp_core::crypto::AccountId32, sp_arithmetic::per_things::Permill>
    **/
   RmrkTypesRoyaltyInfo: {
     recipient: 'AccountId32',
     amount: 'Permill'
   },
   /**
-   * Lookup346: PhantomType::up_data_structs<rmrk_types::ResourceInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
+   * Lookup344: PhantomType::up_data_structs<rmrk_types::ResourceInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
    **/
-  PhantomTypeUpDataStructsResourceInfo: '[Lookup347;0]',
+  PhantomTypeUpDataStructsResourceInfo: '[Lookup345;0]',
   /**
-   * Lookup347: rmrk_types::ResourceInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup345: rmrk_types::ResourceInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesResourceInfo: {
     id: 'Bytes',
@@ -2432,22 +2410,22 @@
     thumb: 'Option<Bytes>'
   },
   /**
-   * Lookup353: PhantomType::up_data_structs<rmrk_types::PropertyInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
+   * Lookup351: PhantomType::up_data_structs<rmrk_types::PropertyInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
    **/
-  PhantomTypeUpDataStructsPropertyInfo: '[Lookup354;0]',
+  PhantomTypeUpDataStructsPropertyInfo: '[Lookup352;0]',
   /**
-   * Lookup354: rmrk_types::PropertyInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup352: rmrk_types::PropertyInfo<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesPropertyInfo: {
     key: 'Bytes',
     value: 'Bytes'
   },
   /**
-   * Lookup358: PhantomType::up_data_structs<rmrk_types::BaseInfo<sp_core::crypto::AccountId32, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
+   * Lookup356: PhantomType::up_data_structs<rmrk_types::BaseInfo<sp_core::crypto::AccountId32, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
    **/
-  PhantomTypeUpDataStructsBaseInfo: '[Lookup359;0]',
+  PhantomTypeUpDataStructsBaseInfo: '[Lookup357;0]',
   /**
-   * Lookup359: rmrk_types::BaseInfo<sp_core::crypto::AccountId32, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup357: rmrk_types::BaseInfo<sp_core::crypto::AccountId32, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesBaseInfo: {
     issuer: 'AccountId32',
@@ -2455,11 +2433,11 @@
     symbol: 'Bytes'
   },
   /**
-   * Lookup361: PhantomType::up_data_structs<rmrk_types::PartType<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
+   * Lookup359: PhantomType::up_data_structs<rmrk_types::PartType<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>>
    **/
-  PhantomTypeUpDataStructsPartType: '[Lookup362;0]',
+  PhantomTypeUpDataStructsPartType: '[Lookup360;0]',
   /**
-   * Lookup362: rmrk_types::PartType<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup360: rmrk_types::PartType<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesPartType: {
     _enum: {
@@ -2468,7 +2446,7 @@
     }
   },
   /**
-   * Lookup364: rmrk_types::FixedPart<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup362: rmrk_types::FixedPart<frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesFixedPart: {
     id: 'u32',
@@ -2476,7 +2454,7 @@
     src: 'Bytes'
   },
   /**
-   * Lookup365: rmrk_types::SlotPart<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup363: rmrk_types::SlotPart<frame_support::storage::bounded_vec::BoundedVec<T, S>, frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesSlotPart: {
     id: 'u32',
@@ -2485,7 +2463,7 @@
     z: 'u32'
   },
   /**
-   * Lookup366: rmrk_types::EquippableList<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup364: rmrk_types::EquippableList<frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesEquippableList: {
     _enum: {
@@ -2495,11 +2473,11 @@
     }
   },
   /**
-   * Lookup368: PhantomType::up_data_structs<rmrk_types::Theme<frame_support::storage::bounded_vec::BoundedVec<T, S>, BoundedPropertyList>>
+   * Lookup366: PhantomType::up_data_structs<rmrk_types::Theme<frame_support::storage::bounded_vec::BoundedVec<T, S>, BoundedPropertyList>>
    **/
-  PhantomTypeUpDataStructsTheme: '[Lookup369;0]',
+  PhantomTypeUpDataStructsTheme: '[Lookup367;0]',
   /**
-   * Lookup369: rmrk_types::Theme<frame_support::storage::bounded_vec::BoundedVec<T, S>, BoundedPropertyList>
+   * Lookup367: rmrk_types::Theme<frame_support::storage::bounded_vec::BoundedVec<T, S>, BoundedPropertyList>
    **/
   RmrkTypesTheme: {
     name: 'Bytes',
@@ -2507,76 +2485,74 @@
     inherit: 'bool'
   },
   /**
-   * Lookup371: rmrk_types::ThemeProperty<frame_support::storage::bounded_vec::BoundedVec<T, S>>
+   * Lookup369: rmrk_types::ThemeProperty<frame_support::storage::bounded_vec::BoundedVec<T, S>>
    **/
   RmrkTypesThemeProperty: {
     key: 'Bytes',
     value: 'Bytes'
   },
   /**
-   * Lookup373: PhantomType::up_data_structs<rmrk_types::NftChild>
+   * Lookup371: PhantomType::up_data_structs<rmrk_types::NftChild>
    **/
-  PhantomTypeUpDataStructsNftChild: '[Lookup374;0]',
+  PhantomTypeUpDataStructsNftChild: '[Lookup372;0]',
   /**
-   * Lookup374: rmrk_types::NftChild
+   * Lookup372: rmrk_types::NftChild
    **/
   RmrkTypesNftChild: {
     collectionId: 'u32',
     nftId: 'u32'
   },
   /**
-   * Lookup376: pallet_common::pallet::Error<T>
+   * Lookup374: pallet_common::pallet::Error<T>
    **/
   PalletCommonError: {
-    _enum: ['CollectionNotFound', 'MustBeTokenOwner', 'NoPermission', 'PublicMintingNotAllowed', 'AddressNotInAllowlist', 'CollectionNameLimitExceeded', 'CollectionDescriptionLimitExceeded', 'CollectionTokenPrefixLimitExceeded', 'TotalCollectionsLimitExceeded', 'TokenVariableDataLimitExceeded', 'CollectionAdminCountExceeded', 'CollectionLimitBoundsExceeded', 'OwnerPermissionsCantBeReverted', 'TransferNotAllowed', 'AccountTokenLimitExceeded', 'CollectionTokenLimitExceeded', 'MetadataFlagFrozen', 'TokenNotFound', 'TokenValueTooLow', 'ApprovedValueTooLow', 'CantApproveMoreThanOwned', 'AddressIsZero', 'UnsupportedOperation', 'NotSufficientFounds', 'NestingIsDisabled', 'OnlyOwnerAllowedToNest', 'SourceCollectionIsNotAllowedToNest', 'CollectionFieldSizeExceeded', 'NoSpaceForProperty', 'PropertyLimitReached', 'UnableToReadUnboundedKeys', 'InvalidCharacterInPropertyKey', 'EmptyPropertyKey']
+    _enum: ['CollectionNotFound', 'MustBeTokenOwner', 'NoPermission', 'PublicMintingNotAllowed', 'AddressNotInAllowlist', 'CollectionNameLimitExceeded', 'CollectionDescriptionLimitExceeded', 'CollectionTokenPrefixLimitExceeded', 'TotalCollectionsLimitExceeded', 'CollectionAdminCountExceeded', 'CollectionLimitBoundsExceeded', 'OwnerPermissionsCantBeReverted', 'TransferNotAllowed', 'AccountTokenLimitExceeded', 'CollectionTokenLimitExceeded', 'MetadataFlagFrozen', 'TokenNotFound', 'TokenValueTooLow', 'ApprovedValueTooLow', 'CantApproveMoreThanOwned', 'AddressIsZero', 'UnsupportedOperation', 'NotSufficientFounds', 'NestingIsDisabled', 'OnlyOwnerAllowedToNest', 'SourceCollectionIsNotAllowedToNest', 'CollectionFieldSizeExceeded', 'NoSpaceForProperty', 'PropertyLimitReached', 'PropertyKeyIsTooLong', 'InvalidCharacterInPropertyKey', 'EmptyPropertyKey']
   },
   /**
-   * Lookup378: pallet_fungible::pallet::Error<T>
+   * Lookup376: pallet_fungible::pallet::Error<T>
    **/
   PalletFungibleError: {
     _enum: ['NotFungibleDataUsedToMintFungibleCollectionToken', 'FungibleItemsHaveNoId', 'FungibleItemsDontHaveData', 'FungibleDisallowsNesting', 'SettingPropertiesNotAllowed']
   },
   /**
-   * Lookup379: pallet_refungible::ItemData
+   * Lookup377: pallet_refungible::ItemData
    **/
   PalletRefungibleItemData: {
-    constData: 'Bytes',
-    variableData: 'Bytes'
+    constData: 'Bytes'
   },
   /**
-   * Lookup383: pallet_refungible::pallet::Error<T>
+   * Lookup381: pallet_refungible::pallet::Error<T>
    **/
   PalletRefungibleError: {
     _enum: ['NotRefungibleDataUsedToMintFungibleCollectionToken', 'WrongRefungiblePieces', 'RefungibleDisallowsNesting', 'SettingPropertiesNotAllowed']
   },
   /**
-   * Lookup384: pallet_nonfungible::ItemData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
+   * Lookup382: pallet_nonfungible::ItemData<pallet_evm::account::BasicCrossAccountIdRepr<sp_core::crypto::AccountId32>>
    **/
   PalletNonfungibleItemData: {
     constData: 'Bytes',
-    variableData: 'Bytes',
     owner: 'PalletEvmAccountBasicCrossAccountIdRepr'
   },
   /**
-   * Lookup385: pallet_nonfungible::pallet::Error<T>
+   * Lookup383: pallet_nonfungible::pallet::Error<T>
    **/
   PalletNonfungibleError: {
     _enum: ['NotNonfungibleDataUsedToMintFungibleCollectionToken', 'NonfungibleItemsHaveNoAmount']
   },
   /**
-   * Lookup386: pallet_structure::pallet::Error<T>
+   * Lookup384: pallet_structure::pallet::Error<T>
    **/
   PalletStructureError: {
     _enum: ['OuroborosDetected', 'DepthLimit', 'TokenNotFound']
   },
   /**
-   * Lookup389: pallet_evm::pallet::Error<T>
+   * Lookup387: pallet_evm::pallet::Error<T>
    **/
   PalletEvmError: {
     _enum: ['BalanceLow', 'FeeOverflow', 'PaymentOverflow', 'WithdrawFailed', 'GasPriceTooLow', 'InvalidNonce']
   },
   /**
-   * Lookup392: fp_rpc::TransactionStatus
+   * Lookup390: fp_rpc::TransactionStatus
    **/
   FpRpcTransactionStatus: {
     transactionHash: 'H256',
@@ -2588,11 +2564,11 @@
     logsBloom: 'EthbloomBloom'
   },
   /**
-   * Lookup394: ethbloom::Bloom
+   * Lookup392: ethbloom::Bloom
    **/
   EthbloomBloom: '[u8;256]',
   /**
-   * Lookup396: ethereum::receipt::ReceiptV3
+   * Lookup394: ethereum::receipt::ReceiptV3
    **/
   EthereumReceiptReceiptV3: {
     _enum: {
@@ -2602,7 +2578,7 @@
     }
   },
   /**
-   * Lookup397: ethereum::receipt::EIP658ReceiptData
+   * Lookup395: ethereum::receipt::EIP658ReceiptData
    **/
   EthereumReceiptEip658ReceiptData: {
     statusCode: 'u8',
@@ -2611,7 +2587,7 @@
     logs: 'Vec<EthereumLog>'
   },
   /**
-   * Lookup398: ethereum::block::Block<ethereum::transaction::TransactionV2>
+   * Lookup396: ethereum::block::Block<ethereum::transaction::TransactionV2>
    **/
   EthereumBlock: {
     header: 'EthereumHeader',
@@ -2619,7 +2595,7 @@
     ommers: 'Vec<EthereumHeader>'
   },
   /**
-   * Lookup399: ethereum::header::Header
+   * Lookup397: ethereum::header::Header
    **/
   EthereumHeader: {
     parentHash: 'H256',
@@ -2639,41 +2615,41 @@
     nonce: 'EthereumTypesHashH64'
   },
   /**
-   * Lookup400: ethereum_types::hash::H64
+   * Lookup398: ethereum_types::hash::H64
    **/
   EthereumTypesHashH64: '[u8;8]',
   /**
-   * Lookup405: pallet_ethereum::pallet::Error<T>
+   * Lookup403: pallet_ethereum::pallet::Error<T>
    **/
   PalletEthereumError: {
     _enum: ['InvalidSignature', 'PreLogExists']
   },
   /**
-   * Lookup406: pallet_evm_coder_substrate::pallet::Error<T>
+   * Lookup404: pallet_evm_coder_substrate::pallet::Error<T>
    **/
   PalletEvmCoderSubstrateError: {
     _enum: ['OutOfGas', 'OutOfFund']
   },
   /**
-   * Lookup407: pallet_evm_contract_helpers::SponsoringModeT
+   * Lookup405: pallet_evm_contract_helpers::SponsoringModeT
    **/
   PalletEvmContractHelpersSponsoringModeT: {
     _enum: ['Disabled', 'Allowlisted', 'Generous']
   },
   /**
-   * Lookup409: pallet_evm_contract_helpers::pallet::Error<T>
+   * Lookup407: pallet_evm_contract_helpers::pallet::Error<T>
    **/
   PalletEvmContractHelpersError: {
     _enum: ['NoPermission']
   },
   /**
-   * Lookup410: pallet_evm_migration::pallet::Error<T>
+   * Lookup408: pallet_evm_migration::pallet::Error<T>
    **/
   PalletEvmMigrationError: {
     _enum: ['AccountNotEmpty', 'AccountIsNotMigrating']
   },
   /**
-   * Lookup412: sp_runtime::MultiSignature
+   * Lookup410: sp_runtime::MultiSignature
    **/
   SpRuntimeMultiSignature: {
     _enum: {
@@ -2683,43 +2659,43 @@
     }
   },
   /**
-   * Lookup413: sp_core::ed25519::Signature
+   * Lookup411: sp_core::ed25519::Signature
    **/
   SpCoreEd25519Signature: '[u8;64]',
   /**
-   * Lookup415: sp_core::sr25519::Signature
+   * Lookup413: sp_core::sr25519::Signature
    **/
   SpCoreSr25519Signature: '[u8;64]',
   /**
-   * Lookup416: sp_core::ecdsa::Signature
+   * Lookup414: sp_core::ecdsa::Signature
    **/
   SpCoreEcdsaSignature: '[u8;65]',
   /**
-   * Lookup419: frame_system::extensions::check_spec_version::CheckSpecVersion<T>
+   * Lookup417: frame_system::extensions::check_spec_version::CheckSpecVersion<T>
    **/
   FrameSystemExtensionsCheckSpecVersion: 'Null',
   /**
-   * Lookup420: frame_system::extensions::check_genesis::CheckGenesis<T>
+   * Lookup418: frame_system::extensions::check_genesis::CheckGenesis<T>
    **/
   FrameSystemExtensionsCheckGenesis: 'Null',
   /**
-   * Lookup423: frame_system::extensions::check_nonce::CheckNonce<T>
+   * Lookup421: frame_system::extensions::check_nonce::CheckNonce<T>
    **/
   FrameSystemExtensionsCheckNonce: 'Compact<u32>',
   /**
-   * Lookup424: frame_system::extensions::check_weight::CheckWeight<T>
+   * Lookup422: frame_system::extensions::check_weight::CheckWeight<T>
    **/
   FrameSystemExtensionsCheckWeight: 'Null',
   /**
-   * Lookup425: pallet_template_transaction_payment::ChargeTransactionPayment<opal_runtime::Runtime>
+   * Lookup423: pallet_template_transaction_payment::ChargeTransactionPayment<opal_runtime::Runtime>
    **/
   PalletTemplateTransactionPaymentChargeTransactionPayment: 'Compact<u128>',
   /**
-   * Lookup426: opal_runtime::Runtime
+   * Lookup424: opal_runtime::Runtime
    **/
   OpalRuntimeRuntime: 'Null',
   /**
-   * Lookup427: pallet_ethereum::FakeTransactionFinalizer<opal_runtime::Runtime>
+   * Lookup425: pallet_ethereum::FakeTransactionFinalizer<opal_runtime::Runtime>
    **/
   PalletEthereumFakeTransactionFinalizer: 'Null'
 };
modifiedtests/src/interfaces/registry.tsdiffbeforeafterboth
--- a/tests/src/interfaces/registry.ts
+++ b/tests/src/interfaces/registry.ts
@@ -1,7 +1,7 @@
 // Auto-generated via `yarn polkadot-types-from-defs`, do not edit
 /* eslint-disable */
 
-import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportPalletId, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PhantomTypeUpDataStructsBaseInfo, PhantomTypeUpDataStructsCollectionInfo, PhantomTypeUpDataStructsNftChild, PhantomTypeUpDataStructsNftInfo, PhantomTypeUpDataStructsPartType, PhantomTypeUpDataStructsPropertyInfo, PhantomTypeUpDataStructsResourceInfo, PhantomTypeUpDataStructsRpcCollection, PhantomTypeUpDataStructsTheme, PhantomTypeUpDataStructsTokenData, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, RmrkTypesAccountIdOrCollectionNftTuple, RmrkTypesBaseInfo, RmrkTypesCollectionInfo, RmrkTypesEquippableList, RmrkTypesFixedPart, RmrkTypesNftChild, RmrkTypesNftInfo, RmrkTypesPartType, RmrkTypesPropertyInfo, RmrkTypesResourceInfo, RmrkTypesRoyaltyInfo, RmrkTypesSlotPart, RmrkTypesTheme, RmrkTypesThemeProperty, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionField, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsMetaUpdatePermission, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRpcCollection, UpDataStructsSchemaVersion, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
+import type { CumulusPalletDmpQueueCall, CumulusPalletDmpQueueConfigData, CumulusPalletDmpQueueError, CumulusPalletDmpQueueEvent, CumulusPalletDmpQueuePageIndexData, CumulusPalletParachainSystemCall, CumulusPalletParachainSystemError, CumulusPalletParachainSystemEvent, CumulusPalletParachainSystemRelayStateSnapshotMessagingStateSnapshot, CumulusPalletXcmCall, CumulusPalletXcmError, CumulusPalletXcmEvent, CumulusPalletXcmpQueueCall, CumulusPalletXcmpQueueError, CumulusPalletXcmpQueueEvent, CumulusPalletXcmpQueueInboundChannelDetails, CumulusPalletXcmpQueueInboundState, CumulusPalletXcmpQueueOutboundChannelDetails, CumulusPalletXcmpQueueOutboundState, CumulusPalletXcmpQueueQueueConfigData, CumulusPrimitivesParachainInherentParachainInherentData, EthbloomBloom, EthereumBlock, EthereumHeader, EthereumLog, EthereumReceiptEip658ReceiptData, EthereumReceiptReceiptV3, EthereumTransactionAccessListItem, EthereumTransactionEip1559Transaction, EthereumTransactionEip2930Transaction, EthereumTransactionLegacyTransaction, EthereumTransactionTransactionAction, EthereumTransactionTransactionSignature, EthereumTransactionTransactionV2, EthereumTypesHashH64, EvmCoreErrorExitError, EvmCoreErrorExitFatal, EvmCoreErrorExitReason, EvmCoreErrorExitRevert, EvmCoreErrorExitSucceed, FpRpcTransactionStatus, FrameSupportPalletId, FrameSupportTokensMiscBalanceStatus, FrameSupportWeightsDispatchClass, FrameSupportWeightsDispatchInfo, FrameSupportWeightsPays, FrameSupportWeightsPerDispatchClassU32, FrameSupportWeightsPerDispatchClassU64, FrameSupportWeightsPerDispatchClassWeightsPerClass, FrameSupportWeightsRuntimeDbWeight, FrameSupportWeightsWeightToFeeCoefficient, FrameSystemAccountInfo, FrameSystemCall, FrameSystemError, FrameSystemEvent, FrameSystemEventRecord, FrameSystemExtensionsCheckGenesis, FrameSystemExtensionsCheckNonce, FrameSystemExtensionsCheckSpecVersion, FrameSystemExtensionsCheckWeight, FrameSystemLastRuntimeUpgradeInfo, FrameSystemLimitsBlockLength, FrameSystemLimitsBlockWeights, FrameSystemLimitsWeightsPerClass, FrameSystemPhase, OpalRuntimeRuntime, OrmlVestingModuleCall, OrmlVestingModuleError, OrmlVestingModuleEvent, OrmlVestingVestingSchedule, PalletBalancesAccountData, PalletBalancesBalanceLock, PalletBalancesCall, PalletBalancesError, PalletBalancesEvent, PalletBalancesReasons, PalletBalancesReleases, PalletBalancesReserveData, PalletCommonError, PalletCommonEvent, PalletEthereumCall, PalletEthereumError, PalletEthereumEvent, PalletEthereumFakeTransactionFinalizer, PalletEvmAccountBasicCrossAccountIdRepr, PalletEvmCall, PalletEvmCoderSubstrateError, PalletEvmContractHelpersError, PalletEvmContractHelpersSponsoringModeT, PalletEvmError, PalletEvmEvent, PalletEvmMigrationCall, PalletEvmMigrationError, PalletFungibleError, PalletInflationCall, PalletNonfungibleError, PalletNonfungibleItemData, PalletRefungibleError, PalletRefungibleItemData, PalletStructureCall, PalletStructureError, PalletStructureEvent, PalletSudoCall, PalletSudoError, PalletSudoEvent, PalletTemplateTransactionPaymentCall, PalletTemplateTransactionPaymentChargeTransactionPayment, PalletTimestampCall, PalletTransactionPaymentReleases, PalletTreasuryCall, PalletTreasuryError, PalletTreasuryEvent, PalletTreasuryProposal, PalletUniqueCall, PalletUniqueError, PalletUniqueRawEvent, PalletXcmCall, PalletXcmError, PalletXcmEvent, PhantomTypeUpDataStructsBaseInfo, PhantomTypeUpDataStructsCollectionInfo, PhantomTypeUpDataStructsNftChild, PhantomTypeUpDataStructsNftInfo, PhantomTypeUpDataStructsPartType, PhantomTypeUpDataStructsPropertyInfo, PhantomTypeUpDataStructsResourceInfo, PhantomTypeUpDataStructsRpcCollection, PhantomTypeUpDataStructsTheme, PhantomTypeUpDataStructsTokenData, PolkadotCorePrimitivesInboundDownwardMessage, PolkadotCorePrimitivesInboundHrmpMessage, PolkadotCorePrimitivesOutboundHrmpMessage, PolkadotParachainPrimitivesXcmpMessageFormat, PolkadotPrimitivesV2AbridgedHostConfiguration, PolkadotPrimitivesV2AbridgedHrmpChannel, PolkadotPrimitivesV2PersistedValidationData, PolkadotPrimitivesV2UpgradeRestriction, RmrkTypesAccountIdOrCollectionNftTuple, RmrkTypesBaseInfo, RmrkTypesCollectionInfo, RmrkTypesEquippableList, RmrkTypesFixedPart, RmrkTypesNftChild, RmrkTypesNftInfo, RmrkTypesPartType, RmrkTypesPropertyInfo, RmrkTypesResourceInfo, RmrkTypesRoyaltyInfo, RmrkTypesSlotPart, RmrkTypesTheme, RmrkTypesThemeProperty, SpCoreEcdsaSignature, SpCoreEd25519Signature, SpCoreSr25519Signature, SpRuntimeArithmeticError, SpRuntimeDigest, SpRuntimeDigestDigestItem, SpRuntimeDispatchError, SpRuntimeModuleError, SpRuntimeMultiSignature, SpRuntimeTokenError, SpRuntimeTransactionalError, SpTrieStorageProof, SpVersionRuntimeVersion, UpDataStructsAccessMode, UpDataStructsCollection, UpDataStructsCollectionField, UpDataStructsCollectionLimits, UpDataStructsCollectionMode, UpDataStructsCollectionStats, UpDataStructsCreateCollectionData, UpDataStructsCreateFungibleData, UpDataStructsCreateItemData, UpDataStructsCreateItemExData, UpDataStructsCreateNftData, UpDataStructsCreateNftExData, UpDataStructsCreateReFungibleData, UpDataStructsCreateRefungibleExData, UpDataStructsNestingRule, UpDataStructsProperties, UpDataStructsPropertiesMapBoundedVec, UpDataStructsPropertiesMapPropertyPermission, UpDataStructsProperty, UpDataStructsPropertyKeyPermission, UpDataStructsPropertyPermission, UpDataStructsRpcCollection, UpDataStructsSchemaVersion, UpDataStructsSponsoringRateLimit, UpDataStructsSponsorshipState, UpDataStructsTokenData, XcmDoubleEncoded, XcmV0Junction, XcmV0JunctionBodyId, XcmV0JunctionBodyPart, XcmV0JunctionNetworkId, XcmV0MultiAsset, XcmV0MultiLocation, XcmV0Order, XcmV0OriginKind, XcmV0Response, XcmV0Xcm, XcmV1Junction, XcmV1MultiAsset, XcmV1MultiLocation, XcmV1MultiassetAssetId, XcmV1MultiassetAssetInstance, XcmV1MultiassetFungibility, XcmV1MultiassetMultiAssetFilter, XcmV1MultiassetMultiAssets, XcmV1MultiassetWildFungibility, XcmV1MultiassetWildMultiAsset, XcmV1MultilocationJunctions, XcmV1Order, XcmV1Response, XcmV1Xcm, XcmV2Instruction, XcmV2Response, XcmV2TraitsError, XcmV2TraitsOutcome, XcmV2WeightLimit, XcmV2Xcm, XcmVersionedMultiAssets, XcmVersionedMultiLocation, XcmVersionedXcm } from '@polkadot/types/lookup';
 
 declare module '@polkadot/types/types/registry' {
   export interface InterfaceTypes {
@@ -183,7 +183,6 @@
     UpDataStructsCreateNftExData: UpDataStructsCreateNftExData;
     UpDataStructsCreateReFungibleData: UpDataStructsCreateReFungibleData;
     UpDataStructsCreateRefungibleExData: UpDataStructsCreateRefungibleExData;
-    UpDataStructsMetaUpdatePermission: UpDataStructsMetaUpdatePermission;
     UpDataStructsNestingRule: UpDataStructsNestingRule;
     UpDataStructsProperties: UpDataStructsProperties;
     UpDataStructsPropertiesMapBoundedVec: UpDataStructsPropertiesMapBoundedVec;
modifiedtests/src/interfaces/rmrk/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/rmrk/definitions.ts
+++ b/tests/src/interfaces/rmrk/definitions.ts
@@ -33,14 +33,14 @@
     types,
     rpc: {
         lastCollectionIdx: fn('Get the latest created collection id', [], 'u32'),
-        collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<RmrkTraitsCollectionCollectionInfo>'),
+        collectionById: fn('Get collection by id', [{name: 'id', type: 'u32'}], 'Option<RmrkTypesCollectionInfo>'),
         nftById: fn(
             'Get NFT by collection id and NFT id',
             [
                 {name: 'collectionId', type: 'u32'},
                 {name: 'nftId', type: 'u32'},
             ],
-            'Option<RmrkTraitsNftNftInfo>'
+            'Option<RmrkTypesNftInfo>'
         ),
         accountTokens: fn(
             'Get tokens owned by an account in a collection',
@@ -56,12 +56,12 @@
                 {name: 'collectionId', type: 'u32'},
                 {name: 'nftId', type: 'u32'},
             ],
-            'Vec<RmrkTraitsNftNftChild>'
+            'Vec<RmrkTypesNftChild>'
         ),
         collectionProperties: fn(
             'Get collection properties',
             [{name: 'collectionId', type: 'u32'}],
-            'Vec<RmrkTraitsPropertyPropertyInfo>'
+            'Vec<RmrkTypesPropertyInfo>'
         ),
         nftProperties: fn(
             'Get NFT properties',
@@ -69,7 +69,7 @@
                 {name: 'collectionId', type: 'u32'},
                 {name: 'nftId', type: 'u32'}
             ],
-            'Vec<RmrkTraitsPropertyPropertyInfo>'
+            'Vec<RmrkTypesPropertyInfo>'
         ),
         nftResources: fn(
             'Get NFT resources',
@@ -77,7 +77,7 @@
                 {name: 'collectionId', type: 'u32'},
                 {name: 'nftId', type: 'u32'}
             ],
-            'Vec<RmrkTraitsResourceResourceInfo>'
+            'Vec<RmrkTypesResourceInfo>'
         ),
         nftResourcePriorities: fn(
             'Get NFT resource priorities',
@@ -90,12 +90,12 @@
         base: fn(
             'Get base info',
             [{name: 'baseId', type: 'u32'}],
-            'Option<RmrkTraitsBaseBaseInfo>'
+            'Option<RmrkTypesBaseInfo>'
         ),
         baseParts: fn(
             'Get all Base\'s parts',
             [{name: 'baseId', type: 'u32'}],
-            'Vec<RmrkTraitsPartPartType>'
+            'Vec<RmrkTypesPartType>'
         ),
         themeNames: fn(
             'Get Base\'s theme names',
@@ -109,7 +109,7 @@
                 {name: 'themeName', type: 'String'},
                 {name: 'keys', type: 'Option<Vec<String>>'}
             ],
-            'Option<RmrkTraitsTheme>'
+            'Option<RmrkTypesTheme>'
         )
     }
 };
modifiedtests/src/interfaces/rmrk/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/rmrk/types.ts
+++ b/tests/src/interfaces/rmrk/types.ts
@@ -446,9 +446,6 @@
 /** @name FrameSupportPalletId */
 export interface FrameSupportPalletId extends U8aFixed {}
 
-/** @name FrameSupportStorageBoundedBTreeSet */
-export interface FrameSupportStorageBoundedBTreeSet extends BTreeSet<u32> {}
-
 /** @name FrameSupportTokensMiscBalanceStatus */
 export interface FrameSupportTokensMiscBalanceStatus extends Enum {
   readonly isFree: boolean;
@@ -875,7 +872,6 @@
   readonly isCollectionDescriptionLimitExceeded: boolean;
   readonly isCollectionTokenPrefixLimitExceeded: boolean;
   readonly isTotalCollectionsLimitExceeded: boolean;
-  readonly isTokenVariableDataLimitExceeded: boolean;
   readonly isCollectionAdminCountExceeded: boolean;
   readonly isCollectionLimitBoundsExceeded: boolean;
   readonly isOwnerPermissionsCantBeReverted: boolean;
@@ -896,10 +892,10 @@
   readonly isCollectionFieldSizeExceeded: boolean;
   readonly isNoSpaceForProperty: boolean;
   readonly isPropertyLimitReached: boolean;
-  readonly isUnableToReadUnboundedKeys: boolean;
+  readonly isPropertyKeyIsTooLong: boolean;
   readonly isInvalidCharacterInPropertyKey: boolean;
   readonly isEmptyPropertyKey: boolean;
-  readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'TokenVariableDataLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'UnableToReadUnboundedKeys' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
+  readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
 }
 
 /** @name PalletCommonEvent */
@@ -1115,7 +1111,6 @@
 /** @name PalletNonfungibleItemData */
 export interface PalletNonfungibleItemData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
 }
 
@@ -1131,7 +1126,6 @@
 /** @name PalletRefungibleItemData */
 export interface PalletRefungibleItemData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
 }
 
 /** @name PalletStructureCall */
@@ -1438,17 +1432,6 @@
     readonly collectionId: u32;
     readonly itemId: u32;
     readonly value: u128;
-  } & Struct;
-  readonly isSetVariableMetaData: boolean;
-  readonly asSetVariableMetaData: {
-    readonly collectionId: u32;
-    readonly itemId: u32;
-    readonly data: Bytes;
-  } & Struct;
-  readonly isSetMetaUpdatePermissionFlag: boolean;
-  readonly asSetMetaUpdatePermissionFlag: {
-    readonly collectionId: u32;
-    readonly value: UpDataStructsMetaUpdatePermission;
   } & Struct;
   readonly isSetSchemaVersion: boolean;
   readonly asSetSchemaVersion: {
@@ -1470,7 +1453,7 @@
     readonly collectionId: u32;
     readonly newLimit: UpDataStructsCollectionLimits;
   } & Struct;
-  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetCollectionLimits';
+  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetCollectionLimits';
 }
 
 /** @name PalletUniqueError */
@@ -1632,34 +1615,34 @@
 }
 
 /** @name PhantomTypeUpDataStructsBaseInfo */
-export interface PhantomTypeUpDataStructsBaseInfo extends Vec<Lookup359> {}
+export interface PhantomTypeUpDataStructsBaseInfo extends Vec<Lookup357> {}
 
 /** @name PhantomTypeUpDataStructsCollectionInfo */
-export interface PhantomTypeUpDataStructsCollectionInfo extends Vec<Lookup336> {}
+export interface PhantomTypeUpDataStructsCollectionInfo extends Vec<Lookup334> {}
 
 /** @name PhantomTypeUpDataStructsNftChild */
-export interface PhantomTypeUpDataStructsNftChild extends Vec<Lookup374> {}
+export interface PhantomTypeUpDataStructsNftChild extends Vec<Lookup372> {}
 
 /** @name PhantomTypeUpDataStructsNftInfo */
-export interface PhantomTypeUpDataStructsNftInfo extends Vec<Lookup341> {}
+export interface PhantomTypeUpDataStructsNftInfo extends Vec<Lookup339> {}
 
 /** @name PhantomTypeUpDataStructsPartType */
-export interface PhantomTypeUpDataStructsPartType extends Vec<Lookup362> {}
+export interface PhantomTypeUpDataStructsPartType extends Vec<Lookup360> {}
 
 /** @name PhantomTypeUpDataStructsPropertyInfo */
-export interface PhantomTypeUpDataStructsPropertyInfo extends Vec<Lookup354> {}
+export interface PhantomTypeUpDataStructsPropertyInfo extends Vec<Lookup352> {}
 
 /** @name PhantomTypeUpDataStructsResourceInfo */
-export interface PhantomTypeUpDataStructsResourceInfo extends Vec<Lookup347> {}
+export interface PhantomTypeUpDataStructsResourceInfo extends Vec<Lookup345> {}
 
 /** @name PhantomTypeUpDataStructsRpcCollection */
-export interface PhantomTypeUpDataStructsRpcCollection extends Vec<Lookup333> {}
+export interface PhantomTypeUpDataStructsRpcCollection extends Vec<Lookup331> {}
 
 /** @name PhantomTypeUpDataStructsTheme */
-export interface PhantomTypeUpDataStructsTheme extends Vec<Lookup369> {}
+export interface PhantomTypeUpDataStructsTheme extends Vec<Lookup367> {}
 
 /** @name PhantomTypeUpDataStructsTokenData */
-export interface PhantomTypeUpDataStructsTokenData extends Vec<Lookup329> {}
+export interface PhantomTypeUpDataStructsTokenData extends Vec<Lookup327> {}
 
 /** @name PolkadotCorePrimitivesInboundDownwardMessage */
 export interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {
@@ -1963,7 +1946,6 @@
   readonly schemaVersion: UpDataStructsSchemaVersion;
   readonly sponsorship: UpDataStructsSponsorshipState;
   readonly limits: UpDataStructsCollectionLimits;
-  readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
 }
 
 /** @name UpDataStructsCollectionField */
@@ -2015,7 +1997,6 @@
   readonly pendingSponsor: Option<AccountId32>;
   readonly limits: Option<UpDataStructsCollectionLimits>;
   readonly constOnChainSchema: Bytes;
-  readonly metaUpdatePermission: Option<UpDataStructsMetaUpdatePermission>;
   readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
   readonly properties: Vec<UpDataStructsProperty>;
 }
@@ -2052,14 +2033,12 @@
 /** @name UpDataStructsCreateNftData */
 export interface UpDataStructsCreateNftData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly properties: Vec<UpDataStructsProperty>;
 }
 
 /** @name UpDataStructsCreateNftExData */
 export interface UpDataStructsCreateNftExData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly properties: Vec<UpDataStructsProperty>;
   readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
 }
@@ -2067,31 +2046,21 @@
 /** @name UpDataStructsCreateReFungibleData */
 export interface UpDataStructsCreateReFungibleData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly pieces: u128;
 }
 
 /** @name UpDataStructsCreateRefungibleExData */
 export interface UpDataStructsCreateRefungibleExData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;
 }
 
-/** @name UpDataStructsMetaUpdatePermission */
-export interface UpDataStructsMetaUpdatePermission extends Enum {
-  readonly isItemOwner: boolean;
-  readonly isAdmin: boolean;
-  readonly isNone: boolean;
-  readonly type: 'ItemOwner' | 'Admin' | 'None';
-}
-
 /** @name UpDataStructsNestingRule */
 export interface UpDataStructsNestingRule extends Enum {
   readonly isDisabled: boolean;
   readonly isOwner: boolean;
   readonly isOwnerRestricted: boolean;
-  readonly asOwnerRestricted: FrameSupportStorageBoundedBTreeSet;
+  readonly asOwnerRestricted: BTreeSet<u32>;
   readonly type: 'Disabled' | 'Owner' | 'OwnerRestricted';
 }
 
@@ -2141,7 +2110,6 @@
   readonly sponsorship: UpDataStructsSponsorshipState;
   readonly limits: UpDataStructsCollectionLimits;
   readonly constOnChainSchema: Bytes;
-  readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
   readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
   readonly properties: Vec<UpDataStructsProperty>;
 }
modifiedtests/src/interfaces/types-lookup.tsdiffbeforeafterboth
--- a/tests/src/interfaces/types-lookup.ts
+++ b/tests/src/interfaces/types-lookup.ts
@@ -1493,17 +1493,6 @@
       readonly itemId: u32;
       readonly value: u128;
     } & Struct;
-    readonly isSetVariableMetaData: boolean;
-    readonly asSetVariableMetaData: {
-      readonly collectionId: u32;
-      readonly itemId: u32;
-      readonly data: Bytes;
-    } & Struct;
-    readonly isSetMetaUpdatePermissionFlag: boolean;
-    readonly asSetMetaUpdatePermissionFlag: {
-      readonly collectionId: u32;
-      readonly value: UpDataStructsMetaUpdatePermission;
-    } & Struct;
     readonly isSetSchemaVersion: boolean;
     readonly asSetSchemaVersion: {
       readonly collectionId: u32;
@@ -1524,7 +1513,7 @@
       readonly collectionId: u32;
       readonly newLimit: UpDataStructsCollectionLimits;
     } & Struct;
-    readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetCollectionLimits';
+    readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetCollectionLimits';
   }
 
   /** @name UpDataStructsCollectionMode (156) */
@@ -1548,7 +1537,6 @@
     readonly pendingSponsor: Option<AccountId32>;
     readonly limits: Option<UpDataStructsCollectionLimits>;
     readonly constOnChainSchema: Bytes;
-    readonly metaUpdatePermission: Option<UpDataStructsMetaUpdatePermission>;
     readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
     readonly properties: Vec<UpDataStructsProperty>;
   }
@@ -1598,34 +1586,26 @@
     readonly type: 'Disabled' | 'Owner' | 'OwnerRestricted';
   }
 
-  /** @name UpDataStructsMetaUpdatePermission (177) */
-  export interface UpDataStructsMetaUpdatePermission extends Enum {
-    readonly isItemOwner: boolean;
-    readonly isAdmin: boolean;
-    readonly isNone: boolean;
-    readonly type: 'ItemOwner' | 'Admin' | 'None';
-  }
-
-  /** @name UpDataStructsPropertyKeyPermission (179) */
+  /** @name UpDataStructsPropertyKeyPermission (177) */
   export interface UpDataStructsPropertyKeyPermission extends Struct {
     readonly key: Bytes;
     readonly permission: UpDataStructsPropertyPermission;
   }
 
-  /** @name UpDataStructsPropertyPermission (181) */
+  /** @name UpDataStructsPropertyPermission (179) */
   export interface UpDataStructsPropertyPermission extends Struct {
     readonly mutable: bool;
     readonly collectionAdmin: bool;
     readonly tokenOwner: bool;
   }
 
-  /** @name UpDataStructsProperty (184) */
+  /** @name UpDataStructsProperty (182) */
   export interface UpDataStructsProperty extends Struct {
     readonly key: Bytes;
     readonly value: Bytes;
   }
 
-  /** @name PalletEvmAccountBasicCrossAccountIdRepr (186) */
+  /** @name PalletEvmAccountBasicCrossAccountIdRepr (184) */
   export interface PalletEvmAccountBasicCrossAccountIdRepr extends Enum {
     readonly isSubstrate: boolean;
     readonly asSubstrate: AccountId32;
@@ -1634,7 +1614,7 @@
     readonly type: 'Substrate' | 'Ethereum';
   }
 
-  /** @name UpDataStructsCreateItemData (188) */
+  /** @name UpDataStructsCreateItemData (186) */
   export interface UpDataStructsCreateItemData extends Enum {
     readonly isNft: boolean;
     readonly asNft: UpDataStructsCreateNftData;
@@ -1645,26 +1625,24 @@
     readonly type: 'Nft' | 'Fungible' | 'ReFungible';
   }
 
-  /** @name UpDataStructsCreateNftData (189) */
+  /** @name UpDataStructsCreateNftData (187) */
   export interface UpDataStructsCreateNftData extends Struct {
     readonly constData: Bytes;
-    readonly variableData: Bytes;
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name UpDataStructsCreateFungibleData (191) */
+  /** @name UpDataStructsCreateFungibleData (189) */
   export interface UpDataStructsCreateFungibleData extends Struct {
     readonly value: u128;
   }
 
-  /** @name UpDataStructsCreateReFungibleData (192) */
+  /** @name UpDataStructsCreateReFungibleData (190) */
   export interface UpDataStructsCreateReFungibleData extends Struct {
     readonly constData: Bytes;
-    readonly variableData: Bytes;
     readonly pieces: u128;
   }
 
-  /** @name UpDataStructsCreateItemExData (196) */
+  /** @name UpDataStructsCreateItemExData (194) */
   export interface UpDataStructsCreateItemExData extends Enum {
     readonly isNft: boolean;
     readonly asNft: Vec<UpDataStructsCreateNftExData>;
@@ -1677,28 +1655,26 @@
     readonly type: 'Nft' | 'Fungible' | 'RefungibleMultipleItems' | 'RefungibleMultipleOwners';
   }
 
-  /** @name UpDataStructsCreateNftExData (198) */
+  /** @name UpDataStructsCreateNftExData (196) */
   export interface UpDataStructsCreateNftExData extends Struct {
     readonly constData: Bytes;
-    readonly variableData: Bytes;
     readonly properties: Vec<UpDataStructsProperty>;
     readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
   }
 
-  /** @name UpDataStructsCreateRefungibleExData (205) */
+  /** @name UpDataStructsCreateRefungibleExData (203) */
   export interface UpDataStructsCreateRefungibleExData extends Struct {
     readonly constData: Bytes;
-    readonly variableData: Bytes;
     readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;
   }
 
-  /** @name PalletTemplateTransactionPaymentCall (207) */
+  /** @name PalletTemplateTransactionPaymentCall (205) */
   export type PalletTemplateTransactionPaymentCall = Null;
 
-  /** @name PalletStructureCall (208) */
+  /** @name PalletStructureCall (206) */
   export type PalletStructureCall = Null;
 
-  /** @name PalletEvmCall (209) */
+  /** @name PalletEvmCall (207) */
   export interface PalletEvmCall extends Enum {
     readonly isWithdraw: boolean;
     readonly asWithdraw: {
@@ -1743,7 +1719,7 @@
     readonly type: 'Withdraw' | 'Call' | 'Create' | 'Create2';
   }
 
-  /** @name PalletEthereumCall (215) */
+  /** @name PalletEthereumCall (213) */
   export interface PalletEthereumCall extends Enum {
     readonly isTransact: boolean;
     readonly asTransact: {
@@ -1752,7 +1728,7 @@
     readonly type: 'Transact';
   }
 
-  /** @name EthereumTransactionTransactionV2 (216) */
+  /** @name EthereumTransactionTransactionV2 (214) */
   export interface EthereumTransactionTransactionV2 extends Enum {
     readonly isLegacy: boolean;
     readonly asLegacy: EthereumTransactionLegacyTransaction;
@@ -1763,7 +1739,7 @@
     readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';
   }
 
-  /** @name EthereumTransactionLegacyTransaction (217) */
+  /** @name EthereumTransactionLegacyTransaction (215) */
   export interface EthereumTransactionLegacyTransaction extends Struct {
     readonly nonce: U256;
     readonly gasPrice: U256;
@@ -1774,7 +1750,7 @@
     readonly signature: EthereumTransactionTransactionSignature;
   }
 
-  /** @name EthereumTransactionTransactionAction (218) */
+  /** @name EthereumTransactionTransactionAction (216) */
   export interface EthereumTransactionTransactionAction extends Enum {
     readonly isCall: boolean;
     readonly asCall: H160;
@@ -1782,14 +1758,14 @@
     readonly type: 'Call' | 'Create';
   }
 
-  /** @name EthereumTransactionTransactionSignature (219) */
+  /** @name EthereumTransactionTransactionSignature (217) */
   export interface EthereumTransactionTransactionSignature extends Struct {
     readonly v: u64;
     readonly r: H256;
     readonly s: H256;
   }
 
-  /** @name EthereumTransactionEip2930Transaction (221) */
+  /** @name EthereumTransactionEip2930Transaction (219) */
   export interface EthereumTransactionEip2930Transaction extends Struct {
     readonly chainId: u64;
     readonly nonce: U256;
@@ -1804,13 +1780,13 @@
     readonly s: H256;
   }
 
-  /** @name EthereumTransactionAccessListItem (223) */
+  /** @name EthereumTransactionAccessListItem (221) */
   export interface EthereumTransactionAccessListItem extends Struct {
     readonly address: H160;
     readonly storageKeys: Vec<H256>;
   }
 
-  /** @name EthereumTransactionEip1559Transaction (224) */
+  /** @name EthereumTransactionEip1559Transaction (222) */
   export interface EthereumTransactionEip1559Transaction extends Struct {
     readonly chainId: u64;
     readonly nonce: U256;
@@ -1826,7 +1802,7 @@
     readonly s: H256;
   }
 
-  /** @name PalletEvmMigrationCall (225) */
+  /** @name PalletEvmMigrationCall (223) */
   export interface PalletEvmMigrationCall extends Enum {
     readonly isBegin: boolean;
     readonly asBegin: {
@@ -1845,7 +1821,7 @@
     readonly type: 'Begin' | 'SetData' | 'Finish';
   }
 
-  /** @name PalletSudoEvent (228) */
+  /** @name PalletSudoEvent (226) */
   export interface PalletSudoEvent extends Enum {
     readonly isSudid: boolean;
     readonly asSudid: {
@@ -1862,7 +1838,7 @@
     readonly type: 'Sudid' | 'KeyChanged' | 'SudoAsDone';
   }
 
-  /** @name SpRuntimeDispatchError (230) */
+  /** @name SpRuntimeDispatchError (228) */
   export interface SpRuntimeDispatchError extends Enum {
     readonly isOther: boolean;
     readonly isCannotLookup: boolean;
@@ -1881,13 +1857,13 @@
     readonly type: 'Other' | 'CannotLookup' | 'BadOrigin' | 'Module' | 'ConsumerRemaining' | 'NoProviders' | 'TooManyConsumers' | 'Token' | 'Arithmetic' | 'Transactional';
   }
 
-  /** @name SpRuntimeModuleError (231) */
+  /** @name SpRuntimeModuleError (229) */
   export interface SpRuntimeModuleError extends Struct {
     readonly index: u8;
     readonly error: U8aFixed;
   }
 
-  /** @name SpRuntimeTokenError (232) */
+  /** @name SpRuntimeTokenError (230) */
   export interface SpRuntimeTokenError extends Enum {
     readonly isNoFunds: boolean;
     readonly isWouldDie: boolean;
@@ -1899,7 +1875,7 @@
     readonly type: 'NoFunds' | 'WouldDie' | 'BelowMinimum' | 'CannotCreate' | 'UnknownAsset' | 'Frozen' | 'Unsupported';
   }
 
-  /** @name SpRuntimeArithmeticError (233) */
+  /** @name SpRuntimeArithmeticError (231) */
   export interface SpRuntimeArithmeticError extends Enum {
     readonly isUnderflow: boolean;
     readonly isOverflow: boolean;
@@ -1907,20 +1883,20 @@
     readonly type: 'Underflow' | 'Overflow' | 'DivisionByZero';
   }
 
-  /** @name SpRuntimeTransactionalError (234) */
+  /** @name SpRuntimeTransactionalError (232) */
   export interface SpRuntimeTransactionalError extends Enum {
     readonly isLimitReached: boolean;
     readonly isNoLayer: boolean;
     readonly type: 'LimitReached' | 'NoLayer';
   }
 
-  /** @name PalletSudoError (235) */
+  /** @name PalletSudoError (233) */
   export interface PalletSudoError extends Enum {
     readonly isRequireSudo: boolean;
     readonly type: 'RequireSudo';
   }
 
-  /** @name FrameSystemAccountInfo (236) */
+  /** @name FrameSystemAccountInfo (234) */
   export interface FrameSystemAccountInfo extends Struct {
     readonly nonce: u32;
     readonly consumers: u32;
@@ -1929,19 +1905,19 @@
     readonly data: PalletBalancesAccountData;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassU64 (237) */
+  /** @name FrameSupportWeightsPerDispatchClassU64 (235) */
   export interface FrameSupportWeightsPerDispatchClassU64 extends Struct {
     readonly normal: u64;
     readonly operational: u64;
     readonly mandatory: u64;
   }
 
-  /** @name SpRuntimeDigest (238) */
+  /** @name SpRuntimeDigest (236) */
   export interface SpRuntimeDigest extends Struct {
     readonly logs: Vec<SpRuntimeDigestDigestItem>;
   }
 
-  /** @name SpRuntimeDigestDigestItem (240) */
+  /** @name SpRuntimeDigestDigestItem (238) */
   export interface SpRuntimeDigestDigestItem extends Enum {
     readonly isOther: boolean;
     readonly asOther: Bytes;
@@ -1955,14 +1931,14 @@
     readonly type: 'Other' | 'Consensus' | 'Seal' | 'PreRuntime' | 'RuntimeEnvironmentUpdated';
   }
 
-  /** @name FrameSystemEventRecord (242) */
+  /** @name FrameSystemEventRecord (240) */
   export interface FrameSystemEventRecord extends Struct {
     readonly phase: FrameSystemPhase;
     readonly event: Event;
     readonly topics: Vec<H256>;
   }
 
-  /** @name FrameSystemEvent (244) */
+  /** @name FrameSystemEvent (242) */
   export interface FrameSystemEvent extends Enum {
     readonly isExtrinsicSuccess: boolean;
     readonly asExtrinsicSuccess: {
@@ -1990,14 +1966,14 @@
     readonly type: 'ExtrinsicSuccess' | 'ExtrinsicFailed' | 'CodeUpdated' | 'NewAccount' | 'KilledAccount' | 'Remarked';
   }
 
-  /** @name FrameSupportWeightsDispatchInfo (245) */
+  /** @name FrameSupportWeightsDispatchInfo (243) */
   export interface FrameSupportWeightsDispatchInfo extends Struct {
     readonly weight: u64;
     readonly class: FrameSupportWeightsDispatchClass;
     readonly paysFee: FrameSupportWeightsPays;
   }
 
-  /** @name FrameSupportWeightsDispatchClass (246) */
+  /** @name FrameSupportWeightsDispatchClass (244) */
   export interface FrameSupportWeightsDispatchClass extends Enum {
     readonly isNormal: boolean;
     readonly isOperational: boolean;
@@ -2005,14 +1981,14 @@
     readonly type: 'Normal' | 'Operational' | 'Mandatory';
   }
 
-  /** @name FrameSupportWeightsPays (247) */
+  /** @name FrameSupportWeightsPays (245) */
   export interface FrameSupportWeightsPays extends Enum {
     readonly isYes: boolean;
     readonly isNo: boolean;
     readonly type: 'Yes' | 'No';
   }
 
-  /** @name OrmlVestingModuleEvent (248) */
+  /** @name OrmlVestingModuleEvent (246) */
   export interface OrmlVestingModuleEvent extends Enum {
     readonly isVestingScheduleAdded: boolean;
     readonly asVestingScheduleAdded: {
@@ -2032,7 +2008,7 @@
     readonly type: 'VestingScheduleAdded' | 'Claimed' | 'VestingSchedulesUpdated';
   }
 
-  /** @name CumulusPalletXcmpQueueEvent (249) */
+  /** @name CumulusPalletXcmpQueueEvent (247) */
   export interface CumulusPalletXcmpQueueEvent extends Enum {
     readonly isSuccess: boolean;
     readonly asSuccess: Option<H256>;
@@ -2053,7 +2029,7 @@
     readonly type: 'Success' | 'Fail' | 'BadVersion' | 'BadFormat' | 'UpwardMessageSent' | 'XcmpMessageSent' | 'OverweightEnqueued' | 'OverweightServiced';
   }
 
-  /** @name PalletXcmEvent (250) */
+  /** @name PalletXcmEvent (248) */
   export interface PalletXcmEvent extends Enum {
     readonly isAttempted: boolean;
     readonly asAttempted: XcmV2TraitsOutcome;
@@ -2090,7 +2066,7 @@
     readonly type: 'Attempted' | 'Sent' | 'UnexpectedResponse' | 'ResponseReady' | 'Notified' | 'NotifyOverweight' | 'NotifyDispatchError' | 'NotifyDecodeFailed' | 'InvalidResponder' | 'InvalidResponderVersion' | 'ResponseTaken' | 'AssetsTrapped' | 'VersionChangeNotified' | 'SupportedVersionChanged' | 'NotifyTargetSendFail' | 'NotifyTargetMigrationFail';
   }
 
-  /** @name XcmV2TraitsOutcome (251) */
+  /** @name XcmV2TraitsOutcome (249) */
   export interface XcmV2TraitsOutcome extends Enum {
     readonly isComplete: boolean;
     readonly asComplete: u64;
@@ -2101,7 +2077,7 @@
     readonly type: 'Complete' | 'Incomplete' | 'Error';
   }
 
-  /** @name CumulusPalletXcmEvent (253) */
+  /** @name CumulusPalletXcmEvent (251) */
   export interface CumulusPalletXcmEvent extends Enum {
     readonly isInvalidFormat: boolean;
     readonly asInvalidFormat: U8aFixed;
@@ -2112,7 +2088,7 @@
     readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward';
   }
 
-  /** @name CumulusPalletDmpQueueEvent (254) */
+  /** @name CumulusPalletDmpQueueEvent (252) */
   export interface CumulusPalletDmpQueueEvent extends Enum {
     readonly isInvalidFormat: boolean;
     readonly asInvalidFormat: U8aFixed;
@@ -2129,7 +2105,7 @@
     readonly type: 'InvalidFormat' | 'UnsupportedVersion' | 'ExecutedDownward' | 'WeightExhausted' | 'OverweightEnqueued' | 'OverweightServiced';
   }
 
-  /** @name PalletUniqueRawEvent (255) */
+  /** @name PalletUniqueRawEvent (253) */
   export interface PalletUniqueRawEvent extends Enum {
     readonly isCollectionSponsorRemoved: boolean;
     readonly asCollectionSponsorRemoved: u32;
@@ -2162,7 +2138,7 @@
     readonly type: 'CollectionSponsorRemoved' | 'CollectionAdminAdded' | 'CollectionOwnedChanged' | 'CollectionSponsorSet' | 'ConstOnChainSchemaSet' | 'SponsorshipConfirmed' | 'CollectionAdminRemoved' | 'AllowListAddressRemoved' | 'AllowListAddressAdded' | 'CollectionLimitSet' | 'MintPermissionSet' | 'OffchainSchemaSet' | 'PublicAccessModeSet' | 'SchemaVersionSet';
   }
 
-  /** @name PalletCommonEvent (256) */
+  /** @name PalletCommonEvent (254) */
   export interface PalletCommonEvent extends Enum {
     readonly isCollectionCreated: boolean;
     readonly asCollectionCreated: ITuple<[u32, u8, AccountId32]>;
@@ -2189,14 +2165,14 @@
     readonly type: 'CollectionCreated' | 'CollectionDestroyed' | 'ItemCreated' | 'ItemDestroyed' | 'Transfer' | 'Approved' | 'CollectionPropertySet' | 'CollectionPropertyDeleted' | 'TokenPropertySet' | 'TokenPropertyDeleted' | 'PropertyPermissionSet';
   }
 
-  /** @name PalletStructureEvent (257) */
+  /** @name PalletStructureEvent (255) */
   export interface PalletStructureEvent extends Enum {
     readonly isExecuted: boolean;
     readonly asExecuted: Result<Null, SpRuntimeDispatchError>;
     readonly type: 'Executed';
   }
 
-  /** @name PalletEvmEvent (258) */
+  /** @name PalletEvmEvent (256) */
   export interface PalletEvmEvent extends Enum {
     readonly isLog: boolean;
     readonly asLog: EthereumLog;
@@ -2215,21 +2191,21 @@
     readonly type: 'Log' | 'Created' | 'CreatedFailed' | 'Executed' | 'ExecutedFailed' | 'BalanceDeposit' | 'BalanceWithdraw';
   }
 
-  /** @name EthereumLog (259) */
+  /** @name EthereumLog (257) */
   export interface EthereumLog extends Struct {
     readonly address: H160;
     readonly topics: Vec<H256>;
     readonly data: Bytes;
   }
 
-  /** @name PalletEthereumEvent (260) */
+  /** @name PalletEthereumEvent (258) */
   export interface PalletEthereumEvent extends Enum {
     readonly isExecuted: boolean;
     readonly asExecuted: ITuple<[H160, H160, H256, EvmCoreErrorExitReason]>;
     readonly type: 'Executed';
   }
 
-  /** @name EvmCoreErrorExitReason (261) */
+  /** @name EvmCoreErrorExitReason (259) */
   export interface EvmCoreErrorExitReason extends Enum {
     readonly isSucceed: boolean;
     readonly asSucceed: EvmCoreErrorExitSucceed;
@@ -2242,7 +2218,7 @@
     readonly type: 'Succeed' | 'Error' | 'Revert' | 'Fatal';
   }
 
-  /** @name EvmCoreErrorExitSucceed (262) */
+  /** @name EvmCoreErrorExitSucceed (260) */
   export interface EvmCoreErrorExitSucceed extends Enum {
     readonly isStopped: boolean;
     readonly isReturned: boolean;
@@ -2250,7 +2226,7 @@
     readonly type: 'Stopped' | 'Returned' | 'Suicided';
   }
 
-  /** @name EvmCoreErrorExitError (263) */
+  /** @name EvmCoreErrorExitError (261) */
   export interface EvmCoreErrorExitError extends Enum {
     readonly isStackUnderflow: boolean;
     readonly isStackOverflow: boolean;
@@ -2271,13 +2247,13 @@
     readonly type: 'StackUnderflow' | 'StackOverflow' | 'InvalidJump' | 'InvalidRange' | 'DesignatedInvalid' | 'CallTooDeep' | 'CreateCollision' | 'CreateContractLimit' | 'OutOfOffset' | 'OutOfGas' | 'OutOfFund' | 'PcUnderflow' | 'CreateEmpty' | 'Other' | 'InvalidCode';
   }
 
-  /** @name EvmCoreErrorExitRevert (266) */
+  /** @name EvmCoreErrorExitRevert (264) */
   export interface EvmCoreErrorExitRevert extends Enum {
     readonly isReverted: boolean;
     readonly type: 'Reverted';
   }
 
-  /** @name EvmCoreErrorExitFatal (267) */
+  /** @name EvmCoreErrorExitFatal (265) */
   export interface EvmCoreErrorExitFatal extends Enum {
     readonly isNotSupported: boolean;
     readonly isUnhandledInterrupt: boolean;
@@ -2288,7 +2264,7 @@
     readonly type: 'NotSupported' | 'UnhandledInterrupt' | 'CallErrorAsFatal' | 'Other';
   }
 
-  /** @name FrameSystemPhase (268) */
+  /** @name FrameSystemPhase (266) */
   export interface FrameSystemPhase extends Enum {
     readonly isApplyExtrinsic: boolean;
     readonly asApplyExtrinsic: u32;
@@ -2297,27 +2273,27 @@
     readonly type: 'ApplyExtrinsic' | 'Finalization' | 'Initialization';
   }
 
-  /** @name FrameSystemLastRuntimeUpgradeInfo (270) */
+  /** @name FrameSystemLastRuntimeUpgradeInfo (268) */
   export interface FrameSystemLastRuntimeUpgradeInfo extends Struct {
     readonly specVersion: Compact<u32>;
     readonly specName: Text;
   }
 
-  /** @name FrameSystemLimitsBlockWeights (271) */
+  /** @name FrameSystemLimitsBlockWeights (269) */
   export interface FrameSystemLimitsBlockWeights extends Struct {
     readonly baseBlock: u64;
     readonly maxBlock: u64;
     readonly perClass: FrameSupportWeightsPerDispatchClassWeightsPerClass;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassWeightsPerClass (272) */
+  /** @name FrameSupportWeightsPerDispatchClassWeightsPerClass (270) */
   export interface FrameSupportWeightsPerDispatchClassWeightsPerClass extends Struct {
     readonly normal: FrameSystemLimitsWeightsPerClass;
     readonly operational: FrameSystemLimitsWeightsPerClass;
     readonly mandatory: FrameSystemLimitsWeightsPerClass;
   }
 
-  /** @name FrameSystemLimitsWeightsPerClass (273) */
+  /** @name FrameSystemLimitsWeightsPerClass (271) */
   export interface FrameSystemLimitsWeightsPerClass extends Struct {
     readonly baseExtrinsic: u64;
     readonly maxExtrinsic: Option<u64>;
@@ -2325,25 +2301,25 @@
     readonly reserved: Option<u64>;
   }
 
-  /** @name FrameSystemLimitsBlockLength (275) */
+  /** @name FrameSystemLimitsBlockLength (273) */
   export interface FrameSystemLimitsBlockLength extends Struct {
     readonly max: FrameSupportWeightsPerDispatchClassU32;
   }
 
-  /** @name FrameSupportWeightsPerDispatchClassU32 (276) */
+  /** @name FrameSupportWeightsPerDispatchClassU32 (274) */
   export interface FrameSupportWeightsPerDispatchClassU32 extends Struct {
     readonly normal: u32;
     readonly operational: u32;
     readonly mandatory: u32;
   }
 
-  /** @name FrameSupportWeightsRuntimeDbWeight (277) */
+  /** @name FrameSupportWeightsRuntimeDbWeight (275) */
   export interface FrameSupportWeightsRuntimeDbWeight extends Struct {
     readonly read: u64;
     readonly write: u64;
   }
 
-  /** @name SpVersionRuntimeVersion (278) */
+  /** @name SpVersionRuntimeVersion (276) */
   export interface SpVersionRuntimeVersion extends Struct {
     readonly specName: Text;
     readonly implName: Text;
@@ -2355,7 +2331,7 @@
     readonly stateVersion: u8;
   }
 
-  /** @name FrameSystemError (282) */
+  /** @name FrameSystemError (280) */
   export interface FrameSystemError extends Enum {
     readonly isInvalidSpecName: boolean;
     readonly isSpecVersionNeedsToIncrease: boolean;
@@ -2366,7 +2342,7 @@
     readonly type: 'InvalidSpecName' | 'SpecVersionNeedsToIncrease' | 'FailedToExtractRuntimeVersion' | 'NonDefaultComposite' | 'NonZeroRefCount' | 'CallFiltered';
   }
 
-  /** @name OrmlVestingModuleError (284) */
+  /** @name OrmlVestingModuleError (282) */
   export interface OrmlVestingModuleError extends Enum {
     readonly isZeroVestingPeriod: boolean;
     readonly isZeroVestingPeriodCount: boolean;
@@ -2377,21 +2353,21 @@
     readonly type: 'ZeroVestingPeriod' | 'ZeroVestingPeriodCount' | 'InsufficientBalanceToLock' | 'TooManyVestingSchedules' | 'AmountLow' | 'MaxVestingSchedulesExceeded';
   }
 
-  /** @name CumulusPalletXcmpQueueInboundChannelDetails (286) */
+  /** @name CumulusPalletXcmpQueueInboundChannelDetails (284) */
   export interface CumulusPalletXcmpQueueInboundChannelDetails extends Struct {
     readonly sender: u32;
     readonly state: CumulusPalletXcmpQueueInboundState;
     readonly messageMetadata: Vec<ITuple<[u32, PolkadotParachainPrimitivesXcmpMessageFormat]>>;
   }
 
-  /** @name CumulusPalletXcmpQueueInboundState (287) */
+  /** @name CumulusPalletXcmpQueueInboundState (285) */
   export interface CumulusPalletXcmpQueueInboundState extends Enum {
     readonly isOk: boolean;
     readonly isSuspended: boolean;
     readonly type: 'Ok' | 'Suspended';
   }
 
-  /** @name PolkadotParachainPrimitivesXcmpMessageFormat (290) */
+  /** @name PolkadotParachainPrimitivesXcmpMessageFormat (288) */
   export interface PolkadotParachainPrimitivesXcmpMessageFormat extends Enum {
     readonly isConcatenatedVersionedXcm: boolean;
     readonly isConcatenatedEncodedBlob: boolean;
@@ -2399,7 +2375,7 @@
     readonly type: 'ConcatenatedVersionedXcm' | 'ConcatenatedEncodedBlob' | 'Signals';
   }
 
-  /** @name CumulusPalletXcmpQueueOutboundChannelDetails (293) */
+  /** @name CumulusPalletXcmpQueueOutboundChannelDetails (291) */
   export interface CumulusPalletXcmpQueueOutboundChannelDetails extends Struct {
     readonly recipient: u32;
     readonly state: CumulusPalletXcmpQueueOutboundState;
@@ -2408,14 +2384,14 @@
     readonly lastIndex: u16;
   }
 
-  /** @name CumulusPalletXcmpQueueOutboundState (294) */
+  /** @name CumulusPalletXcmpQueueOutboundState (292) */
   export interface CumulusPalletXcmpQueueOutboundState extends Enum {
     readonly isOk: boolean;
     readonly isSuspended: boolean;
     readonly type: 'Ok' | 'Suspended';
   }
 
-  /** @name CumulusPalletXcmpQueueQueueConfigData (296) */
+  /** @name CumulusPalletXcmpQueueQueueConfigData (294) */
   export interface CumulusPalletXcmpQueueQueueConfigData extends Struct {
     readonly suspendThreshold: u32;
     readonly dropThreshold: u32;
@@ -2425,7 +2401,7 @@
     readonly xcmpMaxIndividualWeight: u64;
   }
 
-  /** @name CumulusPalletXcmpQueueError (298) */
+  /** @name CumulusPalletXcmpQueueError (296) */
   export interface CumulusPalletXcmpQueueError extends Enum {
     readonly isFailedToSend: boolean;
     readonly isBadXcmOrigin: boolean;
@@ -2435,7 +2411,7 @@
     readonly type: 'FailedToSend' | 'BadXcmOrigin' | 'BadXcm' | 'BadOverweightIndex' | 'WeightOverLimit';
   }
 
-  /** @name PalletXcmError (299) */
+  /** @name PalletXcmError (297) */
   export interface PalletXcmError extends Enum {
     readonly isUnreachable: boolean;
     readonly isSendFailure: boolean;
@@ -2453,29 +2429,29 @@
     readonly type: 'Unreachable' | 'SendFailure' | 'Filtered' | 'UnweighableMessage' | 'DestinationNotInvertible' | 'Empty' | 'CannotReanchor' | 'TooManyAssets' | 'InvalidOrigin' | 'BadVersion' | 'BadLocation' | 'NoSubscription' | 'AlreadySubscribed';
   }
 
-  /** @name CumulusPalletXcmError (300) */
+  /** @name CumulusPalletXcmError (298) */
   export type CumulusPalletXcmError = Null;
 
-  /** @name CumulusPalletDmpQueueConfigData (301) */
+  /** @name CumulusPalletDmpQueueConfigData (299) */
   export interface CumulusPalletDmpQueueConfigData extends Struct {
     readonly maxIndividual: u64;
   }
 
-  /** @name CumulusPalletDmpQueuePageIndexData (302) */
+  /** @name CumulusPalletDmpQueuePageIndexData (300) */
   export interface CumulusPalletDmpQueuePageIndexData extends Struct {
     readonly beginUsed: u32;
     readonly endUsed: u32;
     readonly overweightCount: u64;
   }
 
-  /** @name CumulusPalletDmpQueueError (305) */
+  /** @name CumulusPalletDmpQueueError (303) */
   export interface CumulusPalletDmpQueueError extends Enum {
     readonly isUnknown: boolean;
     readonly isOverLimit: boolean;
     readonly type: 'Unknown' | 'OverLimit';
   }
 
-  /** @name PalletUniqueError (309) */
+  /** @name PalletUniqueError (307) */
   export interface PalletUniqueError extends Enum {
     readonly isCollectionDecimalPointLimitExceeded: boolean;
     readonly isConfirmUnsetSponsorFail: boolean;
@@ -2483,7 +2459,7 @@
     readonly type: 'CollectionDecimalPointLimitExceeded' | 'ConfirmUnsetSponsorFail' | 'EmptyArgument';
   }
 
-  /** @name UpDataStructsCollection (310) */
+  /** @name UpDataStructsCollection (308) */
   export interface UpDataStructsCollection extends Struct {
     readonly owner: AccountId32;
     readonly mode: UpDataStructsCollectionMode;
@@ -2495,10 +2471,9 @@
     readonly schemaVersion: UpDataStructsSchemaVersion;
     readonly sponsorship: UpDataStructsSponsorshipState;
     readonly limits: UpDataStructsCollectionLimits;
-    readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
   }
 
-  /** @name UpDataStructsSponsorshipState (311) */
+  /** @name UpDataStructsSponsorshipState (309) */
   export interface UpDataStructsSponsorshipState extends Enum {
     readonly isDisabled: boolean;
     readonly isUnconfirmed: boolean;
@@ -2508,47 +2483,47 @@
     readonly type: 'Disabled' | 'Unconfirmed' | 'Confirmed';
   }
 
-  /** @name UpDataStructsProperties (312) */
+  /** @name UpDataStructsProperties (310) */
   export interface UpDataStructsProperties extends Struct {
     readonly map: UpDataStructsPropertiesMapBoundedVec;
     readonly consumedSpace: u32;
     readonly spaceLimit: u32;
   }
 
-  /** @name UpDataStructsPropertiesMapBoundedVec (313) */
+  /** @name UpDataStructsPropertiesMapBoundedVec (311) */
   export interface UpDataStructsPropertiesMapBoundedVec extends BTreeMap<Bytes, Bytes> {}
 
-  /** @name UpDataStructsPropertiesMapPropertyPermission (318) */
+  /** @name UpDataStructsPropertiesMapPropertyPermission (316) */
   export interface UpDataStructsPropertiesMapPropertyPermission extends BTreeMap<Bytes, UpDataStructsPropertyPermission> {}
 
-  /** @name UpDataStructsCollectionField (324) */
+  /** @name UpDataStructsCollectionField (322) */
   export interface UpDataStructsCollectionField extends Enum {
     readonly isConstOnChainSchema: boolean;
     readonly isOffchainSchema: boolean;
     readonly type: 'ConstOnChainSchema' | 'OffchainSchema';
   }
 
-  /** @name UpDataStructsCollectionStats (327) */
+  /** @name UpDataStructsCollectionStats (325) */
   export interface UpDataStructsCollectionStats extends Struct {
     readonly created: u32;
     readonly destroyed: u32;
     readonly alive: u32;
   }
 
-  /** @name PhantomTypeUpDataStructsTokenData (328) */
+  /** @name PhantomTypeUpDataStructsTokenData (326) */
   export interface PhantomTypeUpDataStructsTokenData extends Vec<UpDataStructsTokenData> {}
 
-  /** @name UpDataStructsTokenData (329) */
+  /** @name UpDataStructsTokenData (327) */
   export interface UpDataStructsTokenData extends Struct {
     readonly constData: Bytes;
     readonly properties: Vec<UpDataStructsProperty>;
     readonly owner: Option<PalletEvmAccountBasicCrossAccountIdRepr>;
   }
 
-  /** @name PhantomTypeUpDataStructsRpcCollection (332) */
+  /** @name PhantomTypeUpDataStructsRpcCollection (330) */
   export interface PhantomTypeUpDataStructsRpcCollection extends Vec<UpDataStructsRpcCollection> {}
 
-  /** @name UpDataStructsRpcCollection (333) */
+  /** @name UpDataStructsRpcCollection (331) */
   export interface UpDataStructsRpcCollection extends Struct {
     readonly owner: AccountId32;
     readonly mode: UpDataStructsCollectionMode;
@@ -2562,15 +2537,14 @@
     readonly sponsorship: UpDataStructsSponsorshipState;
     readonly limits: UpDataStructsCollectionLimits;
     readonly constOnChainSchema: Bytes;
-    readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
     readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
     readonly properties: Vec<UpDataStructsProperty>;
   }
 
-  /** @name PhantomTypeUpDataStructsCollectionInfo (335) */
+  /** @name PhantomTypeUpDataStructsCollectionInfo (333) */
   export interface PhantomTypeUpDataStructsCollectionInfo extends Vec<RmrkTypesCollectionInfo> {}
 
-  /** @name RmrkTypesCollectionInfo (336) */
+  /** @name RmrkTypesCollectionInfo (334) */
   export interface RmrkTypesCollectionInfo extends Struct {
     readonly issuer: AccountId32;
     readonly metadata: Bytes;
@@ -2579,10 +2553,10 @@
     readonly nftsCount: u32;
   }
 
-  /** @name PhantomTypeUpDataStructsNftInfo (340) */
+  /** @name PhantomTypeUpDataStructsNftInfo (338) */
   export interface PhantomTypeUpDataStructsNftInfo extends Vec<RmrkTypesNftInfo> {}
 
-  /** @name RmrkTypesNftInfo (341) */
+  /** @name RmrkTypesNftInfo (339) */
   export interface RmrkTypesNftInfo extends Struct {
     readonly owner: RmrkTypesAccountIdOrCollectionNftTuple;
     readonly royalty: Option<RmrkTypesRoyaltyInfo>;
@@ -2591,7 +2565,7 @@
     readonly pending: bool;
   }
 
-  /** @name RmrkTypesAccountIdOrCollectionNftTuple (342) */
+  /** @name RmrkTypesAccountIdOrCollectionNftTuple (340) */
   export interface RmrkTypesAccountIdOrCollectionNftTuple extends Enum {
     readonly isAccountId: boolean;
     readonly asAccountId: AccountId32;
@@ -2600,16 +2574,16 @@
     readonly type: 'AccountId' | 'CollectionAndNftTuple';
   }
 
-  /** @name RmrkTypesRoyaltyInfo (344) */
+  /** @name RmrkTypesRoyaltyInfo (342) */
   export interface RmrkTypesRoyaltyInfo extends Struct {
     readonly recipient: AccountId32;
     readonly amount: Permill;
   }
 
-  /** @name PhantomTypeUpDataStructsResourceInfo (346) */
+  /** @name PhantomTypeUpDataStructsResourceInfo (344) */
   export interface PhantomTypeUpDataStructsResourceInfo extends Vec<RmrkTypesResourceInfo> {}
 
-  /** @name RmrkTypesResourceInfo (347) */
+  /** @name RmrkTypesResourceInfo (345) */
   export interface RmrkTypesResourceInfo extends Struct {
     readonly id: Bytes;
     readonly pending: bool;
@@ -2623,29 +2597,29 @@
     readonly thumb: Option<Bytes>;
   }
 
-  /** @name PhantomTypeUpDataStructsPropertyInfo (353) */
+  /** @name PhantomTypeUpDataStructsPropertyInfo (351) */
   export interface PhantomTypeUpDataStructsPropertyInfo extends Vec<RmrkTypesPropertyInfo> {}
 
-  /** @name RmrkTypesPropertyInfo (354) */
+  /** @name RmrkTypesPropertyInfo (352) */
   export interface RmrkTypesPropertyInfo extends Struct {
     readonly key: Bytes;
     readonly value: Bytes;
   }
 
-  /** @name PhantomTypeUpDataStructsBaseInfo (358) */
+  /** @name PhantomTypeUpDataStructsBaseInfo (356) */
   export interface PhantomTypeUpDataStructsBaseInfo extends Vec<RmrkTypesBaseInfo> {}
 
-  /** @name RmrkTypesBaseInfo (359) */
+  /** @name RmrkTypesBaseInfo (357) */
   export interface RmrkTypesBaseInfo extends Struct {
     readonly issuer: AccountId32;
     readonly baseType: Bytes;
     readonly symbol: Bytes;
   }
 
-  /** @name PhantomTypeUpDataStructsPartType (361) */
+  /** @name PhantomTypeUpDataStructsPartType (359) */
   export interface PhantomTypeUpDataStructsPartType extends Vec<RmrkTypesPartType> {}
 
-  /** @name RmrkTypesPartType (362) */
+  /** @name RmrkTypesPartType (360) */
   export interface RmrkTypesPartType extends Enum {
     readonly isFixedPart: boolean;
     readonly asFixedPart: RmrkTypesFixedPart;
@@ -2654,14 +2628,14 @@
     readonly type: 'FixedPart' | 'SlotPart';
   }
 
-  /** @name RmrkTypesFixedPart (364) */
+  /** @name RmrkTypesFixedPart (362) */
   export interface RmrkTypesFixedPart extends Struct {
     readonly id: u32;
     readonly z: u32;
     readonly src: Bytes;
   }
 
-  /** @name RmrkTypesSlotPart (365) */
+  /** @name RmrkTypesSlotPart (363) */
   export interface RmrkTypesSlotPart extends Struct {
     readonly id: u32;
     readonly equippable: RmrkTypesEquippableList;
@@ -2669,7 +2643,7 @@
     readonly z: u32;
   }
 
-  /** @name RmrkTypesEquippableList (366) */
+  /** @name RmrkTypesEquippableList (364) */
   export interface RmrkTypesEquippableList extends Enum {
     readonly isAll: boolean;
     readonly isEmpty: boolean;
@@ -2678,32 +2652,32 @@
     readonly type: 'All' | 'Empty' | 'Custom';
   }
 
-  /** @name PhantomTypeUpDataStructsTheme (368) */
+  /** @name PhantomTypeUpDataStructsTheme (366) */
   export interface PhantomTypeUpDataStructsTheme extends Vec<RmrkTypesTheme> {}
 
-  /** @name RmrkTypesTheme (369) */
+  /** @name RmrkTypesTheme (367) */
   export interface RmrkTypesTheme extends Struct {
     readonly name: Bytes;
     readonly properties: Vec<RmrkTypesThemeProperty>;
     readonly inherit: bool;
   }
 
-  /** @name RmrkTypesThemeProperty (371) */
+  /** @name RmrkTypesThemeProperty (369) */
   export interface RmrkTypesThemeProperty extends Struct {
     readonly key: Bytes;
     readonly value: Bytes;
   }
 
-  /** @name PhantomTypeUpDataStructsNftChild (373) */
+  /** @name PhantomTypeUpDataStructsNftChild (371) */
   export interface PhantomTypeUpDataStructsNftChild extends Vec<RmrkTypesNftChild> {}
 
-  /** @name RmrkTypesNftChild (374) */
+  /** @name RmrkTypesNftChild (372) */
   export interface RmrkTypesNftChild extends Struct {
     readonly collectionId: u32;
     readonly nftId: u32;
   }
 
-  /** @name PalletCommonError (376) */
+  /** @name PalletCommonError (374) */
   export interface PalletCommonError extends Enum {
     readonly isCollectionNotFound: boolean;
     readonly isMustBeTokenOwner: boolean;
@@ -2714,7 +2688,6 @@
     readonly isCollectionDescriptionLimitExceeded: boolean;
     readonly isCollectionTokenPrefixLimitExceeded: boolean;
     readonly isTotalCollectionsLimitExceeded: boolean;
-    readonly isTokenVariableDataLimitExceeded: boolean;
     readonly isCollectionAdminCountExceeded: boolean;
     readonly isCollectionLimitBoundsExceeded: boolean;
     readonly isOwnerPermissionsCantBeReverted: boolean;
@@ -2735,13 +2708,13 @@
     readonly isCollectionFieldSizeExceeded: boolean;
     readonly isNoSpaceForProperty: boolean;
     readonly isPropertyLimitReached: boolean;
-    readonly isUnableToReadUnboundedKeys: boolean;
+    readonly isPropertyKeyIsTooLong: boolean;
     readonly isInvalidCharacterInPropertyKey: boolean;
     readonly isEmptyPropertyKey: boolean;
-    readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'TokenVariableDataLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'UnableToReadUnboundedKeys' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
+    readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
   }
 
-  /** @name PalletFungibleError (378) */
+  /** @name PalletFungibleError (376) */
   export interface PalletFungibleError extends Enum {
     readonly isNotFungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isFungibleItemsHaveNoId: boolean;
@@ -2751,13 +2724,12 @@
     readonly type: 'NotFungibleDataUsedToMintFungibleCollectionToken' | 'FungibleItemsHaveNoId' | 'FungibleItemsDontHaveData' | 'FungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
   }
 
-  /** @name PalletRefungibleItemData (379) */
+  /** @name PalletRefungibleItemData (377) */
   export interface PalletRefungibleItemData extends Struct {
     readonly constData: Bytes;
-    readonly variableData: Bytes;
   }
 
-  /** @name PalletRefungibleError (383) */
+  /** @name PalletRefungibleError (381) */
   export interface PalletRefungibleError extends Enum {
     readonly isNotRefungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isWrongRefungiblePieces: boolean;
@@ -2766,21 +2738,20 @@
     readonly type: 'NotRefungibleDataUsedToMintFungibleCollectionToken' | 'WrongRefungiblePieces' | 'RefungibleDisallowsNesting' | 'SettingPropertiesNotAllowed';
   }
 
-  /** @name PalletNonfungibleItemData (384) */
+  /** @name PalletNonfungibleItemData (382) */
   export interface PalletNonfungibleItemData extends Struct {
     readonly constData: Bytes;
-    readonly variableData: Bytes;
     readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
   }
 
-  /** @name PalletNonfungibleError (385) */
+  /** @name PalletNonfungibleError (383) */
   export interface PalletNonfungibleError extends Enum {
     readonly isNotNonfungibleDataUsedToMintFungibleCollectionToken: boolean;
     readonly isNonfungibleItemsHaveNoAmount: boolean;
     readonly type: 'NotNonfungibleDataUsedToMintFungibleCollectionToken' | 'NonfungibleItemsHaveNoAmount';
   }
 
-  /** @name PalletStructureError (386) */
+  /** @name PalletStructureError (384) */
   export interface PalletStructureError extends Enum {
     readonly isOuroborosDetected: boolean;
     readonly isDepthLimit: boolean;
@@ -2788,7 +2759,7 @@
     readonly type: 'OuroborosDetected' | 'DepthLimit' | 'TokenNotFound';
   }
 
-  /** @name PalletEvmError (389) */
+  /** @name PalletEvmError (387) */
   export interface PalletEvmError extends Enum {
     readonly isBalanceLow: boolean;
     readonly isFeeOverflow: boolean;
@@ -2799,7 +2770,7 @@
     readonly type: 'BalanceLow' | 'FeeOverflow' | 'PaymentOverflow' | 'WithdrawFailed' | 'GasPriceTooLow' | 'InvalidNonce';
   }
 
-  /** @name FpRpcTransactionStatus (392) */
+  /** @name FpRpcTransactionStatus (390) */
   export interface FpRpcTransactionStatus extends Struct {
     readonly transactionHash: H256;
     readonly transactionIndex: u32;
@@ -2810,10 +2781,10 @@
     readonly logsBloom: EthbloomBloom;
   }
 
-  /** @name EthbloomBloom (394) */
+  /** @name EthbloomBloom (392) */
   export interface EthbloomBloom extends U8aFixed {}
 
-  /** @name EthereumReceiptReceiptV3 (396) */
+  /** @name EthereumReceiptReceiptV3 (394) */
   export interface EthereumReceiptReceiptV3 extends Enum {
     readonly isLegacy: boolean;
     readonly asLegacy: EthereumReceiptEip658ReceiptData;
@@ -2824,7 +2795,7 @@
     readonly type: 'Legacy' | 'Eip2930' | 'Eip1559';
   }
 
-  /** @name EthereumReceiptEip658ReceiptData (397) */
+  /** @name EthereumReceiptEip658ReceiptData (395) */
   export interface EthereumReceiptEip658ReceiptData extends Struct {
     readonly statusCode: u8;
     readonly usedGas: U256;
@@ -2832,14 +2803,14 @@
     readonly logs: Vec<EthereumLog>;
   }
 
-  /** @name EthereumBlock (398) */
+  /** @name EthereumBlock (396) */
   export interface EthereumBlock extends Struct {
     readonly header: EthereumHeader;
     readonly transactions: Vec<EthereumTransactionTransactionV2>;
     readonly ommers: Vec<EthereumHeader>;
   }
 
-  /** @name EthereumHeader (399) */
+  /** @name EthereumHeader (397) */
   export interface EthereumHeader extends Struct {
     readonly parentHash: H256;
     readonly ommersHash: H256;
@@ -2858,24 +2829,24 @@
     readonly nonce: EthereumTypesHashH64;
   }
 
-  /** @name EthereumTypesHashH64 (400) */
+  /** @name EthereumTypesHashH64 (398) */
   export interface EthereumTypesHashH64 extends U8aFixed {}
 
-  /** @name PalletEthereumError (405) */
+  /** @name PalletEthereumError (403) */
   export interface PalletEthereumError extends Enum {
     readonly isInvalidSignature: boolean;
     readonly isPreLogExists: boolean;
     readonly type: 'InvalidSignature' | 'PreLogExists';
   }
 
-  /** @name PalletEvmCoderSubstrateError (406) */
+  /** @name PalletEvmCoderSubstrateError (404) */
   export interface PalletEvmCoderSubstrateError extends Enum {
     readonly isOutOfGas: boolean;
     readonly isOutOfFund: boolean;
     readonly type: 'OutOfGas' | 'OutOfFund';
   }
 
-  /** @name PalletEvmContractHelpersSponsoringModeT (407) */
+  /** @name PalletEvmContractHelpersSponsoringModeT (405) */
   export interface PalletEvmContractHelpersSponsoringModeT extends Enum {
     readonly isDisabled: boolean;
     readonly isAllowlisted: boolean;
@@ -2883,20 +2854,20 @@
     readonly type: 'Disabled' | 'Allowlisted' | 'Generous';
   }
 
-  /** @name PalletEvmContractHelpersError (409) */
+  /** @name PalletEvmContractHelpersError (407) */
   export interface PalletEvmContractHelpersError extends Enum {
     readonly isNoPermission: boolean;
     readonly type: 'NoPermission';
   }
 
-  /** @name PalletEvmMigrationError (410) */
+  /** @name PalletEvmMigrationError (408) */
   export interface PalletEvmMigrationError extends Enum {
     readonly isAccountNotEmpty: boolean;
     readonly isAccountIsNotMigrating: boolean;
     readonly type: 'AccountNotEmpty' | 'AccountIsNotMigrating';
   }
 
-  /** @name SpRuntimeMultiSignature (412) */
+  /** @name SpRuntimeMultiSignature (410) */
   export interface SpRuntimeMultiSignature extends Enum {
     readonly isEd25519: boolean;
     readonly asEd25519: SpCoreEd25519Signature;
@@ -2907,34 +2878,34 @@
     readonly type: 'Ed25519' | 'Sr25519' | 'Ecdsa';
   }
 
-  /** @name SpCoreEd25519Signature (413) */
+  /** @name SpCoreEd25519Signature (411) */
   export interface SpCoreEd25519Signature extends U8aFixed {}
 
-  /** @name SpCoreSr25519Signature (415) */
+  /** @name SpCoreSr25519Signature (413) */
   export interface SpCoreSr25519Signature extends U8aFixed {}
 
-  /** @name SpCoreEcdsaSignature (416) */
+  /** @name SpCoreEcdsaSignature (414) */
   export interface SpCoreEcdsaSignature extends U8aFixed {}
 
-  /** @name FrameSystemExtensionsCheckSpecVersion (419) */
+  /** @name FrameSystemExtensionsCheckSpecVersion (417) */
   export type FrameSystemExtensionsCheckSpecVersion = Null;
 
-  /** @name FrameSystemExtensionsCheckGenesis (420) */
+  /** @name FrameSystemExtensionsCheckGenesis (418) */
   export type FrameSystemExtensionsCheckGenesis = Null;
 
-  /** @name FrameSystemExtensionsCheckNonce (423) */
+  /** @name FrameSystemExtensionsCheckNonce (421) */
   export interface FrameSystemExtensionsCheckNonce extends Compact<u32> {}
 
-  /** @name FrameSystemExtensionsCheckWeight (424) */
+  /** @name FrameSystemExtensionsCheckWeight (422) */
   export type FrameSystemExtensionsCheckWeight = Null;
 
-  /** @name PalletTemplateTransactionPaymentChargeTransactionPayment (425) */
+  /** @name PalletTemplateTransactionPaymentChargeTransactionPayment (423) */
   export interface PalletTemplateTransactionPaymentChargeTransactionPayment extends Compact<u128> {}
 
-  /** @name OpalRuntimeRuntime (426) */
+  /** @name OpalRuntimeRuntime (424) */
   export type OpalRuntimeRuntime = Null;
 
-  /** @name PalletEthereumFakeTransactionFinalizer (427) */
+  /** @name PalletEthereumFakeTransactionFinalizer (425) */
   export type PalletEthereumFakeTransactionFinalizer = Null;
 
 } // declare module
modifiedtests/src/interfaces/unique/definitions.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/definitions.ts
+++ b/tests/src/interfaces/unique/definitions.ts
@@ -26,7 +26,7 @@
 
 const collectionParam = {name: 'collection', type: 'u32'};
 const tokenParam = {name: 'tokenId', type: 'u32'};
-const propertyKeysParam = {name: 'propertyKeys', type: 'Vec<String>'};
+const propertyKeysParam = {name: 'propertyKeys', type: 'Vec<String>', isOptional: true};
 const crossAccountParam = (name = 'account') => ({name, type: CROSS_ACCOUNT_ID_TYPE});
 const atParam = {name: 'at', type: 'Hash', isOptional: true};
 
modifiedtests/src/interfaces/unique/types.tsdiffbeforeafterboth
--- a/tests/src/interfaces/unique/types.ts
+++ b/tests/src/interfaces/unique/types.ts
@@ -446,9 +446,6 @@
 /** @name FrameSupportPalletId */
 export interface FrameSupportPalletId extends U8aFixed {}
 
-/** @name FrameSupportStorageBoundedBTreeSet */
-export interface FrameSupportStorageBoundedBTreeSet extends BTreeSet<u32> {}
-
 /** @name FrameSupportTokensMiscBalanceStatus */
 export interface FrameSupportTokensMiscBalanceStatus extends Enum {
   readonly isFree: boolean;
@@ -875,7 +872,6 @@
   readonly isCollectionDescriptionLimitExceeded: boolean;
   readonly isCollectionTokenPrefixLimitExceeded: boolean;
   readonly isTotalCollectionsLimitExceeded: boolean;
-  readonly isTokenVariableDataLimitExceeded: boolean;
   readonly isCollectionAdminCountExceeded: boolean;
   readonly isCollectionLimitBoundsExceeded: boolean;
   readonly isOwnerPermissionsCantBeReverted: boolean;
@@ -896,10 +892,10 @@
   readonly isCollectionFieldSizeExceeded: boolean;
   readonly isNoSpaceForProperty: boolean;
   readonly isPropertyLimitReached: boolean;
-  readonly isUnableToReadUnboundedKeys: boolean;
+  readonly isPropertyKeyIsTooLong: boolean;
   readonly isInvalidCharacterInPropertyKey: boolean;
   readonly isEmptyPropertyKey: boolean;
-  readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'TokenVariableDataLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'UnableToReadUnboundedKeys' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
+  readonly type: 'CollectionNotFound' | 'MustBeTokenOwner' | 'NoPermission' | 'PublicMintingNotAllowed' | 'AddressNotInAllowlist' | 'CollectionNameLimitExceeded' | 'CollectionDescriptionLimitExceeded' | 'CollectionTokenPrefixLimitExceeded' | 'TotalCollectionsLimitExceeded' | 'CollectionAdminCountExceeded' | 'CollectionLimitBoundsExceeded' | 'OwnerPermissionsCantBeReverted' | 'TransferNotAllowed' | 'AccountTokenLimitExceeded' | 'CollectionTokenLimitExceeded' | 'MetadataFlagFrozen' | 'TokenNotFound' | 'TokenValueTooLow' | 'ApprovedValueTooLow' | 'CantApproveMoreThanOwned' | 'AddressIsZero' | 'UnsupportedOperation' | 'NotSufficientFounds' | 'NestingIsDisabled' | 'OnlyOwnerAllowedToNest' | 'SourceCollectionIsNotAllowedToNest' | 'CollectionFieldSizeExceeded' | 'NoSpaceForProperty' | 'PropertyLimitReached' | 'PropertyKeyIsTooLong' | 'InvalidCharacterInPropertyKey' | 'EmptyPropertyKey';
 }
 
 /** @name PalletCommonEvent */
@@ -1115,7 +1111,6 @@
 /** @name PalletNonfungibleItemData */
 export interface PalletNonfungibleItemData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
 }
 
@@ -1131,7 +1126,6 @@
 /** @name PalletRefungibleItemData */
 export interface PalletRefungibleItemData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
 }
 
 /** @name PalletStructureCall */
@@ -1438,17 +1432,6 @@
     readonly collectionId: u32;
     readonly itemId: u32;
     readonly value: u128;
-  } & Struct;
-  readonly isSetVariableMetaData: boolean;
-  readonly asSetVariableMetaData: {
-    readonly collectionId: u32;
-    readonly itemId: u32;
-    readonly data: Bytes;
-  } & Struct;
-  readonly isSetMetaUpdatePermissionFlag: boolean;
-  readonly asSetMetaUpdatePermissionFlag: {
-    readonly collectionId: u32;
-    readonly value: UpDataStructsMetaUpdatePermission;
   } & Struct;
   readonly isSetSchemaVersion: boolean;
   readonly asSetSchemaVersion: {
@@ -1470,7 +1453,7 @@
     readonly collectionId: u32;
     readonly newLimit: UpDataStructsCollectionLimits;
   } & Struct;
-  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetVariableMetaData' | 'SetMetaUpdatePermissionFlag' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetCollectionLimits';
+  readonly type: 'CreateCollection' | 'CreateCollectionEx' | 'DestroyCollection' | 'AddToAllowList' | 'RemoveFromAllowList' | 'SetPublicAccessMode' | 'SetMintPermission' | 'ChangeCollectionOwner' | 'AddCollectionAdmin' | 'RemoveCollectionAdmin' | 'SetCollectionSponsor' | 'ConfirmSponsorship' | 'RemoveCollectionSponsor' | 'CreateItem' | 'CreateMultipleItems' | 'SetCollectionProperties' | 'DeleteCollectionProperties' | 'SetTokenProperties' | 'DeleteTokenProperties' | 'SetPropertyPermissions' | 'CreateMultipleItemsEx' | 'SetTransfersEnabledFlag' | 'BurnItem' | 'BurnFrom' | 'Transfer' | 'Approve' | 'TransferFrom' | 'SetSchemaVersion' | 'SetOffchainSchema' | 'SetConstOnChainSchema' | 'SetCollectionLimits';
 }
 
 /** @name PalletUniqueError */
@@ -1632,34 +1615,34 @@
 }
 
 /** @name PhantomTypeUpDataStructsBaseInfo */
-export interface PhantomTypeUpDataStructsBaseInfo extends Vec<Lookup359> {}
+export interface PhantomTypeUpDataStructsBaseInfo extends Vec<Lookup357> {}
 
 /** @name PhantomTypeUpDataStructsCollectionInfo */
-export interface PhantomTypeUpDataStructsCollectionInfo extends Vec<Lookup336> {}
+export interface PhantomTypeUpDataStructsCollectionInfo extends Vec<Lookup334> {}
 
 /** @name PhantomTypeUpDataStructsNftChild */
-export interface PhantomTypeUpDataStructsNftChild extends Vec<Lookup374> {}
+export interface PhantomTypeUpDataStructsNftChild extends Vec<Lookup372> {}
 
 /** @name PhantomTypeUpDataStructsNftInfo */
-export interface PhantomTypeUpDataStructsNftInfo extends Vec<Lookup341> {}
+export interface PhantomTypeUpDataStructsNftInfo extends Vec<Lookup339> {}
 
 /** @name PhantomTypeUpDataStructsPartType */
-export interface PhantomTypeUpDataStructsPartType extends Vec<Lookup362> {}
+export interface PhantomTypeUpDataStructsPartType extends Vec<Lookup360> {}
 
 /** @name PhantomTypeUpDataStructsPropertyInfo */
-export interface PhantomTypeUpDataStructsPropertyInfo extends Vec<Lookup354> {}
+export interface PhantomTypeUpDataStructsPropertyInfo extends Vec<Lookup352> {}
 
 /** @name PhantomTypeUpDataStructsResourceInfo */
-export interface PhantomTypeUpDataStructsResourceInfo extends Vec<Lookup347> {}
+export interface PhantomTypeUpDataStructsResourceInfo extends Vec<Lookup345> {}
 
 /** @name PhantomTypeUpDataStructsRpcCollection */
-export interface PhantomTypeUpDataStructsRpcCollection extends Vec<Lookup333> {}
+export interface PhantomTypeUpDataStructsRpcCollection extends Vec<Lookup331> {}
 
 /** @name PhantomTypeUpDataStructsTheme */
-export interface PhantomTypeUpDataStructsTheme extends Vec<Lookup369> {}
+export interface PhantomTypeUpDataStructsTheme extends Vec<Lookup367> {}
 
 /** @name PhantomTypeUpDataStructsTokenData */
-export interface PhantomTypeUpDataStructsTokenData extends Vec<Lookup329> {}
+export interface PhantomTypeUpDataStructsTokenData extends Vec<Lookup327> {}
 
 /** @name PolkadotCorePrimitivesInboundDownwardMessage */
 export interface PolkadotCorePrimitivesInboundDownwardMessage extends Struct {
@@ -1963,7 +1946,6 @@
   readonly schemaVersion: UpDataStructsSchemaVersion;
   readonly sponsorship: UpDataStructsSponsorshipState;
   readonly limits: UpDataStructsCollectionLimits;
-  readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
 }
 
 /** @name UpDataStructsCollectionField */
@@ -2015,7 +1997,6 @@
   readonly pendingSponsor: Option<AccountId32>;
   readonly limits: Option<UpDataStructsCollectionLimits>;
   readonly constOnChainSchema: Bytes;
-  readonly metaUpdatePermission: Option<UpDataStructsMetaUpdatePermission>;
   readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
   readonly properties: Vec<UpDataStructsProperty>;
 }
@@ -2052,14 +2033,12 @@
 /** @name UpDataStructsCreateNftData */
 export interface UpDataStructsCreateNftData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly properties: Vec<UpDataStructsProperty>;
 }
 
 /** @name UpDataStructsCreateNftExData */
 export interface UpDataStructsCreateNftExData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly properties: Vec<UpDataStructsProperty>;
   readonly owner: PalletEvmAccountBasicCrossAccountIdRepr;
 }
@@ -2067,31 +2046,21 @@
 /** @name UpDataStructsCreateReFungibleData */
 export interface UpDataStructsCreateReFungibleData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly pieces: u128;
 }
 
 /** @name UpDataStructsCreateRefungibleExData */
 export interface UpDataStructsCreateRefungibleExData extends Struct {
   readonly constData: Bytes;
-  readonly variableData: Bytes;
   readonly users: BTreeMap<PalletEvmAccountBasicCrossAccountIdRepr, u128>;
 }
 
-/** @name UpDataStructsMetaUpdatePermission */
-export interface UpDataStructsMetaUpdatePermission extends Enum {
-  readonly isItemOwner: boolean;
-  readonly isAdmin: boolean;
-  readonly isNone: boolean;
-  readonly type: 'ItemOwner' | 'Admin' | 'None';
-}
-
 /** @name UpDataStructsNestingRule */
 export interface UpDataStructsNestingRule extends Enum {
   readonly isDisabled: boolean;
   readonly isOwner: boolean;
   readonly isOwnerRestricted: boolean;
-  readonly asOwnerRestricted: FrameSupportStorageBoundedBTreeSet;
+  readonly asOwnerRestricted: BTreeSet<u32>;
   readonly type: 'Disabled' | 'Owner' | 'OwnerRestricted';
 }
 
@@ -2141,7 +2110,6 @@
   readonly sponsorship: UpDataStructsSponsorshipState;
   readonly limits: UpDataStructsCollectionLimits;
   readonly constOnChainSchema: Bytes;
-  readonly metaUpdatePermission: UpDataStructsMetaUpdatePermission;
   readonly tokenPropertyPermissions: Vec<UpDataStructsPropertyKeyPermission>;
   readonly properties: Vec<UpDataStructsProperty>;
 }
deletedtests/src/metadataUpdate.test.tsdiffbeforeafterboth
--- a/tests/src/metadataUpdate.test.ts
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import privateKey from './substrate/privateKey';
-import usingApi from './substrate/substrate-api';
-import {
-  createItemExpectSuccess,
-  createCollectionExpectSuccess,
-  enablePublicMintingExpectSuccess,
-  enableAllowListExpectSuccess,
-  setMetadataUpdatePermissionFlagExpectSuccess,
-  setVariableMetaDataExpectSuccess,
-  setMintPermissionExpectSuccess,
-  addToAllowListExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  setVariableMetaDataExpectFailure,
-  setMetadataUpdatePermissionFlagExpectFailure,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-
-describe('Metadata update permissions with ItemOwner flag', () => {
-  it('ItemOwner can set variable metadata with ItemOwner permission flag', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'ItemOwner');
-
-      await setVariableMetaDataExpectSuccess(alice, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('Admin can\'n set variable metadata with ItemOwner permission flag', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'ItemOwner');
-
-      await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
-      await addToAllowListExpectSuccess(alice, nftCollectionId, bob.address);
-      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-
-      await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('User can\'n set variable metadata with ItemOwner permission flag', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'ItemOwner');
-
-      await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
-      await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-});
-
-describe('Metadata update permissions with Admin flag', () => {
-  it('Admin can set variable metadata with Admin permission flag', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'Admin');
-
-      await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
-      await addToAllowListExpectSuccess(alice, nftCollectionId, bob.address);
-      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-
-      await setVariableMetaDataExpectSuccess(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('User can\'n can set variable metadata with Admin permission flag', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'Admin');
-
-      await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
-      await addToAllowListExpectSuccess(alice, nftCollectionId, bob.address);
-      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-
-      await setVariableMetaDataExpectSuccess(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('ItemOwner can\'n can set variable metadata with Admin permission flag', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      await enablePublicMintingExpectSuccess(alice, nftCollectionId);
-      await addToAllowListExpectSuccess(alice, nftCollectionId, bob.address);
-      await enableAllowListExpectSuccess(alice, nftCollectionId);
-      const newNftTokenId = await createItemExpectSuccess(bob, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'Admin');
-
-      await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-});
-
-describe('Metadata update permissions with None flag', () => {
-  it('Nobody can set variable metadata with None flag (Regular)', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
-
-      await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('Nobody can set variable metadata with None flag (Admin)', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-      const bob = privateKey('//Bob');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
-
-      await setMintPermissionExpectSuccess(alice, nftCollectionId, true);
-      await addToAllowListExpectSuccess(alice, nftCollectionId, bob.address);
-      await addCollectionAdminExpectSuccess(alice, nftCollectionId, bob.address);
-
-      await setVariableMetaDataExpectFailure(bob, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('Nobody can set variable metadata with None flag (ItemOwner)', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-
-      const data = [1, 2, 254, 255];
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      const newNftTokenId = await createItemExpectSuccess(alice, nftCollectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
-
-      await setVariableMetaDataExpectFailure(alice, nftCollectionId, newNftTokenId, data);
-    });
-  });
-
-  it('Nobody can set variable metadata flag after freeze', async () => {
-    await usingApi(async () => {
-      const alice = privateKey('//Alice');
-
-      // nft
-      const nftCollectionId = await createCollectionExpectSuccess();
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, nftCollectionId, 'None');
-      await setMetadataUpdatePermissionFlagExpectFailure(alice, nftCollectionId, 'Admin');
-    });
-  });
-});
modifiedtests/src/nesting/migration-check.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/migration-check.test.ts
+++ b/tests/src/nesting/migration-check.test.ts
@@ -37,7 +37,6 @@
           accountTokenOwnershipLimit: 3,
         },
         constOnChainSchema: '0x333333',
-        metaUpdatePermission: 'Admin',
       });
       const events = await submitTransactionAsync(alice, tx);
       const result = getCreateCollectionResult(events);
modifiedtests/src/nesting/rules-smoke.test.tsdiffbeforeafterboth
--- a/tests/src/nesting/rules-smoke.test.ts
+++ b/tests/src/nesting/rules-smoke.test.ts
@@ -23,7 +23,7 @@
       nestTarget = {Ethereum: tokenIdToAddress(collection, token)};
     });
   });
-  
+
   it('called for fungible', async () => {
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'Fungible',decimalPoints:0}});
@@ -39,7 +39,7 @@
   it('called for nonfungible', async () => {
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      await expect(executeTransaction(api, alice, api.tx.unique.createItem(collection, nestTarget, {NFT: {ConstData: [], VariableData: {}}})))
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(collection, nestTarget, {NFT: {ConstData: []}})))
         .to.be.rejectedWith(/^common\.SourceCollectionIsNotAllowedToNest$/);
 
       const token = await createItemExpectSuccess(alice, collection, 'NFT', {Substrate: alice.address});
@@ -51,7 +51,7 @@
   it('called for refungible', async () => {
     await usingApi(async api => {
       const collection = await createCollectionExpectSuccess({mode: {type: 'ReFungible'}});
-      await expect(executeTransaction(api, alice, api.tx.unique.createItem(collection, nestTarget, {ReFungible: {ConstData: [], VariableData: {}}})))
+      await expect(executeTransaction(api, alice, api.tx.unique.createItem(collection, nestTarget, {ReFungible: {ConstData: []}})))
         .to.be.rejectedWith(/^common\.SourceCollectionIsNotAllowedToNest$/);
 
       const token = await createItemExpectSuccess(alice, collection, 'ReFungible', {Substrate: alice.address});
@@ -60,4 +60,3 @@
     });
   });
 });
-  
\ No newline at end of file
deletedtests/src/setVariableMetaData.test.tsdiffbeforeafterboth
--- a/tests/src/setVariableMetaData.test.ts
+++ /dev/null
@@ -1,150 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-import {IKeyringPair} from '@polkadot/types/types';
-import chai from 'chai';
-import chaiAsPromised from 'chai-as-promised';
-import privateKey from './substrate/privateKey';
-import usingApi from './substrate/substrate-api';
-import {
-  burnItemExpectSuccess,
-  createCollectionExpectSuccess,
-  createItemExpectSuccess,
-  destroyCollectionExpectSuccess,
-  findNotExistingCollection,
-  setVariableMetaDataExpectFailure,
-  setVariableMetaDataExpectSuccess,
-  addCollectionAdminExpectSuccess,
-  setMetadataUpdatePermissionFlagExpectSuccess,
-  getVariableMetadata,
-} from './util/helpers';
-
-chai.use(chaiAsPromised);
-const expect = chai.expect;
-
-describe('Integration Test setVariableMetaData', () => {
-  const data = [1, 2, 254, 255];
-
-  let alice: IKeyringPair;
-  let collectionId: number;
-  let tokenId: number;
-  before(async () => {
-    await usingApi(async () => {
-      alice = privateKey('//Alice');
-      collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
-    });
-  });
-
-  it('execute setVariableMetaData', async () => {
-    await setVariableMetaDataExpectSuccess(alice, collectionId, tokenId, data);
-  });
-
-  it('verify data was set', async () => {
-    await usingApi(async api => {
-      expect(await getVariableMetadata(api, collectionId, tokenId)).to.deep.equal(data);
-    });
-  });
-});
-
-describe('Integration Test collection admin setVariableMetaData', () => {
-  const data = [1, 2, 254, 255];
-
-  let alice: IKeyringPair;
-  let bob: IKeyringPair;
-  let collectionId: number;
-  let tokenId: number;
-  before(async () => {
-    await usingApi(async () => {
-      alice = privateKey('//Alice');
-      bob = privateKey('//Bob');
-      collectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      tokenId = await createItemExpectSuccess(alice, collectionId, 'NFT');
-      await setMetadataUpdatePermissionFlagExpectSuccess(alice, collectionId, 'Admin');
-      await addCollectionAdminExpectSuccess(alice, collectionId, bob.address);
-    });
-  });
-
-  it('execute setVariableMetaData', async () => {
-    await setVariableMetaDataExpectSuccess(bob, collectionId, tokenId, data);
-  });
-
-  it('verify data was set', async () => {
-    await usingApi(async api => {
-      expect(await getVariableMetadata(api, collectionId, tokenId)).to.deep.equal(data);
-    });
-  });
-});
-
-describe('Negative Integration Test setVariableMetaData', () => {
-  const data = [1];
-
-  let alice: IKeyringPair;
-  let bob: IKeyringPair;
-
-  let validCollectionId: number;
-  let validTokenId: number;
-
-  before(async () => {
-    await usingApi(async () => {
-      alice = privateKey('//Alice');
-      bob = privateKey('//Bob');
-
-      validCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-      validTokenId = await createItemExpectSuccess(alice, validCollectionId, 'NFT');
-    });
-  });
-
-  it('fails on not existing collection id', async () => {
-    await usingApi(async api => {
-      const nonExistingCollectionId = await findNotExistingCollection(api);
-      await setVariableMetaDataExpectFailure(alice, nonExistingCollectionId, 1, data);
-    });
-  });
-  it('fails on removed collection id', async () => {
-    const removedCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    const removedCollectionTokenId = await createItemExpectSuccess(alice, removedCollectionId, 'NFT');
-
-    await destroyCollectionExpectSuccess(removedCollectionId);
-    await setVariableMetaDataExpectFailure(alice, removedCollectionId, removedCollectionTokenId, data);
-  });
-  it('fails on removed token', async () => {
-    const removedTokenCollectionId = await createCollectionExpectSuccess({mode: {type: 'NFT'}});
-    const removedTokenId = await createItemExpectSuccess(alice, removedTokenCollectionId, 'NFT');
-    await burnItemExpectSuccess(alice, removedTokenCollectionId, removedTokenId);
-
-    await setVariableMetaDataExpectFailure(alice, removedTokenCollectionId, removedTokenId, data);
-  });
-  it('fails on not existing token', async () => {
-    const nonExistingTokenId = validTokenId + 1;
-
-    await setVariableMetaDataExpectFailure(alice, validCollectionId, nonExistingTokenId, data);
-  });
-  it('fails on too long data', async () => {
-    const tooLongData = new Array(4097).fill(0xff);
-
-    await setVariableMetaDataExpectFailure(alice, validCollectionId, validTokenId, tooLongData);
-  });
-  it('fails on fungible token', async () => {
-    const fungibleCollectionId = await createCollectionExpectSuccess({mode: {type: 'Fungible', decimalPoints: 0}});
-    const fungibleTokenId = await createItemExpectSuccess(alice, fungibleCollectionId, 'Fungible');
-
-    await setVariableMetaDataExpectFailure(alice, fungibleCollectionId, fungibleTokenId, data);
-  });
-  it('fails on bad sender', async () => {
-    await setVariableMetaDataExpectFailure(bob, validCollectionId, validTokenId, data);
-  });
-});
deletedtests/src/setVariableMetadataSponsoringRateLimit.test.tsdiffbeforeafterboth
--- a/tests/src/setVariableMetadataSponsoringRateLimit.test.ts
+++ /dev/null
@@ -1,121 +0,0 @@
-// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.
-// This file is part of Unique Network.
-
-// Unique Network is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Unique Network is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.
-
-import {IKeyringPair} from '@polkadot/types/types';
-import {expect} from 'chai';
-import privateKey from './substrate/privateKey';
-import usingApi from './substrate/substrate-api';
-import {
-  confirmSponsorshipExpectSuccess,
-  createCollectionExpectSuccess,
-  createItemExpectSuccess,
-  findUnusedAddress,
-  getDetailedCollectionInfo,
-  setCollectionLimitsExpectSuccess,
-  setCollectionSponsorExpectSuccess,
-  setVariableMetaDataExpectFailure,
-  setVariableMetaDataExpectSuccess,
-} from './util/helpers';
-
-describe('Integration Test setVariableMetadataSponsoringRateLimit', () => {
-  let alice: IKeyringPair;
-  let userWithNoBalance: IKeyringPair;
-
-  before(async () => {
-    await usingApi(async (api) => {
-      alice = privateKey('//Alice');
-      userWithNoBalance = await findUnusedAddress(api);
-    });
-  });
-
-  it('sponsored setVariableMetaData can be called twice with pause for free', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId);
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      sponsoredDataRateLimit: {Blocks: 0},
-    });
-
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', userWithNoBalance.address);
-    await setVariableMetaDataExpectSuccess(userWithNoBalance, collectionId, itemId, [1, 2, 3]);
-    await setVariableMetaDataExpectSuccess(userWithNoBalance, collectionId, itemId, [1, 2, 3]);
-  });
-
-  it('sponsored setVariableMetaData can\'t be called twice without pause for free', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId);
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      sponsoredDataRateLimit: {Blocks: 10},
-    });
-
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', userWithNoBalance.address);
-    await setVariableMetaDataExpectSuccess(userWithNoBalance, collectionId, itemId, [1, 2, 3]);
-    await setVariableMetaDataExpectFailure(userWithNoBalance, collectionId, itemId, [1, 2, 3]);
-  });
-
-  it('sponsored setVariableMetaData can\'t be called for free with variable metadata above collection limits', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId);
-    await setCollectionLimitsExpectSuccess(alice, collectionId, {
-      sponsoredDataRateLimit: {Blocks: 0},
-      sponsoredDataSize: 1,
-    });
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', userWithNoBalance.address);
-
-    await setVariableMetaDataExpectSuccess(userWithNoBalance, collectionId, itemId, [1]);
-    await setVariableMetaDataExpectFailure(userWithNoBalance, collectionId, itemId, [1, 2]);
-  });
-
-  it('Default value of rate limit does not sponsor setting variable metadata', async () => {
-    const collectionId = await createCollectionExpectSuccess();
-    await setCollectionSponsorExpectSuccess(collectionId, alice.address);
-    await confirmSponsorshipExpectSuccess(collectionId);
-
-    const itemId = await createItemExpectSuccess(alice, collectionId, 'NFT', userWithNoBalance.address);
-    await setVariableMetaDataExpectFailure(userWithNoBalance, collectionId, itemId, [1]);
-  });
-
-  it('sponsoring of data is disabled by default', async () => {
-    await usingApi(async api => {
-      const collectionId = await createCollectionExpectSuccess();
-
-      const collection = (await getDetailedCollectionInfo(api, collectionId))!;
-      // limit is none = default is used
-      expect(collection?.limits.sponsoredDataRateLimit.isNone);
-    });
-  });
-
-  it('sponsoring can be disabled explicitly', async () => {
-    await usingApi(async api => {
-      const collectionId = await createCollectionExpectSuccess();
-
-      await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsoredDataRateLimit: {Blocks: 6}});
-      {
-        const collection = (await getDetailedCollectionInfo(api, collectionId))!;
-        expect(collection?.limits.sponsoredDataRateLimit.unwrap().asBlocks.toNumber()).to.equal(6);
-      }
-
-      await setCollectionLimitsExpectSuccess(alice, collectionId, {sponsoredDataRateLimit: 'SponsoringDisabled'});
-      {
-        const collection = (await getDetailedCollectionInfo(api, collectionId))!;
-        // disabled sponsoring = default value
-        expect(collection?.limits.sponsoredDataRateLimit.unwrap().isNone).to.true;
-      }
-    });
-  });
-});
modifiedtests/src/util/helpers.tsdiffbeforeafterboth
--- a/tests/src/util/helpers.ts
+++ b/tests/src/util/helpers.ts
@@ -142,7 +142,6 @@
 export interface IReFungibleTokenDataType {
   owner: IReFungibleOwner[];
   constData: number[];
-  variableData: number[];
 }
 
 export function uniqueEventMessage(events: EventRecord[]): IGetMessage {
@@ -648,28 +647,6 @@
     const sender = privateKey(senderSeed);
     const tx = api.tx.unique.confirmSponsorship(collectionId);
     await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
-  });
-}
-
-export async function setMetadataUpdatePermissionFlagExpectSuccess(sender: IKeyringPair, collectionId: number, flag: string) {
-
-  await usingApi(async (api) => {
-    const tx = api.tx.unique.setMetaUpdatePermissionFlag(collectionId, flag as any);
-    const events = await submitTransactionAsync(sender, tx);
-    const result = getGenericResult(events);
-
-    expect(result.success).to.be.true;
-  });
-}
-
-export async function setMetadataUpdatePermissionFlagExpectFailure(sender: IKeyringPair, collectionId: number, flag: string) {
-
-  await usingApi(async (api) => {
-    const tx = api.tx.unique.setMetaUpdatePermissionFlag(collectionId, flag as any);
-    const events = await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
-    const result = getGenericResult(events);
-
-    expect(result.success).to.be.false;
   });
 }
 
@@ -794,23 +771,6 @@
   });
 }
 
-export async function setVariableMetaDataExpectSuccess(sender: IKeyringPair, collectionId: number, itemId: number, data: number[]) {
-  await usingApi(async (api) => {
-    const tx = api.tx.unique.setVariableMetaData(collectionId, itemId, '0x' + Buffer.from(data).toString('hex'));
-    const events = await submitTransactionAsync(sender, tx);
-    const result = getGenericResult(events);
-
-    expect(result.success).to.be.true;
-  });
-}
-
-export async function setVariableMetaDataExpectFailure(sender: IKeyringPair, collectionId: number, itemId: number, data: number[]) {
-  await usingApi(async (api) => {
-    const tx = api.tx.unique.setVariableMetaData(collectionId, itemId, '0x' + Buffer.from(data).toString('hex'));
-    await expect(submitTransactionExpectFailAsync(sender, tx)).to.be.rejected;
-  });
-}
-
 export async function setOffchainSchemaExpectSuccess(sender: IKeyringPair, collectionId: number, data: number[]) {
   await usingApi(async (api) => {
     const tx = api.tx.unique.setOffchainSchema(collectionId, '0x' + Buffer.from(data).toString('hex'));
@@ -1137,13 +1097,6 @@
   collectionId: number,
 ): Promise<string[]> {
   return (await api.rpc.unique.adminlist(collectionId)).toHuman() as any;
-}
-export async function getVariableMetadata(
-  api: ApiPromise,
-  collectionId: number,
-  tokenId: number,
-): Promise<number[]> {
-  return [...(await api.rpc.unique.variableMetadata(collectionId, tokenId))];
 }
 export async function getConstMetadata(
   api: ApiPromise,
@@ -1182,10 +1135,10 @@
       const createData = {fungible: {value: 10}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     } else if (createMode === 'ReFungible') {
-      const createData = {refungible: {const_data: [], variable_data: [], pieces: 100}};
+      const createData = {refungible: {const_data: [], pieces: 100}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     } else {
-      const createData = {nft: {const_data: [], variable_data: []}};
+      const createData = {nft: {const_data: []}};
       tx = api.tx.unique.createItem(collectionId, to, createData as any);
     }