From c88ca14fd656fe77df8a6495109c894c69de3852 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Tue, 01 Dec 2020 12:10:32 +0000 Subject: [PATCH] Merge pull request #23 from usetech-llc/feature/nftpar-184 Errors messages --- --- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -8,7 +8,7 @@ use codec::{Decode, Encode}; pub use frame_support::{ - construct_runtime, decl_event, decl_module, decl_storage, + construct_runtime, decl_event, decl_module, decl_storage, decl_error, dispatch::DispatchResult, ensure, fail, parameter_types, traits::{ @@ -260,6 +260,59 @@ } } + +decl_error! { + /// Error for non-fungible-token module. + pub enum Error for Module { + /// Total collections bound exceeded + TotalCollectionsLimitExceeded, + /// Decimal_points parameter must be lower than 4 + CollectionDecimalPointLimitExceeded, + /// Collection name can not be longer than 63 char + CollectionNameLimitExceeded, + /// Collection description can not be longer than 255 char + CollectionDescriptionLimitExceeded, + /// Token prefix can not be longer than 15 char + CollectionTokenPrefixLimitExceeded, + /// This collection does not exist + CollectionNotFound, + /// Item not exists + TokenNotFound, + /// Arithmetic calculation overflow + NumOverflow, + /// Account already has admin role + AlreadyAdmin, + /// You do not own this collection + NoPermission, + /// This address is not set as sponsor, use setCollectionSponsor first + ConfirmUnsetSponsorFail, + /// Collection is not in mint mode + PublicMintingNotAllowed, + /// Sender parameter and item owner must be equal + MustBeTokenOwner, + /// Item balance not enouth + TokenValueTooLow, + /// Size of item is too large + NftSizeLimitExceeded, + /// Size of item must be 0 with fungible type + FungibleUnexpectedParam, + /// No approve found + ApproveNotFound, + /// Requested value more than approved + TokenValueNotEnough, + /// Only approved addresses can call this method + ApproveRequired, + /// Address is not in white list + AddresNotInWhiteList, + /// Number of collection admins bound exceeded + CollectionAdminsLimitExceeded, + /// Owned tokens by a single address bound exceeded + AddressOwnershipLimitExceeded, + /// Length of items properties must be greater than 0 + EmptyArgument, + } +} + pub trait Trait: system::Trait + Sized + transaction_payment::Trait + pallet_contracts::Trait { type Event: From> + Into<::Event>; @@ -378,6 +431,7 @@ pub struct Module for enum Call where origin: T::Origin { fn deposit_event() = default; + type Error = Error; fn on_initialize(now: T::BlockNumber) -> Weight { @@ -424,32 +478,32 @@ }; // bound Total number of collections - ensure!(CollectionCount::get() < ChainLimit::get().collection_numbers_limit, "Total collections bound exceeded"); + ensure!(CollectionCount::get() < ChainLimit::get().collection_numbers_limit, Error::::TotalCollectionsLimitExceeded); // check params - ensure!(decimal_points <= 4, "decimal_points parameter must be lower than 4"); + ensure!(decimal_points <= 4, Error::::CollectionDecimalPointLimitExceeded); let mut name = collection_name.to_vec(); name.push(0); - ensure!(name.len() <= 64, "Collection name can not be longer than 63 char"); + ensure!(name.len() <= 64, Error::::CollectionNameLimitExceeded); let mut description = collection_description.to_vec(); description.push(0); - ensure!(name.len() <= 256, "Collection description can not be longer than 255 char"); + ensure!(name.len() <= 256, Error::::CollectionDescriptionLimitExceeded); let mut prefix = token_prefix.to_vec(); prefix.push(0); - ensure!(prefix.len() <= 16, "Token prefix can not be longer than 15 char"); + ensure!(prefix.len() <= 16, Error::::CollectionTokenPrefixLimitExceeded); // Generate next collection ID let next_id = CreatedCollectionCount::get() .checked_add(1) - .expect("collection id error"); + .ok_or(Error::::NumOverflow)?; // bound counter let total = CollectionCount::get() .checked_add(1) - .expect("collection counter error"); + .ok_or(Error::::NumOverflow)?; CreatedCollectionCount::put(next_id); CollectionCount::put(total); @@ -516,7 +570,7 @@ // bound couter let total = CollectionCount::get() .checked_sub(1) - .expect("collection counter error"); + .ok_or(Error::::NumOverflow)?; CollectionCount::put(total); } @@ -685,11 +739,11 @@ if >::contains_key(collection_id) { admin_arr = >::get(collection_id); - ensure!(!admin_arr.contains(&new_admin_id), "Account already has admin role"); + ensure!(!admin_arr.contains(&new_admin_id), Error::::AlreadyAdmin); } // Number of collection admins - ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, "Number of collection admins bound exceeded"); + ensure!((admin_arr.len() as u64) < ChainLimit::get().collections_admins_limit, Error::::CollectionAdminsLimitExceeded); admin_arr.push(new_admin_id); >::insert(collection_id, admin_arr); @@ -738,10 +792,10 @@ pub fn set_collection_sponsor(origin, collection_id: u64, new_sponsor: T::AccountId) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + ensure!(>::contains_key(collection_id), Error::::CollectionNotFound); let mut target_collection = >::get(collection_id); - ensure!(sender == target_collection.owner, "You do not own this collection"); + ensure!(sender == target_collection.owner, Error::::NoPermission); target_collection.unconfirmed_sponsor = new_sponsor; >::insert(collection_id, target_collection); @@ -760,10 +814,10 @@ pub fn confirm_sponsorship(origin, collection_id: u64) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + ensure!(>::contains_key(collection_id), Error::::CollectionNotFound); let mut target_collection = >::get(collection_id); - ensure!(sender == target_collection.unconfirmed_sponsor, "This address is not set as sponsor, use setCollectionSponsor first"); + ensure!(sender == target_collection.unconfirmed_sponsor, Error::::ConfirmUnsetSponsorFail); target_collection.sponsor = target_collection.unconfirmed_sponsor; target_collection.unconfirmed_sponsor = T::AccountId::default(); @@ -785,10 +839,10 @@ pub fn remove_collection_sponsor(origin, collection_id: u64) -> DispatchResult { let sender = ensure_signed(origin)?; - ensure!(>::contains_key(collection_id), "This collection does not exist"); + ensure!(>::contains_key(collection_id), Error::::CollectionNotFound); let mut target_collection = >::get(collection_id); - ensure!(sender == target_collection.owner, "You do not own this collection"); + ensure!(sender == target_collection.owner, Error::::NoPermission); target_collection.sponsor = T::AccountId::default(); >::insert(collection_id, target_collection); @@ -859,7 +913,7 @@ .sum())] pub fn create_multiple_items(origin, collection_id: u64, owner: T::AccountId, items_data: Vec) -> DispatchResult { - ensure!(items_data.len() > 0, "Length of items properties must be greater than 0."); + ensure!(items_data.len() > 0, Error::::EmptyArgument); let sender = ensure_signed(origin)?; Self::collection_exists(collection_id)?; @@ -900,7 +954,7 @@ let target_collection = >::get(collection_id); ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), - "Only item owner, collection owner and admins can modify item"); + Error::::NoPermission); if target_collection.access == AccessMode::WhiteList { Self::check_white_list(collection_id, &sender)?; @@ -952,7 +1006,7 @@ let target_collection = >::get(collection_id); ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), - "Only item owner, collection owner and admins can modify item"); + Error::::NoPermission); if target_collection.access == AccessMode::WhiteList { Self::check_white_list(collection_id, &sender)?; @@ -994,7 +1048,7 @@ let target_collection = >::get(collection_id); ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), - "Only item owner, collection owner and admins can approve"); + Error::::NoPermission); if target_collection.access == AccessMode::WhiteList { Self::check_white_list(collection_id, &sender)?; @@ -1056,14 +1110,14 @@ if opt_item.is_some() { appoved_transfer = true; - ensure!(opt_item.unwrap().amount >= value, "Requested value more than approved"); + ensure!(opt_item.unwrap().amount >= value, Error::::TokenValueNotEnough); } } // Transfer permissions check let target_collection = >::get(collection_id); - ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), - "Only item owner, collection owner and admins can modify items"); + ensure!(appoved_transfer || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), + Error::::NoPermission); if target_collection.access == AccessMode::WhiteList { Self::check_white_list(collection_id, &sender)?; @@ -1130,7 +1184,7 @@ let target_collection = >::get(collection_id); ensure!(Self::is_item_owner(sender.clone(), collection_id, item_id) || Self::is_owner_or_admin_permissions(collection_id, sender.clone()), - "Only item owner, collection owner and admins can modify item"); + Error::::NoPermission); Self::item_exists(collection_id, item_id, &target_collection.mode)?; @@ -1263,7 +1317,7 @@ let owner = >::get(&contract_address); is_owner = sender == owner; } - ensure!(is_owner, "Only contract owner may call this method"); + ensure!(is_owner, Error::::NoPermission); >::insert(contract_address, enable); Ok(()) @@ -1277,7 +1331,7 @@ fn can_create_items_in_collection(collection_id: u64, collection: &CollectionType, sender: &T::AccountId, owner: &T::AccountId) -> DispatchResult { if !Self::is_owner_or_admin_permissions(collection_id, sender.clone()) { - ensure!(collection.mint_mode == true, "Public minting is not allowed for this collection"); + ensure!(collection.mint_mode == true, Error::::PublicMintingNotAllowed); Self::check_white_list(collection_id, owner)?; Self::check_white_list(collection_id, sender)?; } @@ -1367,7 +1421,7 @@ fn add_fungible_item(item: FungibleItemType) -> DispatchResult { let current_index = ::get(item.collection) .checked_add(1) - .expect("Item list index id error"); + .ok_or(Error::::NumOverflow)?; let itemcopy = item.clone(); let owner = item.owner.clone(); let value = item.value as u64; @@ -1384,7 +1438,7 @@ // Update balance let new_balance = >::get(item.collection, owner.clone()) .checked_add(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(item.collection, owner.clone(), new_balance); Ok(()) @@ -1393,7 +1447,7 @@ fn add_refungible_item(item: ReFungibleItemType) -> DispatchResult { let current_index = ::get(item.collection) .checked_add(1) - .expect("Item list index id error"); + .ok_or(Error::::NumOverflow)?; let itemcopy = item.clone(); let value = item.owner.first().unwrap().fraction as u64; @@ -1411,7 +1465,7 @@ // Update balance let new_balance = >::get(item.collection, owner.clone()) .checked_add(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(item.collection, owner.clone(), new_balance); Ok(()) @@ -1420,7 +1474,7 @@ fn add_nft_item(item: NftItemType) -> DispatchResult { let current_index = ::get(item.collection) .checked_add(1) - .expect("Item list index id error"); + .ok_or(Error::::NumOverflow)?; let item_owner = item.owner.clone(); let collection_id = item.collection.clone(); @@ -1436,7 +1490,7 @@ // Update balance let new_balance = >::get(collection_id, item_owner.clone()) .checked_add(1) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, item_owner.clone(), new_balance); Ok(()) @@ -1449,7 +1503,7 @@ ) -> DispatchResult { ensure!( >::contains_key(collection_id, item_id), - "Item does not exists" + Error::::TokenNotFound ); let collection = >::get(collection_id, item_id); let item = collection @@ -1466,7 +1520,7 @@ // update balance let new_balance = >::get(collection_id, item.owner.clone()) .checked_sub(item.fraction as u64) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, item.owner.clone(), new_balance); >::remove(collection_id, item_id); @@ -1477,7 +1531,7 @@ fn burn_nft_item(collection_id: u64, item_id: u64) -> DispatchResult { ensure!( >::contains_key(collection_id, item_id), - "Item does not exists" + Error::::TokenNotFound ); let item = >::get(collection_id, item_id); Self::remove_token_index(collection_id, item_id, item.owner.clone())?; @@ -1488,7 +1542,7 @@ // update balance let new_balance = >::get(collection_id, item.owner.clone()) .checked_sub(1) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, item.owner.clone(), new_balance); >::remove(collection_id, item_id); @@ -1498,7 +1552,7 @@ fn burn_fungible_item(collection_id: u64, item_id: u64) -> DispatchResult { ensure!( >::contains_key(collection_id, item_id), - "Item does not exists" + Error::::TokenNotFound ); let item = >::get(collection_id, item_id); Self::remove_token_index(collection_id, item_id, item.owner.clone())?; @@ -1509,7 +1563,7 @@ // update balance let new_balance = >::get(collection_id, item.owner.clone()) .checked_sub(item.value as u64) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, item.owner.clone(), new_balance); >::remove(collection_id, item_id); @@ -1520,7 +1574,7 @@ fn collection_exists(collection_id: u64) -> DispatchResult { ensure!( >::contains_key(collection_id), - "This collection does not exist" + Error::::CollectionNotFound ); Ok(()) } @@ -1531,7 +1585,7 @@ let target_collection = >::get(collection_id); ensure!( subject == target_collection.owner, - "You do not own this collection" + Error::::NoPermission ); Ok(()) @@ -1560,7 +1614,7 @@ ensure!( result, - "You do not have permissions to modify this collection" + Error::::NoPermission ); Ok(()) } @@ -1586,7 +1640,7 @@ } fn check_white_list(collection_id: u64, address: &T::AccountId) -> DispatchResult { - let mes = "Address is not in white list"; + let mes = Error::::AddresNotInWhiteList; ensure!(>::contains_key(collection_id), mes); let wl = >::get(collection_id); ensure!(wl.contains(address), mes); @@ -1603,18 +1657,18 @@ ) -> DispatchResult { ensure!( >::contains_key(collection_id, item_id), - "Item not exists" + Error::::TokenNotFound ); let full_item = >::get(collection_id, item_id); let amount = full_item.value; - ensure!(amount >= value.into(), "Item balance not enouth"); + ensure!(amount >= value.into(), Error::::TokenValueTooLow); // update balance let balance_old_owner = >::get(collection_id, owner.clone()) .checked_sub(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, owner.clone(), balance_old_owner); let mut new_owner_account_id = 0; @@ -1636,7 +1690,7 @@ // update balance let balance_new_owner = >::get(collection_id, new_owner.clone()) .checked_add(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, new_owner.clone(), balance_new_owner); // update index collection @@ -1654,7 +1708,7 @@ // update balance let balance_new_owner = >::get(collection_id, new_owner.clone()) .checked_add(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, new_owner.clone(), balance_new_owner); >::insert(collection_id, new_owner_account_id, item); @@ -1692,7 +1746,7 @@ ) -> DispatchResult { ensure!( >::contains_key(collection_id, item_id), - "Item not exists" + Error::::TokenNotFound ); let full_item = >::get(collection_id, item_id); @@ -1701,20 +1755,20 @@ .iter() .filter(|i| i.owner == owner) .next() - .unwrap(); + .ok_or(Error::::NumOverflow)?; let amount = item.fraction; - ensure!(amount >= value.into(), "Item balance not enouth"); + ensure!(amount >= value.into(), Error::::TokenValueTooLow); // update balance let balance_old_owner = >::get(collection_id, item.owner.clone()) .checked_sub(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, item.owner.clone(), balance_old_owner); let balance_new_owner = >::get(collection_id, new_owner.clone()) .checked_add(value) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, new_owner.clone(), balance_new_owner); let old_owner = item.owner.clone(); @@ -1777,25 +1831,25 @@ ) -> DispatchResult { ensure!( >::contains_key(collection_id, item_id), - "Item not exists" + Error::::TokenNotFound ); let mut item = >::get(collection_id, item_id); ensure!( sender == item.owner, - "sender parameter and item owner must be equal" + Error::::MustBeTokenOwner ); // update balance let balance_old_owner = >::get(collection_id, item.owner.clone()) .checked_sub(1) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, item.owner.clone(), balance_old_owner); let balance_new_owner = >::get(collection_id, new_owner.clone()) .checked_add(1) - .unwrap(); + .ok_or(Error::::NumOverflow)?; >::insert(collection_id, new_owner.clone(), balance_new_owner); // change owner @@ -1817,9 +1871,9 @@ mode: &CollectionMode ) -> DispatchResult { match mode { - CollectionMode::NFT => ensure!(>::contains_key(collection_id, item_id), "Item does not exists"), - CollectionMode::ReFungible(_) => ensure!(>::contains_key(collection_id, item_id), "Item does not exists"), - CollectionMode::Fungible(_) => ensure!(>::contains_key(collection_id, item_id), "Item does not exists"), + CollectionMode::NFT => ensure!(>::contains_key(collection_id, item_id), Error::::TokenNotFound), + CollectionMode::ReFungible(_) => ensure!(>::contains_key(collection_id, item_id), Error::::TokenNotFound), + CollectionMode::Fungible(_) => ensure!(>::contains_key(collection_id, item_id), Error::::TokenNotFound), _ => () }; @@ -1876,7 +1930,7 @@ // Generate next collection ID let next_id = CreatedCollectionCount::get() .checked_add(1) - .expect("collection id error"); + .unwrap(); CreatedCollectionCount::put(next_id); } @@ -1884,7 +1938,7 @@ fn init_nft_token(item: &NftItemType) { let current_index = ::get(item.collection) .checked_add(1) - .expect("Item list index id error"); + .unwrap(); let item_owner = item.owner.clone(); let collection_id = item.collection.clone(); @@ -1902,7 +1956,7 @@ fn init_fungible_token(item: &FungibleItemType) { let current_index = ::get(item.collection) .checked_add(1) - .expect("Item list index id error"); + .unwrap(); let owner = item.owner.clone(); let value = item.value as u64; @@ -1920,7 +1974,7 @@ fn init_refungible_token(item: &ReFungibleItemType) { let current_index = ::get(item.collection) .checked_add(1) - .expect("Item list index id error"); + .unwrap(); let value = item.owner.first().unwrap().fraction as u64; let owner = item.owner.first().unwrap().owner.clone(); @@ -1943,10 +1997,11 @@ // bound Owned tokens by a single address let count = >::get(owner.clone()); - ensure!(count < ChainLimit::get().account_token_ownership_limit, "Owned tokens by a single address bound exceeded"); + ensure!(count < ChainLimit::get().account_token_ownership_limit, Error::::AddressOwnershipLimitExceeded); - >::insert(owner.clone(), - count.checked_add(1).unwrap()); + >::insert(owner.clone(), count + .checked_add(1) + .ok_or(Error::::NumOverflow)?); } else { >::insert(owner.clone(), 1); @@ -1980,7 +2035,9 @@ // update counter >::insert(owner.clone(), - >::get(owner.clone()).checked_sub(1).unwrap()); + >::get(owner.clone()) + .checked_sub(1) + .ok_or(Error::::NumOverflow)?); let list_exists = >::contains_key(collection_id, owner.clone()); -- gitstuff