1234567891011121314151617use core::marker::PhantomData;1819use frame_support::{dispatch::DispatchResultWithPostInfo, ensure, fail, weights::Weight, traits::Get};20use up_data_structs::{TokenId, CollectionId, CreateItemExData, budget::Budget, CreateItemData};21use pallet_common::{CommonCollectionOperations, CommonWeightInfo, with_weight};22use pallet_structure::Error as StructureError;23use sp_runtime::ArithmeticError;24use sp_std::{vec::Vec, vec};25use up_data_structs::{Property, PropertyKey, PropertyValue, PropertyKeyPermission};2627use crate::{28 Allowance, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf, weights::WeightInfo,29};3031pub struct CommonWeights<T: Config>(PhantomData<T>);32impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {33 fn create_item() -> Weight {34 <SelfWeightOf<T>>::create_item()35 }3637 fn create_multiple_items(_data: &[CreateItemData]) -> Weight {38 39 Self::create_item()40 }4142 fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {43 match data {44 CreateItemExData::Fungible(f) => {45 <SelfWeightOf<T>>::create_multiple_items_ex(f.len() as u32)46 }47 _ => 0,48 }49 }5051 fn burn_item() -> Weight {52 <SelfWeightOf<T>>::burn_item()53 }5455 fn set_collection_properties(_amount: u32) -> Weight {56 57 058 }5960 fn delete_collection_properties(_amount: u32) -> Weight {61 62 063 }6465 fn set_token_properties(_amount: u32) -> Weight {66 67 068 }6970 fn delete_token_properties(_amount: u32) -> Weight {71 72 073 }7475 fn set_property_permissions(_amount: u32) -> Weight {76 77 078 }7980 fn transfer() -> Weight {81 <SelfWeightOf<T>>::transfer()82 }8384 fn approve() -> Weight {85 <SelfWeightOf<T>>::approve()86 }8788 fn transfer_from() -> Weight {89 <SelfWeightOf<T>>::transfer_from()90 }9192 fn burn_from() -> Weight {93 <SelfWeightOf<T>>::burn_from()94 }9596 fn burn_recursively_self_raw() -> Weight {97 98 Self::burn_item() + T::DbWeight::get().reads(1)99 }100101 fn burn_recursively_breadth_raw(_amount: u32) -> Weight {102 103 0104 }105}106107impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {108 fn create_item(109 &self,110 sender: T::CrossAccountId,111 to: T::CrossAccountId,112 data: up_data_structs::CreateItemData,113 nesting_budget: &dyn Budget,114 ) -> DispatchResultWithPostInfo {115 match data {116 up_data_structs::CreateItemData::Fungible(data) => with_weight(117 <Pallet<T>>::create_item(self, &sender, (to, data.value), nesting_budget),118 <CommonWeights<T>>::create_item(),119 ),120 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),121 }122 }123124 fn create_multiple_items(125 &self,126 sender: T::CrossAccountId,127 to: T::CrossAccountId,128 data: Vec<up_data_structs::CreateItemData>,129 nesting_budget: &dyn Budget,130 ) -> DispatchResultWithPostInfo {131 let mut sum: u128 = 0;132 for data in data {133 match data {134 up_data_structs::CreateItemData::Fungible(data) => {135 sum = sum136 .checked_add(data.value)137 .ok_or(ArithmeticError::Overflow)?;138 }139 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),140 }141 }142143 with_weight(144 <Pallet<T>>::create_item(self, &sender, (to, sum), nesting_budget),145 <CommonWeights<T>>::create_item(),146 )147 }148149 fn create_multiple_items_ex(150 &self,151 sender: <T>::CrossAccountId,152 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,153 nesting_budget: &dyn Budget,154 ) -> DispatchResultWithPostInfo {155 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);156 let data = match data {157 up_data_structs::CreateItemExData::Fungible(f) => f,158 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),159 };160161 with_weight(162 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),163 weight,164 )165 }166167 fn burn_item(168 &self,169 sender: T::CrossAccountId,170 token: TokenId,171 amount: u128,172 ) -> DispatchResultWithPostInfo {173 ensure!(174 token == TokenId::default(),175 <Error<T>>::FungibleItemsHaveNoId176 );177178 with_weight(179 <Pallet<T>>::burn(self, &sender, amount),180 <CommonWeights<T>>::burn_item(),181 )182 }183184 fn burn_item_recursively(185 &self,186 sender: T::CrossAccountId,187 token: TokenId,188 self_budget: &dyn Budget,189 _breadth_budget: &dyn Budget,190 ) -> DispatchResultWithPostInfo {191 192 ensure!(193 token == TokenId::default(),194 <Error<T>>::FungibleItemsHaveNoId195 );196 ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);197198 with_weight(199 <Pallet<T>>::burn(self, &sender, <Balance<T>>::get((self.id, &sender))),200 <CommonWeights<T>>::burn_recursively_self_raw(),201 )202 }203204 fn transfer(205 &self,206 from: T::CrossAccountId,207 to: T::CrossAccountId,208 token: TokenId,209 amount: u128,210 nesting_budget: &dyn Budget,211 ) -> DispatchResultWithPostInfo {212 ensure!(213 token == TokenId::default(),214 <Error<T>>::FungibleItemsHaveNoId215 );216217 with_weight(218 <Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget),219 <CommonWeights<T>>::transfer(),220 )221 }222223 fn approve(224 &self,225 sender: T::CrossAccountId,226 spender: T::CrossAccountId,227 token: TokenId,228 amount: u128,229 _nesting_budget: &dyn Budget,230 ) -> DispatchResultWithPostInfo {231 ensure!(232 token == TokenId::default(),233 <Error<T>>::FungibleItemsHaveNoId234 );235236 with_weight(237 <Pallet<T>>::set_allowance(self, &sender, &spender, amount),238 <CommonWeights<T>>::approve(),239 )240 }241242 fn transfer_from(243 &self,244 sender: T::CrossAccountId,245 from: T::CrossAccountId,246 to: T::CrossAccountId,247 token: TokenId,248 amount: u128,249 nesting_budget: &dyn Budget,250 ) -> DispatchResultWithPostInfo {251 ensure!(252 token == TokenId::default(),253 <Error<T>>::FungibleItemsHaveNoId254 );255256 with_weight(257 <Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, nesting_budget),258 <CommonWeights<T>>::transfer_from(),259 )260 }261262 fn burn_from(263 &self,264 sender: T::CrossAccountId,265 from: T::CrossAccountId,266 token: TokenId,267 amount: u128,268 nesting_budget: &dyn Budget,269 ) -> DispatchResultWithPostInfo {270 ensure!(271 token == TokenId::default(),272 <Error<T>>::FungibleItemsHaveNoId273 );274275 with_weight(276 <Pallet<T>>::burn_from(self, &sender, &from, amount, nesting_budget),277 <CommonWeights<T>>::burn_from(),278 )279 }280281 fn set_collection_properties(282 &self,283 _sender: T::CrossAccountId,284 _property: Vec<Property>,285 ) -> DispatchResultWithPostInfo {286 fail!(<Error<T>>::SettingPropertiesNotAllowed)287 }288289 fn delete_collection_properties(290 &self,291 _sender: &T::CrossAccountId,292 _property_keys: Vec<PropertyKey>,293 ) -> DispatchResultWithPostInfo {294 fail!(<Error<T>>::SettingPropertiesNotAllowed)295 }296297 fn set_token_properties(298 &self,299 _sender: T::CrossAccountId,300 _token_id: TokenId,301 _property: Vec<Property>,302 ) -> DispatchResultWithPostInfo {303 fail!(<Error<T>>::SettingPropertiesNotAllowed)304 }305306 fn set_property_permissions(307 &self,308 _sender: &T::CrossAccountId,309 _property_permissions: Vec<PropertyKeyPermission>,310 ) -> DispatchResultWithPostInfo {311 fail!(<Error<T>>::SettingPropertiesNotAllowed)312 }313314 fn delete_token_properties(315 &self,316 _sender: T::CrossAccountId,317 _token_id: TokenId,318 _property_keys: Vec<PropertyKey>,319 ) -> DispatchResultWithPostInfo {320 fail!(<Error<T>>::SettingPropertiesNotAllowed)321 }322323 fn check_nesting(324 &self,325 _sender: <T>::CrossAccountId,326 _from: (CollectionId, TokenId),327 _under: TokenId,328 _budget: &dyn Budget,329 ) -> sp_runtime::DispatchResult {330 fail!(<Error<T>>::FungibleDisallowsNesting)331 }332333 fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}334335 fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}336337 fn collection_tokens(&self) -> Vec<TokenId> {338 vec![TokenId::default()]339 }340341 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {342 if <Balance<T>>::get((self.id, account)) != 0 {343 vec![TokenId::default()]344 } else {345 vec![]346 }347 }348349 fn token_exists(&self, token: TokenId) -> bool {350 token == TokenId::default()351 }352353 fn last_token_id(&self) -> TokenId {354 TokenId::default()355 }356357 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {358 None359 }360361 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {362 None363 }364365 fn token_properties(366 &self,367 _token_id: TokenId,368 _keys: Option<Vec<PropertyKey>>,369 ) -> Vec<Property> {370 Vec::new()371 }372373 fn total_supply(&self) -> u32 {374 1375 }376377 fn account_balance(&self, account: T::CrossAccountId) -> u32 {378 if <Balance<T>>::get((self.id, account)) != 0 {379 1380 } else {381 0382 }383 }384385 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {386 if token != TokenId::default() {387 return 0;388 }389 <Balance<T>>::get((self.id, account))390 }391392 fn allowance(393 &self,394 sender: T::CrossAccountId,395 spender: T::CrossAccountId,396 token: TokenId,397 ) -> u128 {398 if token != TokenId::default() {399 return 0;400 }401 <Allowance<T>>::get((self.id, sender, spender))402 }403}