difftreelog
feat(refungible) transfer from parent token
in: master
2 files changed
pallets/refungible/Cargo.tomldiffbeforeafterboth18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.20" }19pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.20" }20pallet-common = { default-features = false, path = '../common' }20pallet-common = { default-features = false, path = '../common' }21pallet-structure = { default-features = false, path = '../structure' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }23frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }23scale-info = { version = "2.0.1", default-features = false, features = [24scale-info = { version = "2.0.1", default-features = false, features = [33 "sp-std/std",34 "sp-std/std",34 "up-data-structs/std",35 "up-data-structs/std",35 "pallet-common/std",36 "pallet-common/std",37 "pallet-structure/std",36 'frame-benchmarking/std',38 'frame-benchmarking/std',37 "pallet-evm/std",39 "pallet-evm/std",38]40]pallets/refungible/src/lib.rsdiffbeforeafterboth26 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon,26 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon,27 CollectionHandle, dispatch::CollectionDispatch,27 CollectionHandle, dispatch::CollectionDispatch,28};28};29use pallet_structure::Pallet as PalletStructure;29use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};30use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};30use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};31use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};31use core::ops::Deref;32use core::ops::Deref;656666 #[pallet::config]67 #[pallet::config]67 pub trait Config: frame_system::Config + pallet_common::Config {68 pub trait Config:69 frame_system::Config + pallet_common::Config + pallet_structure::Config70 {68 type WeightInfo: WeightInfo;71 type WeightInfo: WeightInfo;69 }72 }534 Ok(())537 Ok(())535 }538 }536539540 /// Returns allowance, which should be set after transaction537 pub fn transfer_from(541 fn check_allowed(538 collection: &RefungibleHandle<T>,542 collection: &RefungibleHandle<T>,539 spender: &T::CrossAccountId,543 spender: &T::CrossAccountId,540 from: &T::CrossAccountId,544 from: &T::CrossAccountId,541 to: &T::CrossAccountId,542 token: TokenId,545 token: TokenId,543 amount: u128,546 amount: u128,544 ) -> DispatchResult {547 ) -> Result<Option<u128>, DispatchError> {545 if spender.conv_eq(from) {548 if spender.conv_eq(from) {546 return Self::transfer(collection, from, to, token, amount);549 return Ok(None);547 }550 }548 if collection.access == AccessMode::AllowList {551 if collection.access == AccessMode::AllowList {549 // `from`, `to` checked in [`transfer`]552 // `from`, `to` checked in [`transfer`]550 collection.check_allowlist(spender)?;553 collection.check_allowlist(spender)?;551 }554 }552555 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {556 // TODO: should collection owner be allowed to perform this transfer?557 ensure!(558 <PalletStructure<T>>::indirectly_owned(spender.clone(), source.0, source.1, 1)?,559 <CommonError<T>>::ApprovedValueTooLow,560 );561 return Ok(None);562 }553 let allowance =563 let allowance =554 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);564 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);555 if allowance.is_none() {565 if allowance.is_none() {559 );569 );560 }570 }561562 // =========563564 Self::transfer(collection, from, to, token, amount)?;565 if let Some(allowance) = allowance {571 Ok(allowance)566 Self::set_allowance_unchecked(collection, from, spender, token, allowance);567 }568 Ok(())569 }572 }570573571 pub fn burn_from(574 pub fn transfer_from(572 collection: &RefungibleHandle<T>,575 collection: &RefungibleHandle<T>,573 spender: &T::CrossAccountId,576 spender: &T::CrossAccountId,574 from: &T::CrossAccountId,577 from: &T::CrossAccountId,578 to: &T::CrossAccountId,575 token: TokenId,579 token: TokenId,576 amount: u128,580 amount: u128,577 ) -> DispatchResult {581 ) -> DispatchResult {582 let allowance = Self::check_allowed(collection, spender, from, token, amount)?;583584 // =========585586 Self::transfer(collection, from, to, token, amount)?;587 if let Some(allowance) = allowance {588 Self::set_allowance_unchecked(collection, from, spender, token, allowance);589 }590 Ok(())591 }592593 pub fn burn_from(594 collection: &RefungibleHandle<T>,578 if spender.conv_eq(from) {595 spender: &T::CrossAccountId,579 return Self::burn(collection, from, token, amount);596 from: &T::CrossAccountId,580 }597 token: TokenId,581 if collection.access == AccessMode::AllowList {598 amount: u128,582 // `from` checked in [`burn`]599 ) -> DispatchResult {583 collection.check_allowlist(spender)?;584 }585586 let allowance =600 let allowance = Self::check_allowed(collection, spender, from, token, amount)?;587 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);588 if allowance.is_none() {589 ensure!(590 collection.ignores_allowance(spender),591 <CommonError<T>>::ApprovedValueTooLow592 );593 }594601595 // =========602 // =========596603599 Self::set_allowance_unchecked(collection, from, spender, token, allowance);606 Self::set_allowance_unchecked(collection, from, spender, token, allowance);600 }607 }601 Ok(())608 Ok(())602 }609 }603610604 pub fn set_variable_metadata(611 pub fn set_variable_metadata(605 collection: &RefungibleHandle<T>,612 collection: &RefungibleHandle<T>,