git.delta.rocks / unique-network / refs/commits / 2748564f7070

difftreelog

feat(nonfungible) transfer from parent token

Yaroslav Bolyukin2022-04-07parent: #11621bb.patch.diff
in: master

2 files changed

modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
18sp-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",
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
27 Error as CommonError, Pallet as PalletCommon, Event as CommonEvent,27 Error as CommonError, Pallet as PalletCommon, Event as CommonEvent,
28 CollectionHandle, dispatch::CollectionDispatch,28 CollectionHandle, dispatch::CollectionDispatch,
29};29};
30use pallet_structure::Pallet as PalletStructure;
30use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};31use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
31use sp_core::H160;32use sp_core::H160;
32use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};33use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
7071
71 #[pallet::config]72 #[pallet::config]
72 pub trait Config: frame_system::Config + pallet_common::Config {73 pub trait Config:
74 frame_system::Config + pallet_common::Config + pallet_structure::Config
75 {
73 type WeightInfo: WeightInfo;76 type WeightInfo: WeightInfo;
74 }77 }
256259
257 let token_data =260 let token_data =
258 <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;261 <TokenData<T>>::get((collection.id, token)).ok_or(<CommonError<T>>::TokenNotFound)?;
262 // TODO: require sender to be token, owner, require admins to go through transfer_from
259 ensure!(263 ensure!(
260 &token_data.owner == from264 &token_data.owner == from
261 || (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(from)),265 || (collection.limits.owner_can_transfer() && collection.is_owner_or_admin(from)),
502 Ok(())506 Ok(())
503 }507 }
504508
505 pub fn transfer_from(509 fn check_allowed(
506 collection: &NonfungibleHandle<T>,510 collection: &NonfungibleHandle<T>,
507 spender: &T::CrossAccountId,511 spender: &T::CrossAccountId,
508 from: &T::CrossAccountId,512 from: &T::CrossAccountId,
509 to: &T::CrossAccountId,
510 token: TokenId,513 token: TokenId,
511 ) -> DispatchResult {514 ) -> DispatchResult {
512 if spender.conv_eq(from) {515 if spender.conv_eq(from) {
513 return Self::transfer(collection, from, to, token);516 return Ok(());
514 }517 }
515 if collection.access == AccessMode::AllowList {518 if collection.access == AccessMode::AllowList {
516 // `from`, `to` checked in [`transfer`]519 // `from`, `to` checked in [`transfer`]
517 collection.check_allowlist(spender)?;520 collection.check_allowlist(spender)?;
518 }521 }
519
520 if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {522 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {
523 // TODO: should collection owner be allowed to perform this transfer?
524 ensure!(
525 <PalletStructure<T>>::indirectly_owned(spender.clone(), source.0, source.1, 1)?,
526 <CommonError<T>>::ApprovedValueTooLow,
527 );
528 return Ok(());
529 }
530 if <Allowance<T>>::get((collection.id, token)).as_ref() == Some(spender) {
531 return Ok(());
532 }
521 ensure!(533 ensure!(
522 collection.ignores_allowance(spender),534 collection.ignores_allowance(spender),
523 <CommonError<T>>::ApprovedValueTooLow535 <CommonError<T>>::ApprovedValueTooLow
524 );536 );
525 }
526
527 // =========
528
529 Self::transfer(collection, from, to, token)?;
530 // Allowance is reset in [`transfer`]
531 Ok(())537 Ok(())
532 }538 }
539
540 pub fn transfer_from(
541 collection: &NonfungibleHandle<T>,
542 spender: &T::CrossAccountId,
543 from: &T::CrossAccountId,
544 to: &T::CrossAccountId,
545 token: TokenId,
546 ) -> DispatchResult {
547 Self::check_allowed(collection, spender, from, token)?;
548
549 // =========
550
551 // Allowance is reset in [`transfer`]
552 Self::transfer(collection, from, to, token)
553 }
533554
534 pub fn burn_from(555 pub fn burn_from(
535 collection: &NonfungibleHandle<T>,556 collection: &NonfungibleHandle<T>,
536 spender: &T::CrossAccountId,557 spender: &T::CrossAccountId,
537 from: &T::CrossAccountId,558 from: &T::CrossAccountId,
538 token: TokenId,559 token: TokenId,
539 ) -> DispatchResult {560 ) -> DispatchResult {
540 if spender.conv_eq(from) {
541 return Self::burn(collection, from, token);561 Self::check_allowed(collection, spender, from, token)?;
542 }
543 if collection.access == AccessMode::AllowList {
544 // `from` checked in [`burn`]
545 collection.check_allowlist(spender)?;
546 }
547
548 if <Allowance<T>>::get((collection.id, token)).as_ref() != Some(spender) {
549 ensure!(
550 collection.ignores_allowance(spender),
551 <CommonError<T>>::ApprovedValueTooLow
552 );
553 }
554562
555 // =========563 // =========
556564