Polkadot Wallet Balances Explained
In a previous article, I explained how locks work, with an example about staking and governance. More information about Polkadot OpenGov locks can be found here.
Here I will explain how wallet balances work. Keep in mind locks are part of the free
balance that is not transferrable.
Soon Polkadot SDK pallets will implement the fungible trait (see Rust Book for more info about traits). This new logic will allow for more efficient use of your wallet balance. This article will briefly explain the new logic to calculate the spendable balance and make more efficient use of your wallet balance.
The new logic will make use of the fungible trait and will allow to use of the free
balance for on-chain activity like setting proxies and identities.
Let’s take for example a wallet with 100 DOT.
Free: 100 DOT
Frozen: 0 DOT
On hold: 0 DOT
Spendable: 99 DOT
Untouchable: 1 DOT (ED)
Where the free
balance is the balance that can be used for on-chain activity but is not necessarily spendable (or transferrable). The free
balance can be frozen
for staking, governance, and vesting (also called locked
balance). Balance that is on_hold
(also called reserved
balance) is used for identities, proxies, etc. and it is no longer free
.
The calculation for the spendable balance is the following:
spendable = free - max(frozen - on_hold, ED)
The untouchable balance is the portion of the free balance that cannot be moved (i.e. not spendable), but can still be used for on-chain activity. In this case, the existential deposit of 1 DOT is untouchable (meaning you can’t touch it if the account can’t or shouldn’t get reaped).
We stake 80 DOT, and we get the following balance structure:
Free: 100 DOT
Frozen : 80 DOT
Onhold: 0 DOT
Spendable: 20 DOT
Untouchable: 80 DOT
The spendable balance would be 20 DOT (- transaction fees). If the account creates a proxy, it will use the free
balance as shown below.
Free: 80 DOT
Frozen : 80 DOT
Onhold: 20 DOT
Spendable: 20 DOT
Untouchable: 60 DOT
Note how the system uses the balance
that is frozen, instead of the free
balance that is spendable (present situation). In other words, holds are subtracted from free, but they overlap with the frozen balance.
The free portion shrinks from 100 to 80 DOT, and the on_hold
portion increases from 0 to 20 DOT.
The creation of an identity will grow the on_hold
portion to 40 DOT, and shrink further the free
from 80 to 60 DOT. Note how in the process, the spendable balance stays the same.
Free: 60 DOT
Frozen: 80 DOT
Onhold: 40 DOT
Spendable: 20 DOT
Untouchable: 40 DOT
This update using the fungible trait allows the use of the frozen balance for on-chain activity like setting up proxies and identities.
Note that holds are slashable, and the pallet migrations need to take that into account. This means that freezes should account for hold being slashed (for example your stash getting reduced because your governance deposit for a proposal was slashed).
Also, note how the account cannot be reaped from the state while it has a frozen balance, or in general any consumer and provider reference. Those references determine if an account can be reaped, usually because there are other accounts depending on the existence of such an account). For example, the existential deposit adds a provider reference simply because the account exists, while a proxy account adds a consumer reference (the proxy existence depends on the existence of the proxied account, the proxy is the consumer). I will probably talk more about provider and consumer references in another article. See you soon!
Acknowledgement
I would like to thank Michalis at the Web3 Foundation for the fruitful discussion and for providing review to this content.
🔥 Web3 explained from the non-developer's POV. 🚀 Helping Polkadot users explore the ecosystem with confidence. I post daily on socials. Opinions are mine.
20 comments