difftreelog
fix separate depositor from sender in transfer_internal (#1013)
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
pallets/balances-adapter/src/common.rsdiffbeforeafterboth1use 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}pallets/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,
pallets/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,
pallets/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?;
pallets/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,
pallets/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,
pallets/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,
pallets/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);
}
pallets/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,