difftreelog
feat(nonfungible) transfer from parent token
in: master
2 files changed
pallets/nonfungible/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' }22evm-coder = { default-features = false, path = '../../crates/evm-coder' }23evm-coder = { default-features = false, path = '../../crates/evm-coder' }23pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }24pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }36 "sp-std/std",37 "sp-std/std",37 "up-data-structs/std",38 "up-data-structs/std",38 "pallet-common/std",39 "pallet-common/std",40 "pallet-structure/std",39 "evm-coder/std",41 "evm-coder/std",40 "ethereum/std",42 "ethereum/std",41 "pallet-evm-coder-substrate/std",43 "pallet-evm-coder-substrate/std",pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -27,6 +27,7 @@
Error as CommonError, Pallet as PalletCommon, Event as CommonEvent,
CollectionHandle, dispatch::CollectionDispatch,
};
+use pallet_structure::Pallet as PalletStructure;
use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
use sp_core::H160;
use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
@@ -69,7 +70,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;
}
@@ -256,6 +259,7 @@
let token_data =
<TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;
+ // TODO: require sender to be token, owner, require admins to go through transfer_from
ensure!(
&token_data.owner == from
|| (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(from)),
@@ -502,33 +506,50 @@
Ok(())
}
- pub fn transfer_from(
+ fn check_allowed(
collection: &NonfungibleHandle<T>,
spender: &T::CrossAccountId,
from: &T::CrossAccountId,
- to: &T::CrossAccountId,
token: TokenId,
) -> DispatchResult {
if spender.conv_eq(from) {
- return Self::transfer(collection, from, to, token);
+ return Ok(());
}
if collection.access == AccessMode::AllowList {
// `from`, `to` checked in [`transfer`]
collection.check_allowlist(spender)?;
}
-
- if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {
+ if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
+ // TODO: should collection owner be allowed to perform this transfer?
ensure!(
- collection.ignores_allowance(spender),
- <CommonError<T>>::ApprovedValueTooLow
+ <PalletStructure<T>>::indirectly_owned(spender.clone(), source.0, source.1, 1)?,
+ <CommonError<T>>::ApprovedValueTooLow,
);
+ return Ok(());
+ }
+ if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {
+ return Ok(());
}
+ ensure!(
+ collection.ignores_allowance(spender),
+ <CommonError<T>>::ApprovedValueTooLow
+ );
+ Ok(())
+ }
+
+ pub fn transfer_from(
+ collection: &NonfungibleHandle<T>,
+ spender: &T::CrossAccountId,
+ from: &T::CrossAccountId,
+ to: &T::CrossAccountId,
+ token: TokenId,
+ ) -> DispatchResult {
+ Self::check_allowed(collection, spender, from, token)?;
// =========
- Self::transfer(collection, from, to, token)?;
// Allowance is reset in [`transfer`]
- Ok(())
+ Self::transfer(collection, from, to, token)
}
pub fn burn_from(
@@ -537,20 +558,7 @@
from: &T::CrossAccountId,
token: TokenId,
) -> DispatchResult {
- if spender.conv_eq(from) {
- return Self::burn(collection, from, token);
- }
- if collection.access == AccessMode::AllowList {
- // `from` checked in [`burn`]
- collection.check_allowlist(spender)?;
- }
-
- if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {
- ensure!(
- collection.ignores_allowance(spender),
- <CommonError<T>>::ApprovedValueTooLow
- );
- }
+ Self::check_allowed(collection, spender, from, token)?;
// =========