git.delta.rocks / unique-network / refs/commits / 9b3f0425fea5

difftreelog

chore fix comments

Grigoriy Simonov2022-12-23parent: #f7442f8.patch.diff
in: master

3 files changed

modifiedpallets/common/src/eth.rsdiffbeforeafterboth
--- a/pallets/common/src/eth.rs
+++ b/pallets/common/src/eth.rs
@@ -125,9 +125,9 @@
 /// Ethereum representation of Optional value with CrossAddress.
 #[derive(Debug, Default, AbiCoder)]
 pub struct OptionCrossAddress {
-	/// TODO: field description
+	/// Is address set
 	pub status: bool,
-	/// TODO: field description
+	/// Address value
 	pub value: CrossAddress,
 }
 
modifiedpallets/refungible/src/erc_token.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc_token.rs
+++ b/pallets/refungible/src/erc_token.rs
@@ -43,6 +43,9 @@
 	TotalSupply, weights::WeightInfo,
 };
 
+/// Refungible token handle contains information about token's collection and id
+///
+/// RefungibleTokenHandle doesn't check token's existance upon creation
 pub struct RefungibleTokenHandle<T: Config>(pub RefungibleHandle<T>, pub TokenId);
 
 #[solidity_interface(name = ERC1633)]
modifiedruntime/common/ethereum/sponsoring/refungible.rsdiffbeforeafterboth
before · runtime/common/ethereum/sponsoring/refungible.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//! Implements EVM sponsoring logic via TransactionValidityHack1819use core::convert::TryInto;20use pallet_common::CollectionHandle;21use pallet_evm::account::CrossAccountId;22use pallet_fungible::Config as FungibleConfig;23use pallet_refungible::Config as RefungibleConfig;24use pallet_nonfungible::Config as NonfungibleConfig;25use pallet_unique::Config as UniqueConfig;26use up_data_structs::{CreateItemData, CreateNftData, TokenId};2728use super::common;29use crate::runtime_common::sponsoring::*;3031use pallet_refungible::{32	erc::{33		ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,34		ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,35		UniqueRefungibleCall,36	},37	erc_token::{38		ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,39		UniqueRefungibleTokenCall,40	},41};4243pub fn call_sponsor<T>(44	call: UniqueRefungibleCall<T>,45	collection: CollectionHandle<T>,46	who: &T::CrossAccountId,47) -> Option<()>48where49	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,50{51	use UniqueRefungibleCall::*;5253	match call {54		// Readonly55		ERC165Call(_, _) => None,5657		ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),58		ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),59		ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),60		Collection(call) => common::collection_call_sponsor(call, collection, who),61		ERC721(call) => erc721::call_sponsor(call, collection, who),62		ERC721UniqueExtensions(call) => {63			erc721::unique_extensions_call_sponsor(call, collection, who)64		}65		ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),66		TokenProperties(call) => token_properties_call_sponsor(call, collection, who),67	}68}6970pub fn token_properties_call_sponsor<T>(71	call: TokenPropertiesCall<T>,72	collection: CollectionHandle<T>,73	who: &T::CrossAccountId,74) -> Option<()>75where76	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,77{78	use TokenPropertiesCall::*;7980	match call {81		// Readonly82		ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8384		// Not sponsored85		SetTokenPropertyPermission { .. }86		| SetTokenPropertyPermissions { .. }87		| SetProperties { .. }88		| DeleteProperty { .. }89		| DeleteProperties { .. } => None,9091		SetProperty {92			token_id,93			key,94			value,95			..96		} => {97			let token_id = TokenId::try_from(token_id).ok()?;98			withdraw_set_token_property::<T>(&collection, &who, &token_id, key.len() + value.len())99		}100	}101}102103pub fn token_call_sponsor<T>(104	call: UniqueRefungibleTokenCall<T>,105	token: RefungibleTokenHandle<T>,106	who: &T::CrossAccountId,107) -> Option<()>108where109	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,110{111	use UniqueRefungibleTokenCall::*;112113	match call {114		// Readonly115		ERC165Call(_, _) => None,116117		ERC20(call) => erc20::call_sponsor(call, token, who),118		ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),119		ERC1633(call) => erc1633::call_sponsor(call, token, who),120	}121}122123mod erc721 {124	use super::*;125126	pub fn call_sponsor<T>(127		call: ERC721Call<T>,128		collection: CollectionHandle<T>,129		_who: &T::CrossAccountId,130	) -> Option<()>131	where132		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,133	{134		use ERC721Call::*;135136		match call {137			// Readonly138			ERC165Call(_, _)139			| BalanceOf { .. }140			| OwnerOf { .. }141			| GetApproved { .. }142			| IsApprovedForAll { .. }143			| CollectionHelperAddress => None,144145			// Not sponsored146			SafeTransferFromWithData { .. }147			| SafeTransferFrom { .. }148			| SetApprovalForAll { .. } => None,149150			TransferFrom { token_id, from, .. } => {151				let token_id = TokenId::try_from(token_id).ok()?;152				let from = T::CrossAccountId::from_eth(from);153				withdraw_transfer::<T>(&collection, &from, &token_id)154			}155156			// Not supported157			Approve { .. } => None,158		}159	}160161	pub fn enumerable_call_sponsor<T>(162		call: ERC721EnumerableCall<T>,163		_collection: CollectionHandle<T>,164		_who: &T::CrossAccountId,165	) -> Option<()>166	where167		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,168	{169		use ERC721EnumerableCall::*;170171		match call {172			// Readonly173			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {174				None175			}176		}177	}178179	pub fn burnable_call_sponsor<T>(180		call: ERC721BurnableCall<T>,181		_collection: CollectionHandle<T>,182		_who: &T::CrossAccountId,183	) -> Option<()>184	where185		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,186	{187		use ERC721BurnableCall::*;188189		match call {190			// Readonly191			ERC165Call(_, _) => None,192193			// Not sponsored194			Burn { .. } => None,195		}196	}197198	pub fn metadata_call_sponsor<T>(199		call: ERC721MetadataCall<T>,200		_collection: CollectionHandle<T>,201		_who: &T::CrossAccountId,202	) -> Option<()>203	where204		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,205	{206		use ERC721MetadataCall::*;207208		match call {209			// Readonly210			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,211		}212	}213214	pub fn unique_extensions_call_sponsor<T>(215		call: ERC721UniqueExtensionsCall<T>,216		collection: CollectionHandle<T>,217		who: &T::CrossAccountId,218	) -> Option<()>219	where220		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,221	{222		use ERC721UniqueExtensionsCall::*;223224		match call {225			// Readonly226			ERC165Call(_, _)227			| Name228			| Symbol229			| Description230			| CrossOwnerOf { .. }231			| Properties { .. }232			| NextTokenId233			| TokenContractAddress { .. } => None,234235			// Not sponsored236			BurnFrom { .. }237			| BurnFromCross { .. }238			| MintBulk { .. }239			| MintBulkWithTokenUri { .. } => None,240241			MintCross { .. } => withdraw_create_item::<T>(242				&collection,243				&who,244				&CreateItemData::NFT(CreateNftData::default()),245			),246247			TransferCross { token_id, .. }248			| TransferFromCross { token_id, .. }249			| Transfer { token_id, .. } => {250				let token_id = TokenId::try_from(token_id).ok()?;251				withdraw_transfer::<T>(&collection, &who, &token_id)252			}253		}254	}255256	pub fn unique_mintable_call_sponsor<T>(257		call: ERC721UniqueMintableCall<T>,258		collection: CollectionHandle<T>,259		who: &T::CrossAccountId,260	) -> Option<()>261	where262		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,263	{264		use ERC721UniqueMintableCall::*;265266		match call {267			// Readonly268			ERC165Call(_, _) | MintingFinished => None,269270			// Not sponsored271			FinishMinting => None,272273			Mint { .. }274			| MintCheckId { .. }275			| MintWithTokenUri { .. }276			| MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(277				&collection,278				&who,279				&CreateItemData::NFT(CreateNftData::default()),280			),281		}282	}283}284285mod erc20 {286	use super::*;287288	pub fn call_sponsor<T>(289		call: ERC20Call<T>,290		token: RefungibleTokenHandle<T>,291		who: &T::CrossAccountId,292	) -> Option<()>293	where294		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,295	{296		use ERC20Call::*;297298		match call {299			// Readonly300			ERC165Call(_, _)301			| Name302			| Symbol303			| TotalSupply304			| Decimals305			| BalanceOf { .. }306			| Allowance { .. } => None,307308			Transfer { .. } => {309				let RefungibleTokenHandle(handle, token_id) = token;310				let token_id = token_id.try_into().ok()?;311				withdraw_transfer::<T>(&handle, &who, &token_id)312			}313			TransferFrom { from, .. } => {314				let RefungibleTokenHandle(handle, token_id) = token;315				let token_id = token_id.try_into().ok()?;316				let from = T::CrossAccountId::from_eth(from);317				withdraw_transfer::<T>(&handle, &from, &token_id)318			}319			Approve { .. } => {320				let RefungibleTokenHandle(handle, token_id) = token;321				let token_id = token_id.try_into().ok()?;322				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)323			}324		}325	}326327	pub fn unique_extensions_call_sponsor<T>(328		call: ERC20UniqueExtensionsCall<T>,329		token: RefungibleTokenHandle<T>,330		who: &T::CrossAccountId,331	) -> Option<()>332	where333		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,334	{335		use ERC20UniqueExtensionsCall::*;336337		match call {338			// Readonly339			ERC165Call(_, _) => None,340341			// Not sponsored342			BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => None,343344			TransferCross { .. } | TransferFromCross { .. } => {345				let RefungibleTokenHandle(handle, token_id) = token;346				let token_id = token_id.try_into().ok()?;347				withdraw_transfer::<T>(&handle, &who, &token_id)348			}349350			ApproveCross { .. } => {351				let RefungibleTokenHandle(handle, token_id) = token;352				let token_id = token_id.try_into().ok()?;353				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)354			}355		}356	}357}358359mod erc1633 {360	use super::*;361362	pub fn call_sponsor<T>(363		call: ERC1633Call<T>,364		_token: RefungibleTokenHandle<T>,365		_who: &T::CrossAccountId,366	) -> Option<()>367	where368		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,369	{370		use ERC1633Call::*;371372		match call {373			// Readonly374			ERC165Call(_, _) | ParentToken | ParentTokenId => None,375		}376	}377}
after · runtime/common/ethereum/sponsoring/refungible.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//! Implements EVM sponsoring logic via TransactionValidityHack1819use core::convert::TryInto;20use pallet_common::CollectionHandle;21use pallet_evm::account::CrossAccountId;22use pallet_fungible::Config as FungibleConfig;23use pallet_refungible::Config as RefungibleConfig;24use pallet_nonfungible::Config as NonfungibleConfig;25use pallet_unique::Config as UniqueConfig;26use up_data_structs::{CreateItemData, CreateNftData, TokenId};2728use super::common;29use crate::runtime_common::sponsoring::*;3031use pallet_refungible::{32	erc::{33		ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,34		ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,35		UniqueRefungibleCall,36	},37	erc_token::{38		ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,39		UniqueRefungibleTokenCall,40	},41};4243pub fn call_sponsor<T>(44	call: UniqueRefungibleCall<T>,45	collection: CollectionHandle<T>,46	who: &T::CrossAccountId,47) -> Option<()>48where49	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,50{51	use UniqueRefungibleCall::*;5253	match call {54		// Readonly55		ERC165Call(_, _) => None,5657		ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),58		ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),59		ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),60		Collection(call) => common::collection_call_sponsor(call, collection, who),61		ERC721(call) => erc721::call_sponsor(call, collection, who),62		ERC721UniqueExtensions(call) => {63			erc721::unique_extensions_call_sponsor(call, collection, who)64		}65		ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),66		TokenProperties(call) => token_properties_call_sponsor(call, collection, who),67	}68}6970pub fn token_properties_call_sponsor<T>(71	call: TokenPropertiesCall<T>,72	collection: CollectionHandle<T>,73	who: &T::CrossAccountId,74) -> Option<()>75where76	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,77{78	use TokenPropertiesCall::*;7980	match call {81		// Readonly82		ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8384		// Not sponsored85		SetTokenPropertyPermission { .. }86		| SetTokenPropertyPermissions { .. }87		| SetProperties { .. }88		| DeleteProperty { .. }89		| DeleteProperties { .. } => None,9091		SetProperty {92			token_id,93			key,94			value,95			..96		} => {97			let token_id = TokenId::try_from(token_id).ok()?;98			withdraw_set_token_property::<T>(&collection, &who, &token_id, key.len() + value.len())99		}100	}101}102103pub fn token_call_sponsor<T>(104	call: UniqueRefungibleTokenCall<T>,105	token: RefungibleTokenHandle<T>,106	who: &T::CrossAccountId,107) -> Option<()>108where109	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,110{111	use UniqueRefungibleTokenCall::*;112113	match call {114		// Readonly115		ERC165Call(_, _) => None,116117		ERC20(call) => erc20::call_sponsor(call, token, who),118		ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),119		ERC1633(call) => erc1633::call_sponsor(call, token, who),120	}121}122123mod erc721 {124	use super::*;125126	pub fn call_sponsor<T>(127		call: ERC721Call<T>,128		collection: CollectionHandle<T>,129		_who: &T::CrossAccountId,130	) -> Option<()>131	where132		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,133	{134		use ERC721Call::*;135136		match call {137			// Readonly138			ERC165Call(_, _)139			| BalanceOf { .. }140			| OwnerOf { .. }141			| GetApproved { .. }142			| IsApprovedForAll { .. }143			| CollectionHelperAddress => None,144145			// Not sponsored146			SafeTransferFromWithData { .. }147			| SafeTransferFrom { .. }148			| SetApprovalForAll { .. } => None,149150			TransferFrom { token_id, from, .. } => {151				let token_id = TokenId::try_from(token_id).ok()?;152				let from = T::CrossAccountId::from_eth(from);153				withdraw_transfer::<T>(&collection, &from, &token_id)154			}155156			// Not supported157			Approve { .. } => None,158		}159	}160161	pub fn enumerable_call_sponsor<T>(162		call: ERC721EnumerableCall<T>,163		_collection: CollectionHandle<T>,164		_who: &T::CrossAccountId,165	) -> Option<()>166	where167		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,168	{169		use ERC721EnumerableCall::*;170171		match call {172			// Readonly173			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {174				None175			}176		}177	}178179	pub fn burnable_call_sponsor<T>(180		call: ERC721BurnableCall<T>,181		_collection: CollectionHandle<T>,182		_who: &T::CrossAccountId,183	) -> Option<()>184	where185		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,186	{187		use ERC721BurnableCall::*;188189		match call {190			// Readonly191			ERC165Call(_, _) => None,192193			// Not sponsored194			Burn { .. } => None,195		}196	}197198	pub fn metadata_call_sponsor<T>(199		call: ERC721MetadataCall<T>,200		_collection: CollectionHandle<T>,201		_who: &T::CrossAccountId,202	) -> Option<()>203	where204		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,205	{206		use ERC721MetadataCall::*;207208		match call {209			// Readonly210			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,211		}212	}213214	pub fn unique_extensions_call_sponsor<T>(215		call: ERC721UniqueExtensionsCall<T>,216		collection: CollectionHandle<T>,217		who: &T::CrossAccountId,218	) -> Option<()>219	where220		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,221	{222		use ERC721UniqueExtensionsCall::*;223224		match call {225			// Readonly226			ERC165Call(_, _)227			| Name228			| Symbol229			| Description230			| CrossOwnerOf { .. }231			| Properties { .. }232			| NextTokenId233			| TokenContractAddress { .. } => None,234235			// Not sponsored236			BurnFrom { .. }237			| BurnFromCross { .. }238			| MintBulk { .. }239			| MintBulkWithTokenUri { .. } => None,240241			MintCross { .. } => withdraw_create_item::<T>(242				&collection,243				&who,244				&CreateItemData::NFT(CreateNftData::default()),245			),246247			TransferCross { token_id, .. }248			| TransferFromCross { token_id, .. }249			| Transfer { token_id, .. } => {250				let token_id = TokenId::try_from(token_id).ok()?;251				withdraw_transfer::<T>(&collection, &who, &token_id)252			}253		}254	}255256	pub fn unique_mintable_call_sponsor<T>(257		call: ERC721UniqueMintableCall<T>,258		collection: CollectionHandle<T>,259		who: &T::CrossAccountId,260	) -> Option<()>261	where262		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,263	{264		use ERC721UniqueMintableCall::*;265266		match call {267			// Readonly268			ERC165Call(_, _) | MintingFinished => None,269270			// Not sponsored271			FinishMinting => None,272273			Mint { .. }274			| MintCheckId { .. }275			| MintWithTokenUri { .. }276			| MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(277				&collection,278				&who,279				&CreateItemData::NFT(CreateNftData::default()),280			),281		}282	}283}284285/// Module for methods of refungible token286///287/// Existance of token should be checked before searching for sponsor288/// because RefungibleTokenHandle doesn't check token's existence upon creation289mod erc20 {290	use super::*;291292	pub fn call_sponsor<T>(293		call: ERC20Call<T>,294		token: RefungibleTokenHandle<T>,295		who: &T::CrossAccountId,296	) -> Option<()>297	where298		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,299	{300		use ERC20Call::*;301302		match call {303			// Readonly304			ERC165Call(_, _)305			| Name306			| Symbol307			| TotalSupply308			| Decimals309			| BalanceOf { .. }310			| Allowance { .. } => None,311312			Transfer { .. } => {313				let RefungibleTokenHandle(handle, token_id) = token;314				let token_id = token_id.try_into().ok()?;315				withdraw_transfer::<T>(&handle, &who, &token_id)316			}317			TransferFrom { from, .. } => {318				let RefungibleTokenHandle(handle, token_id) = token;319				let token_id = token_id.try_into().ok()?;320				let from = T::CrossAccountId::from_eth(from);321				withdraw_transfer::<T>(&handle, &from, &token_id)322			}323			Approve { .. } => {324				let RefungibleTokenHandle(handle, token_id) = token;325				let token_id = token_id.try_into().ok()?;326				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)327			}328		}329	}330331	pub fn unique_extensions_call_sponsor<T>(332		call: ERC20UniqueExtensionsCall<T>,333		token: RefungibleTokenHandle<T>,334		who: &T::CrossAccountId,335	) -> Option<()>336	where337		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,338	{339		use ERC20UniqueExtensionsCall::*;340341		match call {342			// Readonly343			ERC165Call(_, _) => None,344345			// Not sponsored346			BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => None,347348			TransferCross { .. } | TransferFromCross { .. } => {349				let RefungibleTokenHandle(handle, token_id) = token;350				let token_id = token_id.try_into().ok()?;351				withdraw_transfer::<T>(&handle, &who, &token_id)352			}353354			ApproveCross { .. } => {355				let RefungibleTokenHandle(handle, token_id) = token;356				let token_id = token_id.try_into().ok()?;357				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)358			}359		}360	}361}362363mod erc1633 {364	use super::*;365366	pub fn call_sponsor<T>(367		call: ERC1633Call<T>,368		_token: RefungibleTokenHandle<T>,369		_who: &T::CrossAccountId,370	) -> Option<()>371	where372		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,373	{374		use ERC1633Call::*;375376		match call {377			// Readonly378			ERC165Call(_, _) | ParentToken | ParentTokenId => None,379		}380	}381}