git.delta.rocks / unique-network / refs/commits / 7fac866e9347

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			| MintBulkWithTokenUri { .. } => None,246247			MintCross { .. } => withdraw_create_item::<T>(248				&collection,249				who,250				&CreateItemData::NFT(CreateNftData::default()),251			),252253			TransferCross { token_id, .. }254			| TransferFromCross { token_id, .. }255			| Transfer { token_id, .. } => {256				let token_id = TokenId::try_from(token_id).ok()?;257				withdraw_transfer::<T>(&collection, who, &token_id)258			}259		}260	}261262	pub fn unique_mintable_call_sponsor<T>(263		call: ERC721UniqueMintableCall<T>,264		collection: CollectionHandle<T>,265		who: &T::CrossAccountId,266	) -> Option<()>267	where268		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,269	{270		use ERC721UniqueMintableCall::*;271272		match call {273			// Readonly274			ERC165Call(_, _) => None,275276			// Sponsored277			Mint { .. }278			| MintCheckId { .. }279			| MintWithTokenUri { .. }280			| MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(281				&collection,282				who,283				&CreateItemData::NFT(CreateNftData::default()),284			),285		}286	}287}288289/// Module for methods of refungible token290///291/// Existance of token should be checked before searching for sponsor292/// because RefungibleTokenHandle doesn't check token's existence upon creation293mod erc20 {294	use super::*;295296	pub fn call_sponsor<T>(297		call: ERC20Call<T>,298		token: RefungibleTokenHandle<T>,299		who: &T::CrossAccountId,300	) -> Option<()>301	where302		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,303	{304		use ERC20Call::*;305306		match call {307			// Readonly308			ERC165Call(_, _)309			| Name310			| Symbol311			| TotalSupply312			| Decimals313			| BalanceOf { .. }314			| Allowance { .. } => None,315316			Transfer { .. } => {317				let RefungibleTokenHandle(handle, token_id) = token;318				withdraw_transfer::<T>(&handle, who, &token_id)319			}320			TransferFrom { from, .. } => {321				let RefungibleTokenHandle(handle, token_id) = token;322				let from = T::CrossAccountId::from_eth(from);323				withdraw_transfer::<T>(&handle, &from, &token_id)324			}325			Approve { .. } => {326				let RefungibleTokenHandle(handle, token_id) = token;327				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)328			}329		}330	}331332	pub fn unique_extensions_call_sponsor<T>(333		call: ERC20UniqueExtensionsCall<T>,334		token: RefungibleTokenHandle<T>,335		who: &T::CrossAccountId,336	) -> Option<()>337	where338		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,339	{340		use ERC20UniqueExtensionsCall::*;341342		match call {343			// Readonly344			ERC165Call(_, _) => None,345346			// Not sponsored347			AllowanceCross { .. }348			| BalanceOfCross { .. }349			| BurnFrom { .. }350			| BurnFromCross { .. }351			| Repartition { .. } => None,352353			TransferCross { .. } | TransferFromCross { .. } => {354				let RefungibleTokenHandle(handle, token_id) = token;355				withdraw_transfer::<T>(&handle, who, &token_id)356			}357358			ApproveCross { .. } => {359				let RefungibleTokenHandle(handle, token_id) = token;360				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)361			}362		}363	}364}365366mod erc1633 {367	use super::*;368369	pub fn call_sponsor<T>(370		call: ERC1633Call<T>,371		_token: RefungibleTokenHandle<T>,372		_who: &T::CrossAccountId,373	) -> Option<()>374	where375		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,376	{377		use ERC1633Call::*;378379		match call {380			// Readonly381			ERC165Call(_, _) | ParentToken | ParentTokenId => None,382		}383	}384}