git.delta.rocks / unique-network / refs/commits / 11621bb1723c

difftreelog

feat(fungible) transfer from parent token

Yaroslav Bolyukin2022-04-07parent: #6d3c89f.patch.diff
in: master

2 files changed

modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
17sp-std = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }17sp-std = { 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" }18sp-core = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }
19pallet-common = { default-features = false, path = '../common' }19pallet-common = { default-features = false, path = '../common' }
20pallet-structure = { default-features = false, path = '../structure' }
20up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }
21evm-coder = { default-features = false, path = '../../crates/evm-coder' }22evm-coder = { default-features = false, path = '../../crates/evm-coder' }
22pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }23pallet-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/fungible/src/lib.rsdiffbeforeafterboth
26 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};
6364
64 #[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::Config
68 {
66 type WeightInfo: WeightInfo;69 type WeightInfo: WeightInfo;
67 }70 }
353 Ok(())356 Ok(())
354 }357 }
355358
356 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 }
378387
379 // =========
380
381 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 }
387390
388 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);399
396 }400 // =========
397 if collection.access == AccessMode::AllowList {401
398 // `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 }
408
409 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>>::ApprovedValueTooLow
407 );
408 }
409416
410 // =========417 // =========
411418
414 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 }
418425
419 /// Delegated to `create_multiple_items`426 /// Delegated to `create_multiple_items`
420 pub fn create_item(427 pub fn create_item(