git.delta.rocks / unique-network / refs/commits / 31bae1fc2671

difftreelog

fix separate depositor from sender in transfer_internal (#1013)

Daniel Shiposha2023-10-16parent: #71be677.patch.diff
in: master
* fix: transfer-from

* fix: remove Option from nester type

* fix: check_nesting comment

* fix: rename nester to depositor, add docs

9 files changed

modifiedpallets/balances-adapter/src/common.rsdiffbeforeafterboth
before · pallets/balances-adapter/src/common.rs
1use alloc::{vec, vec::Vec};2use core::marker::PhantomData;34use frame_support::{fail, weights::Weight};5use pallet_balances::{weights::SubstrateWeight as BalancesWeight, WeightInfo};6use pallet_common::{CommonCollectionOperations, CommonWeightInfo};7use up_data_structs::TokenId;89use crate::{Config, NativeFungibleHandle, Pallet};1011pub struct CommonWeights<T: Config>(PhantomData<T>);1213// All implementations with `Weight::default` used in methods that return error `UnsupportedOperation`.14impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {15	fn create_multiple_items(_amount: &[up_data_structs::CreateItemData]) -> Weight {16		Weight::default()17	}1819	fn create_multiple_items_ex(20		_cost: &up_data_structs::CreateItemExData<T::CrossAccountId>,21	) -> Weight {22		Weight::default()23	}2425	fn burn_item() -> Weight {26		Weight::default()27	}2829	fn set_collection_properties(_amount: u32) -> Weight {30		Weight::default()31	}3233	fn set_token_properties(_amount: u32) -> Weight {34		Weight::default()35	}3637	fn set_token_property_permissions(_amount: u32) -> Weight {38		Weight::default()39	}4041	fn transfer() -> Weight {42		<BalancesWeight<T> as WeightInfo>::transfer_allow_death()43	}4445	fn approve() -> Weight {46		Weight::default()47	}4849	fn approve_from() -> Weight {50		Weight::default()51	}5253	fn transfer_from() -> Weight {54		<BalancesWeight<T> as WeightInfo>::transfer_allow_death()55	}5657	fn burn_from() -> Weight {58		Weight::default()59	}6061	fn set_allowance_for_all() -> Weight {62		Weight::default()63	}6465	fn force_repair_item() -> Weight {66		Weight::default()67	}68}6970/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallet71/// methods and adds weight info.72impl<T: Config> CommonCollectionOperations<T> for NativeFungibleHandle<T> {73	fn create_item(74		&self,75		_sender: <T>::CrossAccountId,76		_to: <T>::CrossAccountId,77		_data: up_data_structs::CreateItemData,78		_nesting_budget: &dyn up_data_structs::budget::Budget,79	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {80		fail!(<pallet_common::Error<T>>::UnsupportedOperation);81	}8283	fn create_multiple_items(84		&self,85		_sender: <T>::CrossAccountId,86		_to: <T>::CrossAccountId,87		_data: Vec<up_data_structs::CreateItemData>,88		_nesting_budget: &dyn up_data_structs::budget::Budget,89	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {90		fail!(<pallet_common::Error<T>>::UnsupportedOperation);91	}9293	fn create_multiple_items_ex(94		&self,95		_sender: <T>::CrossAccountId,96		_data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,97		_nesting_budget: &dyn up_data_structs::budget::Budget,98	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {99		fail!(<pallet_common::Error<T>>::UnsupportedOperation);100	}101102	fn burn_item(103		&self,104		_sender: <T>::CrossAccountId,105		_token: TokenId,106		_amount: u128,107	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {108		fail!(<pallet_common::Error<T>>::UnsupportedOperation);109	}110111	fn set_collection_properties(112		&self,113		_sender: <T>::CrossAccountId,114		_properties: Vec<up_data_structs::Property>,115	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {116		fail!(<pallet_common::Error<T>>::UnsupportedOperation);117	}118119	fn delete_collection_properties(120		&self,121		_sender: &<T>::CrossAccountId,122		_property_keys: Vec<up_data_structs::PropertyKey>,123	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {124		fail!(<pallet_common::Error<T>>::UnsupportedOperation);125	}126127	fn set_token_properties(128		&self,129		_sender: <T>::CrossAccountId,130		_token_id: TokenId,131		_properties: Vec<up_data_structs::Property>,132		_budget: &dyn up_data_structs::budget::Budget,133	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {134		fail!(<pallet_common::Error<T>>::UnsupportedOperation);135	}136137	fn delete_token_properties(138		&self,139		_sender: <T>::CrossAccountId,140		_token_id: TokenId,141		_property_keys: Vec<up_data_structs::PropertyKey>,142		_budget: &dyn up_data_structs::budget::Budget,143	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {144		fail!(<pallet_common::Error<T>>::UnsupportedOperation);145	}146147	fn get_token_properties_raw(148		&self,149		_token_id: TokenId,150	) -> Option<up_data_structs::TokenProperties> {151		// No token properties are defined on fungibles152		None153	}154155	fn set_token_properties_raw(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {156		// No token properties are defined on fungibles157	}158159	fn set_token_property_permissions(160		&self,161		_sender: &<T>::CrossAccountId,162		_property_permissions: Vec<up_data_structs::PropertyKeyPermission>,163	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {164		fail!(<pallet_common::Error<T>>::UnsupportedOperation);165	}166167	fn transfer(168		&self,169		sender: <T>::CrossAccountId,170		to: <T>::CrossAccountId,171		_token: TokenId,172		amount: u128,173		budget: &dyn up_data_structs::budget::Budget,174	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {175		<Pallet<T>>::transfer(self, &sender, &to, amount, budget)176	}177178	fn approve(179		&self,180		_sender: <T>::CrossAccountId,181		_spender: <T>::CrossAccountId,182		_token: TokenId,183		_amount: u128,184	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {185		fail!(<pallet_common::Error<T>>::UnsupportedOperation);186	}187188	fn approve_from(189		&self,190		_sender: <T>::CrossAccountId,191		_from: <T>::CrossAccountId,192		_to: <T>::CrossAccountId,193		_token: TokenId,194		_amount: u128,195	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {196		fail!(<pallet_common::Error<T>>::UnsupportedOperation);197	}198199	fn transfer_from(200		&self,201		sender: <T>::CrossAccountId,202		from: <T>::CrossAccountId,203		to: <T>::CrossAccountId,204		_token: TokenId,205		amount: u128,206		budget: &dyn up_data_structs::budget::Budget,207	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {208		<Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, budget)209	}210211	fn burn_from(212		&self,213		_sender: <T>::CrossAccountId,214		_from: <T>::CrossAccountId,215		_token: TokenId,216		_amount: u128,217		_budget: &dyn up_data_structs::budget::Budget,218	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {219		fail!(<pallet_common::Error<T>>::UnsupportedOperation);220	}221222	fn check_nesting(223		&self,224		_sender: <T>::CrossAccountId,225		_from: (up_data_structs::CollectionId, TokenId),226		_under: TokenId,227		_budget: &dyn up_data_structs::budget::Budget,228	) -> frame_support::sp_runtime::DispatchResult {229		fail!(<pallet_common::Error<T>>::UnsupportedOperation);230	}231232	fn nest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}233234	fn unnest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}235236	fn account_tokens(&self, account: <T>::CrossAccountId) -> Vec<TokenId> {237		let balance = <Pallet<T>>::total_balance(&account);238		if balance != 0 {239			vec![TokenId::default()]240		} else {241			vec![]242		}243	}244245	fn collection_tokens(&self) -> Vec<TokenId> {246		vec![TokenId::default()]247	}248249	fn token_exists(&self, token: TokenId) -> bool {250		token == TokenId::default()251	}252253	fn last_token_id(&self) -> TokenId {254		TokenId::default()255	}256257	fn token_owner(258		&self,259		_token: TokenId,260	) -> Result<<T>::CrossAccountId, up_data_structs::TokenOwnerError> {261		Err(up_data_structs::TokenOwnerError::MultipleOwners)262	}263264	fn check_token_indirect_owner(265		&self,266		_token: TokenId,267		_maybe_owner: &<T>::CrossAccountId,268		_nesting_budget: &dyn up_data_structs::budget::Budget,269	) -> Result<bool, frame_support::sp_runtime::DispatchError> {270		Ok(false)271	}272273	fn token_owners(&self, _token: TokenId) -> Vec<<T>::CrossAccountId> {274		vec![]275	}276277	fn token_property(278		&self,279		_token_id: TokenId,280		_key: &up_data_structs::PropertyKey,281	) -> Option<up_data_structs::PropertyValue> {282		None283	}284285	fn token_properties(286		&self,287		_token: TokenId,288		_keys: Option<Vec<up_data_structs::PropertyKey>>,289	) -> Vec<up_data_structs::Property> {290		vec![]291	}292293	fn total_supply(&self) -> u32 {294		1295	}296297	fn account_balance(&self, account: T::CrossAccountId) -> u32 {298		let balance = <Pallet<T>>::balance_of(&account);299		(balance != 0).into()300	}301302	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {303		if token != TokenId::default() {304			return 0;305		}306		<Pallet<T>>::balance_of(&account)307	}308309	fn total_pieces(&self, token: TokenId) -> Option<u128> {310		if token != TokenId::default() {311			return None;312		}313		Some(<Pallet<T>>::total_issuance())314	}315316	fn allowance(317		&self,318		_sender: <T>::CrossAccountId,319		_spender: <T>::CrossAccountId,320		_token: TokenId,321	) -> u128 {322		0323	}324325	fn refungible_extensions(&self) -> Option<&dyn pallet_common::RefungibleExtensions<T>> {326		None327	}328329	fn set_allowance_for_all(330		&self,331		_owner: <T>::CrossAccountId,332		_operator: <T>::CrossAccountId,333		_approve: bool,334	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {335		fail!(<pallet_common::Error<T>>::UnsupportedOperation);336	}337338	fn allowance_for_all(339		&self,340		_owner: <T>::CrossAccountId,341		_operator: <T>::CrossAccountId,342	) -> bool {343		false344	}345346	fn repair_item(347		&self,348		_token: TokenId,349	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {350		fail!(<pallet_common::Error<T>>::UnsupportedOperation);351	}352}
after · pallets/balances-adapter/src/common.rs
1use alloc::{vec, vec::Vec};2use core::marker::PhantomData;34use frame_support::{fail, weights::Weight};5use pallet_balances::{weights::SubstrateWeight as BalancesWeight, WeightInfo};6use pallet_common::{CommonCollectionOperations, CommonWeightInfo};7use up_data_structs::TokenId;89use crate::{Config, NativeFungibleHandle, Pallet};1011pub struct CommonWeights<T: Config>(PhantomData<T>);1213// All implementations with `Weight::default` used in methods that return error `UnsupportedOperation`.14impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {15	fn create_multiple_items(_amount: &[up_data_structs::CreateItemData]) -> Weight {16		Weight::default()17	}1819	fn create_multiple_items_ex(20		_cost: &up_data_structs::CreateItemExData<T::CrossAccountId>,21	) -> Weight {22		Weight::default()23	}2425	fn burn_item() -> Weight {26		Weight::default()27	}2829	fn set_collection_properties(_amount: u32) -> Weight {30		Weight::default()31	}3233	fn set_token_properties(_amount: u32) -> Weight {34		Weight::default()35	}3637	fn set_token_property_permissions(_amount: u32) -> Weight {38		Weight::default()39	}4041	fn transfer() -> Weight {42		<BalancesWeight<T> as WeightInfo>::transfer_allow_death()43	}4445	fn approve() -> Weight {46		Weight::default()47	}4849	fn approve_from() -> Weight {50		Weight::default()51	}5253	fn transfer_from() -> Weight {54		<BalancesWeight<T> as WeightInfo>::transfer_allow_death()55	}5657	fn burn_from() -> Weight {58		Weight::default()59	}6061	fn set_allowance_for_all() -> Weight {62		Weight::default()63	}6465	fn force_repair_item() -> Weight {66		Weight::default()67	}68}6970/// Implementation of `CommonCollectionOperations` for `FungibleHandle`. It wraps FungibleHandle Pallet71/// methods and adds weight info.72impl<T: Config> CommonCollectionOperations<T> for NativeFungibleHandle<T> {73	fn create_item(74		&self,75		_sender: <T>::CrossAccountId,76		_to: <T>::CrossAccountId,77		_data: up_data_structs::CreateItemData,78		_nesting_budget: &dyn up_data_structs::budget::Budget,79	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {80		fail!(<pallet_common::Error<T>>::UnsupportedOperation);81	}8283	fn create_multiple_items(84		&self,85		_sender: <T>::CrossAccountId,86		_to: <T>::CrossAccountId,87		_data: Vec<up_data_structs::CreateItemData>,88		_nesting_budget: &dyn up_data_structs::budget::Budget,89	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {90		fail!(<pallet_common::Error<T>>::UnsupportedOperation);91	}9293	fn create_multiple_items_ex(94		&self,95		_sender: <T>::CrossAccountId,96		_data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,97		_nesting_budget: &dyn up_data_structs::budget::Budget,98	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {99		fail!(<pallet_common::Error<T>>::UnsupportedOperation);100	}101102	fn burn_item(103		&self,104		_sender: <T>::CrossAccountId,105		_token: TokenId,106		_amount: u128,107	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {108		fail!(<pallet_common::Error<T>>::UnsupportedOperation);109	}110111	fn set_collection_properties(112		&self,113		_sender: <T>::CrossAccountId,114		_properties: Vec<up_data_structs::Property>,115	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {116		fail!(<pallet_common::Error<T>>::UnsupportedOperation);117	}118119	fn delete_collection_properties(120		&self,121		_sender: &<T>::CrossAccountId,122		_property_keys: Vec<up_data_structs::PropertyKey>,123	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {124		fail!(<pallet_common::Error<T>>::UnsupportedOperation);125	}126127	fn set_token_properties(128		&self,129		_sender: <T>::CrossAccountId,130		_token_id: TokenId,131		_properties: Vec<up_data_structs::Property>,132		_budget: &dyn up_data_structs::budget::Budget,133	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {134		fail!(<pallet_common::Error<T>>::UnsupportedOperation);135	}136137	fn delete_token_properties(138		&self,139		_sender: <T>::CrossAccountId,140		_token_id: TokenId,141		_property_keys: Vec<up_data_structs::PropertyKey>,142		_budget: &dyn up_data_structs::budget::Budget,143	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {144		fail!(<pallet_common::Error<T>>::UnsupportedOperation);145	}146147	fn get_token_properties_raw(148		&self,149		_token_id: TokenId,150	) -> Option<up_data_structs::TokenProperties> {151		// No token properties are defined on fungibles152		None153	}154155	fn set_token_properties_raw(&self, _token_id: TokenId, _map: up_data_structs::TokenProperties) {156		// No token properties are defined on fungibles157	}158159	fn set_token_property_permissions(160		&self,161		_sender: &<T>::CrossAccountId,162		_property_permissions: Vec<up_data_structs::PropertyKeyPermission>,163	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {164		fail!(<pallet_common::Error<T>>::UnsupportedOperation);165	}166167	fn transfer(168		&self,169		sender: <T>::CrossAccountId,170		to: <T>::CrossAccountId,171		_token: TokenId,172		amount: u128,173		budget: &dyn up_data_structs::budget::Budget,174	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {175		<Pallet<T>>::transfer(self, &sender, &to, amount, budget)176	}177178	fn approve(179		&self,180		_sender: <T>::CrossAccountId,181		_spender: <T>::CrossAccountId,182		_token: TokenId,183		_amount: u128,184	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {185		fail!(<pallet_common::Error<T>>::UnsupportedOperation);186	}187188	fn approve_from(189		&self,190		_sender: <T>::CrossAccountId,191		_from: <T>::CrossAccountId,192		_to: <T>::CrossAccountId,193		_token: TokenId,194		_amount: u128,195	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {196		fail!(<pallet_common::Error<T>>::UnsupportedOperation);197	}198199	fn transfer_from(200		&self,201		sender: <T>::CrossAccountId,202		from: <T>::CrossAccountId,203		to: <T>::CrossAccountId,204		_token: TokenId,205		amount: u128,206		budget: &dyn up_data_structs::budget::Budget,207	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {208		<Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, budget)209	}210211	fn burn_from(212		&self,213		_sender: <T>::CrossAccountId,214		_from: <T>::CrossAccountId,215		_token: TokenId,216		_amount: u128,217		_budget: &dyn up_data_structs::budget::Budget,218	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {219		fail!(<pallet_common::Error<T>>::UnsupportedOperation);220	}221222	fn check_nesting(223		&self,224		_sender: &<T>::CrossAccountId,225		_from: (up_data_structs::CollectionId, TokenId),226		_under: TokenId,227		_budget: &dyn up_data_structs::budget::Budget,228	) -> frame_support::sp_runtime::DispatchResult {229		fail!(<pallet_common::Error<T>>::UnsupportedOperation);230	}231232	fn nest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}233234	fn unnest(&self, _under: TokenId, _to_nest: (up_data_structs::CollectionId, TokenId)) {}235236	fn account_tokens(&self, account: <T>::CrossAccountId) -> Vec<TokenId> {237		let balance = <Pallet<T>>::total_balance(&account);238		if balance != 0 {239			vec![TokenId::default()]240		} else {241			vec![]242		}243	}244245	fn collection_tokens(&self) -> Vec<TokenId> {246		vec![TokenId::default()]247	}248249	fn token_exists(&self, token: TokenId) -> bool {250		token == TokenId::default()251	}252253	fn last_token_id(&self) -> TokenId {254		TokenId::default()255	}256257	fn token_owner(258		&self,259		_token: TokenId,260	) -> Result<<T>::CrossAccountId, up_data_structs::TokenOwnerError> {261		Err(up_data_structs::TokenOwnerError::MultipleOwners)262	}263264	fn check_token_indirect_owner(265		&self,266		_token: TokenId,267		_maybe_owner: &<T>::CrossAccountId,268		_nesting_budget: &dyn up_data_structs::budget::Budget,269	) -> Result<bool, frame_support::sp_runtime::DispatchError> {270		Ok(false)271	}272273	fn token_owners(&self, _token: TokenId) -> Vec<<T>::CrossAccountId> {274		vec![]275	}276277	fn token_property(278		&self,279		_token_id: TokenId,280		_key: &up_data_structs::PropertyKey,281	) -> Option<up_data_structs::PropertyValue> {282		None283	}284285	fn token_properties(286		&self,287		_token: TokenId,288		_keys: Option<Vec<up_data_structs::PropertyKey>>,289	) -> Vec<up_data_structs::Property> {290		vec![]291	}292293	fn total_supply(&self) -> u32 {294		1295	}296297	fn account_balance(&self, account: T::CrossAccountId) -> u32 {298		let balance = <Pallet<T>>::balance_of(&account);299		(balance != 0).into()300	}301302	fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {303		if token != TokenId::default() {304			return 0;305		}306		<Pallet<T>>::balance_of(&account)307	}308309	fn total_pieces(&self, token: TokenId) -> Option<u128> {310		if token != TokenId::default() {311			return None;312		}313		Some(<Pallet<T>>::total_issuance())314	}315316	fn allowance(317		&self,318		_sender: <T>::CrossAccountId,319		_spender: <T>::CrossAccountId,320		_token: TokenId,321	) -> u128 {322		0323	}324325	fn refungible_extensions(&self) -> Option<&dyn pallet_common::RefungibleExtensions<T>> {326		None327	}328329	fn set_allowance_for_all(330		&self,331		_owner: <T>::CrossAccountId,332		_operator: <T>::CrossAccountId,333		_approve: bool,334	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {335		fail!(<pallet_common::Error<T>>::UnsupportedOperation);336	}337338	fn allowance_for_all(339		&self,340		_owner: <T>::CrossAccountId,341		_operator: <T>::CrossAccountId,342	) -> bool {343		false344	}345346	fn repair_item(347		&self,348		_token: TokenId,349	) -> frame_support::pallet_prelude::DispatchResultWithPostInfo {350		fail!(<pallet_common::Error<T>>::UnsupportedOperation);351	}352}
modifiedpallets/common/src/lib.rsdiffbeforeafterboth
--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -2194,7 +2194,7 @@
 	/// * `budget` - The maximum budget that can be spent on the check.
 	fn check_nesting(
 		&self,
-		sender: T::CrossAccountId,
+		sender: &T::CrossAccountId,
 		from: (CollectionId, TokenId),
 		under: TokenId,
 		budget: &dyn Budget,
modifiedpallets/fungible/src/common.rsdiffbeforeafterboth
--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -335,7 +335,7 @@
 
 	fn check_nesting(
 		&self,
-		_sender: <T>::CrossAccountId,
+		_sender: &<T>::CrossAccountId,
 		_from: (CollectionId, TokenId),
 		_under: TokenId,
 		_nesting_budget: &dyn Budget,
modifiedpallets/fungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -384,6 +384,21 @@
 		amount: u128,
 		nesting_budget: &dyn Budget,
 	) -> DispatchResultWithPostInfo {
+		let depositor = from;
+		Self::transfer_internal(collection, depositor, from, to, amount, nesting_budget)
+	}
+
+	/// Transfers tokens from the `from` account to the `to` account.
+	/// The `depositor` is the account who deposits the tokens.
+	/// For instance, the nesting rules will be checked against the `depositor`'s permissions.
+	fn transfer_internal(
+		collection: &FungibleHandle<T>,
+		depositor: &T::CrossAccountId,
+		from: &T::CrossAccountId,
+		to: &T::CrossAccountId,
+		amount: u128,
+		nesting_budget: &dyn Budget,
+	) -> DispatchResultWithPostInfo {
 		ensure!(
 			collection.limits.transfers_enabled(),
 			<CommonError<T>>::TransferNotAllowed,
@@ -416,7 +431,7 @@
 			// from != to && amount != 0
 
 			<PalletStructure<T>>::nest_if_sent_to_token(
-				from.clone(),
+				depositor,
 				to,
 				collection.id,
 				TokenId::default(),
@@ -473,7 +488,7 @@
 
 		for (to, _) in data.iter() {
 			<PalletStructure<T>>::check_nesting(
-				sender.clone(),
+				sender,
 				to,
 				collection.id,
 				TokenId::default(),
@@ -730,7 +745,8 @@
 
 		// =========
 
-		let mut result = Self::transfer(collection, from, to, amount, nesting_budget);
+		let mut result =
+			Self::transfer_internal(collection, spender, from, to, amount, nesting_budget);
 		add_weight_to_post_info(&mut result, <SelfWeightOf<T>>::check_allowed_raw());
 		result?;
 
modifiedpallets/nonfungible/src/common.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/common.rs
+++ b/pallets/nonfungible/src/common.rs
@@ -407,7 +407,7 @@
 
 	fn check_nesting(
 		&self,
-		sender: T::CrossAccountId,
+		sender: &T::CrossAccountId,
 		from: (CollectionId, TokenId),
 		under: TokenId,
 		nesting_budget: &dyn Budget,
modifiedpallets/nonfungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -718,6 +718,21 @@
 		token: TokenId,
 		nesting_budget: &dyn Budget,
 	) -> DispatchResultWithPostInfo {
+		let depositor = from;
+		Self::transfer_internal(collection, depositor, from, to, token, nesting_budget)
+	}
+
+	/// Transfers an NFT from the `from` account to the `to` account.
+	/// The `depositor` is the account who deposits the NFT.
+	/// For instance, the nesting rules will be checked against the `depositor`'s permissions.
+	pub fn transfer_internal(
+		collection: &NonfungibleHandle<T>,
+		depositor: &T::CrossAccountId,
+		from: &T::CrossAccountId,
+		to: &T::CrossAccountId,
+		token: TokenId,
+		nesting_budget: &dyn Budget,
+	) -> DispatchResultWithPostInfo {
 		ensure!(
 			collection.limits.transfers_enabled(),
 			<CommonError<T>>::TransferNotAllowed
@@ -754,7 +769,7 @@
 		};
 
 		<PalletStructure<T>>::nest_if_sent_to_token(
-			from.clone(),
+			depositor,
 			to,
 			collection.id,
 			token,
@@ -860,7 +875,7 @@
 			let token = TokenId(first_token + i as u32 + 1);
 
 			<PalletStructure<T>>::check_nesting(
-				sender.clone(),
+				sender,
 				&data.owner,
 				collection.id,
 				token,
@@ -1154,7 +1169,8 @@
 		// =========
 
 		// Allowance is reset in [`transfer`]
-		let mut result = Self::transfer(collection, from, to, token, nesting_budget);
+		let mut result =
+			Self::transfer_internal(collection, spender, from, to, token, nesting_budget);
 		add_weight_to_post_info(&mut result, <SelfWeightOf<T>>::check_allowed_raw());
 		result
 	}
@@ -1183,7 +1199,7 @@
 	///
 	pub fn check_nesting(
 		handle: &NonfungibleHandle<T>,
-		sender: T::CrossAccountId,
+		sender: &T::CrossAccountId,
 		from: (CollectionId, TokenId),
 		under: TokenId,
 		nesting_budget: &dyn Budget,
modifiedpallets/refungible/src/common.rsdiffbeforeafterboth
--- a/pallets/refungible/src/common.rs
+++ b/pallets/refungible/src/common.rs
@@ -416,7 +416,7 @@
 
 	fn check_nesting(
 		&self,
-		_sender: <T>::CrossAccountId,
+		_sender: &<T>::CrossAccountId,
 		_from: (CollectionId, TokenId),
 		_under: TokenId,
 		_nesting_budget: &dyn Budget,
modifiedpallets/refungible/src/lib.rsdiffbeforeafterboth
--- a/pallets/refungible/src/lib.rs
+++ b/pallets/refungible/src/lib.rs
@@ -615,6 +615,30 @@
 		amount: u128,
 		nesting_budget: &dyn Budget,
 	) -> DispatchResult {
+		let depositor = from;
+		Self::transfer_internal(
+			collection,
+			depositor,
+			from,
+			to,
+			token,
+			amount,
+			nesting_budget,
+		)
+	}
+
+	/// Transfers RFT tokens from the `from` account to the `to` account.
+	/// The `depositor` is the account who deposits the tokens.
+	/// For instance, the nesting rules will be checked against the `depositor`'s permissions.
+	pub fn transfer_internal(
+		collection: &RefungibleHandle<T>,
+		depositor: &T::CrossAccountId,
+		from: &T::CrossAccountId,
+		to: &T::CrossAccountId,
+		token: TokenId,
+		amount: u128,
+		nesting_budget: &dyn Budget,
+	) -> DispatchResult {
 		ensure!(
 			collection.limits.transfers_enabled(),
 			<CommonError<T>>::TransferNotAllowed
@@ -683,7 +707,7 @@
 			// from != to && amount != 0
 
 			<PalletStructure<T>>::nest_if_sent_to_token(
-				from.clone(),
+				depositor,
 				to,
 				collection.id,
 				token,
@@ -847,7 +871,7 @@
 			let token_id = TokenId(first_token_id + i as u32 + 1);
 			for (to, _) in token.users.iter() {
 				<PalletStructure<T>>::check_nesting(
-					sender.clone(),
+					sender,
 					to,
 					collection.id,
 					token_id,
@@ -1146,7 +1170,7 @@
 
 		// =========
 
-		Self::transfer(collection, from, to, token, amount, nesting_budget)?;
+		Self::transfer_internal(collection, spender, from, to, token, amount, nesting_budget)?;
 		if let Some(allowance) = allowance {
 			Self::set_allowance_unchecked(collection, from, spender, token, allowance);
 		}
modifiedpallets/structure/src/lib.rsdiffbeforeafterboth
--- a/pallets/structure/src/lib.rs
+++ b/pallets/structure/src/lib.rs
@@ -300,7 +300,7 @@
 	///
 	/// - `nesting_budget`: Limit for searching parents in depth.
 	pub fn check_nesting(
-		from: T::CrossAccountId,
+		from: &T::CrossAccountId,
 		under: &T::CrossAccountId,
 		collection_id: CollectionId,
 		token_id: TokenId,
@@ -317,7 +317,7 @@
 	///
 	/// - `nesting_budget`: Limit for searching parents in depth.
 	pub fn nest_if_sent_to_token(
-		from: T::CrossAccountId,
+		from: &T::CrossAccountId,
 		under: &T::CrossAccountId,
 		collection_id: CollectionId,
 		token_id: TokenId,