Bootstrapping Behavior

Bootstrapping Behavior

To illustrate how the system works, we will constrain the system to an oversimplified case with only three pools: ETH, wBTC and LINK, in addition to the BNT omnipool. Assume that these pools have just recently earned whitelist status, they each have a BNT funding limit of 40,000 BNT, and all are completely empty.

import pandas as pd
from bancor_research import Decimal
whitelisted_tokens: list = ['bnt', 'eth', 'wbtc', 'link']
bnt_funding_limit: Decimal = Decimal('40000')

The protocol is in the “bootstrapping phase” for all three assets. UserState can still interact with the system and deposit liquidity - which is essential for the process. The system needs to attract sufficient quantities of each token to overcome the minimum liquidity threshold prior to the activation of each liquidity pool, respectively. The default minimum liquidity threshold is 10,000 BNT (previously 1,000 BNT in an earlier draft of this proposal), meaning that the pool must mint 10,000 BNT during its activation, and therefore there must be at least a commensurate value of TKN available in the vault.

bnt_min_liquidity: Decimal = Decimal('10000')

Assume that the prices of each asset are as follows: BNT = 2.50, LINK = 15.00, ETH = 2,500.00, wBTC = 40,000.00. Therefore, to bootstrap each pool, at least $25,000 of each asset must be available in the vault.

# Recall from an earlier chapter that we already defined the cooldown period and the exit fees as follows.
cooldown_time: int = 7
iter_limit = 10000
withdrawal_fee: Decimal = Decimal('0.0025')
price_feeds = pd.DataFrame({'INDX':[0 for i in range(iter_limit + 1)],
                            'bnt':[2.5 for i in range(iter_limit + 1)],
                            'link':[15.00 for i in range(iter_limit + 1)],
                            'eth':[2500.00 for i in range(iter_limit + 1)],
                            'wbtc':[40000.00 for i in range(iter_limit + 1)]})

network_fee: Decimal = Decimal('0.2')
trading_fee: Decimal = Decimal('0.01')

# There are other possible configuration settings available, however for the present purpose we will use the defaults.
v3 = BancorDapp(whitelisted_tokens=whitelisted_tokens,
              network_fee=network_fee,
              trading_fee=trading_fee,
              cooldown_time=cooldown_time,
              withdrawal_fee=withdrawal_fee,
              bnt_min_liquidity=bnt_min_liquidity,
              bnt_funding_limit=bnt_funding_limit,
              price_feeds=price_feeds)

During the bootstrap phase, Alice deposits 100 ETH, Bob deposits 100 bnwBTC, and Charlie deposits 10,000 LINK. By default, the initial pool token value is 1:1 with the underlying asset, and only changes after revenue begins accumulating. Therefore, each of these characters receive 100 bnETH, 100 bnwBTC and 1,000 bnLINK pool tokens for their contribution, respectively,

v3.create_user('Alice')
v3.create_user('Bob')
v3.create_user('Charlie')

v3.set_user_balance(user_name='Alice', tkn_name='eth', tkn_amt=101)
v3.set_user_balance(user_name='Charlie', tkn_name='link', tkn_amt=10001)
v3.set_user_balance(user_name='Bob', tkn_name='wbtc', tkn_amt=101)

However, note that the trading liquidity available on the pools remains unchanged until the BancorDAO msig signers initialize each pool.

The condition to initialize a pool is that there must be at least 10,000 BNT ($25,000 at the quoted price) worth of each token - in this case all three satisfy the criteria. The BancorDAO msig signers then sign a transaction with the rate of BNT/TKN for each of the bootstrapping assets. In this case, BNT/ETH = 1,000, BNT/wBTC = 16,000, BNT/LINK = 6. The trading liquidity on each pool begins with exactly 10,000 BNT and the commensurate amount of TKN as determined by the rates supplied by the msig signers.

It is important to note here that each of these pools have been stated to have a 100,000 BNT funding limit, 10× higher than the bootstrapping depth. This is because the pools should equilibrate with the rest of the market and grow in a controlled manner. Therefore, only a fraction of the available ETH, wBTC and LINK has been committed to trading at this stage. The other important change is that the BNT that was created by the protocol causes its own pool token to be issued, bnBNT,

Fortunately, the rate at which the pool can grow is independent of the new liquidity additions, and is determined entirely by the token balances available in the vault. To demonstrate, suppose that each user deposits just 1 more TKN each to their respective pools; Alice deposits 1 ETH, Bob deposits 1 wBTC, and Charlie deposits 1 LINK. Each of these tokens is accepted directly to the vault. Assume that no trading has yet occurred on the pool, therefore the valuation of each pool token remains at 1:1 for the time being. Therefore, each user is issued one additional bnTKN.

# The actual deposits.

v3.deposit(tkn_amt=100, tkn_name='eth', user_name='Alice')

v3.deposit(tkn_amt=10000, tkn_name='link', user_name='Charlie')

v3.deposit(tkn_amt=100, tkn_name='wbtc', user_name='Bob')

v3.describe()
bnt eth wbtc link bnbnt bneth bnwbtc bnlink
Account Alice NaN 1.000000000000000000 NaN NaN NaN 100.000000000000000000 NaN NaN
Bob NaN NaN 1.000000000000000000 NaN NaN NaN 100.000000000000000000 NaN
Charlie NaN NaN NaN 1.000000000000000000 NaN NaN NaN 10000.000000000000000000
Trader NaN NaN NaN NaN NaN NaN NaN NaN
Contract EP Vault 0 0 0 0 NaN NaN NaN NaN
ER Vault 0 0 0 0 NaN NaN NaN NaN
Master Vault 0 100.000000000000000000 100.000000000000000000 10000.000000000000000000 NaN NaN NaN NaN
Protocol NaN NaN NaN NaN 0E-18 0 0 0
Pool a: TKN Staked Balance NaN 100.000000000000000000 100.000000000000000000 10000.000000000000000000 NaN NaN NaN NaN
b: TKN Trading Liquidity NaN 0E-18 0E-18 0E-18 NaN NaN NaN NaN
c: BNT Trading Liquidity NaN 0E-18 0E-18 0E-18 NaN NaN NaN NaN
d: BNT Current Funding NaN 0E-18 0E-18 0E-18 NaN NaN NaN NaN
e: Spot Rate NaN 0 0 0 NaN NaN NaN NaN
f: Average Rate NaN 0 0 0 NaN NaN NaN NaN
g: Average Inverse Rate NaN 0 0 0 NaN NaN NaN NaN
v3.deposit(tkn_amt=1, tkn_name='eth', user_name='Alice')

v3.deposit(tkn_amt=1, tkn_name='link', user_name='Charlie')

v3.deposit(tkn_amt=1, tkn_name='wbtc', user_name='Bob')

v3.dao_msig_init_pools(whitelisted_tokens, 'bnt', timestamp=0)

v3.describe(decimals=6)
Bootstrap requirements met for eth
Bootstrap requirements met for wbtc
Bootstrap requirements met for link
bnt eth wbtc link bnbnt bneth bnwbtc bnlink
Account Alice NaN 0.000000 NaN NaN NaN 101.000000 NaN NaN
Bob NaN NaN 0.000000 NaN NaN NaN 101.000000 NaN
Charlie NaN NaN NaN 0.000000 NaN NaN NaN 10001.000000
Trader NaN NaN NaN NaN NaN NaN NaN NaN
Contract EP Vault 0.000000 0.000000 0.000000 0.000000 NaN NaN NaN NaN
ER Vault 0.000000 0.000000 0.000000 0.000000 NaN NaN NaN NaN
Master Vault 60000.000000 101.000000 101.000000 10001.000000 NaN NaN NaN NaN
Protocol NaN NaN NaN NaN 60000.000000 0.000000 0.000000 0.000000
Pool a: TKN Staked Balance NaN 101.000000 101.000000 10001.000000 NaN NaN NaN NaN
b: TKN Trading Liquidity NaN 20.000000 1.250000 3333.333333 NaN NaN NaN NaN
c: BNT Trading Liquidity NaN 20000.000000 20000.000000 20000.000000 NaN NaN NaN NaN
d: BNT Current Funding NaN 20000.000000 20000.000000 20000.000000 NaN NaN NaN NaN
e: Spot Rate NaN 1000.000000 16000.000000 6.000000 NaN NaN NaN NaN
f: Average Rate NaN 1000.000000 16000.000000 6.000000 NaN NaN NaN NaN
g: Average Inverse Rate NaN 0.000000 0.000000 0.000000 NaN NaN NaN NaN

and the balances of the staking ledger are updated accordingly.