[NFTs] Track item's metadata depositor (#13124)

* Refactor do_mint()

* Track the depositor of item's metadata

* Revert back the access control

* On collection destroy return the metadata deposit

* Clear the metadata on item burn returning the deposit

* Address comments

* Fix clippy

* Don't return Ok on non-existing attribute removal
This commit is contained in:
Jegor Sidorenko
2023-01-11 15:27:59 +02:00
committed by GitHub
parent 643b69c64d
commit 836acb1bd3
8 changed files with 162 additions and 107 deletions
@@ -22,10 +22,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn do_mint(
collection: T::CollectionId,
item: T::ItemId,
depositor: T::AccountId,
maybe_depositor: Option<T::AccountId>,
mint_to: T::AccountId,
item_config: ItemConfig,
deposit_collection_owner: bool,
with_details_and_config: impl FnOnce(
&CollectionDetailsFor<T, I>,
&CollectionConfigFor<T, I>,
@@ -55,9 +54,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
true => T::ItemDeposit::get(),
false => Zero::zero(),
};
let deposit_account = match deposit_collection_owner {
true => collection_details.owner.clone(),
false => depositor,
let deposit_account = match maybe_depositor {
None => collection_details.owner.clone(),
Some(depositor) => depositor,
};
let item_owner = mint_to.clone();
@@ -92,6 +91,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
with_details: impl FnOnce(&ItemDetailsFor<T, I>) -> DispatchResult,
) -> DispatchResult {
ensure!(!T::Locker::is_locked(collection, item), Error::<T, I>::ItemLocked);
let item_config = Self::get_item_config(&collection, &item)?;
let owner = Collection::<T, I>::try_mutate(
&collection,
|maybe_collection_details| -> Result<T::AccountId, DispatchError> {
@@ -104,6 +104,24 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
// Return the deposit.
T::Currency::unreserve(&details.deposit.account, details.deposit.amount);
collection_details.items.saturating_dec();
// Clear the metadata if it's not locked.
if item_config.is_setting_enabled(ItemSetting::UnlockedMetadata) {
if let Some(metadata) = ItemMetadataOf::<T, I>::take(&collection, &item) {
let depositor_account =
metadata.deposit.account.unwrap_or(collection_details.owner.clone());
T::Currency::unreserve(&depositor_account, metadata.deposit.amount);
collection_details.item_metadatas.saturating_dec();
if depositor_account == collection_details.owner {
collection_details
.owner_deposit
.saturating_reduce(metadata.deposit.amount);
}
}
}
Ok(details.owner)
},
)?;
@@ -116,8 +134,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
// NOTE: if item's settings are not empty (e.g. item's metadata is locked)
// then we keep the record and don't remove it
let config = Self::get_item_config(&collection, &item)?;
if !config.has_disabled_settings() {
if !item_config.has_disabled_settings() {
ItemConfigOf::<T, I>::remove(&collection, &item);
}