git.delta.rocks / unique-network / refs/heads / master

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_nonfungible::Config as NonfungibleConfig;23use pallet_refungible::{24	erc::{25		ERC721BurnableCall, ERC721Call, ERC721EnumerableCall, ERC721MetadataCall,26		ERC721UniqueExtensionsCall, ERC721UniqueMintableCall, TokenPropertiesCall,27		UniqueRefungibleCall,28	},29	erc_token::{30		ERC1633Call, ERC20Call, ERC20UniqueExtensionsCall, RefungibleTokenHandle,31		UniqueRefungibleTokenCall,32	},33	Config as RefungibleConfig,34};35use pallet_unique::Config as UniqueConfig;36use up_data_structs::{CreateItemData, CreateNftData, TokenId};3738use super::common;39use crate::runtime_common::sponsoring::*;4041pub fn call_sponsor<T>(42	call: UniqueRefungibleCall<T>,43	collection: CollectionHandle<T>,44	who: &T::CrossAccountId,45) -> Option<()>46where47	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,48{49	use UniqueRefungibleCall::*;5051	match call {52		// Readonly53		ERC165Call(_, _) => None,5455		ERC721Enumerable(call) => erc721::enumerable_call_sponsor(call, collection, who),56		ERC721Burnable(call) => erc721::burnable_call_sponsor(call, collection, who),57		ERC721Metadata(call) => erc721::metadata_call_sponsor(call, collection, who),58		Collection(call) => common::collection_call_sponsor(call, collection, who),59		ERC721(call) => erc721::call_sponsor(call, collection, who),60		ERC721UniqueExtensions(call) => {61			erc721::unique_extensions_call_sponsor(call, collection, who)62		}63		ERC721UniqueMintable(call) => erc721::unique_mintable_call_sponsor(call, collection, who),64		TokenProperties(call) => token_properties_call_sponsor(call, collection, who),65	}66}6768pub fn token_properties_call_sponsor<T>(69	call: TokenPropertiesCall<T>,70	collection: CollectionHandle<T>,71	who: &T::CrossAccountId,72) -> Option<()>73where74	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,75{76	use TokenPropertiesCall::*;7778	match call {79		// Readonly80		ERC165Call(_, _) | Property { .. } | TokenPropertyPermissions => None,8182		// Not sponsored83		SetTokenPropertyPermission { .. }84		| SetTokenPropertyPermissions { .. }85		| SetProperties { .. }86		| DeleteProperty { .. }87		| DeleteProperties { .. } => None,8889		SetProperty {90			token_id,91			key,92			value,93			..94		} => {95			let token_id = TokenId::try_from(token_id).ok()?;96			withdraw_set_existing_token_property::<T>(97				&collection,98				who,99				&token_id,100				key.len() + value.len(),101			)102		}103	}104}105106pub fn token_call_sponsor<T>(107	call: UniqueRefungibleTokenCall<T>,108	token: RefungibleTokenHandle<T>,109	who: &T::CrossAccountId,110) -> Option<()>111where112	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,113{114	use UniqueRefungibleTokenCall::*;115116	match call {117		// Readonly118		ERC165Call(_, _) => None,119120		ERC20(call) => erc20::call_sponsor(call, token, who),121		ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),122		ERC1633(call) => erc1633::call_sponsor(call, token, who),123	}124}125126mod erc721 {127	use super::*;128129	pub fn call_sponsor<T>(130		call: ERC721Call<T>,131		collection: CollectionHandle<T>,132		_who: &T::CrossAccountId,133	) -> Option<()>134	where135		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,136	{137		use ERC721Call::*;138139		match call {140			// Readonly141			ERC165Call(_, _)142			| BalanceOf { .. }143			| OwnerOf { .. }144			| GetApproved { .. }145			| IsApprovedForAll { .. } => None,146147			// Not sponsored148			SafeTransferFromWithData { .. }149			| SafeTransferFrom { .. }150			| SetApprovalForAll { .. } => None,151152			TransferFrom { token_id, from, .. } => {153				let token_id = TokenId::try_from(token_id).ok()?;154				let from = T::CrossAccountId::from_eth(from);155				withdraw_transfer::<T>(&collection, &from, &token_id)156			}157158			// Not supported159			Approve { .. } => None,160		}161	}162163	pub fn enumerable_call_sponsor<T>(164		call: ERC721EnumerableCall<T>,165		_collection: CollectionHandle<T>,166		_who: &T::CrossAccountId,167	) -> Option<()>168	where169		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,170	{171		use ERC721EnumerableCall::*;172173		match call {174			// Readonly175			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {176				None177			}178		}179	}180181	pub fn burnable_call_sponsor<T>(182		call: ERC721BurnableCall<T>,183		_collection: CollectionHandle<T>,184		_who: &T::CrossAccountId,185	) -> Option<()>186	where187		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,188	{189		use ERC721BurnableCall::*;190191		match call {192			// Readonly193			ERC165Call(_, _) => None,194195			// Not sponsored196			Burn { .. } => None,197		}198	}199200	pub fn metadata_call_sponsor<T>(201		call: ERC721MetadataCall<T>,202		_collection: CollectionHandle<T>,203		_who: &T::CrossAccountId,204	) -> Option<()>205	where206		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,207	{208		use ERC721MetadataCall::*;209210		match call {211			// Readonly212			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,213		}214	}215216	pub fn unique_extensions_call_sponsor<T>(217		call: ERC721UniqueExtensionsCall<T>,218		collection: CollectionHandle<T>,219		who: &T::CrossAccountId,220	) -> Option<()>221	where222		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,223	{224		use ERC721UniqueExtensionsCall::*;225226		match call {227			// Readonly228			ERC165Call(_, _)229			| Name230			| Symbol231			| Description232			| CrossOwnerOf { .. }233			| OwnerOfCross { .. }234			| BalanceOfCross { .. }235			| Properties { .. }236			| NextTokenId237			| TokenContractAddress { .. }238			| CollectionHelperAddress => None,239240			// Not sponsored241			BurnFrom { .. }242			| BurnFromCross { .. }243			| MintBulk { .. }244			| MintBulkCross { .. }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}