git.delta.rocks / unique-network / refs/commits / 47433dea42e5

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_token_property::<T>(&collection, who, &token_id, key.len() + value.len())98		}99	}100}101102pub fn token_call_sponsor<T>(103	call: UniqueRefungibleTokenCall<T>,104	token: RefungibleTokenHandle<T>,105	who: &T::CrossAccountId,106) -> Option<()>107where108	T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,109{110	use UniqueRefungibleTokenCall::*;111112	match call {113		// Readonly114		ERC165Call(_, _) => None,115116		ERC20(call) => erc20::call_sponsor(call, token, who),117		ERC20UniqueExtensions(call) => erc20::unique_extensions_call_sponsor(call, token, who),118		ERC1633(call) => erc1633::call_sponsor(call, token, who),119	}120}121122mod erc721 {123	use super::*;124125	pub fn call_sponsor<T>(126		call: ERC721Call<T>,127		collection: CollectionHandle<T>,128		_who: &T::CrossAccountId,129	) -> Option<()>130	where131		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,132	{133		use ERC721Call::*;134135		match call {136			// Readonly137			ERC165Call(_, _)138			| BalanceOf { .. }139			| OwnerOf { .. }140			| GetApproved { .. }141			| IsApprovedForAll { .. } => None,142143			// Not sponsored144			SafeTransferFromWithData { .. }145			| SafeTransferFrom { .. }146			| SetApprovalForAll { .. } => None,147148			TransferFrom { token_id, from, .. } => {149				let token_id = TokenId::try_from(token_id).ok()?;150				let from = T::CrossAccountId::from_eth(from);151				withdraw_transfer::<T>(&collection, &from, &token_id)152			}153154			// Not supported155			Approve { .. } => None,156		}157	}158159	pub fn enumerable_call_sponsor<T>(160		call: ERC721EnumerableCall<T>,161		_collection: CollectionHandle<T>,162		_who: &T::CrossAccountId,163	) -> Option<()>164	where165		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,166	{167		use ERC721EnumerableCall::*;168169		match call {170			// Readonly171			ERC165Call(_, _) | TokenByIndex { .. } | TokenOfOwnerByIndex { .. } | TotalSupply => {172				None173			}174		}175	}176177	pub fn burnable_call_sponsor<T>(178		call: ERC721BurnableCall<T>,179		_collection: CollectionHandle<T>,180		_who: &T::CrossAccountId,181	) -> Option<()>182	where183		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,184	{185		use ERC721BurnableCall::*;186187		match call {188			// Readonly189			ERC165Call(_, _) => None,190191			// Not sponsored192			Burn { .. } => None,193		}194	}195196	pub fn metadata_call_sponsor<T>(197		call: ERC721MetadataCall<T>,198		_collection: CollectionHandle<T>,199		_who: &T::CrossAccountId,200	) -> Option<()>201	where202		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,203	{204		use ERC721MetadataCall::*;205206		match call {207			// Readonly208			ERC165Call(_, _) | NameProxy | SymbolProxy | TokenUri { .. } => None,209		}210	}211212	pub fn unique_extensions_call_sponsor<T>(213		call: ERC721UniqueExtensionsCall<T>,214		collection: CollectionHandle<T>,215		who: &T::CrossAccountId,216	) -> Option<()>217	where218		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,219	{220		use ERC721UniqueExtensionsCall::*;221222		match call {223			// Readonly224			ERC165Call(_, _)225			| Name226			| Symbol227			| Description228			| CrossOwnerOf { .. }229			| OwnerOfCross { .. }230			| BalanceOfCross { .. }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				withdraw_transfer::<T>(&handle, who, &token_id)314			}315			TransferFrom { from, .. } => {316				let RefungibleTokenHandle(handle, token_id) = token;317				let from = T::CrossAccountId::from_eth(from);318				withdraw_transfer::<T>(&handle, &from, &token_id)319			}320			Approve { .. } => {321				let RefungibleTokenHandle(handle, token_id) = token;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			AllowanceCross { .. }343			| BalanceOfCross { .. }344			| BurnFrom { .. }345			| BurnFromCross { .. }346			| Repartition { .. } => None,347348			TransferCross { .. } | TransferFromCross { .. } => {349				let RefungibleTokenHandle(handle, token_id) = token;350				withdraw_transfer::<T>(&handle, who, &token_id)351			}352353			ApproveCross { .. } => {354				let RefungibleTokenHandle(handle, token_id) = token;355				withdraw_approve::<T>(&handle, who.as_sub(), &token_id)356			}357		}358	}359}360361mod erc1633 {362	use super::*;363364	pub fn call_sponsor<T>(365		call: ERC1633Call<T>,366		_token: RefungibleTokenHandle<T>,367		_who: &T::CrossAccountId,368	) -> Option<()>369	where370		T: UniqueConfig + FungibleConfig + NonfungibleConfig + RefungibleConfig,371	{372		use ERC1633Call::*;373374		match call {375			// Readonly376			ERC165Call(_, _) | ParentToken | ParentTokenId => None,377		}378	}379}