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

difftreelog

source

runtime/common/ethereum/sponsoring/refungible.rs9.5 KiBsourcehistory
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 pallet_common::CollectionHandle;20use pallet_evm::account::CrossAccountId;21use pallet_fungible::Config as FungibleConfig;22use pallet_refungible::Config as RefungibleConfig;23use pallet_nonfungible::Config as NonfungibleConfig;24use pallet_unique::Config as UniqueConfig;25use up_data_structs::{CreateItemData, CreateNftData, TokenId};2627use super::common;28use crate::runtime_common::sponsoring::*;2930use pallet_refungible::{31	erc::{32		ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,33		ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,34		UniqueRefungibleCall,35	},36	erc_token::{37		ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,38		UniqueRefungibleTokenCall,39	},40};4142pub fn call_sponsor<T>(43	call: UniqueRefungibleCall<T>,44	collection: CollectionHandle<T>,45	who: &T::CrossAccountId,46) -> Option<()>47where48	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,49{50	use UniqueRefungibleCall::*;5152	match call {53		// Readonly54		ERC165Call(_, _) => None,5556		ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),57		ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),58		ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),59		Collection(call) => common::collection_call_sponsor(call, collection, who),60		ERC721(call) => erc721::call_sponsor(call, collection, who),61		ERC721UniqueExtensions(call) => {62			erc721::unique_extensions_call_sponsor(call, collection, who)63		}64		ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),65		TokenProperties(call) => token_properties_call_sponsor(call, collection, who),66	}67}6869pub fn token_properties_call_sponsor<T>(70	call: TokenPropertiesCall<T>,71	collection: CollectionHandle<T>,72	who: &T::CrossAccountId,73) -> Option<()>74where75	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,76{77	use TokenPropertiesCall::*;7879	match call {80		// Readonly81		ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8283		// Not sponsored84		SetTokenPropertyPermission { .. }85		| SetTokenPropertyPermissions { .. }86		| SetProperties { .. }87		| DeleteProperty { .. }88		| DeleteProperties { .. } => None,8990		SetProperty {91			token_id,92			key,93			value,94			..95		} => {96			let token_id = TokenId::try_from(token_id).ok()?;97			withdraw_set_existing_token_property::<T>(98				&collection,99				who,100				&token_id,101				key.len() + value.len(),102			)103		}104	}105}106107pub fn token_call_sponsor<T>(108	call: UniqueRefungibleTokenCall<T>,109	token: RefungibleTokenHandle<T>,110	who: &T::CrossAccountId,111) -> Option<()>112where113	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,114{115	use UniqueRefungibleTokenCall::*;116117	match call {118		// Readonly119		ERC165Call(_, _) => None,120121		ERC20(call) => erc20::call_sponsor(call, token, who),122		ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),123		ERC1633(call) => erc1633::call_sponsor(call, token, who),124	}125}126127mod erc721 {128	use super::*;129130	pub fn call_sponsor<T>(131		call: ERC721Call<T>,132		collection: CollectionHandle<T>,133		_who: &T::CrossAccountId,134	) -> Option<()>135	where136		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,137	{138		use ERC721Call::*;139140		match call {141			// Readonly142			ERC165Call(_, _)143			| BalanceOf { .. }144			| OwnerOf { .. }145			| GetApproved { .. }146			| IsApprovedForAll { .. } => None,147148			// Not sponsored149			SafeTransferFromWithData { .. }150			| SafeTransferFrom { .. }151			| SetApprovalForAll { .. } => None,152153			TransferFrom { token_id, from, .. } => {154				let token_id = TokenId::try_from(token_id).ok()?;155				let from = T::CrossAccountId::from_eth(from);156				withdraw_transfer::<T>(&collection, &from, &token_id)157			}158159			// Not supported160			Approve { .. } => None,161		}162	}163164	pub fn enumerable_call_sponsor<T>(165		call: ERC721EnumerableCall<T>,166		_collection: CollectionHandle<T>,167		_who: &T::CrossAccountId,168	) -> Option<()>169	where170		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,171	{172		use ERC721EnumerableCall::*;173174		match call {175			// Readonly176			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {177				None178			}179		}180	}181182	pub fn burnable_call_sponsor<T>(183		call: ERC721BurnableCall<T>,184		_collection: CollectionHandle<T>,185		_who: &T::CrossAccountId,186	) -> Option<()>187	where188		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,189	{190		use ERC721BurnableCall::*;191192		match call {193			// Readonly194			ERC165Call(_, _) => None,195196			// Not sponsored197			Burn { .. } => None,198		}199	}200201	pub fn metadata_call_sponsor<T>(202		call: ERC721MetadataCall<T>,203		_collection: CollectionHandle<T>,204		_who: &T::CrossAccountId,205	) -> Option<()>206	where207		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,208	{209		use ERC721MetadataCall::*;210211		match call {212			// Readonly213			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,214		}215	}216217	pub fn unique_extensions_call_sponsor<T>(218		call: ERC721UniqueExtensionsCall<T>,219		collection: CollectionHandle<T>,220		who: &T::CrossAccountId,221	) -> Option<()>222	where223		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,224	{225		use ERC721UniqueExtensionsCall::*;226227		match call {228			// Readonly229			ERC165Call(_, _)230			| Name231			| Symbol232			| Description233			| CrossOwnerOf { .. }234			| OwnerOfCross { .. }235			| BalanceOfCross { .. }236			| Properties { .. }237			| NextTokenId238			| TokenContractAddress { .. }239			| CollectionHelperAddress => None,240241			// Not sponsored242			BurnFrom { .. }243			| BurnFromCross { .. }244			| MintBulk { .. }245			| MintBulkCross { .. }246			| MintBulkWithTokenUri { .. } => None,247248			MintCross { .. } => withdraw_create_item::<T>(249				&collection,250				who,251				&CreateItemData::NFT(CreateNftData::default()),252			),253254			TransferCross { token_id, .. }255			| TransferFromCross { token_id, .. }256			| Transfer { token_id, .. } => {257				let token_id = TokenId::try_from(token_id).ok()?;258				withdraw_transfer::<T>(&collection, who, &token_id)259			}260		}261	}262263	pub fn unique_mintable_call_sponsor<T>(264		call: ERC721UniqueMintableCall<T>,265		collection: CollectionHandle<T>,266		who: &T::CrossAccountId,267	) -> Option<()>268	where269		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,270	{271		use ERC721UniqueMintableCall::*;272273		match call {274			// Readonly275			ERC165Call(_, _) => None,276277			// Sponsored278			Mint { .. }279			| MintCheckId { .. }280			| MintWithTokenUri { .. }281			| MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(282				&collection,283				who,284				&CreateItemData::NFT(CreateNftData::default()),285			),286		}287	}288}289290/// Module for methods of refungible token291///292/// Existance of token should be checked before searching for sponsor293/// because RefungibleTokenHandle doesn't check token's existence upon creation294mod erc20 {295	use super::*;296297	pub fn call_sponsor<T>(298		call: ERC20Call<T>,299		token: RefungibleTokenHandle<T>,300		who: &T::CrossAccountId,301	) -> Option<()>302	where303		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,304	{305		use ERC20Call::*;306307		match call {308			// Readonly309			ERC165Call(_, _)310			| Name311			| Symbol312			| TotalSupply313			| Decimals314			| BalanceOf { .. }315			| Allowance { .. } => None,316317			Transfer { .. } => {318				let RefungibleTokenHandle(handle, token_id) = token;319				withdraw_transfer::<T>(&handle, who, &token_id)320			}321			TransferFrom { from, .. } => {322				let RefungibleTokenHandle(handle, token_id) = token;323				let from = T::CrossAccountId::from_eth(from);324				withdraw_transfer::<T>(&handle, &from, &token_id)325			}326			Approve { .. } => {327				let RefungibleTokenHandle(handle, token_id) = token;328				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)329			}330		}331	}332333	pub fn unique_extensions_call_sponsor<T>(334		call: ERC20UniqueExtensionsCall<T>,335		token: RefungibleTokenHandle<T>,336		who: &T::CrossAccountId,337	) -> Option<()>338	where339		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,340	{341		use ERC20UniqueExtensionsCall::*;342343		match call {344			// Readonly345			ERC165Call(_, _) => None,346347			// Not sponsored348			AllowanceCross { .. }349			| BalanceOfCross { .. }350			| BurnFrom { .. }351			| BurnFromCross { .. }352			| Repartition { .. } => None,353354			TransferCross { .. } | TransferFromCross { .. } => {355				let RefungibleTokenHandle(handle, token_id) = token;356				withdraw_transfer::<T>(&handle, who, &token_id)357			}358359			ApproveCross { .. } => {360				let RefungibleTokenHandle(handle, token_id) = token;361				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)362			}363		}364	}365}366367mod erc1633 {368	use super::*;369370	pub fn call_sponsor<T>(371		call: ERC1633Call<T>,372		_token: RefungibleTokenHandle<T>,373		_who: &T::CrossAccountId,374	) -> Option<()>375	where376		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,377	{378		use ERC1633Call::*;379380		match call {381			// Readonly382			ERC165Call(_, _) | ParentToken | ParentTokenId => None,383		}384	}385}