difftreelog
feat(fungible) transfer from parent token
in: master
2 files changed
pallets/fungible/Cargo.tomldiffbeforeafterboth--- a/pallets/fungible/Cargo.toml
+++ b/pallets/fungible/Cargo.toml
@@ -17,6 +17,7 @@
sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }
sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }
pallet-common = { default-features = false, path = '../common' }
+pallet-structure = { default-features = false, path = '../structure' }
up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
evm-coder = { default-features = false, path = '../../crates/evm-coder' }
pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
@@ -36,6 +37,7 @@
"sp-std/std",
"up-data-structs/std",
"pallet-common/std",
+ "pallet-structure/std",
"evm-coder/std",
"ethereum/std",
"pallet-evm-coder-substrate/std",
pallets/fungible/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 pallet_evm_coder_substrate::WithRecorder;30use pallet_evm_coder_substrate::WithRecorder;30use sp_core::H160;31use sp_core::H160;31use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};32use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};636464 #[pallet::config]65 #[pallet::config]65 pub trait Config: frame_system::Config + pallet_common::Config {66 pub trait Config:67 frame_system::Config + pallet_common::Config + pallet_structure::Config68 {66 type WeightInfo: WeightInfo;69 type WeightInfo: WeightInfo;67 }70 }353 Ok(())356 Ok(())354 }357 }355358356 pub fn transfer_from(359 fn check_allowed(357 collection: &FungibleHandle<T>,360 collection: &FungibleHandle<T>,358 spender: &T::CrossAccountId,361 spender: &T::CrossAccountId,359 from: &T::CrossAccountId,362 from: &T::CrossAccountId,360 to: &T::CrossAccountId,361 amount: u128,363 amount: u128,362 ) -> DispatchResult {364 ) -> Result<Option<u128>, DispatchError> {363 if spender.conv_eq(from) {365 if spender.conv_eq(from) {364 return Self::transfer(collection, from, to, amount);366 return Ok(None);365 }367 }366 if collection.access == AccessMode::AllowList {368 if collection.access == AccessMode::AllowList {367 // `from`, `to` checked in [`transfer`]369 // `from`, `to` checked in [`transfer`]368 collection.check_allowlist(spender)?;370 collection.check_allowlist(spender)?;369 }371 }370372 if let Some(source) = T::CrossTokenAddressMapping::address_to_token(from) {373 // TODO: should collection owner be allowed to perform this transfer?374 ensure!(375 <PalletStructure<T>>::indirectly_owned(spender.clone(), source.0, source.1, 1)?,376 <CommonError<T>>::ApprovedValueTooLow,377 );378 return Ok(None);379 }371 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);380 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);372 if allowance.is_none() {381 if allowance.is_none() {373 ensure!(382 ensure!(376 );385 );377 }386 }378387379 // =========380381 Self::transfer(collection, from, to, amount)?;382 if let Some(allowance) = allowance {388 Ok(allowance)383 Self::set_allowance_unchecked(collection, from, spender, allowance);384 }385 Ok(())386 }389 }387390388 pub fn burn_from(391 pub fn transfer_from(389 collection: &FungibleHandle<T>,392 collection: &FungibleHandle<T>,390 spender: &T::CrossAccountId,393 spender: &T::CrossAccountId,391 from: &T::CrossAccountId,394 from: &T::CrossAccountId,395 to: &T::CrossAccountId,392 amount: u128,396 amount: u128,393 ) -> DispatchResult {397 ) -> DispatchResult {394 if spender.conv_eq(from) {398 let allowance = Self::check_allowed(collection, spender, from, amount)?;395 return Self::burn(collection, from, amount);399396 }400 // =========397 if collection.access == AccessMode::AllowList {401398 // `from` checked in [`burn`]402 Self::transfer(collection, from, to, amount)?;399 collection.check_allowlist(spender)?;403 if let Some(allowance) = allowance {400 }404 Self::set_allowance_unchecked(collection, from, spender, allowance);401405 }406 Ok(())407 }408409 pub fn burn_from(410 collection: &FungibleHandle<T>,411 spender: &T::CrossAccountId,412 from: &T::CrossAccountId,413 amount: u128,414 ) -> DispatchResult {402 let allowance = <Allowance<T>>::get((collection.id, from, spender)).checked_sub(amount);415 let allowance = Self::check_allowed(collection, spender, from, amount)?;403 if allowance.is_none() {404 ensure!(405 collection.ignores_allowance(spender),406 <CommonError<T>>::ApprovedValueTooLow407 );408 }409416410 // =========417 // =========411418414 Self::set_allowance_unchecked(collection, from, spender, allowance);421 Self::set_allowance_unchecked(collection, from, spender, allowance);415 }422 }416 Ok(())423 Ok(())417 }424 }418425419 /// Delegated to `create_multiple_items`426 /// Delegated to `create_multiple_items`420 pub fn create_item(427 pub fn create_item(