Tech talk: Basilisk’s Take on Existential Deposits in a Multi-Asset World
Sub0 — the substrate developer conference
october 13–14, 2021
What is an existential deposit, why is it important and how can it be addressed in a multi chain universe. This is Basilisk’s take on existential deposits and the dusting process where the existential deposit for each asset is determined dynamically based on several factors, such as current price, liquidity etc. The talk is for those who would like to know more about existential deposits, dusting, and how they work generally and in Basilisk’s case.
Speaker: Martin Hloska, Software Engineer, HydraDX | Basilisk
We´ll talk today about how the existential deposits work in a substrate, we will check what is under the root, will focus on two pallets to most used pallet balances and tokens. We will try to have a look how we tackle the issue in Basilisk where we have many assets with dynamic prices.
Hydra DX and Basilisk both are projects in a Polkadot ecosystem. Basilisk already running as parachain on Kusama is a liquidity bootstrapping protocol built for Kusama.HydraDX implements some kind of novel type of multi-asset liquidity pool called omnipool. Both these projects create a synergy where you can bootstrap liquidity on a Basilisk and then move it to a hydra omnipool.
So naturally we will deal with many assets and hence we will have to handle also many different existential deposits.
How subtrade handle accounts?
In blockchain your tokens are usually tied to an account. In substrate account is identified by account ID and some additional data regarding your account are stored on a chain. In substrate it´s the structure called account info
At the moment we are not interested in nons or data so we ignore those, but we can see there are three counters. Each of this serves a different purpose.
The number of modules that depend on this account´s existence. The account cannot be reaped until this is zero.
The number of modules that allow this account to exist. The account cannot be reaped until this and sufficients are both zero.
The number of modules that allow this account to exist for their own purposes only. The account cannot be reaped until this and providers are both zero.
These counters are basically deciding factors about your account on a chain. If all of them are equal to 0, your account can be deactivated.
Now the question is what is increasing and decreasing these counters and how it is related to existential deposit. In case of balance is pallet is where the existential deposit actually comes to play. When a new account is created, pallet balances increases the provider´s count and on the other side if the account is killed it´s decreasing this count.
What is the existential deposit?
We may define it as a minimum balance that account needs to have in order to exist on a chain. If you already worked with substrate you have probably seen events like this:
If the event you want to see is the killed account event (all the references have been removed and all the counters are equal to zero) and your account is now no longer needed on your chain.
But in case there wouldn´t be existential deposit or the deposit was set to zero this would never happen and account would be still refrenced by at least one provider (in this case balances pallet), account would not be killed. It would take up some storage and even when it doesn´t need to.
If the account balance drops below the existential deposit the remaining amount is considered to be low enough that it can be either transferred to another account or burned if you like. This operation we use to call it dusting therefore the remaining balance called dust.
We have some kind of protection to avoid losing your remaining balance. Transaction usually fails if after the transfer the remaining balance would be less than existential deposit. In that case you will get the red event:
Each chain can set its existential deposit differently. Let´s have a look at some examples:
Why do we need it?
Why we cannot just keep and account as long as there is something on it and only kill it when the balance of the account is a zero. First of all the remaining balance would be so low that it wouldn´t be possible to do anything, you would not be able to execute any transaction due to lack of money for transaction fee. The reason why the existential balance exists is so the chain can be efficient, can be safer and eventually can be cheaper. The more stuff you have on your chain, the less efficient it becomes, the more expensive will be to execute transaction.
You can easily flat a chain and create arbitrary number of accounts with no balance. We live in a multi-asset world and hence we will have many different assets, many diffrent existential deposits so that means lots of dust can be left behind.
Let´s have a look on a scenario where existential deposit would not exists or would be set to zero. I transfer some amounts to a new account and immediately transfer it back to the original leaving the new account empty. Let´s see what happens if existential deposit is set to zero:
On the left side we see total number of the system and under the total number of accounts without balance and with one reference only. On the right side we see events for each block. The number of account is increasing and increasing.
How can we configure our existential deposit to some reasonable number and see what wll change:
How can we configure the existential deposit?
In case of balances you set existential deposit by implementing a “get trade” where you return the amount for a native token. In case of tokens you need to implement “get by key” because you also need to provide for which asset you want the deposit to be returned. You also may configure a handler to handle accounts dust.
When do the existential deposits come to play?
During each transfer the existential deposit is checked and if the remaining balance would result less than the existential deposit the transaction would fail. If the remaining balance is zero after the transaction, then the account is killed and we´ll get the killed event.
Also we´ll have a keep-alive flag to prevent losing remaining balance due to the existential deposit so we can control what you want.Whether you want to allow the account to exist or not.
Let´s look how we handle existential deposits. In a Basilisk we have many assets. We implemented our own asset registry and every asset has to be registered first before it can be used.
When registering new asset, you also provide some parametrs and one of these is existential deposit. Using a price oracle, the value of asset can change at any point.
So now the question is how we can dust accounts which balances were OK and has been changed. In basilisk we implemented very simple pallet which we call duster. It´s a simple pallet which has only one dispatchable called dust account. Anybody basically can call this method and providing the account and there are also asset ID the account which can be dusted and in return the core will earn some reward and also transaction fee can be refunded as well if desired. How the core figure out what accounts can be dusted is on them but in case nobody would willing to do this we have also offchain duster which we can run and it will go out and seeks and destroy all dust accounts every end block.
Let´s have a look on an example which demonstrates all we just talked about. Let´s imagine that we are at block number 10 and our registry looks like this:
We have only native token and it´s existential deposit set to 1. Looks like there is only Alice holding some BSX tokens. So we register an asset. Let´s register KSM and set the deposit to file:
Let´s fast forward to block 100 during that period there were some transfers and our account storage looks like this:
We have some new accounts Bob ans Charlie. Alice acquired some KSM as well. So as you can see all the amounts are still above the existential deposit. So nothing can be dusted at the moment. But now something happened and the value of KSM tokens has been changed:
According to the new value we also need to update the deposit of KSM. So we update it to 15. That means that all the accounts which hold KSM can be now dusted because level is low enough.
Let´s say nobody have any desire to do anything with these tokens anymore because it´s not worth for them to transfer it out because of transaction fee that is probably too high. If we did not have any dusting strategy it would remain like this, on the chain. In this case it would take some storage. But we use the duster which we talked about, so let´s jump one block forward so we can write all the changed regarding the KSM deposit to the storage and we can call the dust account method:
We can see that we can dust Charlie´s account box and Alice´s. Charlie´s account has been removed completely because Charlie didn´t have anything else other than KSM. Bob and Alice still hold some BSX so only the storage of non-native tokens have been cleared:
Summarizing all of the above mentioned:
- don´t forget about existential deposit
- have it set to some reasonable amount
- choose your dusting strategy
- if you deal with multiple assets don´t forger about those and set deposits and dusting strategy for them too
Is dust removal a feature that is part of the substrate pallet for accounts or it is just on Basilisk?
Actually it can be a part of any pallet which deals with tokens. It´s not a feature of Basilisk, it´s a feature of substrate.
How often do you need to run your duster?
That´s what we still need to figure out. We haven´t had a chance to have many accounts yet in our chain so we´ll see after a few month how often we need to run it, how often there will be account with less than the existential deposit.
Does the existentional deposit apply to an account that holding maybe very expensive NFT but not necessarily the asset that corresponds to the extent excessive existential deposit capability? How is an existential deposit handled in that case when the account doesn´t have the currency that the existentional deposit is listening to?
I believe if you have an NFT you have also a deposit for the NFT. So that means the amount of the account will take into account also the deposit for the NFT. So even if you have less remaining they would be still together with the deposit.
Where does the dust balances go in a multi-asset system of Basilisk?
Treasury account that´s the answer. But you can configurate it as you want. You can transfer, you can burn it. If you don´t want to do it daily.
What is Basilisk?
Basilisk is a liquidity bootstrapping protocol designed to operate as a parachain in Kusama. Basilisk is a modular Automated Market Maker (AMM) chain which provides liquidity bootstrapping functionality for any new cryptoasset. Basilisk isn’t a mere canary network — it is an independent chain based on HydraDX’s code base.
It allows participants to choose from a variety of AMM models which govern the price discovery. The API design of Basilisk allows for AMM models to be plugged in easily: From basic spot trading to purpose-specific models for derivatives such as PERP or the Siren Protocol.
Need more information about Basilisk？
Website | Github| Twitter| Newsletter| Telegram | Discord | Documentation