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
before · pallets/fungible/Cargo.toml
1[package]2name = "pallet-fungible"3version = "0.1.0"4license = "GPLv3"5edition = "2021"67[dependencies.codec]8default-features = false9features = ['derive']10package = 'parity-scale-codec'11version = '3.1.2'1213[dependencies]14frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }15frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }16sp-runtime = { 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" }19pallet-common = { default-features = false, path = '../common' }20up-data-structs = { default-features = false, path = '../../primitives/data-structs' }21evm-coder = { default-features = false, path = '../../crates/evm-coder' }22pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }23ethereum = { version = "0.12.0", default-features = false }24frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }25pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.20" }26scale-info = { version = "2.0.1", default-features = false, features = [27    "derive",28] }2930[features]31default = ["std"]32std = [33    "frame-support/std",34    "frame-system/std",35    "sp-runtime/std",36    "sp-std/std",37    "up-data-structs/std",38    "pallet-common/std",39    "evm-coder/std",40    "ethereum/std",41    "pallet-evm-coder-substrate/std",42    'frame-benchmarking/std',43    "pallet-evm/std"44]45runtime-benchmarks = ['frame-benchmarking', 'pallet-common/runtime-benchmarks']
after · pallets/fungible/Cargo.toml
1[package]2name = "pallet-fungible"3version = "0.1.0"4license = "GPLv3"5edition = "2021"67[dependencies.codec]8default-features = false9features = ['derive']10package = 'parity-scale-codec'11version = '3.1.2'1213[dependencies]14frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }15frame-system = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }16sp-runtime = { 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" }19pallet-common = { default-features = false, path = '../common' }20pallet-structure = { default-features = false, path = '../structure' }21up-data-structs = { default-features = false, path = '../../primitives/data-structs' }22evm-coder = { default-features = false, path = '../../crates/evm-coder' }23pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }24ethereum = { version = "0.12.0", default-features = false }25frame-benchmarking = { default-features = false, optional = true, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.20" }26pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.20" }27scale-info = { version = "2.0.1", default-features = false, features = [28    "derive",29] }3031[features]32default = ["std"]33std = [34    "frame-support/std",35    "frame-system/std",36    "sp-runtime/std",37    "sp-std/std",38    "up-data-structs/std",39    "pallet-common/std",40    "pallet-structure/std",41    "evm-coder/std",42    "ethereum/std",43    "pallet-evm-coder-substrate/std",44    'frame-benchmarking/std',45    "pallet-evm/std"46]47runtime-benchmarks = ['frame-benchmarking', 'pallet-common/runtime-benchmarks']
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/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 pallet_evm_coder_substrate::WithRecorder;
 use sp_core::H160;
 use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};
@@ -62,7 +63,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;
 	}
 
@@ -353,21 +356,27 @@
 		Ok(())
 	}
 
-	pub fn transfer_from(
+	fn check_allowed(
 		collection: &FungibleHandle<T>,
 		spender: &T::CrossAccountId,
 		from: &T::CrossAccountId,
-		to: &T::CrossAccountId,
 		amount: u128,
-	) -> DispatchResult {
+	) -> Result<Option<u128>, DispatchError> {
 		if spender.conv_eq(from) {
-			return Self::transfer(collection, from, to, 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, from, spender)).checked_sub(amount);
 		if allowance.is_none() {
 			ensure!(
@@ -376,6 +385,18 @@
 			);
 		}
 
+		Ok(allowance)
+	}
+
+	pub fn transfer_from(
+		collection: &FungibleHandle<T>,
+		spender: &T::CrossAccountId,
+		from: &T::CrossAccountId,
+		to: &T::CrossAccountId,
+		amount: u128,
+	) -> DispatchResult {
+		let allowance = Self::check_allowed(collection, spender, from, amount)?;
+
 		// =========
 
 		Self::transfer(collection, from, to, amount)?;
@@ -391,21 +412,7 @@
 		from: &T::CrossAccountId,
 		amount: u128,
 	) -> DispatchResult {
-		if spender.conv_eq(from) {
-			return Self::burn(collection, from, amount);
-		}
-		if collection.access == AccessMode::AllowList {
-			// `from` checked in [`burn`]
-			collection.check_allowlist(spender)?;
-		}
-
-		let allowance = <Allowance<T>>::get((collection.id, 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, amount)?;
 
 		// =========