11

In the Substrate blockchain development framework, the FRAME Balances pallet references 4 different kinds of balance:

  • Free Balance
  • Reserved Balance
  • Locked Balance
  • Vesting Balance

What are the differences between these different types of balances, when do they get used within Substrate, and how should I use them in my own pallets?

1

1 Answer 1

13

The Balances Pallet is a comprehensive on chain currency which has the flexibility to provide a number of different features.

Within the storage of the Balances Pallet, there are only two balances which are directly stored:

  1. Free Balance
  2. Reserved Balance

The sum of these two balances is used to calculate the total balance of an account.

Additional layers of logic are put on top of free balance in order to create abstractions like:

  • Locked Balance
  • Vesting Balance

So let's walk through the different types of balances managed by the Balances Pallet.

Free Balance

From the terminology section of the reference docs:

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.

The free balance of an account is used whenever a transfer, withdraw, or reserve is initiated. Before these operations can complete successfully, ensure_can_withdraw is called with some WithdrawReason and checks that a withdrawal does not interfere with some vesting balance or locked balance.

This does not prevent other operations like slash from occurring, which does not care about any abstractions over free balance.

Vesting Balance

An account's vesting balance is an abstraction over it's free balance. More specifically, an account which has a vesting balance cannot spend from their free balance lower than that amount. Vesting balance does not care about the WithdrawReason.

amount_spendable = free_balance - vesting_balance

So even though an account may seem like it has a lot of liquid funds to spend when querying the free balance, an accounts vesting balance can prevent those funds from being withdrawn.

Vesting balance can only be set at the genesis of a Substrate chain, and decreases at a linear rate per block starting at some starting_block for a length of blocks, at which point vesting balance is zero. The vesting balance can be larger than the free balance in situations when the free balance is reduced by slashing. In these cases amount_spendable is saturated to zero.

Locked Balance

An account's locked balance is another abstraction over it's free balance. In this case, it is a certain amount that is locked from withdrawing for a certain reason.

The different withdraw reasons are:

  • Transaction Payment: In order to pay for (system) transaction costs.
  • Transfer: In order to transfer ownership.
  • Reserve: In order to reserve some funds for a later return or repatriation.
  • Fee: In order to pay some other (higher-level) fees.

So if an account has a lock for 100 units with WithdrawReasons::Transfer, it cannot make a transfer which brings its free balance lower than 100 units. However, this account will be able to perform another operation like reserve taking its free balance below 100 units. A lock can have multiple reasons associated with it, in which case, those funds can only be spent for the other reasons.

Multiple different locks can be placed on an account, but these locks overlay one another rather than stack. This means that if an account has 3 locks for 100 units, the account can spend it's funds for any reason down to 100 units, at which point the locks will start to come into play.

Locked balance also overlays with vesting balance as these two are checked independently, but both checks must pass for ensure_can_withdraw to be successful.

Reserved Balance

From the terminology section:

Reserved Balance: Reserved balance still belongs to the account holder, but is suspended. Reserved balance can still be slashed, but only after all the 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.

Relatively speaking, reserved balance is more simple than free balance because there are no abstractions over it. Funds which are reserved from a user are not meant to be directly touched by any other logic outside of the Balances pallet. Instead, funds should first be unreserved and then modified in the free_balance.

Reserved Balance vs Locked Balance

Reserved balance and locked balance appear similar but are fundamentally different. Locked balance has an identity in terms of a lock identifier, what reasons funds are locked for, and how long they are locked for. A reserved balance has none of these traits, and are untouchable without explicit action from the runtime to unreserve those funds.

Furthermore, there could be implications about having a free balance to versus not having one. For example, if you set a lock on the full free balance of an account, it will still have a free balance, and OnFreeBalanceZero will not be called. However, if you reserve all the funds, the free balance will drop below the existential deposit and OnFreeBalanceZero will be triggered for pallets who have implemented this feature.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.