diff --git a/srml/balances/src/lib.rs b/srml/balances/src/lib.rs
index 6d18410ac5485..09b68f457ec37 100644
--- a/srml/balances/src/lib.rs
+++ b/srml/balances/src/lib.rs
@@ -14,13 +14,158 @@
// You should have received a copy of the GNU General Public License
// along with Substrate. If not, see .
-//! Balances: Handles setting and retrieval of free balance,
-//! retrieving total balance, reserve and unreserve balance,
-//! repatriating a reserved balance to a beneficiary account that exists,
-//! transfering a balance between accounts (when not reserved),
-//! slashing an account balance, account removal, rewards,
-//! lookup of an index to reclaim an account (when not balance not reserved),
-//! increasing total stake.
+//! # Balances Module
+//!
+//! The balances module provides functionality for handling accounts and balances. To use the balances module, you need
+//! to implement the [balances Trait](https://crates.parity.io/srml_balances/trait.Trait.html). Supported dispatchables
+//! are documented in the [`Call` enum](https://crates.parity.io/srml_balances/enum.Call.html).
+//!
+//! ## Overview
+//!
+//! The balances module 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
+//! - Lookup of an index to reclaim an account
+//! - Managing total issuance
+//! - Setting and managing locks
+//!
+//! ### Terminology
+//!
+//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents
+//! "dust accounts" from filling storage.
+//! - **Total Issuance:** The total amount of units in existence in a system.
+//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its balance is set
+//! to zero.
+//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only balance that matters
+//! for most operations. When this balance falls below the existential deposit, most functionality of the account is
+//! removed. When both it and the reserved balance are deleted, then the account is said to be dead.
+//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended. Reserved balance
+//! can still be slashed, but only after all of free balance has been slashed. If the reserved balance falls below the
+//! existential deposit then it and any related functionality will be deleted. When both it and the free balance are
+//! deleted, then the account is said to be dead.
+//! - **Imbalance:** A condition when some funds were created or deducted without equal and opposite accounting.
+//! Functions that result in an imbalance will return an object of the `Imbalance` trait that must be handled.
+//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple
+//! locks always operate over the same funds, so they "overlay" rather than "stack".
+//! - **Vesting:** Similar to a lock, this is another, but independent, liquidity restriction that reduces linearly
+//! over time.
+//!
+//! ### Implementations
+//!
+//! The balances module provides implementations for the following traits. If these traits provide the functionality
+//! that you need, then you can avoid coupling with the balances module.
+//!
+//! - [`Currency`](https://crates.parity.io/srml_support/traits/trait.Currency.html): Functions for dealing with a
+//! fungible assets system.
+//! - [`LockableCurrency`](https://crates.parity.io/srml_support/traits/trait.LockableCurrency.html): Functions for
+//! dealing with accounts that allow liquidity restrictions.
+//! - [`Imbalance`](https://crates.parity.io/srml_support/traits/trait.Imbalance.html): 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).
+//! - [`MakePayent`](https://crates.parity.io/srml_support/traits/trait.MakePayment.html): Simple trait designed
+//! for hooking into a transaction payment.
+//! - [`IsDeadAccount`](https://crates.parity.io/srml_system/trait.IsDeadAccount.html): Determiner to say whether a
+//! given account is unused.
+//!
+//! Example of using the `Currency` trait from the treasury module:
+//!
+//! ```rust,ignore
+//! pub trait Trait: system::Trait {
+//! /// The staking balance.
+//! type Currency: Currency;
+//! }
+//! ```
+//!
+//! ## Interface
+//!
+//! ### Dispatchable Functions
+//!
+//! The `Call` enum is documented [here](https://crates.parity.io/srml_balances/enum.Call.html).
+//!
+//! - `transfer` - Transfer some liquid free balance to another account.
+//! - `set_balance` - Set the balances of a given account. The origin of this call must be root.
+//!
+//! ### Public Functions
+//!
+//! See the [module](https://crates.parity.io/srml_balances/struct.Module.html) for details on publicly available
+//! functions.
+//!
+//! ## Usage
+//!
+//! The following examples show how to use the balances module in your custom module.
+//!
+//! ### Import and Balance Transfer
+//!
+//! Import the `balances` module and derive your module configuration trait with the balances trait. You can now call
+//! functions from the module.
+//!
+//! ```rust,ignore
+//! use support::{decl_module, dispatch::Result};
+//! use system::ensure_signed;
+//!
+//! pub trait Trait: balances::Trait {}
+//!
+//! decl_module! {
+//! pub struct Module for enum Call where origin: T::Origin {
+//! fn transfer_proxy(origin, to: T::AccountId, value: T::Balance) -> Result {
+//! let sender = ensure_signed(origin)?;
+//! >::make_transfer(&sender, &to, value)?;
+//!
+//! Ok(())
+//! }
+//! }
+//! }
+//! ```
+//!
+//! ### Real Use Example
+//!
+//! Use in the `contract` module (gas.rs):
+//!
+//! ```rust,ignore
+//! pub fn refund_unused_gas(
+//! transactor: &T::AccountId,
+//! gas_meter: GasMeter,
+//! imbalance: balances::NegativeImbalance,
+//! ) {
+//! let gas_spent = gas_meter.spent();
+//! let gas_left = gas_meter.gas_left();
+//!
+//! // Increase total spent gas.
+//! >::mutate(|block_gas_spent| *block_gas_spent += gas_spent);
+//!
+//! let refund = >::as_(gas_left) * gas_meter.gas_price;
+//! // Refund gas using balances module
+//! let refund_imbalance = >::deposit_creating(transactor, refund);
+//! // Handle imbalance
+//! if let Ok(imbalance) = imbalance.offset(refund_imbalance) {
+//! T::GasPayment::on_unbalanced(imbalance);
+//! }
+//! }
+//! ```
+//!
+//! ## Genesis config
+//!
+//! The following storage items depend on the genesis config:
+//!
+//! - `TotalIssuance`
+//! - `ExistentialDeposit`
+//! - `TransferFee`
+//! - `CreationFee`
+//! - `Vesting`
+//! - `FreeBalance`
+//! - `TransactionBaseFee`
+//! - `TransactionByteFee`
+//!
+//! ## Related Modules
+//!
+//! The balances module depends on the [`system`](https://crates.parity.io/srml_system/index.html) and
+//! [`srml_support`](https://crates.parity.io/srml_support/index.html) modules as well as Substrate Core
+//! libraries and the Rust standard library.
#![cfg_attr(not(feature = "std"), no_std)]
@@ -47,7 +192,7 @@ pub trait Subtrait: system::Trait {
/// The balance of an account.
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As + As + MaybeSerializeDebug;
- /// A function which is invoked when the free-balance has fallen below the existential deposit and
+ /// A function that is invoked when the free-balance has fallen below the existential deposit and
/// has been reduced to zero.
///
/// Gives a chance to clean up resources associated with the given account.
@@ -61,7 +206,7 @@ pub trait Trait: system::Trait {
/// The balance of an account.
type Balance: Parameter + Member + SimpleArithmetic + Codec + Default + Copy + As + As + MaybeSerializeDebug;
- /// A function which is invoked when the free-balance has fallen below the existential deposit and
+ /// A function that is invoked when the free-balance has fallen below the existential deposit and
/// has been reduced to zero.
///
/// Gives a chance to clean up resources associated with the given account.
@@ -136,15 +281,15 @@ pub struct BalanceLock {
decl_storage! {
trait Store for Module, I: Instance=DefaultInstance> as Balances {
- /// The total amount of stake on the system.
+ /// The total units issued in the system.
pub TotalIssuance get(total_issuance) build(|config: &GenesisConfig| {
config.balances.iter().fold(Zero::zero(), |acc: T::Balance, &(_, n)| acc + n)
}): T::Balance;
- /// The minimum amount allowed to keep an account open.
+ /// The minimum amount required to keep an account open.
pub ExistentialDeposit get(existential_deposit) config(): T::Balance;
/// The fee required to make a transfer.
pub TransferFee get(transfer_fee) config(): T::Balance;
- /// The fee required to create an account. At least as big as ReclaimRebate.
+ /// The fee required to create an account.
pub CreationFee get(creation_fee) config(): T::Balance;
/// The fee to be paid for making a transaction; the base.
pub TransactionBaseFee get(transaction_base_fee) config(): T::Balance;
@@ -175,11 +320,11 @@ decl_storage! {
/// The 'free' balance of a given account.
///
- /// This is the only balance that matters in terms of most operations on tokens. It is
- /// alone used to determine the balance when in the contract execution environment. When this
+ /// This is the only balance that matters in terms of most operations on tokens. It
+ /// alone is used to determine the balance when in the contract execution environment. When this
/// balance falls below the value of `ExistentialDeposit`, then the 'current account' is
- /// deleted: specifically `FreeBalance`. Furthermore, `OnFreeBalanceZero` callback
- /// is invoked, giving a chance to external modules to cleanup data associated with
+ /// deleted: specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback
+ /// is invoked, giving a chance to external modules to clean up data associated with
/// the deleted account.
///
/// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets
@@ -190,14 +335,13 @@ decl_storage! {
/// slashed, but gets slashed last of all.
///
/// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens
- /// that are still 'owned' by the account holder, but which are suspendable. (This is different
- /// and wholly unrelated to the `Bondage` system used in the staking module.)
+ /// that are still 'owned' by the account holder, but which are suspendable.
///
/// When this balance falls below the value of `ExistentialDeposit`, then this 'reserve account'
/// is deleted: specifically, `ReservedBalance`.
///
/// `system::AccountNonce` is also deleted if `FreeBalance` is also zero (it also gets
- /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.
+ /// collapsed to zero if it ever becomes less than `ExistentialDeposit`.)
pub ReservedBalance get(reserved_balance): map T::AccountId => T::Balance;
/// Any liquidity locks on some account balances.
@@ -214,7 +358,14 @@ decl_module! {
pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {
fn deposit_event() = default;
- /// Transfer some liquid free balance to another staker.
+ /// Transfer some liquid free balance to another account.
+ ///
+ /// `transfer` will set the `FreeBalance` of the sender and receiver.
+ /// It will decrease the total issuance of the system by the `TransferFee`.
+ /// If the sender's account is below the existential deposit as a result
+ /// of the transfer, the account will be reaped.
+ ///
+ /// The dispatch origin for this call must be `Signed` by the transactor.
pub fn transfer(
origin,
dest: ::Source,
@@ -226,6 +377,13 @@ decl_module! {
}
/// Set the balances of a given account.
+ ///
+ /// This will alter `FreeBalance` and `ReservedBalance` in storage.
+ /// If the new free or reserved balance is below the existential deposit,
+ /// it will also decrease the total issuance of the system (`TotalIssuance`)
+ /// and reset the account nonce (`system::AccountNonce`).
+ ///
+ /// The dispatch origin for this call is `root`.
fn set_balance(
who: ::Source,
#[compact] free: T::Balance,
@@ -238,7 +396,6 @@ decl_module! {
}
}
-// For funding methods, see Currency trait
impl, I: Instance> Module {
// PUBLIC IMMUTABLES
@@ -254,10 +411,11 @@ impl, I: Instance> Module {
// PRIVATE MUTABLES
- /// Set the free balance of an account to some new value.
+ /// Set the reserved balance of an account to some new value. Will enforce `ExistentialDeposit`
+ /// law, annulling the account as needed.
///
- /// Will enforce ExistentialDeposit law, annulling the account as needed.
- /// In that case it will return `AccountKilled`.
+ /// Doesn't do any preparatory work for creating a new account, so should only be used when it
+ /// is known that the account already exists.
///
/// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that
/// the caller will do this.
@@ -272,14 +430,12 @@ impl, I: Instance> Module {
}
}
- /// Set the free balance of an account to some new value. Will enforce ExistentialDeposit
- /// law annulling the account as needed.
+ /// Set the free balance of an account to some new value. Will enforce `ExistentialDeposit`
+ /// law, annulling the account as needed.
///
/// Doesn't do any preparatory work for creating a new account, so should only be used when it
/// is known that the account already exists.
///
- /// Returns if the account was successfully updated or update has led to killing of the account.
- ///
/// NOTE: LOW-LEVEL: This will not attempt to maintain total issuance. It is expected that
/// the caller will do this.
fn set_free_balance(who: &T::AccountId, balance: T::Balance) -> UpdateBalanceOutcome {
@@ -684,8 +840,6 @@ where
// Free balance can never be less than ED. If that happens, it gets reduced to zero
// and the account information relevant to this subsystem is deleted (i.e. the
// account is reaped).
- // NOTE: This is orthogonal to the `Bondage` value that an account has, a high
- // value of which makes even the `free_balance` unspendable.
let outcome = if balance < >::existential_deposit() {
Self::set_free_balance(who, balance);
UpdateBalanceOutcome::AccountKilled
diff --git a/srml/contract/src/lib.rs b/srml/contract/src/lib.rs
index a3f6faf41c963..2c2d2106a614b 100644
--- a/srml/contract/src/lib.rs
+++ b/srml/contract/src/lib.rs
@@ -366,7 +366,7 @@ decl_event! {
decl_storage! {
trait Store for Module as Contract {
- /// The fee required to create a contract. At least as big as staking's ReclaimRebate.
+ /// The fee required to create a contract.
ContractFee get(contract_fee) config(): T::Balance = T::Balance::sa(21);
/// The fee charged for a call into a contract.
CallBaseFee get(call_base_fee) config(): T::Gas = T::Gas::sa(135);
diff --git a/srml/support/src/traits.rs b/srml/support/src/traits.rs
index 4a676c797a276..7511c8550c4a9 100644
--- a/srml/support/src/traits.rs
+++ b/srml/support/src/traits.rs
@@ -57,7 +57,7 @@ impl OnDilution for () {
pub enum UpdateBalanceOutcome {
/// Account balance was simply updated.
Updated,
- /// The update has led to killing of the account.
+ /// The update led to killing the account.
AccountKilled,
}
@@ -245,7 +245,7 @@ pub trait Currency {
/// The combined balance of `who`.
fn total_balance(who: &AccountId) -> Self::Balance;
- /// Some result as `slash(who, value)` (but without the side-effects) assuming there are no
+ /// Same result as `slash(who, value)` (but without the side-effects) assuming there are no
/// balance changes in the meantime and only the reserved balance is not taken into account.
fn can_slash(who: &AccountId, value: Self::Balance) -> bool;
@@ -253,20 +253,20 @@ pub trait Currency {
/// are no balance changes in the meantime.
fn can_reserve(who: &AccountId, value: Self::Balance) -> bool;
- /// The total amount of stake on the system.
+ /// The total amount of issuance in the system.
fn total_issuance() -> Self::Balance;
- /// The minimum balance any single account may have. This is equivalent to Balances module's
- /// Existential Deposit.
+ /// The minimum balance any single account may have. This is equivalent to the `Balances` module's
+ /// `ExistentialDeposit`.
fn minimum_balance() -> Self::Balance;
/// The 'free' balance of a given account.
///
- /// This is the only balance that matters in terms of most operations on tokens. It is
- /// alone used to determine the balance when in the contract execution environment. When this
+ /// This is the only balance that matters in terms of most operations on tokens. It alone
+ /// is used to determine the balance when in the contract execution environment. When this
/// balance falls below the value of `ExistentialDeposit`, then the 'current account' is
- /// deleted: specifically `FreeBalance`. Furthermore, `OnFreeBalanceZero` callback
- /// is invoked, giving a chance to external modules to cleanup data associated with
+ /// deleted: specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback
+ /// is invoked, giving a chance to external modules to clean up data associated with
/// the deleted account.
///
/// `system::AccountNonce` is also deleted if `ReservedBalance` is also zero (it also gets
@@ -277,8 +277,7 @@ pub trait Currency {
/// slashed, but gets slashed last of all.
///
/// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens
- /// that are still 'owned' by the account holder, but which are suspendable. (This is different
- /// and wholly unrelated to the `Bondage` system used in the staking module.)
+ /// that are still 'owned' by the account holder, but which are suspendable.
///
/// When this balance falls below the value of `ExistentialDeposit`, then this 'reserve account'
/// is deleted: specifically, `ReservedBalance`.
@@ -298,7 +297,7 @@ pub trait Currency {
new_balance: Self::Balance,
) -> result::Result<(), &'static str>;
- // PUBLIC MUTABLES (DANGEROUS)
+ // PUBLIC MUTABLES (DANGEROUS)
/// Transfer some liquid free balance to another staker.
///
@@ -333,7 +332,7 @@ pub trait Currency {
/// Removes some free balance from `who` account for `reason` if possible. If `liveness` is `KeepAlive`,
/// then no less than `ExistentialDeposit` must be left remaining.
///
- /// This checks any locks, vesting and liquidity requirements. If the removal is not possible, then it
+ /// This checks any locks, vesting, and liquidity requirements. If the removal is not possible, then it
/// returns `Err`.
fn withdraw(
who: &AccountId,
@@ -342,7 +341,7 @@ pub trait Currency {
liveness: ExistenceRequirement,
) -> result::Result;
- /// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created
+ /// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created.
///
/// Infallible.
fn deposit_creating(
@@ -363,24 +362,28 @@ pub trait Currency {
UpdateBalanceOutcome,
);
- /// Moves `value` from balance to reserved balance.
+ /// Moves `value` from balance to reserved balance.
///
/// If the free balance is lower than `value`, then no funds will be moved and an `Err` will
- /// be returned to notify of this. This is different behaviour to `unreserve`.
+ /// be returned to notify of this. This is different behavior than `unreserve`.
fn reserve(who: &AccountId, value: Self::Balance) -> result::Result<(), &'static str>;
- /// Moves up to `value` from reserved balance to balance. This function cannot fail.
+ /// Moves up to `value` from reserved balance to free balance. This function cannot fail.
///
- /// As much funds up to `value` will be deducted as possible. If this is less than `value`,
- /// then non-zero will be returned.
+ /// As much funds up to `value` will be moved as possible. If the reserve balance of `who`
+ /// is less than `value`, then the remaining amount will be returned.
+ ///
+ /// # NOTES
///
- /// NOTE: This is different to `reserve`.
+ /// - This is different from `reserve`.
+ /// - If the remaining reserved balance is less than `ExistentialDeposit`, it will
+ /// invoke `on_reserved_too_low` and could reap the account.
fn unreserve(who: &AccountId, value: Self::Balance) -> Self::Balance;
/// Deducts up to `value` from reserved balance of `who`. This function cannot fail.
///
- /// As much funds up to `value` will be deducted as possible. If this is less than `value`,
- /// then non-zero second item will be returned.
+ /// As much funds up to `value` will be deducted as possible. If the reserve balance of `who`
+ /// is less than `value`, then a non-zero second item will be returned.
fn slash_reserved(
who: &AccountId,
value: Self::Balance
@@ -408,7 +411,12 @@ pub trait LockableCurrency: Currency {
/// The quantity used to denote time; usually just a `BlockNumber`.
type Moment;
- /// Introduce a new lock or change an existing one.
+ /// Create a new balance lock on account `who`.
+ ///
+ /// If the new lock is valid (i.e. not already expired), it will push the struct to
+ /// the `Locks` vec in storage. Note that you can lock more funds than a user has.
+ ///
+ /// If the lock `id` already exists, this will update it.
fn set_lock(
id: LockIdentifier,
who: &AccountId,
@@ -417,8 +425,15 @@ pub trait LockableCurrency: Currency {
reasons: WithdrawReasons,
);
- /// Change any existing lock so that it becomes strictly less liquid in all
- /// respects to the given parameters.
+ /// Changes a balance lock (selected by `id`) so that it becomes less liquid in all
+ /// parameters or creates a new one if it does not exist.
+ ///
+ /// Calling `extend_lock` on an existing lock `id` differs from `set_lock` in that it
+ /// applies the most severe constraints of the two, while `set_lock` replaces the lock
+ /// with the new parameters. As in, `extend_lock` will set:
+ /// - maximum `amount`
+ /// - farthest duration (`until`)
+ /// - bitwise mask of all `reasons`
fn extend_lock(
id: LockIdentifier,
who: &AccountId,
@@ -452,3 +467,4 @@ bitmask! {
Fee = 0b00001000,
}
}
+