Skip to content
lib.rs 40.4 KiB
Newer Older
// 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.
//! The Balances pallet provides functionality for handling accounts and balances for a single
//! token.
//! It makes heavy use of concepts such as Holds and Freezes from the
//! [`frame_support::traits::fungible`] traits, therefore you should read and understand those docs
//! as a prerequisite to understanding this pallet.
//!
//! Also see the [`frame_tokens`] reference docs for higher level information regarding the
//! place of this palet in FRAME.
//!
//! ## Overview
//!
//! The Balances pallet provides functions for:
//! - Getting and setting free balances.
//! - Retrieving total, reserved and unreserved balances.
//! - Repatriating a reserved balance to a beneficiary account that exists.
//! - Transferring a balance between accounts (when not reserved).
//! - Slashing an account balance.
//! - Account creation and removal.
//! - Managing total issuance.
//! - Setting and managing locks.
//!
//! ### Terminology
//!
//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after
//!   its total balance has become less than the Existential Deposit.
//!
//! ### Implementations
//!
//! The Balances pallet provides implementations for the following [`fungible`] traits. If these
//! traits provide the functionality that you need, then you should avoid tight coupling with the
//! Balances pallet.
//!
//! - [`fungible::Inspect`]
//! - [`fungible::Mutate`]
//! - [`fungible::Unbalanced`]
//! - [`fungible::Balanced`]
//! - [`fungible::BalancedHold`]
//! - [`fungible::InspectHold`]
//! - [`fungible::MutateHold`]
//! - [`fungible::InspectFreeze`]
//! - [`fungible::MutateFreeze`]
//! - [`fungible::Imbalance`]
//!
//! It also implements the following [`Currency`] related traits, however they are deprecated and
//! will eventually be removed.
//!
//! - [`Currency`]: Functions for dealing with a fungible assets system.
//! - [`ReservableCurrency`]
Xiliang Chen's avatar
Xiliang Chen committed
//! - [`NamedReservableCurrency`](frame_support::traits::NamedReservableCurrency):
//! Functions for dealing with assets that can be reserved from an account.
//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for
//! dealing with accounts that allow liquidity restrictions.
//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling
//! imbalances between total issuance in the system and account balances. Must be used when a
//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee).
//! ## Usage
//! The following examples show how to use the Balances pallet in your custom pallet.
//! ### Examples from the FRAME
//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from
//! `Currency`:
//! use frame_support::traits::Currency;
//! # pub trait Config: frame_system::Config {
//! #   type Currency: Currency<Self::AccountId>;
//! pub type BalanceOf<T> = <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
//! pub type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
//!
//! # fn main() {}
//! The Staking pallet uses the `LockableCurrency` trait to lock a stash account's funds:
//! use frame_support::traits::{WithdrawReasons, LockableCurrency};
//! use sp_runtime::traits::Bounded;
//! pub trait Config: frame_system::Config {
//!     type Currency: LockableCurrency<Self::AccountId, Moment=frame_system::pallet_prelude::BlockNumberFor<Self>>;
//! # struct StakingLedger<T: Config> {
//! #   stash: <T as frame_system::Config>::AccountId,
//! #   total: <<T as Config>::Currency as frame_support::traits::Currency<<T as frame_system::Config>::AccountId>>::Balance,
//! #   phantom: std::marker::PhantomData<T>,
//! # }
//! # const STAKING_ID: [u8; 8] = *b"staking ";
//! fn update_ledger<T: Config>(
//!     controller: &T::AccountId,
//!     ledger: &StakingLedger<T>
//!     T::Currency::set_lock(
//!         STAKING_ID,
//!         &ledger.stash,
//!         ledger.total,
//!         WithdrawReasons::all()
//!     );
//!     // <Ledger<T>>::insert(controller, ledger); // Commented out as we don't have access to Staking's storage here.
//! # fn main() {}
//! ```
//!
//! ## Genesis config
//!
//! The Balances pallet depends on the [`GenesisConfig`].
//! * Total issued balanced of all accounts should be less than `Config::Balance::max_value()`.
//! * Existential Deposit is set to a value greater than zero.
//!
//! Note, you may find the Balances pallet still functions with an ED of zero when the
//! `insecure_zero_ed` cargo feature is enabled. However this is not a configuration which is
//! generally supported, nor will it be.
//!
//! [`frame_tokens`]: ../polkadot_sdk_docs/reference_docs/frame_tokens/index.html

#![cfg_attr(not(feature = "std"), no_std)]
mod benchmarking;
pub mod migration;
pub mod weights;
use frame_support::{
	pallet_prelude::DispatchResult,
		tokens::{
			fungible, BalanceStatus as Status, DepositConsequence,
			Fortitude::{self, Force, Polite},
			Preservation::{Expendable, Preserve, Protect},
			WithdrawConsequence,
		},
		Currency, Defensive, Get, OnUnbalanced, ReservableCurrency, StoredMap,
use frame_system as system;
pub use impl_currency::{NegativeImbalance, PositiveImbalance};
use scale_info::TypeInfo;
use sp_runtime::{
		AtLeast32BitUnsigned, Bounded, CheckedAdd, CheckedSub, MaybeSerializeDeserialize,
		Saturating, StaticLookup, Zero,
	ArithmeticError, DispatchError, FixedPointOperand, Perbill, RuntimeDebug, TokenError,
use sp_std::{cmp, fmt::Debug, mem, prelude::*, result};
pub use types::{
	AccountData, AdjustmentDirection, BalanceLock, DustCleaner, ExtraFlags, IdAmount, Reasons,
	ReserveData,
pub use weights::WeightInfo;
const LOG_TARGET: &str = "runtime::balances";

type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;

#[frame_support::pallet]
pub mod pallet {
	use frame_support::{
		pallet_prelude::*,
		traits::{fungible::Credit, tokens::Precision, VariantCount, VariantCountOf},
	use frame_system::pallet_prelude::*;
	pub type CreditOf<T, I> = Credit<<T as frame_system::Config>::AccountId, Pallet<T, I>>;
Loading full blame...