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, RefungibleExtensions, 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, TotalSupply, Balance, Config, Error, FungibleHandle, Pallet, SelfWeightOf,29 weights::WeightInfo,30};3132pub struct CommonWeights<T: Config>(PhantomData<T>);33impl<T: Config> CommonWeightInfo<T::CrossAccountId> for CommonWeights<T> {34 fn create_item() -> Weight {35 <SelfWeightOf<T>>::create_item()36 }3738 fn create_multiple_items(_data: &[CreateItemData]) -> Weight {39 40 Self::create_item()41 }4243 fn create_multiple_items_ex(data: &CreateItemExData<T::CrossAccountId>) -> Weight {44 match data {45 CreateItemExData::Fungible(f) => {46 <SelfWeightOf<T>>::create_multiple_items_ex(f.len() as u32)47 }48 _ => 0,49 }50 }5152 fn burn_item() -> Weight {53 <SelfWeightOf<T>>::burn_item()54 }5556 fn set_collection_properties(_amount: u32) -> Weight {57 58 059 }6061 fn delete_collection_properties(_amount: u32) -> Weight {62 63 064 }6566 fn set_token_properties(_amount: u32) -> Weight {67 68 069 }7071 fn delete_token_properties(_amount: u32) -> Weight {72 73 074 }7576 fn set_token_property_permissions(_amount: u32) -> Weight {77 78 079 }8081 fn transfer() -> Weight {82 <SelfWeightOf<T>>::transfer()83 }8485 fn approve() -> Weight {86 <SelfWeightOf<T>>::approve()87 }8889 fn transfer_from() -> Weight {90 <SelfWeightOf<T>>::transfer_from()91 }9293 fn burn_from() -> Weight {94 <SelfWeightOf<T>>::burn_from()95 }9697 fn burn_recursively_self_raw() -> Weight {98 99 Self::burn_item() + T::DbWeight::get().reads(1)100 }101102 fn burn_recursively_breadth_raw(_amount: u32) -> Weight {103 104 0105 }106107 fn token_owner() -> Weight {108 0109 }110}111112113114impl<T: Config> CommonCollectionOperations<T> for FungibleHandle<T> {115 fn create_item(116 &self,117 sender: T::CrossAccountId,118 to: T::CrossAccountId,119 data: up_data_structs::CreateItemData,120 nesting_budget: &dyn Budget,121 ) -> DispatchResultWithPostInfo {122 match data {123 up_data_structs::CreateItemData::Fungible(data) => with_weight(124 <Pallet<T>>::create_item(self, &sender, (to, data.value), nesting_budget),125 <CommonWeights<T>>::create_item(),126 ),127 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),128 }129 }130131 fn create_multiple_items(132 &self,133 sender: T::CrossAccountId,134 to: T::CrossAccountId,135 data: Vec<up_data_structs::CreateItemData>,136 nesting_budget: &dyn Budget,137 ) -> DispatchResultWithPostInfo {138 let mut sum: u128 = 0;139 for data in data {140 match data {141 up_data_structs::CreateItemData::Fungible(data) => {142 sum = sum143 .checked_add(data.value)144 .ok_or(ArithmeticError::Overflow)?;145 }146 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),147 }148 }149150 with_weight(151 <Pallet<T>>::create_item(self, &sender, (to, sum), nesting_budget),152 <CommonWeights<T>>::create_item(),153 )154 }155156 fn create_multiple_items_ex(157 &self,158 sender: <T>::CrossAccountId,159 data: up_data_structs::CreateItemExData<<T>::CrossAccountId>,160 nesting_budget: &dyn Budget,161 ) -> DispatchResultWithPostInfo {162 let weight = <CommonWeights<T>>::create_multiple_items_ex(&data);163 let data = match data {164 up_data_structs::CreateItemExData::Fungible(f) => f,165 _ => fail!(<Error<T>>::NotFungibleDataUsedToMintFungibleCollectionToken),166 };167168 with_weight(169 <Pallet<T>>::create_multiple_items(self, &sender, data.into_inner(), nesting_budget),170 weight,171 )172 }173174 fn burn_item(175 &self,176 sender: T::CrossAccountId,177 token: TokenId,178 amount: u128,179 ) -> DispatchResultWithPostInfo {180 ensure!(181 token == TokenId::default(),182 <Error<T>>::FungibleItemsHaveNoId183 );184185 with_weight(186 <Pallet<T>>::burn(self, &sender, amount),187 <CommonWeights<T>>::burn_item(),188 )189 }190191 fn burn_item_recursively(192 &self,193 sender: T::CrossAccountId,194 token: TokenId,195 self_budget: &dyn Budget,196 _breadth_budget: &dyn Budget,197 ) -> DispatchResultWithPostInfo {198 199 ensure!(200 token == TokenId::default(),201 <Error<T>>::FungibleItemsHaveNoId202 );203 ensure!(self_budget.consume(), <StructureError<T>>::DepthLimit,);204205 with_weight(206 <Pallet<T>>::burn(self, &sender, <Balance<T>>::get((self.id, &sender))),207 <CommonWeights<T>>::burn_recursively_self_raw(),208 )209 }210211 fn transfer(212 &self,213 from: T::CrossAccountId,214 to: T::CrossAccountId,215 token: TokenId,216 amount: u128,217 nesting_budget: &dyn Budget,218 ) -> DispatchResultWithPostInfo {219 ensure!(220 token == TokenId::default(),221 <Error<T>>::FungibleItemsHaveNoId222 );223224 with_weight(225 <Pallet<T>>::transfer(self, &from, &to, amount, nesting_budget),226 <CommonWeights<T>>::transfer(),227 )228 }229230 fn approve(231 &self,232 sender: T::CrossAccountId,233 spender: T::CrossAccountId,234 token: TokenId,235 amount: u128,236 ) -> DispatchResultWithPostInfo {237 ensure!(238 token == TokenId::default(),239 <Error<T>>::FungibleItemsHaveNoId240 );241242 with_weight(243 <Pallet<T>>::set_allowance(self, &sender, &spender, amount),244 <CommonWeights<T>>::approve(),245 )246 }247248 fn transfer_from(249 &self,250 sender: T::CrossAccountId,251 from: T::CrossAccountId,252 to: T::CrossAccountId,253 token: TokenId,254 amount: u128,255 nesting_budget: &dyn Budget,256 ) -> DispatchResultWithPostInfo {257 ensure!(258 token == TokenId::default(),259 <Error<T>>::FungibleItemsHaveNoId260 );261262 with_weight(263 <Pallet<T>>::transfer_from(self, &sender, &from, &to, amount, nesting_budget),264 <CommonWeights<T>>::transfer_from(),265 )266 }267268 fn burn_from(269 &self,270 sender: T::CrossAccountId,271 from: T::CrossAccountId,272 token: TokenId,273 amount: u128,274 nesting_budget: &dyn Budget,275 ) -> DispatchResultWithPostInfo {276 ensure!(277 token == TokenId::default(),278 <Error<T>>::FungibleItemsHaveNoId279 );280281 with_weight(282 <Pallet<T>>::burn_from(self, &sender, &from, amount, nesting_budget),283 <CommonWeights<T>>::burn_from(),284 )285 }286287 fn set_collection_properties(288 &self,289 _sender: T::CrossAccountId,290 _property: Vec<Property>,291 ) -> DispatchResultWithPostInfo {292 fail!(<Error<T>>::SettingPropertiesNotAllowed)293 }294295 fn delete_collection_properties(296 &self,297 _sender: &T::CrossAccountId,298 _property_keys: Vec<PropertyKey>,299 ) -> DispatchResultWithPostInfo {300 fail!(<Error<T>>::SettingPropertiesNotAllowed)301 }302303 fn set_token_properties(304 &self,305 _sender: T::CrossAccountId,306 _token_id: TokenId,307 _property: Vec<Property>,308 _nesting_budget: &dyn Budget,309 ) -> DispatchResultWithPostInfo {310 fail!(<Error<T>>::SettingPropertiesNotAllowed)311 }312313 fn set_token_property_permissions(314 &self,315 _sender: &T::CrossAccountId,316 _property_permissions: Vec<PropertyKeyPermission>,317 ) -> DispatchResultWithPostInfo {318 fail!(<Error<T>>::SettingPropertiesNotAllowed)319 }320321 fn delete_token_properties(322 &self,323 _sender: T::CrossAccountId,324 _token_id: TokenId,325 _property_keys: Vec<PropertyKey>,326 _nesting_budget: &dyn Budget,327 ) -> DispatchResultWithPostInfo {328 fail!(<Error<T>>::SettingPropertiesNotAllowed)329 }330331 fn check_nesting(332 &self,333 _sender: <T>::CrossAccountId,334 _from: (CollectionId, TokenId),335 _under: TokenId,336 _nesting_budget: &dyn Budget,337 ) -> sp_runtime::DispatchResult {338 fail!(<Error<T>>::FungibleDisallowsNesting)339 }340341 fn nest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}342343 fn unnest(&self, _under: TokenId, _to_nest: (CollectionId, TokenId)) {}344345 fn collection_tokens(&self) -> Vec<TokenId> {346 vec![TokenId::default()]347 }348349 fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {350 if <Balance<T>>::get((self.id, account)) != 0 {351 vec![TokenId::default()]352 } else {353 vec![]354 }355 }356357 fn token_exists(&self, token: TokenId) -> bool {358 token == TokenId::default()359 }360361 fn last_token_id(&self) -> TokenId {362 TokenId::default()363 }364365 fn token_owner(&self, _token: TokenId) -> Option<T::CrossAccountId> {366 None367 }368369 370 fn token_owners(&self, token: TokenId) -> Vec<T::CrossAccountId> {371 <Pallet<T>>::token_owners(self.id, token).unwrap_or_default()372 }373374 fn token_property(&self, _token_id: TokenId, _key: &PropertyKey) -> Option<PropertyValue> {375 None376 }377378 fn token_properties(379 &self,380 _token_id: TokenId,381 _keys: Option<Vec<PropertyKey>>,382 ) -> Vec<Property> {383 Vec::new()384 }385386 fn total_supply(&self) -> u32 {387 1388 }389390 fn account_balance(&self, account: T::CrossAccountId) -> u32 {391 if <Balance<T>>::get((self.id, account)) != 0 {392 1393 } else {394 0395 }396 }397398 fn balance(&self, account: T::CrossAccountId, token: TokenId) -> u128 {399 if token != TokenId::default() {400 return 0;401 }402 <Balance<T>>::get((self.id, account))403 }404405 fn allowance(406 &self,407 sender: T::CrossAccountId,408 spender: T::CrossAccountId,409 token: TokenId,410 ) -> u128 {411 if token != TokenId::default() {412 return 0;413 }414 <Allowance<T>>::get((self.id, sender, spender))415 }416417 fn refungible_extensions(&self) -> Option<&dyn RefungibleExtensions<T>> {418 None419 }420421 fn total_pieces(&self, token: TokenId) -> Option<u128> {422 if token != TokenId::default() {423 return None;424 }425 <TotalSupply<T>>::try_get(self.id).ok()426 }427}