difftreelog
fix forbid non-1 tokenid in native fungibles (#1015)
in: master
* fix: native fungibles collection * refactor: move FungibleItemsHaveNoId to pallet-common
6 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/balances-adapter/src/erc.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/erc.rs
+++ b/pallets/balances-adapter/src/erc.rs
@@ -58,12 +58,8 @@
let caller = T::CrossAccountId::from_eth(caller);
let to = T::CrossAccountId::from_eth(to);
let amount = amount.try_into().map_err(|_| "amount overflow")?;
- let budget = self
- .recorder()
- .weight_calls_budget(<StructureWeight<T>>::find_parent());
- <Pallet<T>>::transfer(self, &caller, &to, amount, &budget)
- .map_err(|e| dispatch_to_evm::<T>(e.error))?;
+ <Pallet<T>>::transfer(&caller, &to, amount).map_err(|e| dispatch_to_evm::<T>(e.error))?;
Ok(true)
}
@@ -83,7 +79,7 @@
.recorder()
.weight_calls_budget(<StructureWeight<T>>::find_parent());
- <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
+ <Pallet<T>>::transfer_from(&caller, &from, &to, amount, &budget)
.map_err(|e| dispatch_to_evm::<T>(e.error))?;
Ok(true)
}
@@ -106,12 +102,8 @@
let caller = T::CrossAccountId::from_eth(caller);
let to = to.into_sub_cross_account::<T>()?;
let amount = amount.try_into().map_err(|_| "amount overflow")?;
- let budget = self
- .recorder()
- .weight_calls_budget(<StructureWeight<T>>::find_parent());
- <Pallet<T>>::transfer(self, &caller, &to, amount, &budget)
- .map_err(|e| dispatch_to_evm::<T>(e.error))?;
+ <Pallet<T>>::transfer(&caller, &to, amount).map_err(|e| dispatch_to_evm::<T>(e.error))?;
Ok(true)
}
@@ -137,7 +129,7 @@
.recorder()
.weight_calls_budget(<StructureWeight<T>>::find_parent());
- <Pallet<T>>::transfer_from(self, &caller, &from, &to, amount, &budget)
+ <Pallet<T>>::transfer_from(&caller, &from, &to, amount, &budget)
.map_err(|e| dispatch_to_evm::<T>(e.error))?;
Ok(true)
pallets/balances-adapter/src/lib.rsdiffbeforeafterboth--- a/pallets/balances-adapter/src/lib.rs
+++ b/pallets/balances-adapter/src/lib.rs
@@ -155,20 +155,15 @@
Ok(Self::balance_of(from))
}
- /// Transfers the specified amount of tokens. Will check that
- /// the transfer is allowed for the token.
+ /// Transfers the specified amount of tokens.
///
- /// - `collection`: Collection that contains the token.
/// - `from`: Owner of tokens to transfer.
/// - `to`: Recepient of transfered tokens.
/// - `amount`: Amount of tokens to transfer.
- /// - `nesting_budget`: Limit for searching parents in-depth to check ownership.
pub fn transfer(
- _collection: &NativeFungibleHandle<T>,
from: &T::CrossAccountId,
to: &T::CrossAccountId,
amount: u128,
- _nesting_budget: &dyn Budget,
) -> DispatchResultWithPostInfo {
<PalletCommon<T>>::ensure_correct_receiver(to)?;
@@ -185,19 +180,18 @@
})
}
- /// Transfer NFT token from one account to another.
+ /// Transfer tokens from one account to another.
///
- /// Same as the [`Self::transfer`] but spender doesn't needs to be the owner of the token.
- /// The owner should set allowance for the spender to transfer token.
+ /// Same as the [`Self::transfer`] but the spender doesn't needs to be the direct owner of the token.
+ /// The spender must be allowed to transfer token.
+ /// If the tokens are nested in an NFT and the spender owns the NFT, the allowance is considered to be set.
///
- /// - `collection`: Collection that contains the token.
/// - `spender`: Account that spend the money.
/// - `from`: Owner of tokens to transfer.
/// - `to`: Recepient of transfered tokens.
/// - `amount`: Amount of tokens to transfer.
/// - `nesting_budget`: Limit for searching parents in-depth to check ownership.
pub fn transfer_from(
- collection: &NativeFungibleHandle<T>,
spender: &T::CrossAccountId,
from: &T::CrossAccountId,
to: &T::CrossAccountId,
@@ -208,7 +202,7 @@
if allowance < amount {
return Err(<CommonError<T>>::ApprovedValueTooLow.into());
}
- Self::transfer(collection, from, to, amount, nesting_budget)
+ Self::transfer(from, to, amount)
}
}
}
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -783,6 +783,9 @@
/// The user is not an administrator.
UserIsNotCollectionAdmin,
+
+ /// Fungible tokens hold no ID, and the default value of TokenId for a fungible collection is 0.
+ FungibleItemsHaveNoId,
}
/// Storage of the count of created collections. Essentially contains the last collection ID.
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -19,7 +19,7 @@
use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight};
use pallet_common::{
weights::WeightInfo as _, with_weight, CommonCollectionOperations, CommonWeightInfo,
- RefungibleExtensions, SelfWeightOf as PalletCommonWeightOf,
+ Error as CommonError, RefungibleExtensions, SelfWeightOf as PalletCommonWeightOf,
};
use sp_runtime::{ArithmeticError, DispatchError};
use sp_std::{vec, vec::Vec};
@@ -169,7 +169,7 @@
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
- <Error<T>>::FungibleItemsHaveNoId
+ <CommonError<T>>::FungibleItemsHaveNoId
);
with_weight(
@@ -188,7 +188,7 @@
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
- <Error<T>>::FungibleItemsHaveNoId
+ <CommonError<T>>::FungibleItemsHaveNoId
);
<Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget)
@@ -203,7 +203,7 @@
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
- <Error<T>>::FungibleItemsHaveNoId
+ <CommonError<T>>::FungibleItemsHaveNoId
);
with_weight(
@@ -222,7 +222,7 @@
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
- <Error<T>>::FungibleItemsHaveNoId
+ <CommonError<T>>::FungibleItemsHaveNoId
);
with_weight(
@@ -242,7 +242,7 @@
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
- <Error<T>>::FungibleItemsHaveNoId
+ <CommonError<T>>::FungibleItemsHaveNoId
);
<Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, nesting_budget)
@@ -258,7 +258,7 @@
) -> DispatchResultWithPostInfo {
ensure!(
token == TokenId::default(),
- <Error<T>>::FungibleItemsHaveNoId
+ <CommonError<T>>::FungibleItemsHaveNoId
);
with_weight(
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -123,8 +123,6 @@
pub enum Error<T> {
/// Not Fungible item data used to mint in Fungible collection.
NotFungibleDataUsedToMintFungibleCollectionToken,
- /// Fungible tokens hold no ID, and the default value of TokenId for Fungible collection is 0.
- FungibleItemsHaveNoId,
/// Tried to set data for fungible item.
FungibleItemsDontHaveData,
/// Fungible token does not support nesting.