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,46 @@
[package]
name = "pezpallet-assets-freezer"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
license = "MIT-0"
homepage.workspace = true
repository.workspace = true
description = "Provides freezing features to `pezpallet-assets`"
[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 }
scale-info = { features = ["derive"], workspace = true }
[dev-dependencies]
pezpallet-balances = { workspace = true }
[features]
default = ["std"]
std = [
"codec/std",
"frame/std",
"log/std",
"pezpallet-assets/std",
"pezpallet-balances/std",
"scale-info/std",
]
runtime-benchmarks = [
"frame/runtime-benchmarks",
"pezpallet-assets/runtime-benchmarks",
"pezpallet-balances/runtime-benchmarks",
]
try-runtime = [
"frame/try-runtime",
"pezpallet-assets/try-runtime",
"pezpallet-balances/try-runtime",
]
@@ -0,0 +1,172 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: MIT-0
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
use super::*;
use frame::prelude::storage::StorageDoubleMap;
use pezpallet_assets::FrozenBalance;
// Implements [`FrozenBalance`] from [`pezpallet-assets`], so it can understand how much of an
// account balance is frozen, and is able to signal to this pallet when to clear the state of an
// account.
impl<T: Config<I>, I: 'static> FrozenBalance<T::AssetId, T::AccountId, T::Balance>
for Pallet<T, I>
{
fn frozen_balance(asset: T::AssetId, who: &T::AccountId) -> Option<T::Balance> {
FrozenBalances::<T, I>::get(asset, who)
}
fn died(asset: T::AssetId, who: &T::AccountId) {
defensive_assert!(
Freezes::<T, I>::get(asset.clone(), who).is_empty(),
"The list of Freezes should be empty before allowing an account to die"
);
defensive_assert!(
FrozenBalances::<T, I>::get(asset.clone(), who).is_none(),
"There should not be a frozen balance before allowing to die"
);
FrozenBalances::<T, I>::remove(asset.clone(), who);
Freezes::<T, I>::remove(asset, who);
}
fn contains_freezes(asset: T::AssetId) -> bool {
Freezes::<T, I>::contains_prefix(asset)
}
}
// Implement [`fungibles::Inspect`](pezframe_support::traits::fungibles::Inspect) as it is bound by
// [`fungibles::InspectFreeze`](pezframe_support::traits::fungibles::InspectFreeze) and
// [`fungibles::MutateFreeze`](pezframe_support::traits::fungibles::MutateFreeze). To do so, we'll
// re-export all of `pezpallet-assets` implementation of the same trait.
impl<T: Config<I>, I: 'static> Inspect<T::AccountId> for Pallet<T, I> {
type AssetId = T::AssetId;
type Balance = T::Balance;
fn total_issuance(asset: Self::AssetId) -> Self::Balance {
pezpallet_assets::Pallet::<T, I>::total_issuance(asset)
}
fn minimum_balance(asset: Self::AssetId) -> Self::Balance {
pezpallet_assets::Pallet::<T, I>::minimum_balance(asset)
}
fn total_balance(asset: Self::AssetId, who: &T::AccountId) -> Self::Balance {
pezpallet_assets::Pallet::<T, I>::total_balance(asset, who)
}
fn balance(asset: Self::AssetId, who: &T::AccountId) -> Self::Balance {
pezpallet_assets::Pallet::<T, I>::balance(asset, who)
}
fn reducible_balance(
asset: Self::AssetId,
who: &T::AccountId,
preservation: Preservation,
force: Fortitude,
) -> Self::Balance {
pezpallet_assets::Pallet::<T, I>::reducible_balance(asset, who, preservation, force)
}
fn can_deposit(
asset: Self::AssetId,
who: &T::AccountId,
amount: Self::Balance,
provenance: Provenance,
) -> DepositConsequence {
pezpallet_assets::Pallet::<T, I>::can_deposit(asset, who, amount, provenance)
}
fn can_withdraw(
asset: Self::AssetId,
who: &T::AccountId,
amount: Self::Balance,
) -> WithdrawConsequence<Self::Balance> {
pezpallet_assets::Pallet::<T, I>::can_withdraw(asset, who, amount)
}
fn asset_exists(asset: Self::AssetId) -> bool {
pezpallet_assets::Pallet::<T, I>::asset_exists(asset)
}
}
impl<T: Config<I>, I: 'static> InspectFreeze<T::AccountId> for Pallet<T, I> {
type Id = T::RuntimeFreezeReason;
fn balance_frozen(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> Self::Balance {
let freezes = Freezes::<T, I>::get(asset, who);
freezes.into_iter().find(|l| &l.id == id).map_or(Zero::zero(), |l| l.amount)
}
fn can_freeze(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> bool {
let freezes = Freezes::<T, I>::get(asset, who);
!freezes.is_full() || freezes.into_iter().any(|i| i.id == *id)
}
}
impl<T: Config<I>, I: 'static> MutateFreeze<T::AccountId> for Pallet<T, I> {
fn set_freeze(
asset: Self::AssetId,
id: &Self::Id,
who: &T::AccountId,
amount: Self::Balance,
) -> DispatchResult {
if amount.is_zero() {
return Self::thaw(asset, id, who);
}
let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
if let Some(i) = freezes.iter_mut().find(|i| &i.id == id) {
i.amount = amount;
} else {
freezes
.try_push(IdAmount { id: *id, amount })
.map_err(|_| Error::<T, I>::TooManyFreezes)?;
}
Self::update_freezes(asset, who, freezes.as_bounded_slice())
}
fn extend_freeze(
asset: Self::AssetId,
id: &Self::Id,
who: &T::AccountId,
amount: Self::Balance,
) -> DispatchResult {
if amount.is_zero() {
return Ok(());
}
let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
if let Some(i) = freezes.iter_mut().find(|x| &x.id == id) {
i.amount = i.amount.max(amount);
} else {
freezes
.try_push(IdAmount { id: *id, amount })
.map_err(|_| Error::<T, I>::TooManyFreezes)?;
}
Self::update_freezes(asset, who, freezes.as_bounded_slice())
}
fn thaw(asset: Self::AssetId, id: &Self::Id, who: &T::AccountId) -> DispatchResult {
let mut freezes = Freezes::<T, I>::get(asset.clone(), who);
freezes.retain(|f| &f.id != id);
Self::update_freezes(asset, who, freezes.as_bounded_slice())
}
}
@@ -0,0 +1,184 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: MIT-0
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//! # Assets Freezer Pallet
//!
//! A pallet capable of freezing fungibles from `pezpallet-assets`. This is an extension of
//! `pezpallet-assets`, wrapping [`fungibles::Inspect`](`Inspect`).
//! It implements both
//! [`fungibles::freeze::Inspect`](InspectFreeze) and
//! [`fungibles::freeze::Mutate`](MutateFreeze). The complexity
//! of the operations is `O(n)`. where `n` is the variant count of `RuntimeFreezeReason`.
//!
//! ## Pallet API
//!
//! See the [`pallet`] module for more information about the interfaces this pallet exposes,
//! including its configuration trait, dispatchables, storage items, events and errors.
//!
//! ## Overview
//!
//! This pallet provides the following functionality:
//!
//! - Pallet hooks allowing [`pezpallet-assets`] to know the frozen balance for an account on a given
//! asset (see [`pezpallet_assets::FrozenBalance`]).
//! - An implementation of [`fungibles::freeze::Inspect`](InspectFreeze) and
//! [`fungibles::freeze::Mutate`](MutateFreeze), allowing other pallets to manage freezes for the
//! `pezpallet-assets` assets.
#![cfg_attr(not(feature = "std"), no_std)]
use frame::{
prelude::*,
traits::{
fungibles::{Inspect, InspectFreeze, MutateFreeze},
tokens::{
DepositConsequence, Fortitude, IdAmount, Preservation, Provenance, WithdrawConsequence,
},
},
};
pub use pallet::*;
#[cfg(feature = "try-runtime")]
use frame::try_runtime::TryRuntimeError;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
mod impls;
#[frame::pallet]
pub mod pallet {
use super::*;
#[pallet::config(with_default)]
pub trait Config<I: 'static = ()>: pezframe_system::Config + pezpallet_assets::Config<I> {
/// The overarching freeze reason.
#[pallet::no_default_bounds]
type RuntimeFreezeReason: Parameter + Member + MaxEncodedLen + Copy + VariantCount;
/// The overarching event type.
#[pallet::no_default_bounds]
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
}
#[pallet::error]
pub enum Error<T, I = ()> {
/// Number of freezes on an account would exceed `MaxFreezes`.
TooManyFreezes,
}
#[pallet::pallet]
pub struct Pallet<T, I = ()>(_);
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> {
// `who`s frozen balance was increased by `amount`.
Frozen { who: T::AccountId, asset_id: T::AssetId, amount: T::Balance },
// `who`s frozen balance was decreased by `amount`.
Thawed { who: T::AccountId, asset_id: T::AssetId, amount: T::Balance },
}
/// A map that stores freezes applied on an account for a given AssetId.
#[pallet::storage]
pub type Freezes<T: Config<I>, I: 'static = ()> = StorageDoubleMap<
_,
Blake2_128Concat,
T::AssetId,
Blake2_128Concat,
T::AccountId,
BoundedVec<
IdAmount<T::RuntimeFreezeReason, T::Balance>,
VariantCountOf<T::RuntimeFreezeReason>,
>,
ValueQuery,
>;
/// A map that stores the current total frozen balance for every account on a given AssetId.
#[pallet::storage]
pub type FrozenBalances<T: Config<I>, I: 'static = ()> = StorageDoubleMap<
_,
Blake2_128Concat,
T::AssetId,
Blake2_128Concat,
T::AccountId,
T::Balance,
>;
#[pallet::hooks]
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
#[cfg(feature = "try-runtime")]
fn try_state(_: BlockNumberFor<T>) -> Result<(), TryRuntimeError> {
Self::do_try_state()
}
}
}
impl<T: Config<I>, I: 'static> Pallet<T, I> {
fn update_freezes(
asset: T::AssetId,
who: &T::AccountId,
freezes: BoundedSlice<
IdAmount<T::RuntimeFreezeReason, T::Balance>,
VariantCountOf<T::RuntimeFreezeReason>,
>,
) -> DispatchResult {
let prev_frozen = FrozenBalances::<T, I>::get(asset.clone(), who).unwrap_or_default();
let after_frozen = freezes.into_iter().map(|f| f.amount).max().unwrap_or_else(Zero::zero);
FrozenBalances::<T, I>::set(asset.clone(), who, Some(after_frozen));
if freezes.is_empty() {
Freezes::<T, I>::remove(asset.clone(), who);
FrozenBalances::<T, I>::remove(asset.clone(), who);
} else {
Freezes::<T, I>::insert(asset.clone(), who, freezes);
}
if prev_frozen > after_frozen {
let amount = prev_frozen.saturating_sub(after_frozen);
Self::deposit_event(Event::Thawed { asset_id: asset, who: who.clone(), amount });
} else if after_frozen > prev_frozen {
let amount = after_frozen.saturating_sub(prev_frozen);
Self::deposit_event(Event::Frozen { asset_id: asset, who: who.clone(), amount });
}
Ok(())
}
#[cfg(feature = "try-runtime")]
fn do_try_state() -> Result<(), TryRuntimeError> {
for (asset, who, _) in FrozenBalances::<T, I>::iter() {
let max_frozen_amount =
Freezes::<T, I>::get(asset.clone(), who.clone()).iter().map(|l| l.amount).max();
ensure!(
FrozenBalances::<T, I>::get(asset, who) == max_frozen_amount,
"The `FrozenAmount` is not equal to the maximum amount in `Freezes` for (`asset`, `who`)"
);
}
Ok(())
}
}
@@ -0,0 +1,169 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: MIT-0
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//! Tests mock for `pezpallet-assets-freezer`.
use crate as pezpallet_assets_freezer;
pub use crate::*;
use codec::{Compact, Decode, Encode, MaxEncodedLen};
use frame::testing_prelude::*;
use scale_info::TypeInfo;
pub type AccountId = u64;
pub type Balance = u64;
pub type AssetId = u32;
type Block = pezframe_system::mocking::MockBlock<Test>;
construct_runtime!(
pub enum Test
{
System: pezframe_system,
Assets: pezpallet_assets,
AssetsFreezer: pezpallet_assets_freezer,
Balances: pezpallet_balances,
}
);
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type BaseCallFilter = Everything;
type BlockWeights = ();
type BlockLength = ();
type DbWeight = ();
type RuntimeOrigin = RuntimeOrigin;
type Nonce = u64;
type Hash = H256;
type RuntimeCall = RuntimeCall;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = IdentityLookup<Self::AccountId>;
type Block = Block;
type RuntimeEvent = RuntimeEvent;
type BlockHashCount = ConstU64<250>;
type Version = ();
type PalletInfo = PalletInfo;
type AccountData = pezpallet_balances::AccountData<u64>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = ();
type SS58Prefix = ();
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
impl pezpallet_balances::Config for Test {
type MaxLocks = ();
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type Balance = Balance;
type DustRemoval = ();
type RuntimeEvent = RuntimeEvent;
type ExistentialDeposit = ConstU64<1>;
type AccountStore = System;
type WeightInfo = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type RuntimeFreezeReason = ();
type DoneSlashHandler = ();
}
impl pezpallet_assets::Config for Test {
type AssetId = AssetId;
type AssetIdParameter = Compact<AssetId>;
type ReserveData = ();
type AssetDeposit = ConstU64<1>;
type Balance = Balance;
type AssetAccountDeposit = ConstU64<1>;
type MetadataDepositBase = ();
type MetadataDepositPerByte = ();
type ApprovalDeposit = ();
type CreateOrigin = AsEnsureOriginWithArg<pezframe_system::EnsureSigned<u64>>;
type ForceOrigin = pezframe_system::EnsureRoot<u64>;
type StringLimit = ConstU32<32>;
type Extra = ();
type RemoveItemsLimit = ConstU32<10>;
type CallbackHandle = ();
type Currency = Balances;
type Holder = ();
type Freezer = AssetsFreezer;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
#[cfg(feature = "runtime-benchmarks")]
type BenchmarkHelper = ();
}
#[derive(
Decode,
DecodeWithMemTracking,
Encode,
MaxEncodedLen,
PartialEq,
Eq,
Ord,
PartialOrd,
TypeInfo,
Debug,
Clone,
Copy,
)]
pub enum DummyFreezeReason {
Governance,
Staking,
Other,
}
impl VariantCount for DummyFreezeReason {
// Intentionally set below the actual count of variants, to allow testing for `can_freeze`
const VARIANT_COUNT: u32 = 2;
}
impl Config for Test {
type RuntimeFreezeReason = DummyFreezeReason;
type RuntimeEvent = RuntimeEvent;
}
pub fn new_test_ext(execute: impl FnOnce()) -> TestExternalities {
let t = RuntimeGenesisConfig {
assets: pezpallet_assets::GenesisConfig {
assets: vec![(1, 0, true, 1)],
metadata: vec![],
accounts: vec![(1, 1, 100)],
next_asset_id: None,
reserves: vec![],
},
system: Default::default(),
balances: Default::default(),
}
.build_storage()
.unwrap();
let mut ext: TestExternalities = t.into();
ext.execute_with(|| {
System::set_block_number(1);
execute();
#[cfg(feature = "try-runtime")]
assert_ok!(AssetsFreezer::do_try_state());
});
ext
}
@@ -0,0 +1,312 @@
// This file is part of Bizinikiwi.
// Copyright (C) Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: MIT-0
// Permission is hereby granted, free of charge, to any person obtaining a copy of
// this software and associated documentation files (the "Software"), to deal in
// the Software without restriction, including without limitation the rights to
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is furnished to do
// so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//! Tests for pezpallet-assets-freezer.
use crate::mock::{self, *};
use codec::Compact;
use frame::testing_prelude::*;
use pezpallet_assets::FrozenBalance;
const WHO: AccountId = 1;
const ASSET_ID: mock::AssetId = 1;
fn test_set_freeze(id: DummyFreezeReason, amount: mock::Balance) {
let mut freezes = Freezes::<Test>::get(ASSET_ID, WHO);
if let Some(i) = freezes.iter_mut().find(|l| l.id == id) {
i.amount = amount;
} else {
freezes
.try_push(IdAmount { id, amount })
.expect("freeze is added without exceeding bounds; qed");
}
assert_ok!(AssetsFreezer::update_freezes(ASSET_ID, &WHO, freezes.as_bounded_slice()));
}
fn test_thaw(id: DummyFreezeReason) {
let mut freezes = Freezes::<Test>::get(ASSET_ID, WHO);
freezes.retain(|l| l.id != id);
assert_ok!(AssetsFreezer::update_freezes(ASSET_ID, &WHO, freezes.as_bounded_slice()));
}
mod impl_frozen_balance {
use super::*;
#[test]
fn frozen_balance_works() {
new_test_ext(|| {
assert_eq!(AssetsFreezer::frozen_balance(ASSET_ID, &WHO), None);
test_set_freeze(DummyFreezeReason::Governance, 1);
assert_eq!(AssetsFreezer::frozen_balance(ASSET_ID, &WHO), Some(1u64));
test_set_freeze(DummyFreezeReason::Staking, 3);
assert_eq!(AssetsFreezer::frozen_balance(ASSET_ID, &WHO), Some(3u64));
test_set_freeze(DummyFreezeReason::Governance, 2);
assert_eq!(AssetsFreezer::frozen_balance(ASSET_ID, &WHO), Some(3u64));
// also test thawing works to reduce a balance, and finally thawing everything resets to
// None
test_thaw(DummyFreezeReason::Governance);
assert_eq!(AssetsFreezer::frozen_balance(ASSET_ID, &WHO), Some(3u64));
test_thaw(DummyFreezeReason::Staking);
assert_eq!(AssetsFreezer::frozen_balance(ASSET_ID, &WHO), None);
});
}
#[test]
#[should_panic = "The list of Freezes should be empty before allowing an account to die"]
fn died_fails_if_freezes_exist() {
new_test_ext(|| {
test_set_freeze(DummyFreezeReason::Governance, 1);
AssetsFreezer::died(ASSET_ID, &WHO);
});
}
#[test]
fn died_works() {
new_test_ext(|| {
test_set_freeze(DummyFreezeReason::Governance, 1);
test_thaw(DummyFreezeReason::Governance);
AssetsFreezer::died(ASSET_ID, &WHO);
assert!(FrozenBalances::<Test>::get(ASSET_ID, WHO).is_none());
assert!(Freezes::<Test>::get(ASSET_ID, WHO).is_empty());
});
}
}
mod impl_inspect_freeze {
use super::*;
#[test]
fn balance_frozen_works() {
new_test_ext(|| {
assert_eq!(
AssetsFreezer::balance_frozen(ASSET_ID, &DummyFreezeReason::Governance, &WHO),
0u64
);
test_set_freeze(DummyFreezeReason::Governance, 1);
assert_eq!(
AssetsFreezer::balance_frozen(ASSET_ID, &DummyFreezeReason::Governance, &WHO),
1u64
);
test_set_freeze(DummyFreezeReason::Staking, 3);
assert_eq!(
AssetsFreezer::balance_frozen(ASSET_ID, &DummyFreezeReason::Staking, &WHO),
3u64
);
test_set_freeze(DummyFreezeReason::Staking, 2);
assert_eq!(
AssetsFreezer::balance_frozen(ASSET_ID, &DummyFreezeReason::Staking, &WHO),
2u64
);
// also test thawing works to reduce a balance, and finally thawing everything resets to
// 0
test_thaw(DummyFreezeReason::Governance);
assert_eq!(
AssetsFreezer::balance_frozen(ASSET_ID, &DummyFreezeReason::Governance, &WHO),
0u64
);
test_thaw(DummyFreezeReason::Staking);
assert_eq!(
AssetsFreezer::balance_frozen(ASSET_ID, &DummyFreezeReason::Staking, &WHO),
0u64
);
});
}
/// This tests it's not possible to freeze once the freezes [`BoundedVec`] is full. This is,
/// the lenght of the vec is equal to [`Config::MaxFreezes`].
/// This test assumes a mock configuration where this parameter is set to `2`.
#[test]
fn can_freeze_works() {
new_test_ext(|| {
test_set_freeze(DummyFreezeReason::Governance, 1);
assert!(AssetsFreezer::can_freeze(ASSET_ID, &DummyFreezeReason::Staking, &WHO));
test_set_freeze(DummyFreezeReason::Staking, 1);
assert!(!AssetsFreezer::can_freeze(ASSET_ID, &DummyFreezeReason::Other, &WHO));
});
}
}
mod impl_mutate_freeze {
use super::*;
#[test]
fn set_freeze_works() {
new_test_ext(|| {
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
99
);
assert_ok!(AssetsFreezer::set_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
10
));
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
90
);
System::assert_last_event(
Event::<Test>::Frozen { asset_id: ASSET_ID, who: WHO, amount: 10 }.into(),
);
assert_ok!(AssetsFreezer::set_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
8
));
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
92
);
System::assert_last_event(
Event::<Test>::Thawed { asset_id: ASSET_ID, who: WHO, amount: 2 }.into(),
);
});
}
#[test]
fn extend_freeze_works() {
new_test_ext(|| {
assert_ok!(AssetsFreezer::set_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
10
));
assert_storage_noop!(assert_ok!(AssetsFreezer::extend_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
8
)));
System::assert_last_event(
Event::<Test>::Frozen { asset_id: ASSET_ID, who: WHO, amount: 10 }.into(),
);
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
90
);
assert_ok!(AssetsFreezer::extend_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
11
));
System::assert_last_event(
Event::<Test>::Frozen { asset_id: ASSET_ID, who: WHO, amount: 1 }.into(),
);
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
89
);
});
}
#[test]
fn thaw_works() {
new_test_ext(|| {
assert_ok!(AssetsFreezer::set_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
10
));
System::assert_has_event(
Event::<Test>::Frozen { asset_id: ASSET_ID, who: WHO, amount: 10 }.into(),
);
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
90
);
assert_ok!(AssetsFreezer::thaw(ASSET_ID, &DummyFreezeReason::Governance, &WHO));
System::assert_has_event(
Event::<Test>::Thawed { asset_id: ASSET_ID, who: WHO, amount: 10 }.into(),
);
assert_eq!(
Assets::reducible_balance(
ASSET_ID,
&WHO,
Preservation::Preserve,
Fortitude::Polite,
),
99
);
});
}
}
mod with_pallet_assets {
use super::*;
#[test]
fn frozen_balance_affects_balance_transferring() {
new_test_ext(|| {
assert_ok!(AssetsFreezer::set_freeze(
ASSET_ID,
&DummyFreezeReason::Governance,
&WHO,
20
));
assert_noop!(
Assets::transfer(RuntimeOrigin::signed(WHO), Compact(ASSET_ID), 2, 81),
pezpallet_assets::Error::<Test>::BalanceLow,
);
assert_ok!(Assets::transfer(RuntimeOrigin::signed(WHO), Compact(ASSET_ID), 2, 80));
});
}
}