difftreelog
Fix unit test building
in: master
8 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5097,6 +5097,7 @@
"frame-system-rpc-runtime-api",
"hex-literal",
"nft-data-structs",
+ "orml-vesting",
"pallet-aura",
"pallet-balances",
"pallet-common",
@@ -5120,7 +5121,6 @@
"pallet-transaction-payment-rpc-runtime-api",
"pallet-treasury",
"pallet-unq-scheduler",
- "pallet-vesting",
"pallet-xcm",
"parachain-info",
"parity-scale-codec",
@@ -5308,6 +5308,21 @@
]
[[package]]
+name = "orml-vesting"
+version = "0.4.1-dev"
+source = "git+https://github.com/UniqueNetwork/open-runtime-module-library#d69f226e332ae29b7b33d53d2f06f309d2986ea0"
+dependencies = [
+ "frame-support",
+ "frame-system",
+ "parity-scale-codec",
+ "scale-info",
+ "serde",
+ "sp-io",
+ "sp-runtime",
+ "sp-std",
+]
+
+[[package]]
name = "owning_ref"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
pallets/common/src/lib.rsdiffbeforeafterboth--- a/pallets/common/src/lib.rs
+++ b/pallets/common/src/lib.rs
@@ -273,8 +273,8 @@
TotalCollectionsLimitExceeded,
/// variable_data exceeded data limit.
TokenVariableDataLimitExceeded,
- /// Exceeded max admin amount
- CollectionAdminAmountExceeded,
+ /// Exceeded max admin count
+ CollectionAdminCountExceeded,
/// Collection settings not allowing items transferring
TransferNotAllowed,
@@ -479,10 +479,10 @@
if admin {
let amount = amount
.checked_add(1)
- .ok_or(<Error<T>>::CollectionAdminAmountExceeded)?;
+ .ok_or(<Error<T>>::CollectionAdminCountExceeded)?;
ensure!(
amount <= Self::collection_admins_limit(),
- <Error<T>>::CollectionAdminAmountExceeded,
+ <Error<T>>::CollectionAdminCountExceeded,
);
// =========
pallets/fungible/src/common.rsdiffbeforeafterboth--- a/pallets/fungible/src/common.rs
+++ b/pallets/fungible/src/common.rs
@@ -182,7 +182,7 @@
_token: TokenId,
_data: Vec<u8>,
) -> DispatchResultWithPostInfo {
- fail!(<Error<T>>::FungibleItemsHaveData)
+ fail!(<Error<T>>::FungibleItemsDontHaveData)
}
fn account_tokens(&self, account: T::CrossAccountId) -> Vec<TokenId> {
pallets/fungible/src/lib.rsdiffbeforeafterboth--- a/pallets/fungible/src/lib.rs
+++ b/pallets/fungible/src/lib.rs
@@ -35,7 +35,7 @@
/// Not default id passed as TokenId argument
FungibleItemsHaveNoId,
/// Tried to set data for fungible item
- FungibleItemsHaveData,
+ FungibleItemsDontHaveData,
}
#[pallet::config]
@@ -44,15 +44,15 @@
}
#[pallet::pallet]
- #[pallet::generate_store(pub(super) trait Store)]
+ #[pallet::generate_store(pub trait Store)]
pub struct Pallet<T>(_);
#[pallet::storage]
- pub(super) type TotalSupply<T: Config> =
+ pub type TotalSupply<T: Config> =
StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u128, QueryKind = ValueQuery>;
#[pallet::storage]
- pub(super) type Balance<T: Config> = StorageNMap<
+ pub type Balance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
Key<Blake2_128Concat, T::CrossAccountId>,
@@ -62,7 +62,7 @@
>;
#[pallet::storage]
- pub(super) type Allowance<T: Config> = StorageNMap<
+ pub type Allowance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
Key<Blake2_128, T::CrossAccountId>,
pallets/nft/src/mock.rsdiffbeforeafterboth--- a/pallets/nft/src/mock.rs
+++ b/pallets/nft/src/mock.rs
@@ -124,25 +124,35 @@
#[derive(Encode, Decode, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, TypeInfo)]
pub struct TestCrossAccountId(u64, sp_core::H160);
impl CrossAccountId<u64> for TestCrossAccountId {
+ fn as_sub(&self) -> &u64 {
+ &self.0
+ }
+ fn as_eth(&self) -> &sp_core::H160 {
+ &self.1
+ }
fn from_sub(sub: u64) -> Self {
let mut eth = [0; 20];
eth[12..20].copy_from_slice(&sub.to_be_bytes());
Self(sub, sp_core::H160(eth))
}
- fn as_sub(&self) -> &u64 {
- &self.0
- }
fn from_eth(eth: sp_core::H160) -> Self {
let mut sub_raw = [0; 8];
sub_raw.copy_from_slice(ð.0[0..8]);
let sub = u64::from_be_bytes(sub_raw);
Self(sub, eth)
}
- fn as_eth(&self) -> &sp_core::H160 {
- &self.1
+ fn conv_eq(&self, other: &Self) -> bool {
+ self.as_sub() == other.as_sub()
+ }
+}
+
+impl Default for TestCrossAccountId {
+ fn default() -> Self {
+ Self::from_sub(0)
}
}
+
pub struct TestEtheremTransactionSender;
impl pallet_ethereum::EthereumTransactionSender for TestEtheremTransactionSender {
fn submit_logs_transaction(
@@ -157,6 +167,27 @@
type EthereumTransactionSender = TestEtheremTransactionSender;
}
+impl pallet_common::Config for Test {
+ type Event = ();
+ type EvmBackwardsAddressMapping = TestEvmBackwardsAddressMapping;
+ type EvmAddressMapping = TestEvmAddressMapping;
+ type CrossAccountId = TestCrossAccountId;
+
+ type Currency = Balances;
+ type CollectionCreationPrice = CollectionCreationPrice;
+ type TreasuryAccountId = TreasuryAccountId;
+}
+
+impl pallet_fungible::Config for Test {
+ type WeightInfo = ();
+}
+impl pallet_refungible::Config for Test {
+ type WeightInfo = ();
+}
+impl pallet_nonfungible::Config for Test {
+ type WeightInfo = ();
+}
+
impl pallet_template::Config for Test {
type WeightInfo = ();
}
pallets/nft/src/tests.rsdiffbeforeafterboth--- a/pallets/nft/src/tests.rs
+++ b/pallets/nft/src/tests.rs
@@ -1,11 +1,14 @@
// Tests to be written here
use super::*;
use crate::mock::*;
-use crate::{AccessMode, CollectionMode, CreateItemData};
+use crate::{AccessMode, CollectionMode};
use nft_data_structs::{
- CreateNftData, CreateFungibleData, CreateReFungibleData, CollectionId, TokenId,
- MAX_DECIMAL_POINTS,
+ COLLECTION_NUMBER_LIMIT, Collection, CollectionId, CreateItemData, CreateFungibleData,
+ CreateNftData, CreateReFungibleData, ExistenceRequirement, MAX_COLLECTION_DESCRIPTION_LENGTH,
+ MAX_COLLECTION_NAME_LENGTH, MAX_DECIMAL_POINTS, MAX_TOKEN_PREFIX_LENGTH, COLLECTION_ADMINS_LIMIT,
+ MetaUpdatePermission, Pays, PostDispatchInfo, TokenId, Weight, WithdrawReasons,
};
+
use frame_support::{assert_noop, assert_ok};
use sp_std::convert::TryInto;
@@ -49,18 +52,18 @@
let saved_col_name: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
let saved_description: Vec<u16> = "TestDescription1\0".encode_utf16().collect::<Vec<u16>>();
let saved_prefix: Vec<u8> = b"token_prefix1\0".to_vec();
- assert_eq!(TemplateModule::collection_id(id).unwrap().owner, owner);
+ assert_eq!(<pallet_common::CollectionById<Test>>::get(id).unwrap().owner, owner);
assert_eq!(
- TemplateModule::collection_id(id).unwrap().name,
+ <pallet_common::CollectionById<Test>>::get(id).unwrap().name,
saved_col_name
);
- assert_eq!(TemplateModule::collection_id(id).unwrap().mode, *mode);
+ assert_eq!(<pallet_common::CollectionById<Test>>::get(id).unwrap().mode, *mode);
assert_eq!(
- TemplateModule::collection_id(id).unwrap().description,
+ <pallet_common::CollectionById<Test>>::get(id).unwrap().description,
saved_description
);
assert_eq!(
- TemplateModule::collection_id(id).unwrap().token_prefix,
+ <pallet_common::CollectionById<Test>>::get(id).unwrap().token_prefix,
saved_prefix
);
id
@@ -91,7 +94,7 @@
fn set_version_schema() {
new_test_ext().execute_with(|| {
let origin1 = Origin::signed(1);
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
assert_ok!(TemplateModule::set_schema_version(
origin1,
@@ -99,7 +102,7 @@
SchemaVersion::Unique
));
assert_eq!(
- TemplateModule::collection_id(collection_id)
+ <pallet_common::CollectionById<Test>>::get(collection_id)
.unwrap()
.schema_version,
SchemaVersion::Unique
@@ -131,11 +134,12 @@
#[test]
fn create_nft_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.clone().into());
- let item = TemplateModule::nft_item_id(collection_id, 1).unwrap();
+
+ let item = <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1)).unwrap();
assert_eq!(item.const_data, data.const_data.into_inner());
assert_eq!(item.variable_data, data.variable_data.into_inner());
});
@@ -146,7 +150,7 @@
#[test]
fn create_nft_multiple_items() {
new_test_ext().execute_with(|| {
- create_test_collection(&CollectionMode::NFT, 1);
+ create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -154,7 +158,7 @@
assert_ok!(TemplateModule::create_multiple_items(
origin1,
- 1,
+ CollectionId(1),
account(1),
items_data
.clone()
@@ -163,7 +167,7 @@
.collect()
));
for (index, data) in items_data.into_iter().enumerate() {
- let item = TemplateModule::nft_item_id(1, (index + 1) as TokenId).unwrap();
+ let item = <pallet_nonfungible::TokenData<Test>>::get((CollectionId(1), TokenId((index + 1) as u32))).unwrap();
assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
}
@@ -173,12 +177,12 @@
#[test]
fn create_refungible_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+ let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let data = default_re_fungible_data();
create_test_item(collection_id, &data.clone().into());
- let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();
- let balance = TemplateModule::balance(collection_id, 1, account(1));
+ let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));
+ let balance = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));
assert_eq!(item.const_data, data.const_data.into_inner());
assert_eq!(item.variable_data, data.variable_data.into_inner());
assert_eq!(balance, 1023);
@@ -188,7 +192,7 @@
#[test]
fn create_multiple_refungible_items() {
new_test_ext().execute_with(|| {
- create_test_collection(&CollectionMode::ReFungible, 1);
+ create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -200,7 +204,7 @@
assert_ok!(TemplateModule::create_multiple_items(
origin1,
- 1,
+ CollectionId(1),
account(1),
items_data
.clone()
@@ -209,8 +213,8 @@
.collect()
));
for (index, data) in items_data.into_iter().enumerate() {
- let item = TemplateModule::refungible_item_id(1, (index + 1) as TokenId).unwrap();
- let balance = TemplateModule::balance(1, 1, account(1));
+ let item = <pallet_nonfungible::TokenData<Test>>::get((CollectionId(1), TokenId((index + 1) as u32))).unwrap();
+ let balance = <pallet_refungible::Balance<Test>>::get((CollectionId(1), TokenId(1), account(1)));
assert_eq!(item.const_data.to_vec(), data.const_data.into_inner());
assert_eq!(item.variable_data.to_vec(), data.variable_data.into_inner());
assert_eq!(balance, 1023);
@@ -221,12 +225,12 @@
#[test]
fn create_fungible_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+ let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
let data = default_fungible_data();
create_test_item(collection_id, &data.into());
- assert_eq!(TemplateModule::fungible_item_id(collection_id, 1).value, 5);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((collection_id, account(1))), 5);
});
}
@@ -235,7 +239,7 @@
// new_test_ext().execute_with(|| {
// default_limits();
-// create_test_collection(&CollectionMode::Fungible(3), 1);
+// create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
// let origin1 = Origin::signed(1);
@@ -259,7 +263,7 @@
#[test]
fn transfer_fungible_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+ let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -267,39 +271,32 @@
let data = default_fungible_data();
create_test_item(collection_id, &data.into());
- assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 5);
- assert_eq!(TemplateModule::balance_count(1, 1), 5);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))), 5);
// change owner scenario
- assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 5));
- assert_eq!(TemplateModule::fungible_item_id(1, 1).value, 0);
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
- assert_eq!(TemplateModule::balance_count(1, 2), 5);
+ assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 5));
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(1))), 0);
// split item scenario
assert_ok!(TemplateModule::transfer(
origin2.clone(),
account(3),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
3
));
- assert_eq!(TemplateModule::balance_count(1, 2), 2);
- assert_eq!(TemplateModule::balance_count(1, 3), 3);
// split item and new owner has account scenario
- assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 1));
- assert_eq!(TemplateModule::fungible_item_id(1, 2).value, 1);
- assert_eq!(TemplateModule::fungible_item_id(1, 3).value, 4);
- assert_eq!(TemplateModule::balance_count(1, 2), 1);
- assert_eq!(TemplateModule::balance_count(1, 3), 4);
+ assert_ok!(TemplateModule::transfer(origin2, account(3), CollectionId(1), TokenId(1), 1));
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(2))), 1);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((CollectionId(1), account(3))), 4);
});
}
#[test]
fn transfer_refungible_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+ let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let data = default_re_fungible_data();
create_test_item(collection_id, &data.clone().into());
@@ -307,86 +304,87 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
{
- let item = TemplateModule::refungible_item_id(collection_id, 1).unwrap();
- let balance = TemplateModule::balance(collection_id, 1, account(1));
+ let item = <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)));
+ let balance = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1)));
assert_eq!(item.const_data, data.const_data.into_inner());
assert_eq!(item.variable_data, data.variable_data.into_inner());
assert_eq!(balance, 1023);
}
- assert_eq!(TemplateModule::balance_count(1, 1), 1023);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1023);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
// change owner scenario
- assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1023));
+ assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1023));
- let balance2 = TemplateModule::balance(collection_id, 1, account(2));
+ let balance2 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2)));
assert_eq!(balance2, 1023);
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
- assert_eq!(TemplateModule::balance_count(1, 2), 1023);
- // assert_eq!(TemplateModule::address_tokens(1, 1), []);
- assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))), 1023);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), false);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
// split item scenario
assert_ok!(TemplateModule::transfer(
origin2.clone(),
account(3),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
500
));
{
- let item = TemplateModule::refungible_item_id(1, 1).unwrap();
- let balance2 = TemplateModule::balance(collection_id, 1, account(2));
- let balance3 = TemplateModule::balance(collection_id, 1, account(3));
+ let item = <pallet_refungible::TokenData<Test>>::get((CollectionId(1), TokenId(1)));
+ let balance2 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2)));
+ let balance3 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3)));
assert_eq!(balance2, 523);
assert_eq!(balance3, 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]);
- assert_eq!(TemplateModule::address_tokens(1, 3), [1]);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))), 523);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))), 500);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))), true);
// split item and new owner has account scenario
- assert_ok!(TemplateModule::transfer(origin2, account(3), 1, 1, 200));
+ assert_ok!(TemplateModule::transfer(origin2, account(3), CollectionId(1), TokenId(1), 200));
{
- let item = TemplateModule::refungible_item_id(1, 1).unwrap();
- let balance2 = TemplateModule::balance(collection_id, 1, account(2));
- let balance3 = TemplateModule::balance(collection_id, 1, account(3));
+ let item = <pallet_refungible::TokenData<Test>>::get((CollectionId(1), TokenId(1)));
+ let balance2 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(2)));
+ let balance3 = <pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(3)));
assert_eq!(balance2, 323);
assert_eq!(balance3, 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]);
- assert_eq!(TemplateModule::address_tokens(1, 3), [1]);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(2))), 323);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))), 700);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(3), TokenId(1))), true);
});
}
#[test]
fn transfer_nft_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
+
let origin1 = Origin::signed(1);
// default scenario
- assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));
- assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
- assert_eq!(TemplateModule::balance_count(1, 2), 1);
- // assert_eq!(TemplateModule::address_tokens(1, 1), []);
- assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+ assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1000));
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))), 1);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), false);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
});
}
#[test]
fn nft_approve_and_transfer_from() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
@@ -394,36 +392,35 @@
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
// neg transfer
assert_noop!(
- TemplateModule::transfer_from(origin2.clone(), account(1), account(2), 1, 1, 1),
- Error::<Test>::NoPermission
+ TemplateModule::transfer_from(origin2.clone(), account(1), account(2), CollectionId(1), TokenId(1), 1),
+ CommonError::<Test>::NoPermission
);
// do approve
- assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 5));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
+ assert_ok!(TemplateModule::approve(origin1, account(2), CollectionId(1), TokenId(1), 5));
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
assert_ok!(TemplateModule::transfer_from(
origin2,
account(1),
account(3),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
1
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);
+ assert!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none());
});
}
#[test]
fn nft_approve_and_transfer_from_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -432,35 +429,35 @@
create_test_item(collection_id, &data.clone().into());
assert_eq!(
- &TemplateModule::nft_item_id(1, 1).unwrap().const_data,
+ &<pallet_nonfungible::TokenData<Test>>::get((collection_id, TokenId(1))).unwrap().const_data,
&data.const_data.into_inner()
);
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
assert_ok!(TemplateModule::set_mint_permission(
origin1.clone(),
- 1,
+ CollectionId(1),
true
));
assert_ok!(TemplateModule::set_public_access_mode(
origin1.clone(),
- 1,
+ CollectionId(1),
AccessMode::AllowList
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(1)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(2)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(3)
));
@@ -468,30 +465,30 @@
assert_ok!(TemplateModule::approve(
origin1.clone(),
account(2),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
5
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
- assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));
- assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
+ assert_ok!(TemplateModule::approve(origin1, account(3), CollectionId(1), TokenId(1), 5));
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(3));
assert_ok!(TemplateModule::transfer_from(
origin2,
account(1),
account(3),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
1
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 4);
+ assert!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).is_none());
});
}
#[test]
fn refungible_approve_and_transfer_from() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+ let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -499,92 +496,89 @@
let data = default_re_fungible_data();
create_test_item(collection_id, &data.into());
- assert_eq!(TemplateModule::balance_count(1, 1), 1023);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1023);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
assert_ok!(TemplateModule::set_mint_permission(
origin1.clone(),
- 1,
+ CollectionId(1),
true
));
assert_ok!(TemplateModule::set_public_access_mode(
origin1.clone(),
- 1,
+ CollectionId(1),
AccessMode::AllowList
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(1)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(2)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(3)
));
// do approve
- assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1023));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1023);
+ assert_ok!(TemplateModule::approve(origin1, account(2), CollectionId(1), TokenId(1), 1023));
+ assert_eq!(<pallet_refungible::Allowance<Test>>::get((CollectionId(1), TokenId(1), account(1), account(2))), 1023);
assert_ok!(TemplateModule::transfer_from(
origin2,
account(1),
account(3),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
100
));
- assert_eq!(TemplateModule::balance_count(1, 1), 923);
- assert_eq!(TemplateModule::balance_count(1, 3), 100);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
- assert_eq!(TemplateModule::address_tokens(1, 3), [1]);
-
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 923);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 923);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(3))), 100);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((collection_id, account(1), TokenId(3))), true);
+ assert_eq!(<pallet_refungible::Allowance<Test>>::get((CollectionId(1), TokenId(1), account(1), account(2))), 923);
});
}
#[test]
fn fungible_approve_and_transfer_from() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+ let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
let data = default_fungible_data();
create_test_item(collection_id, &data.into());
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
-
- assert_eq!(TemplateModule::balance_count(1, 1), 5);
assert_ok!(TemplateModule::set_mint_permission(
origin1.clone(),
- 1,
+ CollectionId(1),
true
));
assert_ok!(TemplateModule::set_public_access_mode(
origin1.clone(),
- 1,
+ CollectionId(1),
AccessMode::AllowList
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(1)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(2)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(3)
));
@@ -592,31 +586,29 @@
assert_ok!(TemplateModule::approve(
origin1.clone(),
account(2),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
5
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
- assert_ok!(TemplateModule::approve(origin1, account(3), 1, 1, 5));
- assert_eq!(TemplateModule::approved(1, (1, 1, 3)), 5);
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 5);
+ assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))), 5);
+ assert_ok!(TemplateModule::approve(origin1, account(3), CollectionId(1), TokenId(1), 5));
+ assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))), 5);
+ assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(3))), 5);
assert_ok!(TemplateModule::transfer_from(
origin2.clone(),
account(1),
account(3),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
4
));
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::balance_count(1, 3), 4);
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);
+ assert_eq!(<pallet_fungible::Allowance<Test>>::get((CollectionId(1), account(1), account(2))), 1);
assert_noop!(
- TemplateModule::transfer_from(origin2, account(1), account(3), 1, 1, 4),
- Error::<Test>::NoPermission
+ TemplateModule::transfer_from(origin2, account(1), account(3), CollectionId(1), TokenId(1), 4),
+ CommonError::<Test>::NoPermission
);
});
}
@@ -624,7 +616,7 @@
#[test]
fn change_collection_owner() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::change_collection_owner(
@@ -633,7 +625,7 @@
2
));
assert_eq!(
- TemplateModule::collection_id(collection_id).unwrap().owner,
+ <pallet_common::CollectionById<Test>>::get(collection_id).unwrap().owner,
2
);
});
@@ -642,7 +634,7 @@
#[test]
fn destroy_collection() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));
@@ -652,7 +644,7 @@
#[test]
fn burn_nft_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::add_collection_admin(
@@ -665,28 +657,28 @@
create_test_item(collection_id, &data.into());
// check balance (collection with id = 1, user id = 1)
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
// burn item
assert_ok!(TemplateModule::burn_item(
origin1.clone(),
collection_id,
- 1,
+ TokenId(1),
1
));
assert_noop!(
- TemplateModule::burn_item(origin1, collection_id, 1, 1),
- Error::<Test>::TokenNotFound
+ TemplateModule::burn_item(origin1, collection_id, TokenId(1), 1),
+ CommonError::<Test>::TokenNotFound
);
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
});
}
#[test]
fn burn_fungible_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+ let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::add_collection_admin(
@@ -699,23 +691,23 @@
create_test_item(collection_id, &data.into());
// check balance (collection with id = 1, user id = 1)
- assert_eq!(TemplateModule::balance_count(1, 1), 5);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((collection_id, account(1))), 5);
// burn item
- assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 5));
+ assert_ok!(TemplateModule::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 5));
assert_noop!(
- TemplateModule::burn_item(origin1, 1, 1, 5),
- Error::<Test>::TokenValueNotEnough
+ TemplateModule::burn_item(origin1, CollectionId(1), TokenId(1), 5),
+ CommonError::<Test>::TokenValueNotEnough
);
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((collection_id, account(1))), 0);
});
}
#[test]
fn burn_refungible_item() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+ let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::set_mint_permission(
@@ -730,13 +722,13 @@
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ collection_id,
account(1)
));
assert_ok!(TemplateModule::add_collection_admin(
origin1.clone(),
- 1,
+ collection_id,
account(2)
));
@@ -744,25 +736,26 @@
create_test_item(collection_id, &data.into());
// check balance (collection with id = 1, user id = 2)
- assert_eq!(TemplateModule::balance_count(1, 1), 1023);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((collection_id, account(1))), 1023);
+ assert_eq!(<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))), 1023);
// burn item
- assert_ok!(TemplateModule::burn_item(origin1.clone(), 1, 1, 1023));
+ assert_ok!(TemplateModule::burn_item(origin1.clone(), collection_id, TokenId(1), 1023));
assert_noop!(
- TemplateModule::burn_item(origin1, 1, 1, 1023),
- Error::<Test>::TokenNotFound
+ TemplateModule::burn_item(origin1, collection_id, TokenId(1), 1023),
+ CommonError::<Test>::TokenNotFound
);
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
+ assert_eq!(<pallet_refungible::Balance<Test>>::get((collection_id, TokenId(1), account(1))), 0);
});
}
#[test]
fn add_collection_admin() {
new_test_ext().execute_with(|| {
- let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
- create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);
- create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);
+ let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
+ create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(2));
+ create_test_collection_for_owner(&CollectionMode::NFT, 3, CollectionId(3));
let origin1 = Origin::signed(1);
@@ -778,17 +771,18 @@
account(3)
));
- assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(2)),);
- assert!(TemplateModule::admin_list_collection(collection1_id).contains(&account(3)),);
+ assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(1))));
+ assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(2))));
+ assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))));
});
}
#[test]
fn remove_collection_admin() {
new_test_ext().execute_with(|| {
- let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
- create_test_collection_for_owner(&CollectionMode::NFT, 2, 2);
- create_test_collection_for_owner(&CollectionMode::NFT, 3, 3);
+ let collection1_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
+ create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(2));
+ create_test_collection_for_owner(&CollectionMode::NFT, 3, CollectionId(3));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -805,33 +799,31 @@
account(3)
));
- assert!(TemplateModule::admin_list_collection(1).contains(&account(2)),);
- assert!(TemplateModule::admin_list_collection(1).contains(&account(3)),);
+ assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(2))));
+ assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))));
// remove admin
assert_ok!(TemplateModule::remove_collection_admin(
origin2,
- 1,
+ CollectionId(1),
account(3)
));
- assert!(!TemplateModule::admin_list_collection(1).contains(&account(3)),);
+ assert!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(3))));
+ assert_eq!(<pallet_common::IsAdmin<Test>>::get((CollectionId(1), account(2))), false);
});
}
#[test]
fn balance_of() {
new_test_ext().execute_with(|| {
- let nft_collection_id = create_test_collection(&CollectionMode::NFT, 1);
- let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), 2);
- let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, 3);
+ let nft_collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
+ let fungible_collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(2));
+ let re_fungible_collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(3));
// check balance before
- assert_eq!(TemplateModule::balance_count(nft_collection_id, 1), 0);
- assert_eq!(TemplateModule::balance_count(fungible_collection_id, 1), 0);
- assert_eq!(
- TemplateModule::balance_count(re_fungible_collection_id, 1),
- 0
- );
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))), 0);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))), 0);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))), 0);
let nft_data = default_nft_data();
create_test_item(nft_collection_id, &nft_data.into());
@@ -843,36 +835,19 @@
create_test_item(re_fungible_collection_id, &re_fungible_data.into());
// check balance (collection with id = 1, user id = 1)
- 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)
- .unwrap()
- .owner,
- account(1)
- );
- assert_eq!(
- TemplateModule::fungible_item_id(fungible_collection_id, 1).value,
- 5
- );
- assert_eq!(
- TemplateModule::refungible_item_id(re_fungible_collection_id, 1)
- .unwrap()
- .owner[0]
- .owner,
- account(1)
- );
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((nft_collection_id, account(1))), 1);
+ assert_eq!(<pallet_fungible::Balance<Test>>::get((fungible_collection_id, account(1))), 5);
+ assert_eq!(<pallet_refungible::AccountBalance<Test>>::get((re_fungible_collection_id, account(1))), 1023);
+
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))), true);
+ assert_eq!(<pallet_refungible::Owned<Test>>::get((nft_collection_id, account(1), TokenId(1))), true);
});
}
#[test]
fn approve() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
@@ -880,15 +855,15 @@
let origin1 = Origin::signed(1);
// approve
- assert_ok!(TemplateModule::approve(origin1, account(2), 1, 1, 1));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);
+ assert_ok!(TemplateModule::approve(origin1, account(2), CollectionId(1), TokenId(1), 1));
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
});
}
#[test]
fn transfer_from() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -899,46 +874,46 @@
assert_ok!(TemplateModule::approve(
origin1.clone(),
account(2),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
1
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 2)), 1);
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(2));
assert_ok!(TemplateModule::set_mint_permission(
origin1.clone(),
- 1,
+ CollectionId(1),
true
));
assert_ok!(TemplateModule::set_public_access_mode(
origin1.clone(),
- 1,
+ CollectionId(1),
AccessMode::AllowList
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(1)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ CollectionId(1),
account(2)
));
- assert_ok!(TemplateModule::add_to_allow_list(origin1, 1, account(3)));
+ assert_ok!(TemplateModule::add_to_allow_list(origin1, CollectionId(1), account(3)));
assert_ok!(TemplateModule::transfer_from(
origin2,
account(1),
account(2),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
1
));
// after transfer
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
- assert_eq!(TemplateModule::balance_count(1, 2), 1);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(1))), 0);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((CollectionId(1), account(2))), 1);
});
}
@@ -950,7 +925,7 @@
#[test]
fn owner_can_add_address_to_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::add_to_allow_list(
@@ -958,14 +933,14 @@
collection_id,
account(2)
));
- assert!(TemplateModule::allow_list(collection_id, 2));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
});
}
#[test]
fn admin_can_add_address_to_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -979,19 +954,19 @@
collection_id,
account(3)
));
- assert!(TemplateModule::allow_list(collection_id, 3));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(3))));
});
}
#[test]
fn nonprivileged_user_cannot_add_address_to_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin2 = Origin::signed(2);
assert_noop!(
TemplateModule::add_to_allow_list(origin2, collection_id, account(3)),
- Error::<Test>::NoPermission
+ CommonError::<Test>::NoPermission
);
});
}
@@ -1002,8 +977,8 @@
let origin1 = Origin::signed(1);
assert_noop!(
- TemplateModule::add_to_allow_list(origin1, 1, account(2)),
- Error::<Test>::CollectionNotFound
+ TemplateModule::add_to_allow_list(origin1, CollectionId(1), account(2)),
+ CommonError::<Test>::CollectionNotFound
);
});
}
@@ -1011,7 +986,7 @@
#[test]
fn nobody_can_add_address_to_allow_list_of_deleted_collection() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::destroy_collection(
@@ -1020,7 +995,7 @@
));
assert_noop!(
TemplateModule::add_to_allow_list(origin1, collection_id, account(2)),
- Error::<Test>::CollectionNotFound
+ CommonError::<Test>::CollectionNotFound
);
});
}
@@ -1029,7 +1004,7 @@
#[test]
fn address_is_already_added_to_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::add_to_allow_list(
@@ -1042,14 +1017,14 @@
collection_id,
account(2)
));
- assert!(TemplateModule::allow_list(collection_id, 2));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
});
}
#[test]
fn owner_can_remove_address_from_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::add_to_allow_list(
@@ -1062,14 +1037,14 @@
collection_id,
account(2)
));
- assert!(!TemplateModule::allow_list(collection_id, 2));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
});
}
#[test]
fn admin_can_remove_address_from_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1089,14 +1064,14 @@
collection_id,
account(3)
));
- assert!(!TemplateModule::allow_list(collection_id, 3));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(3))));
});
}
#[test]
fn nonprivileged_user_cannot_remove_address_from_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1107,9 +1082,9 @@
));
assert_noop!(
TemplateModule::remove_from_allow_list(origin2, collection_id, account(2)),
- Error::<Test>::NoPermission
+ CommonError::<Test>::NoPermission
);
- assert!(TemplateModule::allow_list(collection_id, 2));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
});
}
@@ -1119,8 +1094,8 @@
let origin1 = Origin::signed(1);
assert_noop!(
- TemplateModule::remove_from_allow_list(origin1, 1, account(2)),
- Error::<Test>::CollectionNotFound
+ TemplateModule::remove_from_allow_list(origin1, CollectionId(1), account(2)),
+ CommonError::<Test>::CollectionNotFound
);
});
}
@@ -1128,7 +1103,7 @@
#[test]
fn nobody_can_remove_address_from_allow_list_of_deleted_collection() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1140,9 +1115,9 @@
assert_ok!(TemplateModule::destroy_collection(origin1, collection_id));
assert_noop!(
TemplateModule::remove_from_allow_list(origin2, collection_id, account(2)),
- Error::<Test>::CollectionNotFound
+ CommonError::<Test>::CollectionNotFound
);
- assert!(!TemplateModule::allow_list(collection_id, 2));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
});
}
@@ -1150,7 +1125,7 @@
#[test]
fn address_is_already_removed_from_allow_list() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::add_to_allow_list(
@@ -1168,7 +1143,7 @@
collection_id,
account(2)
));
- assert!(!TemplateModule::allow_list(collection_id, 2));
+ assert!(<pallet_common::Allowlist<Test>>::get((collection_id, account(2))));
});
}
@@ -1176,7 +1151,7 @@
#[test]
fn allow_list_test_1() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1195,8 +1170,8 @@
));
assert_noop!(
- TemplateModule::transfer(origin1, account(3), 1, 1, 1),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::transfer(origin1, account(3), CollectionId(1), TokenId(1), 1),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1204,7 +1179,7 @@
#[test]
fn allow_list_test_2() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_nft_data();
@@ -1217,12 +1192,12 @@
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ collection_id,
account(1)
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ collection_id,
account(2)
));
@@ -1230,21 +1205,21 @@
assert_ok!(TemplateModule::approve(
origin1.clone(),
account(1),
- 1,
- 1,
+ collection_id,
+ TokenId(1),
1
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(1));
assert_ok!(TemplateModule::remove_from_allow_list(
origin1.clone(),
- 1,
+ collection_id,
account(1)
));
assert_noop!(
- TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::transfer_from(origin1, account(1), account(3), CollectionId(1), TokenId(1), 1),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1253,7 +1228,7 @@
#[test]
fn allow_list_test_3() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1267,13 +1242,13 @@
));
assert_ok!(TemplateModule::add_to_allow_list(
origin1.clone(),
- 1,
+ collection_id,
account(1)
));
assert_noop!(
- TemplateModule::transfer(origin1, account(3), 1, 1, 1),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::transfer(origin1, account(3), collection_id, TokenId(1), 1),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1281,7 +1256,7 @@
#[test]
fn allow_list_test_4() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1308,11 +1283,11 @@
assert_ok!(TemplateModule::approve(
origin1.clone(),
account(1),
- 1,
- 1,
+ collection_id,
+ TokenId(1),
1
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 1);
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(1));
assert_ok!(TemplateModule::remove_from_allow_list(
origin1.clone(),
@@ -1321,8 +1296,8 @@
));
assert_noop!(
- TemplateModule::transfer_from(origin1, account(1), account(3), 1, 1, 1),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::transfer_from(origin1, account(1), account(3), collection_id, TokenId(1), 1),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1331,7 +1306,7 @@
#[test]
fn allow_list_test_5() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1344,8 +1319,8 @@
AccessMode::AllowList
));
assert_noop!(
- TemplateModule::burn_item(origin1.clone(), 1, 1, 5),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::burn_item(origin1.clone(), CollectionId(1), TokenId(1), 5),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1354,7 +1329,7 @@
#[test]
fn allow_list_test_6() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1369,8 +1344,8 @@
// do approve
assert_noop!(
- TemplateModule::approve(origin1, account(1), 1, 1, 5),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::approve(origin1, account(1), CollectionId(1), TokenId(1), 5),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1380,7 +1355,7 @@
#[test]
fn allow_list_test_7() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
@@ -1403,14 +1378,14 @@
account(2)
));
- assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1));
+ assert_ok!(TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1));
});
}
#[test]
fn allow_list_test_8() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
@@ -1437,18 +1412,18 @@
assert_ok!(TemplateModule::approve(
origin1.clone(),
account(1),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
5
));
- assert_eq!(TemplateModule::approved(1, (1, 1, 1)), 5);
+ assert_eq!(<pallet_nonfungible::Allowance<Test>>::get((CollectionId(1), TokenId(1))).unwrap(), account(1));
assert_ok!(TemplateModule::transfer_from(
origin1,
account(1),
account(2),
- 1,
- 1,
+ CollectionId(1),
+ TokenId(1),
1
));
});
@@ -1458,7 +1433,7 @@
#[test]
fn allow_list_test_9() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::set_public_access_mode(
@@ -1481,7 +1456,7 @@
#[test]
fn allow_list_test_10() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1516,7 +1491,7 @@
#[test]
fn allow_list_test_11() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1538,8 +1513,8 @@
));
assert_noop!(
- TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),
- Error::<Test>::PublicMintingNotAllowed
+ TemplateModule::create_item(origin2, CollectionId(1), account(2), default_nft_data().into()),
+ CommonError::<Test>::PublicMintingNotAllowed
);
});
}
@@ -1548,7 +1523,7 @@
#[test]
fn allow_list_test_12() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1565,8 +1540,8 @@
));
assert_noop!(
- TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),
- Error::<Test>::PublicMintingNotAllowed
+ TemplateModule::create_item(origin2, CollectionId(1), account(2), default_nft_data().into()),
+ CommonError::<Test>::PublicMintingNotAllowed
);
});
}
@@ -1575,7 +1550,7 @@
#[test]
fn allow_list_test_13() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1599,7 +1574,7 @@
#[test]
fn allow_list_test_14() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1623,7 +1598,7 @@
assert_ok!(TemplateModule::create_item(
origin2,
- 1,
+ collection_id,
account(2),
default_nft_data().into()
));
@@ -1634,7 +1609,7 @@
#[test]
fn allow_list_test_15() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1651,8 +1626,8 @@
));
assert_noop!(
- TemplateModule::create_item(origin2, 1, account(2), default_nft_data().into()),
- Error::<Test>::AddresNotInAllowList
+ TemplateModule::create_item(origin2, collection_id, account(2), default_nft_data().into()),
+ CommonError::<Test>::AddressNotInAllowlist
);
});
}
@@ -1661,7 +1636,7 @@
#[test]
fn allow_list_test_16() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -1684,7 +1659,7 @@
assert_ok!(TemplateModule::create_item(
origin2,
- 1,
+ collection_id,
account(2),
default_nft_data().into()
));
@@ -1695,7 +1670,7 @@
#[test]
fn total_number_collections_bound() {
new_test_ext().execute_with(|| {
- create_test_collection(&CollectionMode::NFT, 1);
+ create_test_collection(&CollectionMode::NFT, CollectionId(1));
});
}
@@ -1706,7 +1681,7 @@
let origin1 = Origin::signed(1);
for i in 0..COLLECTION_NUMBER_LIMIT {
- create_test_collection(&CollectionMode::NFT, i + 1);
+ create_test_collection(&CollectionMode::NFT, CollectionId(i + 1));
}
let col_name1: Vec<u16> = "Test1\0".encode_utf16().collect::<Vec<u16>>();
@@ -1722,7 +1697,7 @@
token_prefix1,
CollectionMode::NFT
),
- Error::<Test>::TotalCollectionsLimitExceeded
+ CommonError::<Test>::TotalCollectionsLimitExceeded
);
});
}
@@ -1731,7 +1706,7 @@
#[test]
fn owned_tokens_bound() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let data = default_nft_data();
create_test_item(collection_id, &data.clone().into());
@@ -1743,19 +1718,19 @@
#[test]
fn owned_tokens_bound_neg() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
- for _ in 0..ACCOUNT_TOKEN_OWNERSHIP_LIMIT {
+ for _ in 0..MAX_TOKEN_OWNERSHIP {
let data = default_nft_data();
create_test_item(collection_id, &data.clone().into());
}
let data = default_nft_data();
assert_noop!(
- TemplateModule::create_item(origin1, 1, account(1), data.into()),
- Error::<Test>::AccountTokenLimitExceeded
+ TemplateModule::create_item(origin1, CollectionId(1), account(1), data.into()),
+ CommonError::<Test>::AccountTokenLimitExceeded
);
});
}
@@ -1764,7 +1739,7 @@
#[test]
fn collection_admins_bound() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1785,7 +1760,7 @@
#[test]
fn collection_admins_bound_neg() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -1793,16 +1768,16 @@
assert_ok!(TemplateModule::add_collection_admin(
origin1.clone(),
collection_id,
- account(2 + i)
+ account((2 + i).into())
));
}
assert_noop!(
TemplateModule::add_collection_admin(
origin1,
collection_id,
- account(3 + COLLECTION_ADMINS_LIMIT)
+ account((3 + COLLECTION_ADMINS_LIMIT).into())
),
- Error::<Test>::CollectionAdminsLimitExceeded
+ CommonError::<Test>::CollectionAdminCountExceeded
);
});
}
@@ -1811,7 +1786,7 @@
#[test]
fn set_const_on_chain_schema() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::set_const_on_chain_schema(
@@ -1821,13 +1796,13 @@
));
assert_eq!(
- TemplateModule::collection_id(collection_id)
+ <pallet_common::CollectionById<Test>>::get(collection_id)
.unwrap()
.const_on_chain_schema,
b"test const on chain schema".to_vec()
);
assert_eq!(
- TemplateModule::collection_id(collection_id)
+ <pallet_common::CollectionById<Test>>::get(collection_id)
.unwrap()
.variable_on_chain_schema,
b"".to_vec()
@@ -1838,7 +1813,7 @@
#[test]
fn set_variable_on_chain_schema() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
assert_ok!(TemplateModule::set_variable_on_chain_schema(
@@ -1848,13 +1823,13 @@
));
assert_eq!(
- TemplateModule::collection_id(collection_id)
+ <pallet_common::CollectionById<Test>>::get(collection_id)
.unwrap()
.const_on_chain_schema,
b"".to_vec()
);
assert_eq!(
- TemplateModule::collection_id(collection_id)
+ <pallet_common::CollectionById<Test>>::get(collection_id)
.unwrap()
.variable_on_chain_schema,
b"test variable on chain schema".to_vec()
@@ -1865,23 +1840,23 @@
#[test]
fn set_variable_meta_data_on_nft_token_stores_variable_meta_data() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(CollectionId(1), &data.into());
let variable_data = b"test data".to_vec();
assert_ok!(TemplateModule::set_variable_meta_data(
origin1,
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
));
assert_eq!(
- TemplateModule::nft_item_id(collection_id, 1)
+ <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
.unwrap()
.variable_data,
variable_data
@@ -1892,24 +1867,23 @@
#[test]
fn set_variable_meta_data_on_re_fungible_token_stores_variable_meta_data() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+ let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_re_fungible_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
let variable_data = b"test data".to_vec();
assert_ok!(TemplateModule::set_variable_meta_data(
origin1,
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
));
assert_eq!(
- TemplateModule::refungible_item_id(collection_id, 1)
- .unwrap()
+ <pallet_refungible::TokenData<Test>>::get((collection_id, TokenId(1)))
.variable_data,
variable_data
);
@@ -1919,17 +1893,17 @@
#[test]
fn set_variable_meta_data_on_fungible_token_fails() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::Fungible(3), 1);
+ let collection_id = create_test_collection(&CollectionMode::Fungible(3), CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_fungible_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
let variable_data = b"test data".to_vec();
assert_noop!(
- TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
- Error::<Test>::CantStoreMetadataInFungibleTokens
+ TemplateModule::set_variable_meta_data(origin1, collection_id, TokenId(1), variable_data),
+ <pallet_fungible::Error<Test>>::FungibleItemsDontHaveData
);
});
}
@@ -1937,17 +1911,17 @@
#[test]
fn set_variable_meta_data_on_nft_token_fails_for_big_data() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();
assert_noop!(
- TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
- Error::<Test>::TokenVariableDataLimitExceeded
+ TemplateModule::set_variable_meta_data(origin1, collection_id, TokenId(1), variable_data),
+ CommonError::<Test>::TokenVariableDataLimitExceeded
);
});
}
@@ -1955,17 +1929,17 @@
#[test]
fn set_variable_meta_data_on_re_fungible_token_fails_for_big_data() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection(&CollectionMode::ReFungible, 1);
+ let collection_id = create_test_collection(&CollectionMode::ReFungible, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_re_fungible_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
let variable_data = b"test set_variable_meta_data method, bigger than limits.".to_vec();
assert_noop!(
- TemplateModule::set_variable_meta_data(origin1, collection_id, 1, variable_data),
- Error::<Test>::TokenVariableDataLimitExceeded
+ TemplateModule::set_variable_meta_data(origin1, collection_id, TokenId(1), variable_data),
+ CommonError::<Test>::TokenVariableDataLimitExceeded
);
});
}
@@ -1975,12 +1949,12 @@
new_test_ext().execute_with(|| {
//default_limits();
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
assert_ok!(TemplateModule::set_meta_update_permission_flag(
origin1.clone(),
@@ -1992,12 +1966,12 @@
assert_ok!(TemplateModule::set_variable_meta_data(
origin1,
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
));
assert_eq!(
- TemplateModule::nft_item_id(collection_id, 1)
+ <pallet_nonfungible::TokenData<Test>>::get((collection_id, TokenId(1)))
.unwrap()
.variable_data,
variable_data
@@ -2008,7 +1982,7 @@
#[test]
fn set_variable_meta_data_on_nft_with_item_owner_permission_flag_neg() {
new_test_ext().execute_with(|| {
- let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
+ let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
let origin1 = Origin::signed(1);
@@ -2024,7 +1998,7 @@
));
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
assert_ok!(TemplateModule::set_meta_update_permission_flag(
origin1.clone(),
@@ -2037,10 +2011,10 @@
TemplateModule::set_variable_meta_data(
origin1,
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
),
- Error::<Test>::TokenVariableDataLimitExceeded
+ CommonError::<Test>::TokenVariableDataLimitExceeded
);
})
}
@@ -2050,23 +2024,22 @@
new_test_ext().execute_with(|| {
let origin1 = Origin::signed(1);
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
- assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, 1, true));
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
+ assert_ok!(TemplateModule::set_transfers_enabled_flag(origin1, collection_id, true));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
let origin1 = Origin::signed(1);
// default scenario
- assert_ok!(TemplateModule::transfer(origin1, account(2), 1, 1, 1000));
- assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(2));
- assert_eq!(TemplateModule::balance_count(1, 1), 0);
- assert_eq!(TemplateModule::balance_count(1, 2), 1);
-
- assert_eq!(TemplateModule::address_tokens(1, 2), [1]);
+ assert_ok!(TemplateModule::transfer(origin1, account(2), collection_id, TokenId(1), 1000));
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), false);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), true);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 0);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))), 1);
});
}
@@ -2075,7 +2048,7 @@
new_test_ext().execute_with(|| {
// default_limits();
- let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);
+ let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -2098,7 +2071,7 @@
));
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
assert_ok!(TemplateModule::set_meta_update_permission_flag(
origin2.clone(),
@@ -2110,12 +2083,12 @@
assert_ok!(TemplateModule::set_variable_meta_data(
origin1,
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
));
assert_eq!(
- TemplateModule::nft_item_id(collection_id, 1)
+ <pallet_nonfungible::TokenData<Test>>::get((collection_id, 1))
.unwrap()
.variable_data,
variable_data
@@ -2128,7 +2101,7 @@
new_test_ext().execute_with(|| {
// default_limits();
- let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);
+ let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
let origin1 = Origin::signed(1);
let origin2 = Origin::signed(2);
@@ -2145,7 +2118,7 @@
));
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
assert_ok!(TemplateModule::set_meta_update_permission_flag(
origin2.clone(),
@@ -2158,10 +2131,10 @@
TemplateModule::set_variable_meta_data(
origin1,
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
),
- Error::<Test>::NoPermission
+ CommonError::<Test>::NoPermission
);
});
}
@@ -2171,7 +2144,7 @@
new_test_ext().execute_with(|| {
// default_limits();
- let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, 1);
+ let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 2, CollectionId(1));
let origin2 = Origin::signed(2);
@@ -2186,7 +2159,7 @@
collection_id,
MetaUpdatePermission::Admin
),
- Error::<Test>::MetadataFlagFrozen
+ CommonError::<Test>::MetadataFlagFrozen
);
});
}
@@ -2196,11 +2169,11 @@
new_test_ext().execute_with(|| {
// default_limits();
- let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, 1);
+ let collection_id = create_test_collection_for_owner(&CollectionMode::NFT, 1, CollectionId(1));
let origin1 = Origin::signed(1);
let data = default_nft_data();
- create_test_item(1, &data.into());
+ create_test_item(collection_id, &data.into());
assert_ok!(TemplateModule::set_meta_update_permission_flag(
origin1.clone(),
@@ -2213,10 +2186,10 @@
TemplateModule::set_variable_meta_data(
origin1.clone(),
collection_id,
- 1,
+ TokenId(1),
variable_data.clone()
),
- Error::<Test>::MetadataUpdateDenied
+ CommonError::<Test>::NoPermission
);
});
}
@@ -2226,27 +2199,26 @@
new_test_ext().execute_with(|| {
let origin1 = Origin::signed(1);
- let collection_id = create_test_collection(&CollectionMode::NFT, 1);
+ let collection_id = create_test_collection(&CollectionMode::NFT, CollectionId(1));
assert_ok!(TemplateModule::set_transfers_enabled_flag(
- origin1, 1, false
+ origin1, collection_id, false
));
let data = default_nft_data();
create_test_item(collection_id, &data.into());
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
let origin1 = Origin::signed(1);
// default scenario
assert_noop!(
- TemplateModule::transfer(origin1, account(2), 1, 1, 1000),
- Error::<Test>::TransferNotAllowed
+ TemplateModule::transfer(origin1, account(2), CollectionId(1), TokenId(1), 1000),
+ CommonError::<Test>::TransferNotAllowed
);
- assert_eq!(TemplateModule::nft_item_id(1, 1).unwrap().owner, account(1));
- assert_eq!(TemplateModule::balance_count(1, 1), 1);
- assert_eq!(TemplateModule::balance_count(1, 2), 0);
-
- assert_eq!(TemplateModule::address_tokens(1, 1), [1]);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(1))), 1);
+ assert_eq!(<pallet_nonfungible::AccountBalance<Test>>::get((collection_id, account(2))), 0);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(1), TokenId(1))), true);
+ assert_eq!(<pallet_nonfungible::Owned<Test>>::get((collection_id, account(2), TokenId(1))), false);
});
}
pallets/nonfungible/src/lib.rsdiffbeforeafterboth--- a/pallets/nonfungible/src/lib.rs
+++ b/pallets/nonfungible/src/lib.rs
@@ -58,18 +58,18 @@
}
#[pallet::pallet]
- #[pallet::generate_store(pub(super) trait Store)]
+ #[pallet::generate_store(pub trait Store)]
pub struct Pallet<T>(_);
#[pallet::storage]
- pub(super) type TokensMinted<T: Config> =
+ pub type TokensMinted<T: Config> =
StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
#[pallet::storage]
- pub(super) type TokensBurnt<T: Config> =
+ pub type TokensBurnt<T: Config> =
StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;
#[pallet::storage]
- pub(super) type TokenData<T: Config> = StorageNMap<
+ pub type TokenData<T: Config> = StorageNMap<
Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
Value = ItemData<T>,
QueryKind = OptionQuery,
@@ -77,7 +77,7 @@
/// Used to enumerate tokens owned by account
#[pallet::storage]
- pub(super) type Owned<T: Config> = StorageNMap<
+ pub type Owned<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
Key<Blake2_128Concat, T::CrossAccountId>,
@@ -88,7 +88,7 @@
>;
#[pallet::storage]
- pub(super) type AccountBalance<T: Config> = StorageNMap<
+ pub type AccountBalance<T: Config> = StorageNMap<
Key = (
Key<Twox64Concat, CollectionId>,
Key<Blake2_128Concat, T::CrossAccountId>,
@@ -98,7 +98,7 @@
>;
#[pallet::storage]
- pub(super) type Allowance<T: Config> = StorageNMap<
+ pub type Allowance<T: Config> = StorageNMap<
Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),
Value = T::CrossAccountId,
QueryKind = OptionQuery,
pallets/refungible/src/lib.rsdiffbeforeafterboth1#![cfg_attr(not(feature = "std"), no_std)]23use frame_support::{ensure, BoundedVec};4use nft_data_structs::{5 AccessMode, CUSTOM_DATA_LIMIT, Collection, CollectionId, CustomDataLimit,6 MAX_REFUNGIBLE_PIECES, TokenId,7};8use pallet_common::{9 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,10};11use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};12use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};13use core::ops::Deref;14use codec::{Encode, Decode};15use scale_info::TypeInfo;1617pub use pallet::*;18#[cfg(feature = "runtime-benchmarks")]19pub mod benchmarking;20pub mod common;21pub mod erc;22pub mod weights;23pub struct CreateItemData<T: Config> {24 pub const_data: BoundedVec<u8, CustomDataLimit>,25 pub variable_data: BoundedVec<u8, CustomDataLimit>,26 pub users: BTreeMap<T::CrossAccountId, u128>,27}28pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;2930#[derive(Encode, Decode, Default, TypeInfo)]31pub struct ItemData {32 pub const_data: Vec<u8>,33 pub variable_data: Vec<u8>,34}3536#[frame_support::pallet]37pub mod pallet {38 use super::*;39 use frame_support::{Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};40 use nft_data_structs::{CollectionId, TokenId};41 use super::weights::WeightInfo;4243 #[pallet::error]44 pub enum Error<T> {45 /// Not Refungible item data used to mint in Refungible collection.46 NotRefungibleDataUsedToMintFungibleCollectionToken,47 /// Maximum refungibility exceeded48 WrongRefungiblePieces,49 }5051 #[pallet::config]52 pub trait Config: frame_system::Config + pallet_common::Config {53 type WeightInfo: WeightInfo;54 }5556 #[pallet::pallet]57 #[pallet::generate_store(pub(super) trait Store)]58 pub struct Pallet<T>(_);5960 #[pallet::storage]61 pub(super) type TokensMinted<T: Config> =62 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;63 #[pallet::storage]64 pub(super) type TokensBurnt<T: Config> =65 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;6667 #[pallet::storage]68 pub(super) type TokenData<T: Config> = StorageNMap<69 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),70 Value = ItemData,71 QueryKind = ValueQuery,72 >;7374 #[pallet::storage]75 pub(super) type TotalSupply<T: Config> = StorageNMap<76 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),77 Value = u128,78 QueryKind = ValueQuery,79 >;8081 /// Used to enumerate tokens owned by account82 #[pallet::storage]83 pub(super) type Owned<T: Config> = StorageNMap<84 Key = (85 Key<Twox64Concat, CollectionId>,86 Key<Blake2_128Concat, T::CrossAccountId>,87 Key<Twox64Concat, TokenId>,88 ),89 Value = bool,90 QueryKind = ValueQuery,91 >;9293 #[pallet::storage]94 pub(super) type AccountBalance<T: Config> = StorageNMap<95 Key = (96 Key<Twox64Concat, CollectionId>,97 // Owner98 Key<Blake2_128Concat, T::CrossAccountId>,99 ),100 Value = u32,101 QueryKind = ValueQuery,102 >;103104 #[pallet::storage]105 pub(super) type Balance<T: Config> = StorageNMap<106 Key = (107 Key<Twox64Concat, CollectionId>,108 Key<Twox64Concat, TokenId>,109 // Owner110 Key<Blake2_128Concat, T::CrossAccountId>,111 ),112 Value = u128,113 QueryKind = ValueQuery,114 >;115116 #[pallet::storage]117 pub(super) type Allowance<T: Config> = StorageNMap<118 Key = (119 Key<Twox64Concat, CollectionId>,120 Key<Twox64Concat, TokenId>,121 // Owner122 Key<Blake2_128, T::CrossAccountId>,123 // Spender124 Key<Blake2_128Concat, T::CrossAccountId>,125 ),126 Value = u128,127 QueryKind = ValueQuery,128 >;129}130131pub struct RefungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);132impl<T: Config> RefungibleHandle<T> {133 pub fn cast(inner: pallet_common::CollectionHandle<T>) -> Self {134 Self(inner)135 }136 pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {137 self.0138 }139}140impl<T: Config> Deref for RefungibleHandle<T> {141 type Target = pallet_common::CollectionHandle<T>;142143 fn deref(&self) -> &Self::Target {144 &self.0145 }146}147148impl<T: Config> Pallet<T> {149 pub fn total_supply(collection: &RefungibleHandle<T>) -> u32 {150 <TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)151 }152 pub fn token_exists(collection: &RefungibleHandle<T>, token: TokenId) -> bool {153 <TotalSupply<T>>::contains_key((collection.id, token))154 }155}156157// unchecked calls skips any permission checks158impl<T: Config> Pallet<T> {159 pub fn init_collection(data: Collection<T>) -> Result<CollectionId, DispatchError> {160 PalletCommon::init_collection(data)161 }162 pub fn destroy_collection(163 collection: RefungibleHandle<T>,164 sender: &T::CrossAccountId,165 ) -> DispatchResult {166 let id = collection.id;167168 // =========169170 PalletCommon::destroy_collection(collection.0, sender)?;171172 <TokensMinted<T>>::remove(id);173 <TokensBurnt<T>>::remove(id);174 <TokenData<T>>::remove_prefix((id,), None);175 <TotalSupply<T>>::remove_prefix((id,), None);176 <Balance<T>>::remove_prefix((id,), None);177 <Allowance<T>>::remove_prefix((id,), None);178 Ok(())179 }180181 pub fn burn_token(collection: &RefungibleHandle<T>, token_id: TokenId) -> DispatchResult {182 let burnt = <TokensBurnt<T>>::get(collection.id)183 .checked_add(1)184 .ok_or(ArithmeticError::Overflow)?;185186 <TokensBurnt<T>>::insert(collection.id, burnt);187 <TokenData<T>>::remove((collection.id, token_id));188 <TotalSupply<T>>::remove((collection.id, token_id));189 <Balance<T>>::remove_prefix((collection.id, token_id), None);190 <Allowance<T>>::remove_prefix((collection.id, token_id), None);191 // TODO: ERC721 transfer event192 return Ok(());193 }194195 pub fn burn(196 collection: &RefungibleHandle<T>,197 owner: &T::CrossAccountId,198 token: TokenId,199 amount: u128,200 ) -> DispatchResult {201 let total_supply = <TotalSupply<T>>::get((collection.id, token))202 .checked_sub(amount)203 .ok_or(<CommonError<T>>::TokenValueTooLow)?;204205 // This was probally last owner of this token?206 if total_supply == 0 {207 // Ensure user actually owns this amount208 ensure!(209 <Balance<T>>::get((collection.id, token, owner)) == amount,210 <CommonError<T>>::TokenValueTooLow211 );212 let account_balance = <AccountBalance<T>>::get((collection.id, owner))213 .checked_sub(1)214 // Should not occur215 .ok_or(ArithmeticError::Underflow)?;216217 // =========218219 <Owned<T>>::remove((collection.id, owner, token));220 <AccountBalance<T>>::insert((collection.id, owner), account_balance);221 Self::burn_token(collection, token)?;222 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(223 collection.id,224 token,225 owner.clone(),226 amount,227 ));228 return Ok(());229 }230231 let balance = <Balance<T>>::get((collection.id, token, owner))232 .checked_sub(amount)233 .ok_or(<CommonError<T>>::TokenValueTooLow)?;234 let account_balance = if balance == 0 {235 <AccountBalance<T>>::get((collection.id, owner))236 .checked_sub(1)237 // Should not occur238 .ok_or(ArithmeticError::Underflow)?239 } else {240 0241 };242243 // =========244245 if balance == 0 {246 <Owned<T>>::remove((collection.id, owner, token));247 <Balance<T>>::remove((collection.id, token, owner));248 <AccountBalance<T>>::insert((collection.id, owner), account_balance);249 } else {250 <Balance<T>>::insert((collection.id, token, owner), balance);251 }252 <TotalSupply<T>>::insert((collection.id, token), total_supply);253 // TODO: ERC20 transfer event254 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(255 collection.id,256 token,257 owner.clone(),258 amount,259 ));260 Ok(())261 }262263 pub fn transfer(264 collection: &RefungibleHandle<T>,265 from: &T::CrossAccountId,266 to: &T::CrossAccountId,267 token: TokenId,268 amount: u128,269 ) -> DispatchResult {270 ensure!(271 collection.limits.transfers_enabled(),272 <CommonError<T>>::TransferNotAllowed273 );274275 if collection.access == AccessMode::AllowList {276 collection.check_allowlist(from)?;277 collection.check_allowlist(to)?;278 }279 <PalletCommon<T>>::ensure_correct_receiver(to)?;280281 let balance_from = <Balance<T>>::get((collection.id, token, from))282 .checked_sub(amount)283 .ok_or(<CommonError<T>>::TokenValueTooLow)?;284 let mut create_target = false;285 let from_to_differ = from != to;286 let balance_to = if from != to {287 let old_balance = <Balance<T>>::get((collection.id, token, to));288 if old_balance == 0 {289 create_target = true;290 }291 Some(292 old_balance293 .checked_add(amount)294 .ok_or(ArithmeticError::Overflow)?,295 )296 } else {297 None298 };299300 let account_balance_from = if balance_from == 0 {301 Some(302 <AccountBalance<T>>::get((collection.id, from))303 .checked_sub(1)304 // Should not occur305 .ok_or(ArithmeticError::Underflow)?,306 )307 } else {308 None309 };310 // Account data is created in token, AccountBalance should be increased311 // But only if from != to as we shouldn't check overflow in this case312 let account_balance_to = if create_target && from_to_differ {313 let account_balance_to = <AccountBalance<T>>::get((collection.id, to))314 .checked_add(1)315 .ok_or(ArithmeticError::Overflow)?;316 ensure!(317 account_balance_to < collection.limits.account_token_ownership_limit(),318 <CommonError<T>>::AccountTokenLimitExceeded,319 );320321 Some(account_balance_to)322 } else {323 None324 };325326 // =========327328 if let Some(balance_to) = balance_to {329 // from != to330 if balance_from == 0 {331 <Balance<T>>::remove((collection.id, token, from));332 } else {333 <Balance<T>>::insert((collection.id, token, from), balance_from);334 }335 <Balance<T>>::insert((collection.id, token, to), balance_to);336 if let Some(account_balance_from) = account_balance_from {337 <AccountBalance<T>>::insert((collection.id, from), account_balance_from);338 <Owned<T>>::remove((collection.id, from, token));339 }340 if let Some(account_balance_to) = account_balance_to {341 <AccountBalance<T>>::insert((collection.id, to), account_balance_to);342 <Owned<T>>::insert((collection.id, to, token), true);343 }344 }345346 // TODO: ERC20 transfer event347 <PalletCommon<T>>::deposit_event(CommonEvent::Transfer(348 collection.id,349 token,350 from.clone(),351 to.clone(),352 amount,353 ));354 Ok(())355 }356357 pub fn create_multiple_items(358 collection: &RefungibleHandle<T>,359 sender: &T::CrossAccountId,360 data: Vec<CreateItemData<T>>,361 ) -> DispatchResult {362 let unrestricted_minting = collection.is_owner_or_admin(sender)?;363 if !unrestricted_minting {364 ensure!(365 collection.mint_mode,366 <CommonError<T>>::PublicMintingNotAllowed367 );368 collection.check_allowlist(sender)?;369370 for item in data.iter() {371 for (user, _) in &item.users {372 collection.check_allowlist(&user)?;373 }374 }375 }376377 for item in data.iter() {378 for (owner, _) in item.users.iter() {379 <PalletCommon<T>>::ensure_correct_receiver(owner)?;380 }381 }382383 // Total pieces per tokens384 let totals = data385 .iter()386 .map(|data| {387 Ok(data388 .users389 .iter()390 .map(|u| u.1)391 .try_fold(0u128, |acc, v| acc.checked_add(*v))392 .ok_or(ArithmeticError::Overflow)?)393 })394 .collect::<Result<Vec<_>, DispatchError>>()?;395 for total in &totals {396 ensure!(397 *total <= MAX_REFUNGIBLE_PIECES,398 <Error<T>>::WrongRefungiblePieces399 );400 }401402 let first_token_id = <TokensMinted<T>>::get(collection.id);403 let tokens_minted = first_token_id404 .checked_add(data.len() as u32)405 .ok_or(ArithmeticError::Overflow)?;406 ensure!(407 tokens_minted < collection.limits.token_limit(),408 <CommonError<T>>::CollectionTokenLimitExceeded409 );410411 let mut balances = BTreeMap::new();412 for data in &data {413 for (owner, _) in &data.users {414 let balance = balances415 .entry(owner)416 .or_insert_with(|| <AccountBalance<T>>::get((collection.id, owner)));417 *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;418419 ensure!(420 *balance <= collection.limits.account_token_ownership_limit(),421 <CommonError<T>>::AccountTokenLimitExceeded,422 );423 }424 }425426 // =========427428 <TokensMinted<T>>::insert(collection.id, tokens_minted);429 for (account, balance) in balances {430 <AccountBalance<T>>::insert((collection.id, account), balance);431 }432 for (i, token) in data.into_iter().enumerate() {433 let token_id = first_token_id + i as u32 + 1;434 <TotalSupply<T>>::insert((collection.id, token_id), totals[i]);435436 <TokenData<T>>::insert(437 (collection.id, token_id),438 ItemData {439 const_data: token.const_data.into(),440 variable_data: token.variable_data.into(),441 },442 );443 for (user, amount) in token.users.into_iter() {444 if amount == 0 {445 continue;446 }447 <Balance<T>>::insert((collection.id, token_id, &user), amount);448 <Owned<T>>::insert((collection.id, &user, TokenId(token_id)), true);449 // TODO: ERC20 transfer event450 <PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(451 collection.id,452 TokenId(token_id),453 user,454 amount,455 ));456 }457 }458 Ok(())459 }460461 pub fn set_allowance_unchecked(462 collection: &RefungibleHandle<T>,463 sender: &T::CrossAccountId,464 spender: &T::CrossAccountId,465 token: TokenId,466 amount: u128,467 ) {468 <Allowance<T>>::insert((collection.id, token, sender, spender), amount);469 // TODO: ERC20 approval event470 <PalletCommon<T>>::deposit_event(CommonEvent::Approved(471 collection.id,472 token,473 sender.clone(),474 spender.clone(),475 amount,476 ))477 }478479 pub fn set_allowance(480 collection: &RefungibleHandle<T>,481 sender: &T::CrossAccountId,482 spender: &T::CrossAccountId,483 token: TokenId,484 amount: u128,485 ) -> DispatchResult {486 if collection.access == AccessMode::AllowList {487 collection.check_allowlist(&sender)?;488 collection.check_allowlist(&spender)?;489 }490491 <PalletCommon<T>>::ensure_correct_receiver(spender)?;492493 if <Balance<T>>::get((collection.id, token, sender)) < amount {494 ensure!(495 collection.ignores_owned_amount(sender)? && Self::token_exists(collection, token),496 <CommonError<T>>::CantApproveMoreThanOwned497 );498 }499500 // =========501502 Self::set_allowance_unchecked(collection, sender, spender, token, amount);503 Ok(())504 }505506 pub fn transfer_from(507 collection: &RefungibleHandle<T>,508 spender: &T::CrossAccountId,509 from: &T::CrossAccountId,510 to: &T::CrossAccountId,511 token: TokenId,512 amount: u128,513 ) -> DispatchResult {514 if spender.conv_eq(from) {515 return Self::transfer(collection, from, to, token, amount);516 }517 if collection.access == AccessMode::AllowList {518 // `from`, `to` checked in [`transfer`]519 collection.check_allowlist(spender)?;520 }521522 let allowance =523 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);524 if allowance.is_none() {525 ensure!(526 collection.ignores_allowance(spender)?,527 <CommonError<T>>::TokenValueNotEnough528 );529 }530531 // =========532533 Self::transfer(collection, from, to, token, amount)?;534 if let Some(allowance) = allowance {535 Self::set_allowance_unchecked(collection, from, spender, token, allowance);536 }537 Ok(())538 }539540 pub fn burn_from(541 collection: &RefungibleHandle<T>,542 spender: &T::CrossAccountId,543 from: &T::CrossAccountId,544 token: TokenId,545 amount: u128,546 ) -> DispatchResult {547 if spender.conv_eq(from) {548 return Self::burn(collection, from, token, amount);549 }550 if collection.access == AccessMode::AllowList {551 // `from` checked in [`burn`]552 collection.check_allowlist(spender)?;553 }554555 let allowance =556 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);557 if allowance.is_none() {558 ensure!(559 collection.ignores_allowance(spender)?,560 <CommonError<T>>::TokenValueNotEnough561 );562 }563564 // =========565566 Self::burn(collection, from, token, amount)?;567 if let Some(allowance) = allowance {568 Self::set_allowance_unchecked(collection, from, spender, token, allowance);569 }570 Ok(())571 }572573 pub fn set_variable_metadata(574 collection: &RefungibleHandle<T>,575 sender: &T::CrossAccountId,576 token: TokenId,577 data: Vec<u8>,578 ) -> DispatchResult {579 ensure!(580 data.len() as u32 <= CUSTOM_DATA_LIMIT,581 <CommonError<T>>::TokenVariableDataLimitExceeded582 );583 collection.check_can_update_meta(584 sender,585 &T::CrossAccountId::from_sub(collection.owner.clone()),586 )?;587588 collection.consume_sstore()?;589 let token_data = <TokenData<T>>::get((collection.id, token));590591 // =========592593 <TokenData<T>>::insert(594 (collection.id, token),595 ItemData {596 variable_data: data,597 ..token_data598 },599 );600 Ok(())601 }602603 /// Delegated to `create_multiple_items`604 pub fn create_item(605 collection: &RefungibleHandle<T>,606 sender: &T::CrossAccountId,607 data: CreateItemData<T>,608 ) -> DispatchResult {609 Self::create_multiple_items(collection, sender, vec![data])610 }611}1#![cfg_attr(not(feature = "std"), no_std)]23use frame_support::{ensure, BoundedVec};4use nft_data_structs::{5 AccessMode, CUSTOM_DATA_LIMIT, Collection, CollectionId, CustomDataLimit,6 MAX_REFUNGIBLE_PIECES, TokenId,7};8use pallet_common::{9 Error as CommonError, Event as CommonEvent, Pallet as PalletCommon, account::CrossAccountId,10};11use sp_runtime::{ArithmeticError, DispatchError, DispatchResult};12use sp_std::{vec::Vec, vec, collections::btree_map::BTreeMap};13use core::ops::Deref;14use codec::{Encode, Decode};15use scale_info::TypeInfo;1617pub use pallet::*;18#[cfg(feature = "runtime-benchmarks")]19pub mod benchmarking;20pub mod common;21pub mod erc;22pub mod weights;23pub struct CreateItemData<T: Config> {24 pub const_data: BoundedVec<u8, CustomDataLimit>,25 pub variable_data: BoundedVec<u8, CustomDataLimit>,26 pub users: BTreeMap<T::CrossAccountId, u128>,27}28pub(crate) type SelfWeightOf<T> = <T as Config>::WeightInfo;2930#[derive(Encode, Decode, Default, TypeInfo)]31pub struct ItemData {32 pub const_data: Vec<u8>,33 pub variable_data: Vec<u8>,34}3536#[frame_support::pallet]37pub mod pallet {38 use super::*;39 use frame_support::{Blake2_128, Blake2_128Concat, Twox64Concat, pallet_prelude::*, storage::Key};40 use nft_data_structs::{CollectionId, TokenId};41 use super::weights::WeightInfo;4243 #[pallet::error]44 pub enum Error<T> {45 /// Not Refungible item data used to mint in Refungible collection.46 NotRefungibleDataUsedToMintFungibleCollectionToken,47 /// Maximum refungibility exceeded48 WrongRefungiblePieces,49 }5051 #[pallet::config]52 pub trait Config: frame_system::Config + pallet_common::Config {53 type WeightInfo: WeightInfo;54 }5556 #[pallet::pallet]57 #[pallet::generate_store(pub trait Store)]58 pub struct Pallet<T>(_);5960 #[pallet::storage]61 pub type TokensMinted<T: Config> =62 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;63 #[pallet::storage]64 pub type TokensBurnt<T: Config> =65 StorageMap<Hasher = Twox64Concat, Key = CollectionId, Value = u32, QueryKind = ValueQuery>;6667 #[pallet::storage]68 pub type TokenData<T: Config> = StorageNMap<69 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),70 Value = ItemData,71 QueryKind = ValueQuery,72 >;7374 #[pallet::storage]75 pub type TotalSupply<T: Config> = StorageNMap<76 Key = (Key<Twox64Concat, CollectionId>, Key<Twox64Concat, TokenId>),77 Value = u128,78 QueryKind = ValueQuery,79 >;8081 /// Used to enumerate tokens owned by account82 #[pallet::storage]83 pub type Owned<T: Config> = StorageNMap<84 Key = (85 Key<Twox64Concat, CollectionId>,86 Key<Blake2_128Concat, T::CrossAccountId>,87 Key<Twox64Concat, TokenId>,88 ),89 Value = bool,90 QueryKind = ValueQuery,91 >;9293 #[pallet::storage]94 pub type AccountBalance<T: Config> = StorageNMap<95 Key = (96 Key<Twox64Concat, CollectionId>,97 // Owner98 Key<Blake2_128Concat, T::CrossAccountId>,99 ),100 Value = u32,101 QueryKind = ValueQuery,102 >;103104 #[pallet::storage]105 pub type Balance<T: Config> = StorageNMap<106 Key = (107 Key<Twox64Concat, CollectionId>,108 Key<Twox64Concat, TokenId>,109 // Owner110 Key<Blake2_128Concat, T::CrossAccountId>,111 ),112 Value = u128,113 QueryKind = ValueQuery,114 >;115116 #[pallet::storage]117 pub type Allowance<T: Config> = StorageNMap<118 Key = (119 Key<Twox64Concat, CollectionId>,120 Key<Twox64Concat, TokenId>,121 // Owner122 Key<Blake2_128, T::CrossAccountId>,123 // Spender124 Key<Blake2_128Concat, T::CrossAccountId>,125 ),126 Value = u128,127 QueryKind = ValueQuery,128 >;129}130131pub struct RefungibleHandle<T: Config>(pallet_common::CollectionHandle<T>);132impl<T: Config> RefungibleHandle<T> {133 pub fn cast(inner: pallet_common::CollectionHandle<T>) -> Self {134 Self(inner)135 }136 pub fn into_inner(self) -> pallet_common::CollectionHandle<T> {137 self.0138 }139}140impl<T: Config> Deref for RefungibleHandle<T> {141 type Target = pallet_common::CollectionHandle<T>;142143 fn deref(&self) -> &Self::Target {144 &self.0145 }146}147148impl<T: Config> Pallet<T> {149 pub fn total_supply(collection: &RefungibleHandle<T>) -> u32 {150 <TokensMinted<T>>::get(collection.id) - <TokensBurnt<T>>::get(collection.id)151 }152 pub fn token_exists(collection: &RefungibleHandle<T>, token: TokenId) -> bool {153 <TotalSupply<T>>::contains_key((collection.id, token))154 }155}156157// unchecked calls skips any permission checks158impl<T: Config> Pallet<T> {159 pub fn init_collection(data: Collection<T>) -> Result<CollectionId, DispatchError> {160 PalletCommon::init_collection(data)161 }162 pub fn destroy_collection(163 collection: RefungibleHandle<T>,164 sender: &T::CrossAccountId,165 ) -> DispatchResult {166 let id = collection.id;167168 // =========169170 PalletCommon::destroy_collection(collection.0, sender)?;171172 <TokensMinted<T>>::remove(id);173 <TokensBurnt<T>>::remove(id);174 <TokenData<T>>::remove_prefix((id,), None);175 <TotalSupply<T>>::remove_prefix((id,), None);176 <Balance<T>>::remove_prefix((id,), None);177 <Allowance<T>>::remove_prefix((id,), None);178 Ok(())179 }180181 pub fn burn_token(collection: &RefungibleHandle<T>, token_id: TokenId) -> DispatchResult {182 let burnt = <TokensBurnt<T>>::get(collection.id)183 .checked_add(1)184 .ok_or(ArithmeticError::Overflow)?;185186 <TokensBurnt<T>>::insert(collection.id, burnt);187 <TokenData<T>>::remove((collection.id, token_id));188 <TotalSupply<T>>::remove((collection.id, token_id));189 <Balance<T>>::remove_prefix((collection.id, token_id), None);190 <Allowance<T>>::remove_prefix((collection.id, token_id), None);191 // TODO: ERC721 transfer event192 return Ok(());193 }194195 pub fn burn(196 collection: &RefungibleHandle<T>,197 owner: &T::CrossAccountId,198 token: TokenId,199 amount: u128,200 ) -> DispatchResult {201 let total_supply = <TotalSupply<T>>::get((collection.id, token))202 .checked_sub(amount)203 .ok_or(<CommonError<T>>::TokenValueTooLow)?;204205 // This was probally last owner of this token?206 if total_supply == 0 {207 // Ensure user actually owns this amount208 ensure!(209 <Balance<T>>::get((collection.id, token, owner)) == amount,210 <CommonError<T>>::TokenValueTooLow211 );212 let account_balance = <AccountBalance<T>>::get((collection.id, owner))213 .checked_sub(1)214 // Should not occur215 .ok_or(ArithmeticError::Underflow)?;216217 // =========218219 <Owned<T>>::remove((collection.id, owner, token));220 <AccountBalance<T>>::insert((collection.id, owner), account_balance);221 Self::burn_token(collection, token)?;222 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(223 collection.id,224 token,225 owner.clone(),226 amount,227 ));228 return Ok(());229 }230231 let balance = <Balance<T>>::get((collection.id, token, owner))232 .checked_sub(amount)233 .ok_or(<CommonError<T>>::TokenValueTooLow)?;234 let account_balance = if balance == 0 {235 <AccountBalance<T>>::get((collection.id, owner))236 .checked_sub(1)237 // Should not occur238 .ok_or(ArithmeticError::Underflow)?239 } else {240 0241 };242243 // =========244245 if balance == 0 {246 <Owned<T>>::remove((collection.id, owner, token));247 <Balance<T>>::remove((collection.id, token, owner));248 <AccountBalance<T>>::insert((collection.id, owner), account_balance);249 } else {250 <Balance<T>>::insert((collection.id, token, owner), balance);251 }252 <TotalSupply<T>>::insert((collection.id, token), total_supply);253 // TODO: ERC20 transfer event254 <PalletCommon<T>>::deposit_event(CommonEvent::ItemDestroyed(255 collection.id,256 token,257 owner.clone(),258 amount,259 ));260 Ok(())261 }262263 pub fn transfer(264 collection: &RefungibleHandle<T>,265 from: &T::CrossAccountId,266 to: &T::CrossAccountId,267 token: TokenId,268 amount: u128,269 ) -> DispatchResult {270 ensure!(271 collection.limits.transfers_enabled(),272 <CommonError<T>>::TransferNotAllowed273 );274275 if collection.access == AccessMode::AllowList {276 collection.check_allowlist(from)?;277 collection.check_allowlist(to)?;278 }279 <PalletCommon<T>>::ensure_correct_receiver(to)?;280281 let balance_from = <Balance<T>>::get((collection.id, token, from))282 .checked_sub(amount)283 .ok_or(<CommonError<T>>::TokenValueTooLow)?;284 let mut create_target = false;285 let from_to_differ = from != to;286 let balance_to = if from != to {287 let old_balance = <Balance<T>>::get((collection.id, token, to));288 if old_balance == 0 {289 create_target = true;290 }291 Some(292 old_balance293 .checked_add(amount)294 .ok_or(ArithmeticError::Overflow)?,295 )296 } else {297 None298 };299300 let account_balance_from = if balance_from == 0 {301 Some(302 <AccountBalance<T>>::get((collection.id, from))303 .checked_sub(1)304 // Should not occur305 .ok_or(ArithmeticError::Underflow)?,306 )307 } else {308 None309 };310 // Account data is created in token, AccountBalance should be increased311 // But only if from != to as we shouldn't check overflow in this case312 let account_balance_to = if create_target && from_to_differ {313 let account_balance_to = <AccountBalance<T>>::get((collection.id, to))314 .checked_add(1)315 .ok_or(ArithmeticError::Overflow)?;316 ensure!(317 account_balance_to < collection.limits.account_token_ownership_limit(),318 <CommonError<T>>::AccountTokenLimitExceeded,319 );320321 Some(account_balance_to)322 } else {323 None324 };325326 // =========327328 if let Some(balance_to) = balance_to {329 // from != to330 if balance_from == 0 {331 <Balance<T>>::remove((collection.id, token, from));332 } else {333 <Balance<T>>::insert((collection.id, token, from), balance_from);334 }335 <Balance<T>>::insert((collection.id, token, to), balance_to);336 if let Some(account_balance_from) = account_balance_from {337 <AccountBalance<T>>::insert((collection.id, from), account_balance_from);338 <Owned<T>>::remove((collection.id, from, token));339 }340 if let Some(account_balance_to) = account_balance_to {341 <AccountBalance<T>>::insert((collection.id, to), account_balance_to);342 <Owned<T>>::insert((collection.id, to, token), true);343 }344 }345346 // TODO: ERC20 transfer event347 <PalletCommon<T>>::deposit_event(CommonEvent::Transfer(348 collection.id,349 token,350 from.clone(),351 to.clone(),352 amount,353 ));354 Ok(())355 }356357 pub fn create_multiple_items(358 collection: &RefungibleHandle<T>,359 sender: &T::CrossAccountId,360 data: Vec<CreateItemData<T>>,361 ) -> DispatchResult {362 let unrestricted_minting = collection.is_owner_or_admin(sender)?;363 if !unrestricted_minting {364 ensure!(365 collection.mint_mode,366 <CommonError<T>>::PublicMintingNotAllowed367 );368 collection.check_allowlist(sender)?;369370 for item in data.iter() {371 for (user, _) in &item.users {372 collection.check_allowlist(&user)?;373 }374 }375 }376377 for item in data.iter() {378 for (owner, _) in item.users.iter() {379 <PalletCommon<T>>::ensure_correct_receiver(owner)?;380 }381 }382383 // Total pieces per tokens384 let totals = data385 .iter()386 .map(|data| {387 Ok(data388 .users389 .iter()390 .map(|u| u.1)391 .try_fold(0u128, |acc, v| acc.checked_add(*v))392 .ok_or(ArithmeticError::Overflow)?)393 })394 .collect::<Result<Vec<_>, DispatchError>>()?;395 for total in &totals {396 ensure!(397 *total <= MAX_REFUNGIBLE_PIECES,398 <Error<T>>::WrongRefungiblePieces399 );400 }401402 let first_token_id = <TokensMinted<T>>::get(collection.id);403 let tokens_minted = first_token_id404 .checked_add(data.len() as u32)405 .ok_or(ArithmeticError::Overflow)?;406 ensure!(407 tokens_minted < collection.limits.token_limit(),408 <CommonError<T>>::CollectionTokenLimitExceeded409 );410411 let mut balances = BTreeMap::new();412 for data in &data {413 for (owner, _) in &data.users {414 let balance = balances415 .entry(owner)416 .or_insert_with(|| <AccountBalance<T>>::get((collection.id, owner)));417 *balance = balance.checked_add(1).ok_or(ArithmeticError::Overflow)?;418419 ensure!(420 *balance <= collection.limits.account_token_ownership_limit(),421 <CommonError<T>>::AccountTokenLimitExceeded,422 );423 }424 }425426 // =========427428 <TokensMinted<T>>::insert(collection.id, tokens_minted);429 for (account, balance) in balances {430 <AccountBalance<T>>::insert((collection.id, account), balance);431 }432 for (i, token) in data.into_iter().enumerate() {433 let token_id = first_token_id + i as u32 + 1;434 <TotalSupply<T>>::insert((collection.id, token_id), totals[i]);435436 <TokenData<T>>::insert(437 (collection.id, token_id),438 ItemData {439 const_data: token.const_data.into(),440 variable_data: token.variable_data.into(),441 },442 );443 for (user, amount) in token.users.into_iter() {444 if amount == 0 {445 continue;446 }447 <Balance<T>>::insert((collection.id, token_id, &user), amount);448 <Owned<T>>::insert((collection.id, &user, TokenId(token_id)), true);449 // TODO: ERC20 transfer event450 <PalletCommon<T>>::deposit_event(CommonEvent::ItemCreated(451 collection.id,452 TokenId(token_id),453 user,454 amount,455 ));456 }457 }458 Ok(())459 }460461 pub fn set_allowance_unchecked(462 collection: &RefungibleHandle<T>,463 sender: &T::CrossAccountId,464 spender: &T::CrossAccountId,465 token: TokenId,466 amount: u128,467 ) {468 <Allowance<T>>::insert((collection.id, token, sender, spender), amount);469 // TODO: ERC20 approval event470 <PalletCommon<T>>::deposit_event(CommonEvent::Approved(471 collection.id,472 token,473 sender.clone(),474 spender.clone(),475 amount,476 ))477 }478479 pub fn set_allowance(480 collection: &RefungibleHandle<T>,481 sender: &T::CrossAccountId,482 spender: &T::CrossAccountId,483 token: TokenId,484 amount: u128,485 ) -> DispatchResult {486 if collection.access == AccessMode::AllowList {487 collection.check_allowlist(&sender)?;488 collection.check_allowlist(&spender)?;489 }490491 <PalletCommon<T>>::ensure_correct_receiver(spender)?;492493 if <Balance<T>>::get((collection.id, token, sender)) < amount {494 ensure!(495 collection.ignores_owned_amount(sender)? && Self::token_exists(collection, token),496 <CommonError<T>>::CantApproveMoreThanOwned497 );498 }499500 // =========501502 Self::set_allowance_unchecked(collection, sender, spender, token, amount);503 Ok(())504 }505506 pub fn transfer_from(507 collection: &RefungibleHandle<T>,508 spender: &T::CrossAccountId,509 from: &T::CrossAccountId,510 to: &T::CrossAccountId,511 token: TokenId,512 amount: u128,513 ) -> DispatchResult {514 if spender.conv_eq(from) {515 return Self::transfer(collection, from, to, token, amount);516 }517 if collection.access == AccessMode::AllowList {518 // `from`, `to` checked in [`transfer`]519 collection.check_allowlist(spender)?;520 }521522 let allowance =523 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);524 if allowance.is_none() {525 ensure!(526 collection.ignores_allowance(spender)?,527 <CommonError<T>>::TokenValueNotEnough528 );529 }530531 // =========532533 Self::transfer(collection, from, to, token, amount)?;534 if let Some(allowance) = allowance {535 Self::set_allowance_unchecked(collection, from, spender, token, allowance);536 }537 Ok(())538 }539540 pub fn burn_from(541 collection: &RefungibleHandle<T>,542 spender: &T::CrossAccountId,543 from: &T::CrossAccountId,544 token: TokenId,545 amount: u128,546 ) -> DispatchResult {547 if spender.conv_eq(from) {548 return Self::burn(collection, from, token, amount);549 }550 if collection.access == AccessMode::AllowList {551 // `from` checked in [`burn`]552 collection.check_allowlist(spender)?;553 }554555 let allowance =556 <Allowance<T>>::get((collection.id, token, from, &spender)).checked_sub(amount);557 if allowance.is_none() {558 ensure!(559 collection.ignores_allowance(spender)?,560 <CommonError<T>>::TokenValueNotEnough561 );562 }563564 // =========565566 Self::burn(collection, from, token, amount)?;567 if let Some(allowance) = allowance {568 Self::set_allowance_unchecked(collection, from, spender, token, allowance);569 }570 Ok(())571 }572573 pub fn set_variable_metadata(574 collection: &RefungibleHandle<T>,575 sender: &T::CrossAccountId,576 token: TokenId,577 data: Vec<u8>,578 ) -> DispatchResult {579 ensure!(580 data.len() as u32 <= CUSTOM_DATA_LIMIT,581 <CommonError<T>>::TokenVariableDataLimitExceeded582 );583 collection.check_can_update_meta(584 sender,585 &T::CrossAccountId::from_sub(collection.owner.clone()),586 )?;587588 collection.consume_sstore()?;589 let token_data = <TokenData<T>>::get((collection.id, token));590591 // =========592593 <TokenData<T>>::insert(594 (collection.id, token),595 ItemData {596 variable_data: data,597 ..token_data598 },599 );600 Ok(())601 }602603 /// Delegated to `create_multiple_items`604 pub fn create_item(605 collection: &RefungibleHandle<T>,606 sender: &T::CrossAccountId,607 data: CreateItemData<T>,608 ) -> DispatchResult {609 Self::create_multiple_items(collection, sender, vec![data])610 }611}