feat: Rebrand Polkadot/Substrate references to PezkuwiChain

This commit systematically rebrands various references from Parity Technologies'
Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk.

Key changes include:
- Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks.
- Modified internal documentation and code comments to reflect PezkuwiChain naming and structure.
- Replaced direct references to  with  or specific paths within the  for XCM, Pezkuwi, and other modules.
- Cleaned up deprecated  issue and PR references in various  and  files, particularly in  and  modules.
- Adjusted image and logo URLs in documentation to point to PezkuwiChain assets.
- Removed or rephrased comments related to external Polkadot/Substrate PRs and issues.

This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
2025-12-14 00:04:10 +03:00
parent 286de54384
commit 1c0e57d984
9084 changed files with 997839 additions and 997557 deletions
@@ -0,0 +1,51 @@
[package]
name = "pezpallet-nft-fractionalization"
version = "10.0.0"
authors.workspace = true
edition.workspace = true
license = "Apache-2.0"
homepage.workspace = true
repository.workspace = true
description = "FRAME pallet to convert non-fungible to fungible tokens."
readme = "README.md"
[lints]
workspace = true
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[dependencies]
codec = { workspace = true }
frame = { workspace = true, features = ["runtime"] }
log = { workspace = true }
pezpallet-assets = { workspace = true }
pezpallet-nfts = { workspace = true }
scale-info = { features = ["derive"], workspace = true }
[dev-dependencies]
pezpallet-balances = { workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"codec/std",
"frame/std",
"log/std",
"pezpallet-assets/std",
"pezpallet-balances/std",
"pezpallet-nfts/std",
"scale-info/std",
]
runtime-benchmarks = [
"frame/runtime-benchmarks",
"pezpallet-assets/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
"pezpallet-nfts/runtime-benchmarks",
]
try-runtime = [
"frame/try-runtime",
"pezpallet-assets/try-runtime",
"pezpallet-balances/try-runtime",
"pezpallet-nfts/try-runtime",
]
@@ -0,0 +1,8 @@
# Lock NFT
Lock an NFT from `pezpallet-nfts` and mint fungible assets from `pezpallet-assets`.
The NFT gets locked by putting a system-level attribute named `Locked`. This prevents the NFT from being transferred
further. The NFT becomes unlocked when the `Locked` attribute is removed. In order to unify the fungible asset and
unlock the NFT, an account must hold the full issuance of the asset the NFT was fractionalised into. Holding less of the
fungible asset will not allow the unlocking of the NFT.
@@ -0,0 +1,149 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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::prelude::*;
use frame::deps::pezframe_support::assert_ok;
use fungible::{Inspect as InspectFungible, Mutate as MutateFungible};
use nonfungibles_v2::{Create, Mutate};
use pezframe_system::RawOrigin as SystemOrigin;
use pezpallet_nfts::{CollectionConfig, CollectionSettings, ItemConfig, MintSettings};
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>, BlockNumberFor<T>, <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::Nfts: Create<T::AccountId, CollectionConfig<BalanceOf<T>, BlockNumberFor<T>, T::NftCollectionId>>
+ Mutate<T::AccountId, ItemConfig>,
{
let caller: T::AccountId = whitelisted_caller();
let caller_lookup = T::Lookup::unlookup(caller.clone());
let ed = T::Currency::minimum_balance();
let multiplier = BalanceOf::<T>::from(100u8);
T::Currency::set_balance(&caller, ed * multiplier + T::Deposit::get() * multiplier);
assert_ok!(T::Nfts::create_collection(&caller, &caller, &default_collection_config::<T>()));
let collection = T::BenchmarkHelper::collection(0);
assert_ok!(T::Nfts::mint_into(&collection, &nft_id, &caller, &ItemConfig::default(), true));
(caller, caller_lookup)
}
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
let events = pezframe_system::Pallet::<T>::events();
let system_event: <T as pezframe_system::Config>::RuntimeEvent = generic_event.into();
// compare to the last event record
let pezframe_system::EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}
#[benchmarks(
where
T::Nfts:
Create<
T::AccountId,
CollectionConfig<BalanceOf<T>,
pezframe_system::pezpallet_prelude::BlockNumberFor::<T>,
T::NftCollectionId>
>
+ Mutate<T::AccountId, ItemConfig>,
)]
mod benchmarks {
use super::*;
#[benchmark]
fn fractionalize() {
let asset = T::BenchmarkHelper::asset(0);
let collection = T::BenchmarkHelper::collection(0);
let nft = T::BenchmarkHelper::nft(0);
let (caller, caller_lookup) = mint_nft::<T>(nft);
#[extrinsic_call]
_(
SystemOrigin::Signed(caller.clone()),
collection,
nft,
asset.clone(),
caller_lookup,
1000u32.into(),
);
assert_last_event::<T>(
Event::NftFractionalized {
nft_collection: collection,
nft,
fractions: 1000u32.into(),
asset,
beneficiary: caller,
}
.into(),
);
}
#[benchmark]
fn unify() {
let asset = T::BenchmarkHelper::asset(0);
let collection = T::BenchmarkHelper::collection(0);
let nft = T::BenchmarkHelper::nft(0);
let (caller, caller_lookup) = mint_nft::<T>(nft);
assert_ok!(NftFractionalization::<T>::fractionalize(
SystemOrigin::Signed(caller.clone()).into(),
collection,
nft,
asset.clone(),
caller_lookup.clone(),
1000u32.into(),
));
#[extrinsic_call]
_(SystemOrigin::Signed(caller.clone()), collection, nft, asset.clone(), caller_lookup);
assert_last_event::<T>(
Event::NftUnified { nft_collection: collection, nft, asset, beneficiary: caller }
.into(),
);
}
impl_benchmark_test_suite!(
NftFractionalization,
crate::mock::new_test_ext(),
crate::mock::Test
);
}
@@ -0,0 +1,402 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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
//!
//! This pallet provides the basic functionality that should allow users
//! to leverage partial ownership, transfers, and sales, of illiquid assets,
//! whether real-world assets represented by their digital twins, or NFTs,
//! or original NFTs.
//!
//! The functionality allows a user to lock an NFT they own, create a new
//! fungible asset, and mint a set amount of tokens (`fractions`).
//!
//! It also allows the user to burn 100% of the asset and to unlock the NFT
//! into their account.
//!
//! ### Functions
//!
//! * `fractionalize`: Lock the NFT and create and mint a new fungible asset.
//! * `unify`: Return 100% of the asset and unlock the NFT.
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
mod types;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
#[cfg(test)]
pub mod mock;
#[cfg(test)]
mod tests;
pub mod weights;
use frame::prelude::*;
use pezframe_system::Config as SystemConfig;
pub use pallet::*;
pub use types::*;
pub use weights::WeightInfo;
#[frame::pallet]
pub mod pallet {
use super::*;
use core::fmt::Display;
use fungible::{
hold::Mutate as HoldMutateFungible, Inspect as InspectFungible, Mutate as MutateFungible,
};
use fungibles::{
metadata::{MetadataDeposit, Mutate as MutateMetadata},
Create, Destroy, Inspect, Mutate,
};
use nonfungibles_v2::{Inspect as NonFungiblesInspect, Transfer};
use scale_info::prelude::{format, string::String};
use tokens::{
AssetId, Balance as AssetBalance,
Fortitude::Polite,
Precision::{BestEffort, Exact},
Preservation::{Expendable, Preserve},
};
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
/// The currency mechanism, used for paying for deposits.
type Currency: InspectFungible<Self::AccountId>
+ MutateFungible<Self::AccountId>
+ HoldMutateFungible<Self::AccountId, Reason = Self::RuntimeHoldReason>;
/// Overarching hold reason.
type RuntimeHoldReason: From<HoldReason>;
/// The deposit paid by the user locking an NFT. The deposit is returned to the original NFT
/// owner when the asset is unified and the NFT is unlocked.
#[pallet::constant]
type Deposit: Get<DepositOf<Self>>;
/// Identifier for the collection of NFT.
type NftCollectionId: Member + Parameter + MaxEncodedLen + Copy + Display;
/// The type used to identify an NFT within a collection.
type NftId: Member + Parameter + MaxEncodedLen + Copy + Display;
/// The type used to describe the amount of fractions converted into assets.
type AssetBalance: AssetBalance;
/// The type used to identify the assets created during fractionalization.
type AssetId: AssetId;
/// Registry for the minted assets.
type Assets: Inspect<Self::AccountId, AssetId = Self::AssetId, Balance = Self::AssetBalance>
+ Create<Self::AccountId>
+ Destroy<Self::AccountId>
+ Mutate<Self::AccountId>
+ MutateMetadata<Self::AccountId>
+ MetadataDeposit<DepositOf<Self>>;
/// Registry for minted NFTs.
type Nfts: NonFungiblesInspect<
Self::AccountId,
ItemId = Self::NftId,
CollectionId = Self::NftCollectionId,
> + Transfer<Self::AccountId>;
/// The pallet's id, used for deriving its sovereign account ID.
#[pallet::constant]
type PalletId: Get<PalletId>;
/// The newly created asset's symbol.
#[pallet::constant]
type NewAssetSymbol: Get<BoundedVec<u8, Self::StringLimit>>;
/// The newly created asset's name.
#[pallet::constant]
type NewAssetName: Get<BoundedVec<u8, Self::StringLimit>>;
/// The maximum length of a name or symbol stored on-chain.
#[pallet::constant]
type StringLimit: Get<u32>;
/// A set of helper functions for benchmarking.
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper: BenchmarkHelper<Self::AssetId, Self::NftCollectionId, Self::NftId>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
/// Keeps track of the corresponding NFT ID, asset ID and amount minted.
#[pallet::storage]
pub type NftToAsset<T: Config> = StorageMap<
_,
Blake2_128Concat,
(T::NftCollectionId, T::NftId),
Details<AssetIdOf<T>, AssetBalanceOf<T>, DepositOf<T>, T::AccountId>,
OptionQuery,
>;
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// An NFT was successfully fractionalized.
NftFractionalized {
nft_collection: T::NftCollectionId,
nft: T::NftId,
fractions: AssetBalanceOf<T>,
asset: AssetIdOf<T>,
beneficiary: T::AccountId,
},
/// An NFT was successfully returned back.
NftUnified {
nft_collection: T::NftCollectionId,
nft: T::NftId,
asset: AssetIdOf<T>,
beneficiary: T::AccountId,
},
}
#[pallet::error]
pub enum Error<T> {
/// Asset ID does not correspond to locked NFT.
IncorrectAssetId,
/// The signing account has no permission to do the operation.
NoPermission,
/// NFT doesn't exist.
NftNotFound,
/// NFT has not yet been fractionalised.
NftNotFractionalized,
}
/// A reason for the pallet placing a hold on funds.
#[pallet::composite_enum]
pub enum HoldReason {
/// Reserved for a fractionalized NFT.
#[codec(index = 0)]
Fractionalized,
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Lock the NFT and mint a new fungible asset.
///
/// The dispatch origin for this call must be Signed.
/// The origin must be the owner of the NFT they are trying to lock.
///
/// `Deposit` funds of sender are reserved.
///
/// - `nft_collection_id`: The ID used to identify the collection of the NFT.
/// Is used within the context of `pezpallet_nfts`.
/// - `nft_id`: The ID used to identify the NFT within the given collection.
/// Is used within the context of `pezpallet_nfts`.
/// - `asset_id`: The ID of the new asset. It must not exist.
/// Is used within the context of `pezpallet_assets`.
/// - `beneficiary`: The account that will receive the newly created asset.
/// - `fractions`: The total issuance of the newly created asset class.
///
/// Emits `NftFractionalized` event when successful.
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::fractionalize())]
pub fn fractionalize(
origin: OriginFor<T>,
nft_collection_id: T::NftCollectionId,
nft_id: T::NftId,
asset_id: AssetIdOf<T>,
beneficiary: AccountIdLookupOf<T>,
fractions: AssetBalanceOf<T>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let beneficiary = T::Lookup::lookup(beneficiary)?;
let nft_owner =
T::Nfts::owner(&nft_collection_id, &nft_id).ok_or(Error::<T>::NftNotFound)?;
ensure!(nft_owner == who, Error::<T>::NoPermission);
let pezpallet_account = Self::get_pallet_account();
let deposit = T::Deposit::get();
T::Currency::hold(&HoldReason::Fractionalized.into(), &nft_owner, deposit)?;
Self::do_lock_nft(nft_collection_id, nft_id)?;
Self::do_create_asset(asset_id.clone(), pezpallet_account.clone())?;
Self::do_mint_asset(asset_id.clone(), &beneficiary, fractions)?;
Self::do_set_metadata(
asset_id.clone(),
&who,
&pezpallet_account,
&nft_collection_id,
&nft_id,
)?;
NftToAsset::<T>::insert(
(nft_collection_id, nft_id),
Details { asset: asset_id.clone(), fractions, asset_creator: nft_owner, deposit },
);
Self::deposit_event(Event::NftFractionalized {
nft_collection: nft_collection_id,
nft: nft_id,
fractions,
asset: asset_id,
beneficiary,
});
Ok(())
}
/// Burn the total issuance of the fungible asset and return (unlock) the locked NFT.
///
/// The dispatch origin for this call must be Signed.
///
/// `Deposit` funds will be returned to `asset_creator`.
///
/// - `nft_collection_id`: The ID used to identify the collection of the NFT.
/// Is used within the context of `pezpallet_nfts`.
/// - `nft_id`: The ID used to identify the NFT within the given collection.
/// Is used within the context of `pezpallet_nfts`.
/// - `asset_id`: The ID of the asset being returned and destroyed. Must match
/// the original ID of the created asset, corresponding to the NFT.
/// Is used within the context of `pezpallet_assets`.
/// - `beneficiary`: The account that will receive the unified NFT.
///
/// Emits `NftUnified` event when successful.
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::unify())]
pub fn unify(
origin: OriginFor<T>,
nft_collection_id: T::NftCollectionId,
nft_id: T::NftId,
asset_id: AssetIdOf<T>,
beneficiary: AccountIdLookupOf<T>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let beneficiary = T::Lookup::lookup(beneficiary)?;
NftToAsset::<T>::try_mutate_exists((nft_collection_id, nft_id), |maybe_details| {
let details = maybe_details.take().ok_or(Error::<T>::NftNotFractionalized)?;
ensure!(details.asset == asset_id, Error::<T>::IncorrectAssetId);
let deposit = details.deposit;
let asset_creator = details.asset_creator;
Self::do_burn_asset(asset_id.clone(), &who, details.fractions)?;
Self::do_unlock_nft(nft_collection_id, nft_id, &beneficiary)?;
T::Currency::release(
&HoldReason::Fractionalized.into(),
&asset_creator,
deposit,
BestEffort,
)?;
Self::deposit_event(Event::NftUnified {
nft_collection: nft_collection_id,
nft: nft_id,
asset: asset_id,
beneficiary,
});
Ok(())
})
}
}
impl<T: Config> Pallet<T> {
/// The account ID of the pallet.
///
/// This actually does computation. If you need to keep using it, then make sure you cache
/// the value and only call this once.
fn get_pallet_account() -> T::AccountId {
T::PalletId::get().into_account_truncating()
}
/// Keeps track of the corresponding NFT ID, asset ID and amount minted.
pub fn nft_to_asset(
key: (T::NftCollectionId, T::NftId),
) -> Option<Details<AssetIdOf<T>, AssetBalanceOf<T>, DepositOf<T>, T::AccountId>> {
NftToAsset::<T>::get(key)
}
/// Prevent further transferring of NFT.
fn do_lock_nft(nft_collection_id: T::NftCollectionId, nft_id: T::NftId) -> DispatchResult {
T::Nfts::disable_transfer(&nft_collection_id, &nft_id)
}
/// Remove the transfer lock and transfer the NFT to the account returning the tokens.
fn do_unlock_nft(
nft_collection_id: T::NftCollectionId,
nft_id: T::NftId,
account: &T::AccountId,
) -> DispatchResult {
T::Nfts::enable_transfer(&nft_collection_id, &nft_id)?;
T::Nfts::transfer(&nft_collection_id, &nft_id, account)
}
/// Create the new asset.
fn do_create_asset(asset_id: AssetIdOf<T>, admin: T::AccountId) -> DispatchResult {
T::Assets::create(asset_id, admin, false, One::one())
}
/// Mint the `amount` of tokens with `asset_id` into the beneficiary's account.
fn do_mint_asset(
asset_id: AssetIdOf<T>,
beneficiary: &T::AccountId,
amount: AssetBalanceOf<T>,
) -> DispatchResult {
T::Assets::mint_into(asset_id, beneficiary, amount)?;
Ok(())
}
/// Burn tokens from the account.
fn do_burn_asset(
asset_id: AssetIdOf<T>,
account: &T::AccountId,
amount: AssetBalanceOf<T>,
) -> DispatchResult {
T::Assets::burn_from(asset_id.clone(), account, amount, Expendable, Exact, Polite)?;
T::Assets::start_destroy(asset_id, None)
}
/// Set the metadata for the newly created asset.
fn do_set_metadata(
asset_id: AssetIdOf<T>,
depositor: &T::AccountId,
pezpallet_account: &T::AccountId,
nft_collection_id: &T::NftCollectionId,
nft_id: &T::NftId,
) -> DispatchResult {
let name = format!(
"{} {nft_collection_id}-{nft_id}",
String::from_utf8_lossy(&T::NewAssetName::get())
);
let symbol: &[u8] = &T::NewAssetSymbol::get();
let existential_deposit = T::Currency::minimum_balance();
let pezpallet_account_balance = T::Currency::balance(&pezpallet_account);
if pezpallet_account_balance < existential_deposit {
T::Currency::transfer(&depositor, &pezpallet_account, existential_deposit, Preserve)?;
}
let metadata_deposit = T::Assets::calc_metadata_deposit(name.as_bytes(), symbol);
if !metadata_deposit.is_zero() {
T::Currency::transfer(&depositor, &pezpallet_account, metadata_deposit, Preserve)?;
}
T::Assets::set(asset_id, &pezpallet_account, name.into(), symbol.into(), 0)
}
}
}
@@ -0,0 +1,151 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Test environment for Nft fractionalization pallet.
use super::*;
use crate as pezpallet_nft_fractionalization;
use frame::{deps::pezsp_runtime::MultiSignature, testing_prelude::*, traits::Verify};
use pezpallet_nfts::PalletFeatures;
type Block = MockBlock<Test>;
type Signature = MultiSignature;
type AccountPublic = <Signature as Verify>::Signer;
type AccountId = <AccountPublic as IdentifyAccount>::AccountId;
// Configure a mock runtime to test the pallet.
construct_runtime!(
pub enum Test
{
System: pezframe_system,
NftFractionalization: pezpallet_nft_fractionalization,
Assets: pezpallet_assets,
Balances: pezpallet_balances,
Nfts: pezpallet_nfts,
}
);
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type AccountData = pezpallet_balances::AccountData<u64>;
}
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
impl pezpallet_balances::Config for Test {
type AccountStore = System;
}
impl pezpallet_assets::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Balance = u64;
type RemoveItemsLimit = ConstU32<1000>;
type AssetId = u32;
type AssetIdParameter = u32;
type ReserveData = ();
type Currency = Balances;
type CreateOrigin = AsEnsureOriginWithArg<EnsureSigned<Self::AccountId>>;
type ForceOrigin = pezframe_system::EnsureRoot<Self::AccountId>;
type AssetDeposit = ConstU64<1>;
type AssetAccountDeposit = ConstU64<10>;
type MetadataDepositBase = ConstU64<1>;
type MetadataDepositPerByte = ConstU64<1>;
type ApprovalDeposit = ConstU64<1>;
type StringLimit = ConstU32<50>;
type Holder = ();
type Freezer = ();
type Extra = ();
type CallbackHandle = ();
type WeightInfo = ();
pezpallet_assets::runtime_benchmarks_enabled! {
type BenchmarkHelper = ();
}
}
parameter_types! {
pub storage Features: PalletFeatures = PalletFeatures::all_enabled();
}
impl pezpallet_nfts::Config for Test {
type RuntimeEvent = RuntimeEvent;
type CollectionId = u32;
type ItemId = u32;
type Currency = Balances;
type CreateOrigin = AsEnsureOriginWithArg<pezframe_system::EnsureSigned<Self::AccountId>>;
type ForceOrigin = pezframe_system::EnsureRoot<Self::AccountId>;
type Locker = ();
type CollectionDeposit = ConstU64<2>;
type ItemDeposit = ConstU64<1>;
type MetadataDepositBase = ConstU64<1>;
type AttributeDepositBase = ConstU64<1>;
type DepositPerByte = ConstU64<1>;
type StringLimit = ConstU32<50>;
type KeyLimit = ConstU32<50>;
type ValueLimit = ConstU32<50>;
type ApprovalsLimit = ConstU32<10>;
type ItemAttributesApprovalsLimit = ConstU32<2>;
type MaxTips = ConstU32<10>;
type MaxDeadlineDuration = ConstU64<10000>;
type MaxAttributesPerCall = ConstU32<2>;
type Features = Features;
type OffchainSignature = Signature;
type OffchainPublic = AccountPublic;
type WeightInfo = ();
type BlockNumberProvider = pezframe_system::Pallet<Test>;
pezpallet_nfts::runtime_benchmarks_enabled! {
type Helper = ();
}
}
parameter_types! {
pub const StringLimit: u32 = 50;
pub const NftFractionalizationPalletId: PalletId = PalletId(*b"fraction");
pub NewAssetSymbol: BoundedVec<u8, StringLimit> = (*b"FRAC").to_vec().try_into().unwrap();
pub NewAssetName: BoundedVec<u8, StringLimit> = (*b"Frac").to_vec().try_into().unwrap();
}
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type Deposit = ConstU64<1>;
type Currency = Balances;
type NewAssetSymbol = NewAssetSymbol;
type NewAssetName = NewAssetName;
type NftCollectionId = <Self as pezpallet_nfts::Config>::CollectionId;
type NftId = <Self as pezpallet_nfts::Config>::ItemId;
type AssetBalance = <Self as pezpallet_balances::Config>::Balance;
type AssetId = <Self as pezpallet_assets::Config>::AssetId;
type Assets = Assets;
type Nfts = Nfts;
type PalletId = NftFractionalizationPalletId;
type WeightInfo = ();
type StringLimit = StringLimit;
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
type RuntimeHoldReason = RuntimeHoldReason;
}
// Build genesis storage according to the mock runtime.
pub(crate) fn new_test_ext() -> TestExternalities {
let t = pezframe_system::GenesisConfig::<Test>::default().build_storage().unwrap();
let mut ext = TestExternalities::new(t);
ext.execute_with(|| System::set_block_number(1));
ext
}
@@ -0,0 +1,309 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Tests for Nft fractionalization pallet.
use crate::{mock::*, *};
use frame::{deps::pezsp_runtime::ModuleError, testing_prelude::*};
use fungible::{hold::Inspect as InspectHold, Mutate as MutateFungible};
use fungibles::{metadata::Inspect, InspectEnumerable};
use TokenError::FundsUnavailable;
use pezpallet_nfts::CollectionConfig;
fn assets() -> Vec<u32> {
let mut s: Vec<_> = <<Test as Config>::Assets>::asset_ids().collect();
s.sort();
s
}
fn events() -> Vec<Event<Test>> {
let result = System::events()
.into_iter()
.map(|r| r.event)
.filter_map(|e| {
if let mock::RuntimeEvent::NftFractionalization(inner) = e {
Some(inner)
} else {
None
}
})
.collect();
System::reset_events();
result
}
type AccountIdOf<Test> = <Test as pezframe_system::Config>::AccountId;
fn account(id: u8) -> AccountIdOf<Test> {
[id; 32].into()
}
#[test]
fn fractionalize_should_work() {
new_test_ext().execute_with(|| {
let nft_collection_id = 0;
let nft_id = 0;
let asset_id = 0;
let fractions = 1000;
Balances::set_balance(&account(1), 100);
Balances::set_balance(&account(2), 100);
assert_ok!(Nfts::force_create(
RuntimeOrigin::root(),
account(1),
CollectionConfig::default(),
));
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(1),
None,
));
assert_ok!(NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
));
assert_eq!(assets(), vec![asset_id]);
assert_eq!(Assets::balance(asset_id, account(2)), fractions);
assert_eq!(Balances::total_balance_on_hold(&account(1)), 2);
assert_eq!(
String::from_utf8(
<Assets as Inspect<<Test as pezframe_system::Config>::AccountId>>::name(0)
)
.unwrap(),
"Frac 0-0"
);
assert_eq!(String::from_utf8(Assets::symbol(0)).unwrap(), "FRAC");
assert_eq!(Nfts::owner(nft_collection_id, nft_id), Some(account(1)));
assert_noop!(
Nfts::transfer(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(2),
),
DispatchError::Module(ModuleError {
index: 4,
error: [12, 0, 0, 0],
message: Some("ItemLocked")
})
);
let details = NftToAsset::<Test>::get((&nft_collection_id, &nft_id)).unwrap();
assert_eq!(details.asset, asset_id);
assert_eq!(details.fractions, fractions);
assert!(events().contains(&Event::<Test>::NftFractionalized {
nft_collection: nft_collection_id,
nft: nft_id,
fractions,
asset: asset_id,
beneficiary: account(2),
}));
// owner can't burn an already fractionalized NFT
assert_noop!(
Nfts::burn(RuntimeOrigin::signed(account(1)), nft_collection_id, nft_id),
DispatchError::Module(ModuleError {
index: 4,
error: [12, 0, 0, 0],
message: Some("ItemLocked")
})
);
// can't fractionalize twice
assert_noop!(
NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id + 1,
account(2),
fractions,
),
DispatchError::Module(ModuleError {
index: 4,
error: [12, 0, 0, 0],
message: Some("ItemLocked")
})
);
let nft_id = nft_id + 1;
assert_noop!(
NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
),
Error::<Test>::NftNotFound
);
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(2),
None
));
assert_noop!(
NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
),
Error::<Test>::NoPermission
);
});
}
#[test]
fn unify_should_work() {
new_test_ext().execute_with(|| {
let nft_collection_id = 0;
let nft_id = 0;
let asset_id = 0;
let fractions = 1000;
Balances::set_balance(&account(1), 100);
Balances::set_balance(&account(2), 100);
assert_ok!(Nfts::force_create(
RuntimeOrigin::root(),
account(1),
CollectionConfig::default(),
));
assert_ok!(Nfts::mint(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
account(1),
None,
));
assert_ok!(NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
fractions,
));
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(2)),
nft_collection_id + 1,
nft_id,
asset_id,
account(1),
),
Error::<Test>::NftNotFractionalized
);
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(2)),
nft_collection_id,
nft_id,
asset_id + 1,
account(1),
),
Error::<Test>::IncorrectAssetId
);
// can't unify the asset a user doesn't hold
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(1),
),
DispatchError::Token(FundsUnavailable)
);
assert_ok!(NftFractionalization::unify(
RuntimeOrigin::signed(account(2)),
nft_collection_id,
nft_id,
asset_id,
account(1),
));
assert_eq!(Assets::balance(asset_id, account(2)), 0);
assert_eq!(Balances::reserved_balance(&account(1)), 1);
assert_eq!(Nfts::owner(nft_collection_id, nft_id), Some(account(1)));
assert!(!NftToAsset::<Test>::contains_key((&nft_collection_id, &nft_id)));
assert!(events().contains(&Event::<Test>::NftUnified {
nft_collection: nft_collection_id,
nft: nft_id,
asset: asset_id,
beneficiary: account(1),
}));
// validate we need to hold the full balance to un-fractionalize the NFT
let asset_id = asset_id + 1;
assert_ok!(NftFractionalization::fractionalize(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(1),
fractions,
));
assert_ok!(Assets::transfer(RuntimeOrigin::signed(account(1)), asset_id, account(2), 1));
assert_eq!(Assets::balance(asset_id, account(1)), fractions - 1);
assert_eq!(Assets::balance(asset_id, account(2)), 1);
assert_noop!(
NftFractionalization::unify(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(1),
),
DispatchError::Token(FundsUnavailable)
);
assert_ok!(Assets::transfer(RuntimeOrigin::signed(account(2)), asset_id, account(1), 1));
assert_ok!(NftFractionalization::unify(
RuntimeOrigin::signed(account(1)),
nft_collection_id,
nft_id,
asset_id,
account(2),
));
assert_eq!(Nfts::owner(nft_collection_id, nft_id), Some(account(2)));
});
}
@@ -0,0 +1,76 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Various basic types for use in the Nft fractionalization pallet.
use super::*;
use codec::{Decode, Encode, MaxEncodedLen};
use fungible::Inspect as FunInspect;
use fungibles::Inspect;
use scale_info::TypeInfo;
pub type AssetIdOf<T> = <<T as Config>::Assets as Inspect<<T as SystemConfig>::AccountId>>::AssetId;
pub type AssetBalanceOf<T> =
<<T as Config>::Assets as Inspect<<T as SystemConfig>::AccountId>>::Balance;
pub type DepositOf<T> =
<<T as Config>::Currency as FunInspect<<T as SystemConfig>::AccountId>>::Balance;
pub type AccountIdLookupOf<T> = <<T as SystemConfig>::Lookup as StaticLookup>::Source;
/// Stores the details of a fractionalized item.
#[derive(Decode, Encode, Default, PartialEq, Eq, MaxEncodedLen, TypeInfo)]
pub struct Details<AssetId, Fractions, Deposit, AccountId> {
/// Minted asset.
pub asset: AssetId,
/// Number of fractions minted.
pub fractions: Fractions,
/// Reserved deposit for creating a new asset.
pub deposit: Deposit,
/// Account that fractionalized an item.
pub asset_creator: AccountId,
}
/// Benchmark Helper
#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<AssetId, CollectionId, ItemId> {
/// Returns an asset id from a given integer.
fn asset(id: u32) -> AssetId;
/// Returns a collection id from a given integer.
fn collection(id: u32) -> CollectionId;
/// Returns an nft id from a given integer.
fn nft(id: u32) -> ItemId;
}
#[cfg(feature = "runtime-benchmarks")]
impl<AssetId, CollectionId, ItemId> BenchmarkHelper<AssetId, CollectionId, ItemId> for ()
where
AssetId: From<u32>,
CollectionId: From<u32>,
ItemId: From<u32>,
{
fn asset(id: u32) -> AssetId {
id.into()
}
fn collection(id: u32) -> CollectionId {
id.into()
}
fn nft(id: u32) -> ItemId {
id.into()
}
}
@@ -0,0 +1,210 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Autogenerated weights for `pezpallet_nft_fractionalization`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `4563561839a5`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024`
// Executed Command:
// frame-omni-bencher
// v1
// benchmark
// pallet
// --extrinsic=*
// --runtime=target/production/wbuild/kitchensink-runtime/kitchensink_runtime.wasm
// --pallet=pezpallet_nft_fractionalization
// --header=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/HEADER-APACHE2
// --output=/__w/pezkuwi-sdk/pezkuwi-sdk/bizinikiwi/pezframe/nft-fractionalization/src/weights.rs
// --wasm-execution=compiled
// --steps=50
// --repeat=20
// --heap-pages=4096
// --template=bizinikiwi/.maintain/frame-weight-template.hbs
// --no-storage-info
// --no-min-squares
// --no-median-slopes
// --genesis-builder-policy=none
// --exclude-pallets=pezpallet_xcm,pezpallet_xcm_benchmarks::fungible,pezpallet_xcm_benchmarks::generic,pezpallet_nomination_pools,pezpallet_remark,pezpallet_transaction_storage,pezpallet_election_provider_multi_block,pezpallet_election_provider_multi_block::signed,pezpallet_election_provider_multi_block::unsigned,pezpallet_election_provider_multi_block::verifier
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
#![allow(dead_code)]
use frame::weights_prelude::*;
use core::marker::PhantomData;
/// Weight functions needed for `pezpallet_nft_fractionalization`.
pub trait WeightInfo {
fn fractionalize() -> Weight;
fn unify() -> Weight;
}
/// Weights for `pezpallet_nft_fractionalization` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `Nfts::Item` (r:1 w:0)
/// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Attribute` (r:1 w:1)
/// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Collection` (r:1 w:1)
/// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
/// Storage: `Assets::Asset` (r:1 w:1)
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
/// Storage: `Assets::NextAssetId` (r:1 w:0)
/// Proof: `Assets::NextAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Assets::Account` (r:1 w:1)
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Assets::Metadata` (r:1 w:1)
/// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`)
/// Storage: `NftFractionalization::NftToAsset` (r:0 w:1)
/// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
fn fractionalize() -> Weight {
// Proof Size summary in bytes:
// Measured: `364`
// Estimated: `4326`
// Minimum execution time: 173_042_000 picoseconds.
Weight::from_parts(176_398_000, 4326)
.saturating_add(T::DbWeight::get().reads(9_u64))
.saturating_add(T::DbWeight::get().writes(8_u64))
}
/// Storage: `NftFractionalization::NftToAsset` (r:1 w:1)
/// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
/// Storage: `Assets::Asset` (r:1 w:1)
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
/// Storage: `Assets::Account` (r:1 w:1)
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Attribute` (r:1 w:1)
/// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Collection` (r:1 w:1)
/// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
/// Storage: `Nfts::CollectionConfigOf` (r:1 w:0)
/// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
/// Storage: `Nfts::ItemConfigOf` (r:1 w:0)
/// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Item` (r:1 w:1)
/// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Account` (r:0 w:1)
/// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`)
/// Storage: `Nfts::ItemPriceOf` (r:0 w:1)
/// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `Nfts::PendingSwapOf` (r:0 w:1)
/// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`)
fn unify() -> Weight {
// Proof Size summary in bytes:
// Measured: `1174`
// Estimated: `4326`
// Minimum execution time: 124_038_000 picoseconds.
Weight::from_parts(127_219_000, 4326)
.saturating_add(T::DbWeight::get().reads(9_u64))
.saturating_add(T::DbWeight::get().writes(10_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `Nfts::Item` (r:1 w:0)
/// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Attribute` (r:1 w:1)
/// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Collection` (r:1 w:1)
/// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
/// Storage: `Assets::Asset` (r:1 w:1)
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
/// Storage: `Assets::NextAssetId` (r:1 w:0)
/// Proof: `Assets::NextAssetId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Assets::Account` (r:1 w:1)
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Assets::Metadata` (r:1 w:1)
/// Proof: `Assets::Metadata` (`max_values`: None, `max_size`: Some(140), added: 2615, mode: `MaxEncodedLen`)
/// Storage: `NftFractionalization::NftToAsset` (r:0 w:1)
/// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
fn fractionalize() -> Weight {
// Proof Size summary in bytes:
// Measured: `364`
// Estimated: `4326`
// Minimum execution time: 173_042_000 picoseconds.
Weight::from_parts(176_398_000, 4326)
.saturating_add(RocksDbWeight::get().reads(9_u64))
.saturating_add(RocksDbWeight::get().writes(8_u64))
}
/// Storage: `NftFractionalization::NftToAsset` (r:1 w:1)
/// Proof: `NftFractionalization::NftToAsset` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
/// Storage: `Assets::Asset` (r:1 w:1)
/// Proof: `Assets::Asset` (`max_values`: None, `max_size`: Some(210), added: 2685, mode: `MaxEncodedLen`)
/// Storage: `Assets::Account` (r:1 w:1)
/// Proof: `Assets::Account` (`max_values`: None, `max_size`: Some(134), added: 2609, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Attribute` (r:1 w:1)
/// Proof: `Nfts::Attribute` (`max_values`: None, `max_size`: Some(479), added: 2954, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Collection` (r:1 w:1)
/// Proof: `Nfts::Collection` (`max_values`: None, `max_size`: Some(84), added: 2559, mode: `MaxEncodedLen`)
/// Storage: `Nfts::CollectionConfigOf` (r:1 w:0)
/// Proof: `Nfts::CollectionConfigOf` (`max_values`: None, `max_size`: Some(73), added: 2548, mode: `MaxEncodedLen`)
/// Storage: `Nfts::ItemConfigOf` (r:1 w:0)
/// Proof: `Nfts::ItemConfigOf` (`max_values`: None, `max_size`: Some(48), added: 2523, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Item` (r:1 w:1)
/// Proof: `Nfts::Item` (`max_values`: None, `max_size`: Some(861), added: 3336, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(427), added: 2902, mode: `MaxEncodedLen`)
/// Storage: `Nfts::Account` (r:0 w:1)
/// Proof: `Nfts::Account` (`max_values`: None, `max_size`: Some(88), added: 2563, mode: `MaxEncodedLen`)
/// Storage: `Nfts::ItemPriceOf` (r:0 w:1)
/// Proof: `Nfts::ItemPriceOf` (`max_values`: None, `max_size`: Some(89), added: 2564, mode: `MaxEncodedLen`)
/// Storage: `Nfts::PendingSwapOf` (r:0 w:1)
/// Proof: `Nfts::PendingSwapOf` (`max_values`: None, `max_size`: Some(71), added: 2546, mode: `MaxEncodedLen`)
fn unify() -> Weight {
// Proof Size summary in bytes:
// Measured: `1174`
// Estimated: `4326`
// Minimum execution time: 124_038_000 picoseconds.
Weight::from_parts(127_219_000, 4326)
.saturating_add(RocksDbWeight::get().reads(9_u64))
.saturating_add(RocksDbWeight::get().writes(10_u64))
}
}