mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 15:47:58 +00:00
fungible conformance tests: Inspect and Mutate (#13852)
* typo * - create test files for each fungile trait - begin implementing tests for the Inspect trait * wrap inspect tests in a macro * first run of mutate tests * move test implementation out of ballances * make tests more generic * transfer tests * combine inspect and mutate tests * set balance failing tests * can_deposit tests * can_withdraw tests * test reducible_balance * remove balanced stub * revert set_balance return val fix * typo * macro and dust trap tests * disable test when it doesn't make sense * remove debug comment * reduce macro boilerplate * improved var naming * improve variable naming * remove redundant comment * remove placeholder tests * remove placeholder tests * simplify macro * Update frame/balances/src/tests/fungible_conformance_tests.rs Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com> * use Balance from T * fix copyright * add test doc comments * improve test naming * clippy * fix rustdoc errors * fix rustdoc * improve macro * improve variable naming * remove redundant comment * use path --------- Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
+975
@@ -0,0 +1,975 @@
|
||||
// This file is part of Substrate.
|
||||
|
||||
// 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.
|
||||
|
||||
use crate::traits::{
|
||||
fungible::{Inspect, Mutate},
|
||||
tokens::{
|
||||
DepositConsequence, Fortitude, Precision, Preservation, Provenance, WithdrawConsequence,
|
||||
},
|
||||
};
|
||||
use core::fmt::Debug;
|
||||
use sp_arithmetic::traits::AtLeast8BitUnsigned;
|
||||
use sp_runtime::traits::{Bounded, Zero};
|
||||
|
||||
/// Test the `mint_into` function for successful token minting.
|
||||
///
|
||||
/// This test checks the `mint_into` function in the `Mutate` trait implementation for type `T`.
|
||||
/// It ensures that account balances and total issuance values are updated correctly after minting
|
||||
/// tokens into two distinct accounts.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn mint_into_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account_0 = AccountId::from(0);
|
||||
let account_1 = AccountId::from(1);
|
||||
|
||||
// Test: Mint an amount into each account
|
||||
let amount_0 = T::minimum_balance();
|
||||
let amount_1 = T::minimum_balance() + 5.into();
|
||||
T::mint_into(&account_0, amount_0).unwrap();
|
||||
T::mint_into(&account_1, amount_1).unwrap();
|
||||
|
||||
// Verify: Account balances are updated correctly
|
||||
assert_eq!(T::total_balance(&account_0), amount_0);
|
||||
assert_eq!(T::total_balance(&account_1), amount_1);
|
||||
assert_eq!(T::balance(&account_0), amount_0);
|
||||
assert_eq!(T::balance(&account_1), amount_1);
|
||||
|
||||
// Verify: Total issuance is updated correctly
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + amount_0 + amount_1);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + amount_0 + amount_1);
|
||||
}
|
||||
|
||||
/// Test the `mint_into` function for overflow prevention.
|
||||
///
|
||||
/// This test ensures that minting tokens beyond the maximum balance value for an account
|
||||
/// returns an error and does not change the account balance or total issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn mint_into_overflow<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account = AccountId::from(10);
|
||||
let amount = T::Balance::max_value() - 5.into() - initial_total_issuance;
|
||||
|
||||
// Mint just below the maximum balance
|
||||
T::mint_into(&account, amount).unwrap();
|
||||
|
||||
// Verify: Minting beyond the maximum balance value returns an Err
|
||||
T::mint_into(&account, 10.into()).unwrap_err();
|
||||
|
||||
// Verify: The balance did not change
|
||||
assert_eq!(T::total_balance(&account), amount);
|
||||
assert_eq!(T::balance(&account), amount);
|
||||
|
||||
// Verify: The total issuance did not change
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + amount);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + amount);
|
||||
}
|
||||
|
||||
/// Test the `mint_into` function for handling balances below the minimum value.
|
||||
///
|
||||
/// This test verifies that minting tokens below the minimum balance for an account
|
||||
/// returns an error and has no impact on the account balance or total issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn mint_into_below_minimum<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
// Skip if there is no minimum balance
|
||||
if T::minimum_balance() == T::Balance::zero() {
|
||||
return
|
||||
}
|
||||
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account = AccountId::from(10);
|
||||
let amount = T::minimum_balance() - 1.into();
|
||||
|
||||
// Verify: Minting below the minimum balance returns Err
|
||||
T::mint_into(&account, amount).unwrap_err();
|
||||
|
||||
// Verify: noop
|
||||
assert_eq!(T::total_balance(&account), T::Balance::zero());
|
||||
assert_eq!(T::balance(&account), T::Balance::zero());
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance);
|
||||
}
|
||||
|
||||
/// Test the `burn_from` function for successfully burning an exact amount of tokens.
|
||||
///
|
||||
/// This test checks that the `burn_from` function with `Precision::Exact` correctly
|
||||
/// reduces the account balance and total issuance values by the burned amount.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate` for `AccountId`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn burn_from_exact_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
|
||||
// Setup account
|
||||
let account = AccountId::from(5);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Test: Burn an exact amount from the account
|
||||
let amount_to_burn = T::Balance::from(5);
|
||||
let precision = Precision::Exact;
|
||||
let force = Fortitude::Polite;
|
||||
T::burn_from(&account, amount_to_burn, precision, force).unwrap();
|
||||
|
||||
// Verify: The balance and total issuance should be reduced by the burned amount
|
||||
assert_eq!(T::balance(&account), initial_balance - amount_to_burn);
|
||||
assert_eq!(T::total_balance(&account), initial_balance - amount_to_burn);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - amount_to_burn);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - amount_to_burn);
|
||||
}
|
||||
|
||||
/// Test the `burn_from` function for successfully burning tokens with a best-effort approach.
|
||||
///
|
||||
/// This test verifies that the `burn_from` function with `Precision::BestEffort` correctly
|
||||
/// reduces the account balance and total issuance values by the reducible balance when
|
||||
/// attempting to burn an amount greater than the reducible balance.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate` for `AccountId`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn burn_from_best_effort_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
|
||||
// Setup account
|
||||
let account = AccountId::from(5);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Get reducible balance
|
||||
let force = Fortitude::Polite;
|
||||
let reducible_balance = T::reducible_balance(&account, Preservation::Expendable, force);
|
||||
|
||||
// Test: Burn a best effort amount from the account that is greater than the reducible balance
|
||||
let amount_to_burn = reducible_balance + 5.into();
|
||||
let precision = Precision::BestEffort;
|
||||
assert!(amount_to_burn > reducible_balance);
|
||||
assert!(amount_to_burn > T::balance(&account));
|
||||
T::burn_from(&account, amount_to_burn, precision, force).unwrap();
|
||||
|
||||
// Verify: The balance and total issuance should be reduced by the reducible_balance
|
||||
assert_eq!(T::balance(&account), initial_balance - reducible_balance);
|
||||
assert_eq!(T::total_balance(&account), initial_balance - reducible_balance);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - reducible_balance);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - reducible_balance);
|
||||
}
|
||||
|
||||
/// Test the `burn_from` function for handling insufficient funds with `Precision::Exact`.
|
||||
///
|
||||
/// This test verifies that burning an amount greater than the account's balance with
|
||||
/// `Precision::Exact` returns an error and does not change the account balance or total issuance
|
||||
/// values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn burn_from_exact_insufficient_funds<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
// Set up the initial conditions and parameters for the test
|
||||
let account = AccountId::from(5);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
|
||||
// Verify: Burn an amount greater than the account's balance with Exact precision returns Err
|
||||
let amount_to_burn = initial_balance + 10.into();
|
||||
let precision = Precision::Exact;
|
||||
let force = Fortitude::Polite;
|
||||
T::burn_from(&account, amount_to_burn, precision, force).unwrap_err();
|
||||
|
||||
// Verify: The balance and total issuance should remain unchanged
|
||||
assert_eq!(T::balance(&account), initial_balance);
|
||||
assert_eq!(T::total_balance(&account), initial_balance);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance);
|
||||
}
|
||||
|
||||
/// Test the `restore` function for successful restoration.
|
||||
///
|
||||
/// This test verifies that restoring an amount into each account updates their balances and the
|
||||
/// total issuance values correctly.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn restore_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let account_0 = AccountId::from(0);
|
||||
let account_1 = AccountId::from(1);
|
||||
|
||||
// Test: Restore an amount into each account
|
||||
let amount_0 = T::minimum_balance();
|
||||
let amount_1 = T::minimum_balance() + 5.into();
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
T::restore(&account_0, amount_0).unwrap();
|
||||
T::restore(&account_1, amount_1).unwrap();
|
||||
|
||||
// Verify: Account balances are updated correctly
|
||||
assert_eq!(T::total_balance(&account_0), amount_0);
|
||||
assert_eq!(T::total_balance(&account_1), amount_1);
|
||||
assert_eq!(T::balance(&account_0), amount_0);
|
||||
assert_eq!(T::balance(&account_1), amount_1);
|
||||
|
||||
// Verify: Total issuance is updated correctly
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + amount_0 + amount_1);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + amount_0 + amount_1);
|
||||
}
|
||||
|
||||
/// Test the `restore` function for handling balance overflow.
|
||||
///
|
||||
/// This test verifies that restoring an amount beyond the maximum balance returns an error and
|
||||
/// does not change the account balance or total issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn restore_overflow<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account = AccountId::from(10);
|
||||
let amount = T::Balance::max_value() - 5.into() - initial_total_issuance;
|
||||
|
||||
// Restore just below the maximum balance
|
||||
T::restore(&account, amount).unwrap();
|
||||
|
||||
// Verify: Restoring beyond the maximum balance returns an Err
|
||||
T::restore(&account, 10.into()).unwrap_err();
|
||||
|
||||
// Verify: The balance and total issuance did not change
|
||||
assert_eq!(T::total_balance(&account), amount);
|
||||
assert_eq!(T::balance(&account), amount);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + amount);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + amount);
|
||||
}
|
||||
|
||||
/// Test the `restore` function for handling restoration below the minimum balance.
|
||||
///
|
||||
/// This test verifies that restoring an amount below the minimum balance returns an error and
|
||||
/// does not change the account balance or total issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn restore_below_minimum<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
// Skip if there is no minimum balance
|
||||
if T::minimum_balance() == T::Balance::zero() {
|
||||
return
|
||||
}
|
||||
|
||||
let account = AccountId::from(10);
|
||||
let amount = T::minimum_balance() - 1.into();
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
|
||||
// Verify: Restoring below the minimum balance returns Err
|
||||
T::restore(&account, amount).unwrap_err();
|
||||
|
||||
// Verify: noop
|
||||
assert_eq!(T::total_balance(&account), T::Balance::zero());
|
||||
assert_eq!(T::balance(&account), T::Balance::zero());
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance);
|
||||
}
|
||||
|
||||
/// Test the `shelve` function for successful shelving.
|
||||
///
|
||||
/// This test verifies that shelving an amount from an account reduces the account balance and
|
||||
/// total issuance values by the shelved amount.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn shelve_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
|
||||
// Setup account
|
||||
let account = AccountId::from(5);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
|
||||
T::restore(&account, initial_balance).unwrap();
|
||||
|
||||
// Test: Shelve an amount from the account
|
||||
let amount_to_shelve = T::Balance::from(5);
|
||||
T::shelve(&account, amount_to_shelve).unwrap();
|
||||
|
||||
// Verify: The balance and total issuance should be reduced by the shelved amount
|
||||
assert_eq!(T::balance(&account), initial_balance - amount_to_shelve);
|
||||
assert_eq!(T::total_balance(&account), initial_balance - amount_to_shelve);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance - amount_to_shelve);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance - amount_to_shelve);
|
||||
}
|
||||
|
||||
/// Test the `shelve` function for handling insufficient funds.
|
||||
///
|
||||
/// This test verifies that attempting to shelve an amount greater than the account's balance
|
||||
/// returns an error and does not change the account balance or total issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn shelve_insufficient_funds<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
|
||||
// Set up the initial conditions and parameters for the test
|
||||
let account = AccountId::from(5);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::restore(&account, initial_balance).unwrap();
|
||||
|
||||
// Verify: Shelving greater than the balance with Exact precision returns Err
|
||||
let amount_to_shelve = initial_balance + 10.into();
|
||||
T::shelve(&account, amount_to_shelve).unwrap_err();
|
||||
|
||||
// Verify: The balance and total issuance should remain unchanged
|
||||
assert_eq!(T::balance(&account), initial_balance);
|
||||
assert_eq!(T::total_balance(&account), initial_balance);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance);
|
||||
}
|
||||
|
||||
/// Test the `transfer` function for a successful transfer.
|
||||
///
|
||||
/// This test verifies that transferring an amount between two accounts with
|
||||
/// `Preservation::Expendable` updates the account balances and maintains the total issuance and
|
||||
/// active issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn transfer_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account_0 = AccountId::from(0);
|
||||
let account_1 = AccountId::from(1);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::set_balance(&account_0, initial_balance);
|
||||
T::set_balance(&account_1, initial_balance);
|
||||
|
||||
// Test: Transfer an amount from account_0 to account_1
|
||||
let transfer_amount = T::Balance::from(3);
|
||||
T::transfer(&account_0, &account_1, transfer_amount, Preservation::Expendable).unwrap();
|
||||
|
||||
// Verify: Account balances are updated correctly
|
||||
assert_eq!(T::total_balance(&account_0), initial_balance - transfer_amount);
|
||||
assert_eq!(T::total_balance(&account_1), initial_balance + transfer_amount);
|
||||
assert_eq!(T::balance(&account_0), initial_balance - transfer_amount);
|
||||
assert_eq!(T::balance(&account_1), initial_balance + transfer_amount);
|
||||
|
||||
// Verify: Total issuance doesn't change
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into());
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into());
|
||||
}
|
||||
|
||||
/// Test the `transfer` function with `Preservation::Expendable` for transferring the entire
|
||||
/// balance.
|
||||
///
|
||||
/// This test verifies that transferring the entire balance from one account to another with
|
||||
/// `Preservation::Expendable` updates the account balances and maintains the total issuance and
|
||||
/// active issuance values.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn transfer_expendable_all<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account_0 = AccountId::from(0);
|
||||
let account_1 = AccountId::from(1);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::set_balance(&account_0, initial_balance);
|
||||
T::set_balance(&account_1, initial_balance);
|
||||
|
||||
// Test: Transfer entire balance from account_0 to account_1
|
||||
let preservation = Preservation::Expendable;
|
||||
let transfer_amount = initial_balance;
|
||||
T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap();
|
||||
|
||||
// Verify: Account balances are updated correctly
|
||||
assert_eq!(T::total_balance(&account_0), T::Balance::zero());
|
||||
assert_eq!(T::total_balance(&account_1), initial_balance * 2.into());
|
||||
assert_eq!(T::balance(&account_0), T::Balance::zero());
|
||||
assert_eq!(T::balance(&account_1), initial_balance * 2.into());
|
||||
|
||||
// Verify: Total issuance doesn't change
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into());
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into());
|
||||
}
|
||||
|
||||
/// Test the transfer function with Preservation::Expendable for transferring amounts that leaves
|
||||
/// an account with less than the minimum balance.
|
||||
///
|
||||
/// This test verifies that when transferring an amount using Preservation::Expendable and an
|
||||
/// account will be left with less than the minimum balance, the account balances are updated, dust
|
||||
/// is collected properly depending on whether a dust_trap exists, and the total issuance and active
|
||||
/// issuance values remain consistent.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// - dust_trap: An optional account identifier to which dust will be collected. If None, dust will
|
||||
/// be removed from the total and active issuance.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn transfer_expendable_dust<T, AccountId>(dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
if T::minimum_balance() == T::Balance::zero() {
|
||||
return
|
||||
}
|
||||
|
||||
let account_0 = AccountId::from(10);
|
||||
let account_1 = AccountId::from(20);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::set_balance(&account_0, initial_balance);
|
||||
T::set_balance(&account_1, initial_balance);
|
||||
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let initial_dust_trap_balance = match dust_trap.clone() {
|
||||
Some(dust_trap) => T::total_balance(&dust_trap),
|
||||
None => T::Balance::zero(),
|
||||
};
|
||||
|
||||
// Test: Transfer balance
|
||||
let preservation = Preservation::Expendable;
|
||||
let transfer_amount = T::Balance::from(11);
|
||||
T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap();
|
||||
|
||||
// Verify: Account balances are updated correctly
|
||||
assert_eq!(T::total_balance(&account_0), T::Balance::zero());
|
||||
assert_eq!(T::total_balance(&account_1), initial_balance + transfer_amount);
|
||||
assert_eq!(T::balance(&account_0), T::Balance::zero());
|
||||
assert_eq!(T::balance(&account_1), initial_balance + transfer_amount);
|
||||
|
||||
match dust_trap {
|
||||
Some(dust_trap) => {
|
||||
// Verify: Total issuance and active issuance don't change
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance);
|
||||
// Verify: Dust is collected into dust trap
|
||||
assert_eq!(
|
||||
T::total_balance(&dust_trap),
|
||||
initial_dust_trap_balance + T::minimum_balance() - 1.into()
|
||||
);
|
||||
assert_eq!(
|
||||
T::balance(&dust_trap),
|
||||
initial_dust_trap_balance + T::minimum_balance() - 1.into()
|
||||
);
|
||||
},
|
||||
None => {
|
||||
// Verify: Total issuance and active issuance are reduced by the dust amount
|
||||
assert_eq!(
|
||||
T::total_issuance(),
|
||||
initial_total_issuance - T::minimum_balance() + 1.into()
|
||||
);
|
||||
assert_eq!(
|
||||
T::active_issuance(),
|
||||
initial_active_issuance - T::minimum_balance() + 1.into()
|
||||
);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Test the `transfer` function with `Preservation::Protect` and `Preservation::Preserve` for
|
||||
/// transferring the entire balance.
|
||||
///
|
||||
/// This test verifies that attempting to transfer the entire balance with `Preservation::Protect`
|
||||
/// or `Preservation::Preserve` returns an error, and the account balances, total issuance, and
|
||||
/// active issuance values remain unchanged.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - `T`: Implements `Mutate<AccountId>`.
|
||||
/// - `AccountId`: Account identifier implementing `AtLeast8BitUnsigned`.
|
||||
/// ```
|
||||
pub fn transfer_protect_preserve<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
// This test means nothing if there is no minimum balance
|
||||
if T::minimum_balance() == T::Balance::zero() {
|
||||
return
|
||||
}
|
||||
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account_0 = AccountId::from(0);
|
||||
let account_1 = AccountId::from(1);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::set_balance(&account_0, initial_balance);
|
||||
T::set_balance(&account_1, initial_balance);
|
||||
|
||||
// Verify: Transfer Protect entire balance from account_0 to account_1 should Err
|
||||
let preservation = Preservation::Protect;
|
||||
let transfer_amount = initial_balance;
|
||||
T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap_err();
|
||||
|
||||
// Verify: Noop
|
||||
assert_eq!(T::total_balance(&account_0), initial_balance);
|
||||
assert_eq!(T::total_balance(&account_1), initial_balance);
|
||||
assert_eq!(T::balance(&account_0), initial_balance);
|
||||
assert_eq!(T::balance(&account_1), initial_balance);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into());
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into());
|
||||
|
||||
// Verify: Transfer Preserve entire balance from account_0 to account_1 should Err
|
||||
let preservation = Preservation::Preserve;
|
||||
T::transfer(&account_0, &account_1, transfer_amount, preservation).unwrap_err();
|
||||
|
||||
// Verify: Noop
|
||||
assert_eq!(T::total_balance(&account_0), initial_balance);
|
||||
assert_eq!(T::total_balance(&account_1), initial_balance);
|
||||
assert_eq!(T::balance(&account_0), initial_balance);
|
||||
assert_eq!(T::balance(&account_1), initial_balance);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + initial_balance * 2.into());
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + initial_balance * 2.into());
|
||||
}
|
||||
|
||||
/// Test the set_balance function for successful minting.
|
||||
///
|
||||
/// This test verifies that minting a balance using set_balance updates the account balance, total
|
||||
/// issuance, and active issuance correctly.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn set_balance_mint_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Test: Increase the account balance with set_balance
|
||||
let increase_amount: T::Balance = 5.into();
|
||||
let new = T::set_balance(&account, initial_balance + increase_amount);
|
||||
|
||||
// Verify: set_balance returned the new balance
|
||||
let expected_new = initial_balance + increase_amount;
|
||||
assert_eq!(new, expected_new);
|
||||
|
||||
// Verify: Balance and issuance is updated correctly
|
||||
assert_eq!(T::total_balance(&account), expected_new);
|
||||
assert_eq!(T::balance(&account), expected_new);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + expected_new);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + expected_new);
|
||||
}
|
||||
|
||||
/// Test the set_balance function for successful burning.
|
||||
///
|
||||
/// This test verifies that burning a balance using set_balance updates the account balance, total
|
||||
/// issuance, and active issuance correctly.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn set_balance_burn_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let initial_total_issuance = T::total_issuance();
|
||||
let initial_active_issuance = T::active_issuance();
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Test: Increase the account balance with set_balance
|
||||
let burn_amount: T::Balance = 5.into();
|
||||
let new = T::set_balance(&account, initial_balance - burn_amount);
|
||||
|
||||
// Verify: set_balance returned the new balance
|
||||
let expected_new = initial_balance - burn_amount;
|
||||
assert_eq!(new, expected_new);
|
||||
|
||||
// Verify: Balance and issuance is updated correctly
|
||||
assert_eq!(T::total_balance(&account), expected_new);
|
||||
assert_eq!(T::balance(&account), expected_new);
|
||||
assert_eq!(T::total_issuance(), initial_total_issuance + expected_new);
|
||||
assert_eq!(T::active_issuance(), initial_active_issuance + expected_new);
|
||||
}
|
||||
|
||||
/// Test the can_deposit function for returning a success value.
|
||||
///
|
||||
/// This test verifies that the can_deposit function returns DepositConsequence::Success when
|
||||
/// depositing a reasonable amount.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn can_deposit_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Test: can_deposit a reasonable amount
|
||||
let ret = T::can_deposit(&account, 5.into(), Provenance::Minted);
|
||||
|
||||
// Verify: Returns success
|
||||
assert_eq!(ret, DepositConsequence::Success);
|
||||
}
|
||||
|
||||
/// Test the can_deposit function for returning a minimum balance error.
|
||||
///
|
||||
/// This test verifies that the can_deposit function returns DepositConsequence::BelowMinimum when
|
||||
/// depositing below the minimum balance.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn can_deposit_below_minimum<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
// can_deposit always returns Success for amount 0
|
||||
if T::minimum_balance() < 2.into() {
|
||||
return
|
||||
}
|
||||
|
||||
let account = AccountId::from(10);
|
||||
|
||||
// Test: can_deposit below the minimum
|
||||
let ret = T::can_deposit(&account, T::minimum_balance() - 1.into(), Provenance::Minted);
|
||||
|
||||
// Verify: Returns success
|
||||
assert_eq!(ret, DepositConsequence::BelowMinimum);
|
||||
}
|
||||
|
||||
/// Test the can_deposit function for returning an overflow error.
|
||||
///
|
||||
/// This test verifies that the can_deposit function returns DepositConsequence::Overflow when
|
||||
/// depositing an amount that would cause an overflow.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn can_deposit_overflow<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let account = AccountId::from(10);
|
||||
|
||||
// Test: Try deposit over the max balance
|
||||
let initial_balance = T::Balance::max_value() - 5.into() - T::total_issuance();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
let ret = T::can_deposit(&account, 10.into(), Provenance::Minted);
|
||||
|
||||
// Verify: Returns success
|
||||
assert_eq!(ret, DepositConsequence::Overflow);
|
||||
}
|
||||
|
||||
/// Test the can_withdraw function for returning a success value.
|
||||
///
|
||||
/// This test verifies that the can_withdraw function returns WithdrawConsequence::Success when
|
||||
/// withdrawing a reasonable amount.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn can_withdraw_success<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Test: can_withdraw a reasonable amount
|
||||
let ret = T::can_withdraw(&account, 5.into());
|
||||
|
||||
// Verify: Returns success
|
||||
assert_eq!(ret, WithdrawConsequence::Success);
|
||||
}
|
||||
|
||||
/// Test the can_withdraw function for withdrawal resulting in a reduced balance of zero.
|
||||
///
|
||||
/// This test verifies that the can_withdraw function returns WithdrawConsequence::ReducedToZero
|
||||
/// when withdrawing an amount that would reduce the account balance below the minimum balance.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn can_withdraw_reduced_to_zero<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
if T::minimum_balance() == T::Balance::zero() {
|
||||
return
|
||||
}
|
||||
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Verify: can_withdraw below the minimum balance returns ReducedToZero
|
||||
let ret = T::can_withdraw(&account, 1.into());
|
||||
assert_eq!(ret, WithdrawConsequence::ReducedToZero(T::minimum_balance() - 1.into()));
|
||||
}
|
||||
|
||||
/// Test the can_withdraw function for returning a low balance error.
|
||||
///
|
||||
/// This test verifies that the can_withdraw function returns WithdrawConsequence::BalanceLow when
|
||||
/// withdrawing an amount that would result in an account balance below the current balance.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn can_withdraw_balance_low<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
if T::minimum_balance() == T::Balance::zero() {
|
||||
return
|
||||
}
|
||||
|
||||
let account = AccountId::from(10);
|
||||
let other_account = AccountId::from(100);
|
||||
let initial_balance = T::minimum_balance() + 5.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
T::mint_into(&other_account, initial_balance * 2.into()).unwrap();
|
||||
|
||||
// Verify: can_withdraw below the account balance returns BalanceLow
|
||||
let ret = T::can_withdraw(&account, initial_balance + 1.into());
|
||||
assert_eq!(ret, WithdrawConsequence::BalanceLow);
|
||||
}
|
||||
|
||||
/// Test the reducible_balance function with Preservation::Expendable.
|
||||
///
|
||||
/// This test verifies that the reducible_balance function returns the full account balance when
|
||||
/// using Preservation::Expendable.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn reducible_balance_expendable<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Verify: reducible_balance returns the full balance
|
||||
let ret = T::reducible_balance(&account, Preservation::Expendable, Fortitude::Polite);
|
||||
assert_eq!(ret, initial_balance);
|
||||
}
|
||||
|
||||
/// Test the reducible_balance function with Preservation::Protect and Preservation::Preserve.
|
||||
///
|
||||
/// This test verifies that the reducible_balance function returns the account balance minus the
|
||||
/// minimum balance when using either Preservation::Protect or Preservation::Preserve.
|
||||
///
|
||||
/// # Type Parameters
|
||||
///
|
||||
/// ```text
|
||||
/// - T: Implements Mutate<AccountId>.
|
||||
/// - AccountId: Account identifier implementing AtLeast8BitUnsigned.
|
||||
/// ```
|
||||
pub fn reducible_balance_protect_preserve<T, AccountId>(_dust_trap: Option<AccountId>)
|
||||
where
|
||||
T: Mutate<AccountId>,
|
||||
<T as Inspect<AccountId>>::Balance: AtLeast8BitUnsigned + Debug,
|
||||
AccountId: AtLeast8BitUnsigned,
|
||||
{
|
||||
let account = AccountId::from(10);
|
||||
let initial_balance = T::minimum_balance() + 10.into();
|
||||
T::mint_into(&account, initial_balance).unwrap();
|
||||
|
||||
// Verify: reducible_balance returns the full balance - min balance
|
||||
let ret = T::reducible_balance(&account, Preservation::Protect, Fortitude::Polite);
|
||||
assert_eq!(ret, initial_balance - T::minimum_balance());
|
||||
let ret = T::reducible_balance(&account, Preservation::Preserve, Fortitude::Polite);
|
||||
assert_eq!(ret, initial_balance - T::minimum_balance());
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
pub mod inspect_mutate;
|
||||
@@ -38,6 +38,7 @@
|
||||
//! funds must be removed from an account before it is known precisely what should be done with
|
||||
//! them.
|
||||
|
||||
pub mod conformance_tests;
|
||||
pub mod freeze;
|
||||
pub mod hold;
|
||||
mod imbalance;
|
||||
|
||||
@@ -122,7 +122,7 @@ impl<A, T: Balanced<A>> Dust<A, T> {
|
||||
/// **WARNING**
|
||||
/// Do not use this directly unless you want trouble, since it allows you to alter account balances
|
||||
/// without keeping the issuance up to date. It has no safeguards against accidentally creating
|
||||
/// token imbalances in your system leading to accidental imflation or deflation. It's really just
|
||||
/// token imbalances in your system leading to accidental inflation or deflation. It's really just
|
||||
/// for the underlying datatype to implement so the user gets the much safer `Balanced` trait to
|
||||
/// use.
|
||||
pub trait Unbalanced<AccountId>: Inspect<AccountId> {
|
||||
|
||||
Reference in New Issue
Block a user