# 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.