--- a/pallets/nft/src/lib.rs +++ b/pallets/nft/src/lib.rs @@ -1295,11 +1295,9 @@ Self::check_white_list(&target_collection, &spender)?; } - let allowance_exists = >::contains_key(collection_id, (item_id, &sender, &spender)); - let mut allowance: u128 = amount; - if allowance_exists { - allowance += >::get(collection_id, (item_id, &sender, &spender)); - } + let allowance: u128 = amount + .checked_add(>::get(collection_id, (item_id, &sender, &spender))) + .ok_or(Error::::NumOverflow)?; if let Some(limit) = allowance_limit { ensure!(limit >= allowance, Error::::TokenValueTooLow); } @@ -1334,23 +1332,16 @@ let sender = ensure_signed(origin)?; let target_collection = Self::get_collection(collection_id)?; - - let mut appoved_transfer = false; // Check approval - let mut approval: u128 = 0; - if >::contains_key(collection_id, (item_id, &from, &sender)) { - approval = >::get(collection_id, (item_id, &from, &sender)); - ensure!(approval >= value, Error::::TokenValueNotEnough); - appoved_transfer = true; - } + let approval: u128 = >::get(collection_id, (item_id, &from, &sender)); // Limits check Self::is_correct_transfer(&target_collection, &recipient)?; // Transfer permissions check ensure!( - appoved_transfer || + approval >= value || ( target_collection.limits.owner_can_transfer && Self::is_owner_or_admin_permissions(&target_collection, sender.clone()) --- a/pallets/nft/src/mock.rs +++ b/pallets/nft/src/mock.rs @@ -24,6 +24,7 @@ { System: frame_system::{Module, Call, Config, Storage, Event}, TemplateModule: pallet_template::{Module, Call, Storage}, + Balances: pallet_balances::{Module, Call, Storage}, } ); @@ -134,13 +135,16 @@ } parameter_types! { - pub const CollectionCreationPrice: u64 = 1_000_000_000_000; + pub const CollectionCreationPrice: u32 = 0; + pub TreasuryAccountId: u64 = 1234; } impl pallet_template::Config for Test { type Event = (); type WeightInfo = (); type CollectionCreationPrice = CollectionCreationPrice; + type Currency = pallet_balances::Module; + type TreasuryAccountId = TreasuryAccountId; } // Build genesis storage according to the mock runtime. --- a/pallets/nft/src/tests.rs +++ b/pallets/nft/src/tests.rs @@ -121,8 +121,9 @@ let data = default_nft_data(); create_test_item(collection_id, &data.clone().into()); - assert_eq!(TemplateModule::nft_item_id(collection_id, 1).const_data, data.const_data); - assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, data.variable_data); + let item = TemplateModule::nft_item_id(collection_id, 1).unwrap(); + assert_eq!(item.const_data, data.const_data); + assert_eq!(item.variable_data, data.variable_data); }); } @@ -146,8 +147,9 @@ items_data.clone().into_iter().map(|d| { d.into() }).collect() )); for (index, data) in items_data.iter().enumerate() { - assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).const_data.to_vec(), data.const_data); - assert_eq!(TemplateModule::nft_item_id(1, (index + 1) as TokenId).variable_data.to_vec(), data.variable_data); + let item = TemplateModule::nft_item_id(1, (index + 1) as TokenId).unwrap(); + assert_eq!(item.const_data.to_vec(), data.const_data); + assert_eq!(item.variable_data.to_vec(), data.variable_data); } }); } @@ -160,16 +162,17 @@ let data = default_re_fungible_data(); create_test_item(collection_id, &data.clone().into()); + let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap(); assert_eq!( - TemplateModule::refungible_item_id(collection_id, 1).const_data, + item.const_data, data.const_data ); assert_eq!( - TemplateModule::refungible_item_id(collection_id, 1).variable_data, + item.variable_data, data.variable_data ); assert_eq!( - TemplateModule::refungible_item_id(collection_id, 1).owner[0], + item.owner[0], Ownership { owner: 1, fraction: 1023 @@ -197,7 +200,7 @@ )); for (index, data) in items_data.iter().enumerate() { - let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId); + let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId).unwrap(); assert_eq!(item.const_data.to_vec(), data.const_data); assert_eq!(item.variable_data.to_vec(), data.variable_data); assert_eq!( @@ -299,28 +302,31 @@ let origin1 = Origin::signed(1); let origin2 = Origin::signed(2); - assert_eq!( - TemplateModule::refungible_item_id(collection_id, 1).const_data, - data.const_data - ); - assert_eq!( - TemplateModule::refungible_item_id(collection_id, 1).variable_data, - data.variable_data - ); - assert_eq!( - TemplateModule::refungible_item_id(collection_id, 1).owner[0], - Ownership { - owner: 1, - fraction: 1023 - } - ); + { + let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap(); + assert_eq!( + item.const_data, + data.const_data + ); + assert_eq!( + item.variable_data, + data.variable_data + ); + assert_eq!( + item.owner[0], + Ownership { + owner: 1, + fraction: 1023 + } + ); + } assert_eq!(TemplateModule::balance_count(1, 1), 1023); assert_eq!(TemplateModule::address_tokens(1, 1), [1]); // change owner scenario assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1023)); assert_eq!( - TemplateModule::refungible_item_id(1, 1).owner[0], + TemplateModule::refungible_item_id(1, 1).unwrap().owner[0], Ownership { owner: 2, fraction: 1023 @@ -333,20 +339,23 @@ // split item scenario assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 500)); - assert_eq!( - TemplateModule::refungible_item_id(1, 1).owner[0], - Ownership { - owner: 2, - fraction: 523 - } - ); - assert_eq!( - TemplateModule::refungible_item_id(1, 1).owner[1], - Ownership { - owner: 3, - fraction: 500 - } - ); + { + let item = TemplateModule::refungible_item_id(1, 1).unwrap(); + assert_eq!( + item.owner[0], + Ownership { + owner: 2, + fraction: 523 + } + ); + assert_eq!( + item.owner[1], + Ownership { + owner: 3, + fraction: 500 + } + ); + } assert_eq!(TemplateModule::balance_count(1, 2), 523); assert_eq!(TemplateModule::balance_count(1, 3), 500); assert_eq!(TemplateModule::address_tokens(1, 2), [1]); @@ -354,20 +363,23 @@ // split item and new owner has account scenario assert_ok!(TemplateModule::transfer(origin2.clone(), 3, 1, 1, 200)); - assert_eq!( - TemplateModule::refungible_item_id(1, 1).owner[0], - Ownership { - owner: 2, - fraction: 323 - } - ); - assert_eq!( - TemplateModule::refungible_item_id(1, 1).owner[1], - Ownership { - owner: 3, - fraction: 700 - } - ); + { + let item = TemplateModule::refungible_item_id(1, 1).unwrap(); + assert_eq!( + item.owner[0], + Ownership { + owner: 2, + fraction: 323 + } + ); + assert_eq!( + item.owner[1], + Ownership { + owner: 3, + fraction: 700 + } + ); + } assert_eq!(TemplateModule::balance_count(1, 2), 323); assert_eq!(TemplateModule::balance_count(1, 3), 700); assert_eq!(TemplateModule::address_tokens(1, 2), [1]); @@ -390,7 +402,7 @@ let origin1 = Origin::signed(1); // default scenario assert_ok!(TemplateModule::transfer(origin1.clone(), 2, 1, 1, 1000)); - assert_eq!(TemplateModule::nft_item_id(1, 1).owner, 2); + assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, 2); assert_eq!(TemplateModule::balance_count(1, 1), 0); assert_eq!(TemplateModule::balance_count(1, 2), 1); // assert_eq!(TemplateModule::address_tokens(1, 1), []); @@ -456,7 +468,7 @@ let data = default_nft_data(); create_test_item(collection_id, &data.clone().into()); - assert_eq!(TemplateModule::nft_item_id(1, 1).const_data, data.const_data); + assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().const_data, data.const_data); assert_eq!(TemplateModule::balance_count(1, 1), 1); assert_eq!(TemplateModule::address_tokens(1, 1), [1]); @@ -605,7 +617,7 @@ 1, 1, 4 - ), Error::::TokenValueNotEnough); + ), Error::::NoPermission); }); } @@ -685,7 +697,7 @@ assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5)); assert_noop!( TemplateModule::burn_item(origin1.clone(), 1, 1, 5), - Error::::TokenNotFound + Error::::TokenValueNotEnough ); assert_eq!(TemplateModule::balance_count(1, 1), 0); @@ -807,9 +819,9 @@ assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 1); assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 5); assert_eq!(TemplateModule::balance_count(re_fungible_collection_id, 1), 1023); - assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).owner, 1); + assert_eq!(TemplateModule::nft_item_id(nft_collection_id, 1).unwrap().owner, 1); assert_eq!(TemplateModule::fungible_item_id(fungible_collection_id, 1).value, 5); - assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).owner[0].owner, 1); + assert_eq!(TemplateModule::refungible_item_id(re_fungible_collection_id, 1).unwrap().owner[0].owner, 1); }); } @@ -1876,7 +1888,7 @@ let variable_data = b"test set_variable_meta_data method.".to_vec(); assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone())); - assert_eq!(TemplateModule::nft_item_id(collection_id, 1).variable_data, variable_data); + assert_eq!(TemplateModule::nft_item_id(collection_id, 1).unwrap().variable_data, variable_data); }); } @@ -1895,7 +1907,7 @@ let variable_data = b"test set_variable_meta_data method.".to_vec(); assert_ok!(TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data.clone())); - assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).variable_data, variable_data); + assert_eq!(TemplateModule::refungible_item_id(collection_id, 1).unwrap().variable_data, variable_data); }); }