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.rsdiffbeforeafterboth--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -26,6 +26,7 @@
Error as CommonError, Event as CommonEvent, Pallet as PalletCommon,
CollectionHandle, dispatch::CollectionDispatch,
};
+use pallet_structure::Pallet as PalletStructure;
use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};
use core::ops::Deref;
@@ -64,7 +65,9 @@
}
#[pallet::config]
- pub trait Config: frame_system::Config + pallet_common::Config {
+ pub trait Config:
+ frame_system::Config + pallet_common::Config + pallet_structure::Config
+ {
type WeightInfo: WeightInfo;
}
@@ -534,22 +537,29 @@
Ok(())
}
- pub fn transfer_from(
+ /// Returns allowance, which should be set after transaction
+ fn check_allowed(
collection: &RefungibleHandle<T>,
spender: &T::CrossAccountId,
from: &T::CrossAccountId,
- to: &T::CrossAccountId,
token: TokenId,
amount: u128,
- ) -> DispatchResult {
+ ) -> Result<Option<u128>, DispatchError> {
if spender.conv_eq(from) {
- return Self::transfer(collection, from, to, token, amount);
+ return Ok(None);
}
if collection.access == AccessMode::AllowList {
// `from`, `to` checked in [`transfer`]
collection.check_allowlist(spender)?;
}
-
+ if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
+ // TODO: should collection owner be allowed to perform this transfer?
+ ensure!(
+ <PalletStructure<T>>::indirectly_owned(spender.clone(), source.0, source.1, 1)?,
+ <CommonError<T>>::ApprovedValueTooLow,
+ );
+ return Ok(None);
+ }
let allowance =
<Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
if allowance.is_none() {
@@ -558,7 +568,19 @@
<CommonError<T>>::ApprovedValueTooLow
);
}
+ Ok(allowance)
+ }
+ pub fn transfer_from(
+ collection: &RefungibleHandle<T>,
+ spender: &T::CrossAccountId,
+ from: &T::CrossAccountId,
+ to: &T::CrossAccountId,
+ token: TokenId,
+ amount: u128,
+ ) -> DispatchResult {
+ let allowance = Self::check_allowed(collection, spender, from, token, amount)?;
+
// =========
Self::transfer(collection, from, to, token, amount)?;
@@ -575,22 +597,7 @@
token: TokenId,
amount: u128,
) -> DispatchResult {
- if spender.conv_eq(from) {
- return Self::burn(collection, from, token, amount);
- }
- if collection.access == AccessMode::AllowList {
- // `from` checked in [`burn`]
- collection.check_allowlist(spender)?;
- }
-
- let allowance =
- <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);
- if allowance.is_none() {
- ensure!(
- collection.ignores_allowance(spender),
- <CommonError<T>>::ApprovedValueTooLow
- );
- }
+ let allowance = Self::check_allowed(collection, spender, from, token, amount)?;
// =========