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

difftreelog

source

runtime/common/ethereum/sponsoring/refungible.rs9.7 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 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 { .. } => None,143144			// Not sponsored145			SafeTransferFromWithData { .. }146			| SafeTransferFrom { .. }147			| SetApprovalForAll { .. } => None,148149			TransferFrom { token_id, from, .. } => {150				let token_id = TokenId::try_from(token_id).ok()?;151				let from = T::CrossAccountId::from_eth(from);152				withdraw_transfer::<T>(&collection, &from, &token_id)153			}154155			// Not supported156			Approve { .. } => None,157		}158	}159160	pub fn enumerable_call_sponsor<T>(161		call: ERC721EnumerableCall<T>,162		_collection: CollectionHandle<T>,163		_who: &T::CrossAccountId,164	) -> Option<()>165	where166		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,167	{168		use ERC721EnumerableCall::*;169170		match call {171			// Readonly172			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {173				None174			}175		}176	}177178	pub fn burnable_call_sponsor<T>(179		call: ERC721BurnableCall<T>,180		_collection: CollectionHandle<T>,181		_who: &T::CrossAccountId,182	) -> Option<()>183	where184		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,185	{186		use ERC721BurnableCall::*;187188		match call {189			// Readonly190			ERC165Call(_, _) => None,191192			// Not sponsored193			Burn { .. } => None,194		}195	}196197	pub fn metadata_call_sponsor<T>(198		call: ERC721MetadataCall<T>,199		_collection: CollectionHandle<T>,200		_who: &T::CrossAccountId,201	) -> Option<()>202	where203		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,204	{205		use ERC721MetadataCall::*;206207		match call {208			// Readonly209			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,210		}211	}212213	pub fn unique_extensions_call_sponsor<T>(214		call: ERC721UniqueExtensionsCall<T>,215		collection: CollectionHandle<T>,216		who: &T::CrossAccountId,217	) -> Option<()>218	where219		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,220	{221		use ERC721UniqueExtensionsCall::*;222223		match call {224			// Readonly225			ERC165Call(_, _)226			| Name227			| Symbol228			| Description229			| CrossOwnerOf { .. }230			| CrossBalanceOf { .. }231			| Properties { .. }232			| NextTokenId233			| TokenContractAddress { .. }234			| CollectionHelperAddress => None,235236			// Not sponsored237			BurnFrom { .. }238			| BurnFromCross { .. }239			| MintBulk { .. }240			| MintBulkWithTokenUri { .. } => None,241242			MintCross { .. } => withdraw_create_item::<T>(243				&collection,244				&who,245				&CreateItemData::NFT(CreateNftData::default()),246			),247248			TransferCross { token_id, .. }249			| TransferFromCross { token_id, .. }250			| Transfer { token_id, .. } => {251				let token_id = TokenId::try_from(token_id).ok()?;252				withdraw_transfer::<T>(&collection, &who, &token_id)253			}254		}255	}256257	pub fn unique_mintable_call_sponsor<T>(258		call: ERC721UniqueMintableCall<T>,259		collection: CollectionHandle<T>,260		who: &T::CrossAccountId,261	) -> Option<()>262	where263		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,264	{265		use ERC721UniqueMintableCall::*;266267		match call {268			// Readonly269			ERC165Call(_, _) => None,270271			// Sponsored272			Mint { .. }273			| MintCheckId { .. }274			| MintWithTokenUri { .. }275			| MintWithTokenUriCheckId { .. } => withdraw_create_item::<T>(276				&collection,277				&who,278				&CreateItemData::NFT(CreateNftData::default()),279			),280		}281	}282}283284/// Module for methods of refungible token285///286/// Existance of token should be checked before searching for sponsor287/// because RefungibleTokenHandle doesn't check token's existence upon creation288mod erc20 {289	use super::*;290291	pub fn call_sponsor<T>(292		call: ERC20Call<T>,293		token: RefungibleTokenHandle<T>,294		who: &T::CrossAccountId,295	) -> Option<()>296	where297		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,298	{299		use ERC20Call::*;300301		match call {302			// Readonly303			ERC165Call(_, _)304			| Name305			| Symbol306			| TotalSupply307			| Decimals308			| BalanceOf { .. }309			| Allowance { .. } => None,310311			Transfer { .. } => {312				let RefungibleTokenHandle(handle, token_id) = token;313				let token_id = token_id.try_into().ok()?;314				withdraw_transfer::<T>(&handle, &who, &token_id)315			}316			TransferFrom { from, .. } => {317				let RefungibleTokenHandle(handle, token_id) = token;318				let token_id = token_id.try_into().ok()?;319				let from = T::CrossAccountId::from_eth(from);320				withdraw_transfer::<T>(&handle, &from, &token_id)321			}322			Approve { .. } => {323				let RefungibleTokenHandle(handle, token_id) = token;324				let token_id = token_id.try_into().ok()?;325				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)326			}327		}328	}329330	pub fn unique_extensions_call_sponsor<T>(331		call: ERC20UniqueExtensionsCall<T>,332		token: RefungibleTokenHandle<T>,333		who: &T::CrossAccountId,334	) -> Option<()>335	where336		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,337	{338		use ERC20UniqueExtensionsCall::*;339340		match call {341			// Readonly342			ERC165Call(_, _) => None,343344			// Not sponsored345			AllowanceCross { .. } | BurnFrom { .. } | BurnFromCross { .. } | Repartition { .. } => {346				None347			}348349			TransferCross { .. } | TransferFromCross { .. } => {350				let RefungibleTokenHandle(handle, token_id) = token;351				let token_id = token_id.try_into().ok()?;352				withdraw_transfer::<T>(&handle, &who, &token_id)353			}354355			ApproveCross { .. } => {356				let RefungibleTokenHandle(handle, token_id) = token;357				let token_id = token_id.try_into().ok()?;358				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)359			}360		}361	}362}363364mod erc1633 {365	use super::*;366367	pub fn call_sponsor<T>(368		call: ERC1633Call<T>,369		_token: RefungibleTokenHandle<T>,370		_who: &T::CrossAccountId,371	) -> Option<()>372	where373		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,374	{375		use ERC1633Call::*;376377		match call {378			// Readonly379			ERC165Call(_, _) | ParentToken | ParentTokenId => None,380		}381	}382}