git.delta.rocks / unique-network / refs/commits / 137320b42c82

difftreelog

source

pallets/balances-adapter/src/lib.rs5.6 KiBsourcehistory
1#![cfg_attr(not(feature = "std"), no_std)]23extern crate alloc;4use core::ops::Deref;56use frame_support::sp_runtime::DispatchResult;7pub use pallet::*;8use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};910pub mod common;11pub mod erc;1213pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;1415/// Handle for native fungible collection16pub struct NativeFungibleHandle<T: Config>(SubstrateRecorder<T>);17impl<T: Config> NativeFungibleHandle<T> {18	/// Creates a handle19	pub fn new() -> NativeFungibleHandle<T> {20		Self(SubstrateRecorder::new(u64::MAX))21	}2223	/// Creates a handle24	pub fn new_with_gas_limit(gas_limit: u64) -> NativeFungibleHandle<T> {25		Self(SubstrateRecorder::new(gas_limit))26	}2728	/// Check if the collection is internal29	pub fn check_is_internal(&self) -> DispatchResult {30		Ok(())31	}32}3334impl<T: Config> Default for NativeFungibleHandle<T> {35	fn default() -> Self {36		Self::new()37	}38}3940impl<T: Config> WithRecorder<T> for NativeFungibleHandle<T> {41	fn recorder(&self) -> &pallet_evm_coder_substrate::SubstrateRecorder<T> {42		&self.043	}44	fn into_recorder(self) -> pallet_evm_coder_substrate::SubstrateRecorder<T> {45		self.046	}47}4849impl<T: Config> Deref for NativeFungibleHandle<T> {50	type Target = SubstrateRecorder<T>;5152	fn deref(&self) -> &Self::Target {53		&self.054	}55}56#[frame_support::pallet]57pub mod pallet {58	use alloc::string::String;5960	use frame_support::{61		dispatch::PostDispatchInfo,62		ensure,63		pallet_prelude::*,64		traits::{65			fungible::{Inspect, Mutate},66			tokens::Preservation,67			Get,68		},69	};70	use pallet_balances::WeightInfo;71	use pallet_common::{erc::CrossAccountId, Error as CommonError, Pallet as PalletCommon};72	use pallet_structure::Pallet as PalletStructure;73	use sp_core::U256;74	use sp_runtime::DispatchError;75	use up_data_structs::{budget::Budget, mapping::TokenAddressMapping};7677	use super::*;7879	#[pallet::config]80	pub trait Config:81		frame_system::Config82		+ pallet_evm_coder_substrate::Config83		+ pallet_common::Config84		+ pallet_structure::Config85	{86		/// Inspect from `pallet_balances`87		type Inspect: frame_support::traits::tokens::fungible::Inspect<88			Self::AccountId,89			Balance = Self::CurrencyBalance,90		>;9192		/// Mutate from `pallet_balances`93		type Mutate: frame_support::traits::tokens::fungible::Mutate<94			Self::AccountId,95			Balance = Self::CurrencyBalance,96		>;9798		/// Balance type of chain99		type CurrencyBalance: Into<U256> + TryFrom<U256> + TryFrom<u128> + Into<u128>;100101		/// Decimals of balance102		type Decimals: Get<u8>;103		/// Collection name104		type Name: Get<String>;105		/// Collection symbol106		type Symbol: Get<String>;107108		/// Weight information109		type WeightInfo: WeightInfo;110	}111	#[pallet::pallet]112	pub struct Pallet<T>(_);113114	impl<T: Config> Pallet<T> {115		pub fn balance_of(account: &T::CrossAccountId) -> u128 {116			T::Inspect::balance(account.as_sub()).into()117		}118119		pub fn total_balance(account: &T::CrossAccountId) -> u128 {120			T::Inspect::total_balance(account.as_sub()).into()121		}122123		pub fn total_issuance() -> u128 {124			T::Inspect::total_issuance().into()125		}126127		/// Checks if a non-owner has (enough) allowance from the owner to perform operations on the tokens.128		/// Returns the expected remaining allowance - it should be set manually if the transaction proceeds.129		///130		/// - `spender`: CrossAccountId who has the allowance rights.131		/// - `from`: The owner of the tokens who sets the allowance.132		/// - `nesting_budget`: Limit for searching parents in-depth to check ownership.133		fn check_allowed(134			spender: &T::CrossAccountId,135			from: &T::CrossAccountId,136			nesting_budget: &dyn Budget,137		) -> Result<u128, DispatchError> {138			if let Some((collection_id, token_id)) =139				T::CrossTokenAddressMapping::address_to_token(from)140			{141				ensure!(142					<PalletStructure<T>>::check_indirectly_owned(143						spender.clone(),144						collection_id,145						token_id,146						None,147						nesting_budget148					)?,149					<CommonError<T>>::ApprovedValueTooLow,150				);151			} else if !spender.conv_eq(from) {152				return Ok(0);153			}154155			Ok(Self::balance_of(from))156		}157158		/// Transfers the specified amount of tokens.159		///160		/// - `from`: Owner of tokens to transfer.161		/// - `to`: Recepient of transfered tokens.162		/// - `amount`: Amount of tokens to transfer.163		pub fn transfer(164			from: &T::CrossAccountId,165			to: &T::CrossAccountId,166			amount: u128,167		) -> DispatchResultWithPostInfo {168			<PalletCommon<T>>::ensure_correct_receiver(to)?;169170			if from != to && amount != 0 {171				let amount = amount172					.try_into()173					.map_err(|_| sp_runtime::ArithmeticError::Overflow)?;174				T::Mutate::transfer(from.as_sub(), to.as_sub(), amount, Preservation::Expendable)?;175			};176177			Ok(PostDispatchInfo {178				actual_weight: Some(<SelfWeightOf<T>>::transfer_allow_death()),179				pays_fee: Pays::Yes,180			})181		}182183		/// Transfer tokens from one account to another.184		///185		/// Same as the [`Self::transfer`] but the spender doesn't needs to be the direct owner of the token.186		/// The spender must be allowed to transfer token.187		/// If the tokens are nested in an NFT and the spender owns the NFT, the allowance is considered to be set.188		///189		/// - `spender`: Account that spend the money.190		/// - `from`: Owner of tokens to transfer.191		/// - `to`: Recepient of transfered tokens.192		/// - `amount`: Amount of tokens to transfer.193		/// - `nesting_budget`: Limit for searching parents in-depth to check ownership.194		pub fn transfer_from(195			spender: &T::CrossAccountId,196			from: &T::CrossAccountId,197			to: &T::CrossAccountId,198			amount: u128,199			nesting_budget: &dyn Budget,200		) -> DispatchResultWithPostInfo {201			let allowance = Self::check_allowed(spender, from, nesting_budget)?;202			if allowance < amount {203				return Err(<CommonError<T>>::ApprovedValueTooLow.into());204			}205			Self::transfer(from, to, amount)206		}207	}208}