Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

NFTs fractionalization #12565

Merged
merged 131 commits into from
May 23, 2023
Merged
Show file tree
Hide file tree
Changes from 109 commits
Commits
Show all changes
131 commits
Select commit Hold shift + click to select a range
10c6230
Copy Uniques into Nfts
jsidorenko Aug 29, 2022
af8875d
Connect new pallet
jsidorenko Aug 29, 2022
cd15630
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Sep 8, 2022
69edfb2
Update weights
jsidorenko Sep 9, 2022
028ea38
Nfts: Multiple approvals (#12178)
Szegoo Sep 13, 2022
e337c5a
Merge remote-tracking branch 'origin/master' into js/uniques-v2-main-…
KiChjang Sep 15, 2022
4930d81
Fixes
KiChjang Sep 15, 2022
f369ba9
cargo fmt
KiChjang Sep 15, 2022
ae5561e
Fixes
KiChjang Sep 15, 2022
f34b0ff
Fixes
KiChjang Sep 15, 2022
0edd25b
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Sep 19, 2022
c62ec92
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Sep 19, 2022
d09df86
Fix CI
jsidorenko Sep 19, 2022
3ab3356
Nfts: Fix Auto-Increment (#12223)
Szegoo Sep 23, 2022
e5a31cf
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Sep 24, 2022
6434da8
Rename Origin to RuntimeOrigin
jsidorenko Sep 24, 2022
61dee82
[Uniques V2] Tips (#12168)
jsidorenko Sep 24, 2022
490a0fa
[Uniques V2] Atomic NFTs swap (#12285)
jsidorenko Oct 5, 2022
3137791
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Oct 14, 2022
ef16fd2
[Uniques V2] Feature flags (#12367)
jsidorenko Oct 18, 2022
6763dd6
[Uniques V2] Refactor roles (#12437)
jsidorenko Oct 20, 2022
fef9b48
Fix copy
jsidorenko Oct 23, 2022
799cdf3
Remove storage_prefix
jsidorenko Oct 23, 2022
83a601d
Remove transactional
jsidorenko Oct 23, 2022
cbffb27
Initial commit SFT pallet.
lana-shanghai Oct 26, 2022
e1b24d7
Update comment
jsidorenko Oct 28, 2022
0c3f77f
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Nov 8, 2022
3c12fed
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Nov 14, 2022
c3d9a60
Merge uniques v2
lana-shanghai Nov 15, 2022
1813960
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Nov 16, 2022
afd4c18
[Uniques V2] Minting options (#12483)
jsidorenko Nov 16, 2022
090cd18
Merge branch 'js/uniques-v2-main-branch' into li/sft-main-branch
lana-shanghai Nov 16, 2022
841574f
Rename module to NFT fractionalisation
lana-shanghai Nov 16, 2022
eab8e04
Loose coupling for pallet-assets
lana-shanghai Nov 17, 2022
a37f8d1
cargo fmt
lana-shanghai Nov 17, 2022
8b95f6b
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Nov 17, 2022
8caecbb
[Uniques V2] Smart attributes (#12702)
jsidorenko Nov 21, 2022
b4ff566
[Uniques V2] Final improvements (#12736)
jsidorenko Nov 23, 2022
4c1b7f7
Update frame/nfts/src/lib.rs
jsidorenko Nov 23, 2022
f94926b
Merge branch 'master' of https://github.com/paritytech/substrate into…
Nov 25, 2022
beb8caa
".git/.scripts/bench-bot.sh" pallet dev pallet_nfts
Nov 25, 2022
6e651a8
Update docs
jsidorenko Nov 28, 2022
b051fd8
Typo
jsidorenko Nov 28, 2022
0556185
Fix benchmarks
jsidorenko Nov 28, 2022
992601b
Add more docs
jsidorenko Nov 28, 2022
5732492
Replace uniques with nfts, add minted volume storage
lana-shanghai Dec 1, 2022
e907e15
DepositRequired setting should affect only the attributes within the …
jsidorenko Dec 8, 2022
524c336
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Dec 13, 2022
3ad4980
Add unlock functionality
lana-shanghai Dec 13, 2022
9f27e91
[NFTs] Implement missed methods to set the attributes from other pall…
jsidorenko Dec 13, 2022
ea37f25
Revert snapshot changes
jsidorenko Dec 14, 2022
b15c602
Merge branch 'master' into js/uniques-v2-main-branch
jsidorenko Dec 14, 2022
c057f02
Update snapshots
jsidorenko Dec 14, 2022
5aaa37f
Yet another snapshot update..
jsidorenko Dec 14, 2022
0482d19
Asset to NFT id storage mutations
lana-shanghai Dec 14, 2022
9a0e3b2
Merge branch 'js/uniques-v2-main-branch' into li/sft-main-branch
lana-shanghai Dec 14, 2022
6fea293
Minor fixes
lana-shanghai Dec 14, 2022
0f9f4a9
Minor comments
lana-shanghai Dec 14, 2022
6814a94
cargo fmt
lana-shanghai Dec 15, 2022
95493ad
Remove benchmarking, unused clone()
lana-shanghai Dec 15, 2022
f07e7d0
Update frame/support/src/traits/tokens/nonfungible_v2.rs
jsidorenko Dec 20, 2022
b1fe6f7
Update frame/support/src/traits/tokens/nonfungible_v2.rs
jsidorenko Dec 20, 2022
917bb1e
Update frame/support/src/traits/tokens/nonfungible_v2.rs
jsidorenko Dec 20, 2022
92f43f6
Update frame/support/src/traits/tokens/nonfungibles_v2.rs
jsidorenko Dec 20, 2022
30985da
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
0d1a442
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
d429d6e
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
5de99c8
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
dcbce57
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
1db5061
Update frame/support/src/traits/tokens/nonfungible_v2.rs
jsidorenko Dec 20, 2022
7653b99
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
46f6451
Update frame/support/src/traits/tokens/nonfungibles_v2.rs
jsidorenko Dec 20, 2022
91ffabb
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
8057d72
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
d082300
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
8f18f08
Update frame/nfts/src/lib.rs
jsidorenko Dec 20, 2022
27e2f38
Address comments
jsidorenko Dec 20, 2022
56f228d
[NFTs] Add the new `owner` param to mint() method (#12997)
jsidorenko Dec 22, 2022
105c8f5
Merge branch 'master' of https://github.com/paritytech/substrate into…
Dec 22, 2022
a8c69a9
".git/.scripts/bench-bot.sh" pallet dev pallet_nfts
Dec 22, 2022
08c1205
Merge branch 'js/uniques-v2-main-branch' into li/sft-main-branch
jsidorenko Dec 22, 2022
72501e4
Fmt
jsidorenko Dec 22, 2022
7df1e2c
Update frame/nfts/src/common_functions.rs
jsidorenko Dec 23, 2022
2323614
Update frame/nfts/src/types.rs
jsidorenko Dec 23, 2022
08f0ea2
Update frame/nfts/src/types.rs
jsidorenko Dec 23, 2022
66cbec6
Update frame/nfts/src/types.rs
jsidorenko Dec 23, 2022
3218b20
Update frame/nfts/src/types.rs
jsidorenko Dec 23, 2022
40ecc60
Update frame/nfts/src/types.rs
jsidorenko Dec 23, 2022
30c0f23
Add call indexes
jsidorenko Dec 23, 2022
f618543
Update snapshots
jsidorenko Dec 23, 2022
3fb7c72
Merge branch 'js/uniques-v2-main-branch' into li/sft-main-branch
jsidorenko Dec 23, 2022
39d5c0c
Merge branch 'master' into li/sft-main-branch
jsidorenko Dec 30, 2022
84587d0
Merge branch 'master' into li/sft-main-branch
jsidorenko Jan 2, 2023
e8e3bed
Merge branch 'master' into li/sft-main-branch
jsidorenko Jan 5, 2023
553d262
Refactor nft fractionalisation pallet (#13008)
jsidorenko Jan 27, 2023
92f860b
Merge branch 'master' into li/sft-main-branch
jsidorenko Jan 27, 2023
c4ab35c
fmt
jsidorenko Jan 27, 2023
8e00a6b
Add fee reserved before creating an asset
lana-shanghai Feb 8, 2023
9df16c3
Use ReservableCurrency for fee deposit
lana-shanghai Feb 8, 2023
ea81d24
Improvements
jsidorenko Feb 13, 2023
e27331b
Revert fmt changes
jsidorenko Feb 13, 2023
4a13b27
A bit more cleanup
jsidorenko Feb 13, 2023
bd619d2
Consistent naming
jsidorenko Feb 13, 2023
98236e1
Make it more generic
jsidorenko Feb 13, 2023
caccb14
Leftover
jsidorenko Feb 13, 2023
96ec9a3
Use Vec<u8> instead of String
jsidorenko Feb 14, 2023
a172c1c
Merge branch 'master' into li/sft-main-branch
jsidorenko Feb 24, 2023
ed16d14
Update to the latest + improve the Locker trait
jsidorenko Feb 24, 2023
aabff98
Refactor NFTs locker
jsidorenko Mar 1, 2023
447df48
Replace Vec with BoundedVec, add clearer errors
lana-shanghai Mar 28, 2023
50212e3
cargo fmt
lana-shanghai Mar 28, 2023
14bb74d
Add README about unlocking NFTs
lana-shanghai Mar 28, 2023
9aa89e3
add constant definition
lana-shanghai Apr 17, 2023
f2ff0f7
Merge branch 'master' into li/sft-main-branch
lana-shanghai Apr 17, 2023
d539da0
add fortitude & precision to asset related functions
lana-shanghai Apr 17, 2023
ab7ad4a
fix mock and tests
lana-shanghai Apr 17, 2023
200ff45
transfer ExistentialDeposit to pallet if it's balance is below
lana-shanghai Apr 19, 2023
2b01abe
Merge branch 'master' into li/sft-main-branch
lana-shanghai May 2, 2023
6b28757
Merge remote-tracking branch 'origin/master' into li/sft-main-branch
May 16, 2023
af4725d
Refactoring
jsidorenko May 17, 2023
0fa54b0
Simplify the locking mechanism
jsidorenko May 17, 2023
4990242
Use PalletAttributes enum instead of the LOCKED_NFT_KEY
jsidorenko May 18, 2023
2bd4dc9
Fix benchmark
jsidorenko May 18, 2023
5631060
Merge remote-tracking branch 'origin/master' into li/sft-main-branch
May 18, 2023
7e54a89
Add missing licence details
jsidorenko May 19, 2023
042d152
Update Cargo.toml
jsidorenko May 19, 2023
507d485
Merge branch 'master' of https://github.com/paritytech/substrate into…
May 19, 2023
16f256f
".git/.scripts/commands/bench/bench.sh" pallet dev pallet_nft_fractio…
May 19, 2023
594b2cb
Apply suggestions from code review
jsidorenko May 19, 2023
e4cb5ac
Update frame/nft-fractionalization/README.md
jsidorenko May 19, 2023
9d34086
Merge remote-tracking branch 'origin/master' into li/sft-main-branch
May 22, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ members = [
"frame/message-queue",
"frame/nfts",
"frame/nfts/runtime-api",
"frame/nft-fractionalization",
"frame/nomination-pools",
"frame/nomination-pools/fuzzer",
"frame/nomination-pools/benchmarking",
Expand Down
4 changes: 4 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pallet-mmr = { version = "4.0.0-dev", default-features = false, path = "../../..
pallet-multisig = { version = "4.0.0-dev", default-features = false, path = "../../../frame/multisig" }
pallet-nfts = { version = "4.0.0-dev", default-features = false, path = "../../../frame/nfts" }
pallet-nfts-runtime-api = { version = "4.0.0-dev", default-features = false, path = "../../../frame/nfts/runtime-api" }
pallet-nft-fractionalization = { version = "4.0.0-dev", default-features = false, path = "../../../frame/nft-fractionalization" }
pallet-nomination-pools = { version = "1.0.0", default-features = false, path = "../../../frame/nomination-pools"}
pallet-nomination-pools-benchmarking = { version = "1.0.0", default-features = false, optional = true, path = "../../../frame/nomination-pools/benchmarking" }
pallet-nomination-pools-runtime-api = { version = "1.0.0-dev", default-features = false, path = "../../../frame/nomination-pools/runtime-api" }
Expand Down Expand Up @@ -207,6 +208,7 @@ std = [
"pallet-uniques/std",
"pallet-nfts/std",
"pallet-nfts-runtime-api/std",
"pallet-nft-fractionalization/std",
"pallet-vesting/std",
"log/std",
"frame-try-runtime?/std",
Expand Down Expand Up @@ -267,6 +269,7 @@ runtime-benchmarks = [
"pallet-utility/runtime-benchmarks",
"pallet-uniques/runtime-benchmarks",
"pallet-nfts/runtime-benchmarks",
"pallet-nft-fractionalization/runtime-benchmarks",
"pallet-vesting/runtime-benchmarks",
"pallet-whitelist/runtime-benchmarks",
"frame-system-benchmarking/runtime-benchmarks",
Expand Down Expand Up @@ -329,6 +332,7 @@ try-runtime = [
"pallet-transaction-storage/try-runtime",
"pallet-uniques/try-runtime",
"pallet-nfts/try-runtime",
"pallet-nft-fractionalization/try-runtime",
"pallet-vesting/try-runtime",
"pallet-whitelist/try-runtime",
]
42 changes: 38 additions & 4 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ use frame_support::{
traits::{
fungible::ItemOf, tokens::nonfungibles_v2::Inspect, AsEnsureOriginWithArg, ConstBool,
ConstU128, ConstU16, ConstU32, Currency, EitherOfDiverse, EqualPrivilegeOnly, Everything,
Imbalance, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, Nothing, OnUnbalanced,
U128CurrencyToVote, WithdrawReasons,
Imbalance, InstanceFilter, KeyOwnerProofSystem, LockIdentifier, Locker, Nothing,
OnUnbalanced, U128CurrencyToVote, WithdrawReasons,
},
weights::{
constants::{
Expand All @@ -56,7 +56,7 @@ use pallet_grandpa::{
fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList,
};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use pallet_nfts::PalletFeatures;
use pallet_nfts::{PalletFeatures, LOCKED_NFT_KEY};
use pallet_nis::WithMaximumOf;
use pallet_session::historical::{self as pallet_session_historical};
pub use pallet_transaction_payment::{CurrencyAdapter, Multiplier, TargetedFeeAdjustment};
Expand Down Expand Up @@ -1575,6 +1575,16 @@ parameter_types! {
pub const MaxAttributesPerCall: u32 = 10;
}

type ItemId = <Runtime as pallet_nfts::Config>::ItemId;
type CollectionId = <Runtime as pallet_nfts::Config>::CollectionId;

pub struct NftLocker;
impl Locker<CollectionId, ItemId> for NftLocker {
fn is_locked(collection: CollectionId, item: ItemId) -> bool {
<Nfts as Inspect<AccountId>>::system_attribute(&collection, &item, LOCKED_NFT_KEY).is_some()
}
}

impl pallet_nfts::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type CollectionId = u32;
Expand All @@ -1601,7 +1611,29 @@ impl pallet_nfts::Config for Runtime {
#[cfg(feature = "runtime-benchmarks")]
type Helper = ();
type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<AccountId>>;
type Locker = ();
type Locker = NftLocker;
}

parameter_types! {
pub const NftFractionalizationPalletId: PalletId = PalletId(*b"fraction");
pub NewAssetSymbol: Vec<u8> = (*b"FRAC").into();
pub NewAssetName: Vec<u8> = (*b"Frac").into();
}

impl pallet_nft_fractionalization::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Deposit = AssetDeposit;
type Currency = Balances;
type NewAssetSymbol = NewAssetSymbol;
type NewAssetName = NewAssetName;
type NftCollectionId = <Self as pallet_nfts::Config>::CollectionId;
type NftId = <Self as pallet_nfts::Config>::ItemId;
type AssetBalance = <Self as pallet_balances::Config>::Balance;
type AssetId = <Self as pallet_assets::Config>::AssetId;
type Assets = Assets;
type Nfts = Nfts;
type PalletId = NftFractionalizationPalletId;
type WeightInfo = pallet_nft_fractionalization::weights::SubstrateWeight<Runtime>;
}

impl pallet_transaction_storage::Config for Runtime {
Expand Down Expand Up @@ -1765,6 +1797,7 @@ construct_runtime!(
Nis: pallet_nis,
Uniques: pallet_uniques,
Nfts: pallet_nfts,
NftFractionalization: pallet_nft_fractionalization,
TransactionStorage: pallet_transaction_storage,
VoterList: pallet_bags_list::<Instance1>,
StateTrieMigration: pallet_state_trie_migration,
Expand Down Expand Up @@ -1896,6 +1929,7 @@ mod benches {
[pallet_treasury, Treasury]
[pallet_uniques, Uniques]
[pallet_nfts, Nfts]
[pallet_nft_fractionalization, NftFractionalization]
[pallet_utility, Utility]
[pallet_vesting, Vesting]
[pallet_whitelist, Whitelist]
Expand Down
14 changes: 11 additions & 3 deletions frame/assets/src/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -896,9 +896,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
ensure!(metadata.as_ref().map_or(true, |m| !m.is_frozen), Error::<T, I>::NoPermission);

let old_deposit = metadata.take().map_or(Zero::zero(), |m| m.deposit);
let new_deposit = T::MetadataDepositPerByte::get()
.saturating_mul(((name.len() + symbol.len()) as u32).into())
.saturating_add(T::MetadataDepositBase::get());
let new_deposit = Self::calc_metadata_deposit(&name, &symbol);

if new_deposit > old_deposit {
T::Currency::reserve(from, new_deposit - old_deposit)?;
Expand All @@ -924,4 +922,14 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Ok(())
})
}

/// Calculate the metadata deposit for the provided data.
pub(super) fn calc_metadata_deposit(
name: &Vec<u8>,
symbol: &Vec<u8>,
) -> DepositBalanceOf<T, I> {
T::MetadataDepositPerByte::get()
.saturating_mul(((name.len() + symbol.len()) as u32).into())
.saturating_add(T::MetadataDepositBase::get())
}
}
13 changes: 13 additions & 0 deletions frame/assets/src/impl_fungibles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,19 @@ impl<T: Config<I>, I: 'static> fungibles::metadata::Mutate<<T as SystemConfig>::
}
}

impl<T: Config<I>, I: 'static>
fungibles::metadata::CalcMetadataDeposit<
<T::Currency as Currency<<T as SystemConfig>::AccountId>>::Balance,
> for Pallet<T, I>
{
fn calc(
name: &Vec<u8>,
symbol: &Vec<u8>,
) -> <T::Currency as Currency<<T as SystemConfig>::AccountId>>::Balance {
Self::calc_metadata_deposit(name, symbol)
}
}

impl<T: Config<I>, I: 'static> fungibles::approvals::Inspect<<T as SystemConfig>::AccountId>
for Pallet<T, I>
{
Expand Down
46 changes: 46 additions & 0 deletions frame/nft-fractionalization/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
[package]
name = "pallet-nft-fractionalization"
version = "4.0.0-dev"
description = "FRAME pallet for semi-fungible tokens."
authors = ["Parity Technologies <[email protected]>"]
homepage = "https://substrate.io"
edition = "2021"
repository = "https://github.com/paritytech/substrate/"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false }
log = { version = "0.4.17", default-features = false }
scale-info = { version = "2.1.1", default-features = false, features = ["derive"] }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, path = "../benchmarking" }
frame-support = { version = "4.0.0-dev", default-features = false, path = "../support" }
frame-system = { version = "4.0.0-dev", default-features = false, path = "../system" }
pallet-assets = { version = "4.0.0-dev", default-features = false, path = "../assets" }
pallet-nfts = { version = "4.0.0-dev", default-features = false, path = "../nfts" }
sp-runtime = { version = "7.0.0", default-features = false, path = "../../primitives/runtime" }
sp-std = { version = "5.0.0", default-features = false, path = "../../primitives/std" }

[dev-dependencies]
pallet-balances = { version = "4.0.0-dev", path = "../balances" }
sp-core = { version = "7.0.0", path = "../../primitives/core" }
sp-io = { version = "7.0.0", path = "../../primitives/io" }
sp-std = { version = "5.0.0", path = "../../primitives/std" }

[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking/std",
"frame-support/std",
"frame-system/std",
"log/std",
"pallet-assets/std",
"pallet-nfts/std",
"scale-info/std",
"sp-runtime/std",
"sp-std/std",
]
runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"]
try-runtime = ["frame-support/try-runtime"]
3 changes: 3 additions & 0 deletions frame/nft-fractionalization/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
### Lock NFT

Lock an NFT from `pallet-nfts` and mint fungible assets from `pallet-assets`.
lana-shanghai marked this conversation as resolved.
Show resolved Hide resolved
131 changes: 131 additions & 0 deletions frame/nft-fractionalization/src/benchmarking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// This file is part of Substrate.

// Copyright (C) 2020-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Nft fractionalization pallet benchmarking.

#![cfg(feature = "runtime-benchmarks")]

use super::*;
use frame_benchmarking::{benchmarks, whitelisted_caller};
use frame_support::{
assert_ok,
traits::{
fungible::{Inspect as InspectFungible, Unbalanced},
tokens::nonfungibles_v2::{Create, Mutate},
},
};
use frame_system::RawOrigin as SystemOrigin;
use pallet_nfts::{CollectionConfig, CollectionSettings, ItemConfig, MintSettings};
use sp_runtime::traits::{Bounded, StaticLookup};
use sp_std::prelude::*;

use crate::Pallet as NftFractionalization;

type BalanceOf<T> =
<<T as Config>::Currency as InspectFungible<<T as SystemConfig>::AccountId>>::Balance;

type CollectionConfigOf<T> = CollectionConfig<
BalanceOf<T>,
<T as SystemConfig>::BlockNumber,
<T as Config>::NftCollectionId,
>;

fn default_collection_config<T: Config>() -> CollectionConfigOf<T>
where
T::Currency: InspectFungible<T::AccountId>,
{
CollectionConfig {
settings: CollectionSettings::all_enabled(),
max_supply: None,
mint_settings: MintSettings::default(),
}
}

fn mint_nft<T: Config>(nft_id: T::NftId) -> (T::AccountId, AccountIdLookupOf<T>)
where
T::NftCollectionId: From<u32>,
T::Currency: Unbalanced<T::AccountId>,
T::Nfts: Create<T::AccountId, CollectionConfig<BalanceOf<T>, T::BlockNumber, T::NftCollectionId>>
+ Mutate<T::AccountId, ItemConfig>,
{
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
assert_ok!(T::Currency::set_balance(&caller, BalanceOf::<T>::max_value()));
assert_ok!(T::Nfts::create_collection(&caller, &caller, &default_collection_config::<T>()));
assert_ok!(T::Nfts::mint_into(&0.into(), &nft_id, &caller, &ItemConfig::default(), true));
(caller, caller_lookup)
}

fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
let events = frame_system::Pallet::<T>::events();
let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
// compare to the last event record
let frame_system::EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}

benchmarks! {
where_clause {
where
T::AssetBalance: From<u64>,
T::AssetId: From<u32>,
T::NftCollectionId: From<u32>,
T::NftId: From<u32>,
T::Currency: Unbalanced<T::AccountId>,
T::Nfts: Create<T::AccountId, CollectionConfig<BalanceOf<T>, T::BlockNumber, T::NftCollectionId>>
+ Mutate<T::AccountId, ItemConfig>,
}

fractionalize {
let (caller, caller_lookup) = mint_nft::<T>(0.into());
}: _(SystemOrigin::Signed(caller.clone()), 0.into(), 0.into(), 0.into(), caller_lookup, 1000u32.into())
verify {
assert_last_event::<T>(
Event::NftFractionalized {
nft_collection: 0.into(),
nft: 0.into(),
fractions: 1000u32.into(),
asset: 0.into(),
beneficiary: caller,
}.into()
);
}

unify {
let (caller, caller_lookup) = mint_nft::<T>(0.into());
NftFractionalization::<T>::fractionalize(
SystemOrigin::Signed(caller.clone()).into(),
0.into(),
0.into(),
0.into(),
caller_lookup.clone(),
1000u32.into(),
)?;
}: _(SystemOrigin::Signed(caller.clone()), 0.into(), 0.into(), 0.into(), caller_lookup)
verify {
assert_last_event::<T>(
Event::NftUnified {
nft_collection: 0.into(),
nft: 0.into(),
asset: 0.into(),
beneficiary: caller,
}.into()
);
}

impl_benchmark_test_suite!(NftFractionalization, crate::mock::new_test_ext(), crate::mock::Test);
}
Loading