Balancer

  • Python implementation of Balancer Weighted Pools ‘broadly’ consists of two main components

  • The mapping (contract code -> math refactor -> exchange refactor) is as follows:

    • Price

      • BMath.calcSpotPrice() -> BalancerMath.calc_spot_price() -> BalancerExchange.get_price()

    • Swapping

      • BMath.calcOutGivenIn() -> BalancerMath.calc_out_given_in() -> BalancerExchange.get_amount_out()

      • BMath.calcInGivenOut() -> BalancerMath.calc_in_given_out() -> BalancerExchange.get_amount_in()

    • Adding Liquidity

      • BMath.calcPoolOutGivenSingleIn() -> BalancerMath.calc_pool_out_given_single_in() -> BalancerExchange.join_swap_extern_amount_in()

      • BMath.calcSingleInGivenPoolOut() -> BalancerMath.calc_single_in_given_pool_out() -> BalancerExchange.join_swap_pool_amount_out()

    • Removing Liquidity

      • BMath.calcPoolInGivenSingleOut() -> BalancerMath.calc_pool_in_given_single_out() -> BalancerExchange.exit_swap_extern_amount_out()

      • BMath.calcSingleOutGivenPoolIn() -> BalancerMath.calc_single_out_given_pool_in() -> BalancerExchange.exit_swap_pool_amount_in()

[1]:
import os
import json
import numpy as np
[2]:
from defipy import *

Benchmarks

[3]:
cwd =  os.getcwd().replace("notebooks","")
os.chdir(cwd)
actions_json = 'resources/dev/cwpt/0x8b6e6e7b5b3801fed2cafd4b22b8a16c2f2db21a-actions-prices.json'
with open(actions_json, "r") as f:
    pool_actions = json.load(f)

Parameters

[4]:
USER = 'user_test'

amt_dai = 10000000
denorm_wt_dai = 10

amt_eth = 67738.6361731024
denorm_wt_eth = 40

init_pool_shares = 100

Join balancer pool

  • Join all assets

[5]:
dai = ERC20("DAI", "0x111")
dai.deposit(None, amt_dai)

weth = ERC20("WETH", "0x09")
weth.deposit(None, amt_eth)

bgrp = BalancerVault()
bgrp.add_token(dai, denorm_wt_dai)
bgrp.add_token(weth, denorm_wt_eth)

bfactory = BalancerFactory("WETH pool factory", "0x2")
exchg_data = BalancerExchangeData(vault = bgrp, symbol="LP", address="0x011")
lp = bfactory.deploy(exchg_data)
lp.join_pool(bgrp, init_pool_shares, USER)
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 10000000, WETH = 67738.6361731024
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 100

Price

[6]:
p = lp.get_price(dai, weth)

print(f"The price of {weth.token_name} is {p} {dai.token_name}")
The price of WETH is 591.984912776992 DAI

Swap (out-given-in)

[7]:
amt_tkn_in = float(pool_actions[3]['action']['token_in']['amount'])
tkn_in = dai
tkn_out = weth
res = lp.swap_exact_amount_in(amt_tkn_in, tkn_in, tkn_out, USER)

print(f"{amt_tkn_in} {tkn_in.token_name} was swapped into {res['tkn_out_amt']} {tkn_out.token_name}")
11861.328308361 DAI was swapped into 20.021734704865246 WETH
[8]:
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 10011861.32830836, WETH = 67718.61443839753
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 100

Swap (in-given-out)

[9]:
amt_tkn_out = res['tkn_out_amt']
tkn_out = weth
tkn_in = dai

res = lp.swap_exact_amount_out(amt_tkn_out, tkn_out, tkn_in, USER)

print(f"{amt_tkn_out} {tkn_out.token_name} was swapped into {res['tkn_in_amt']} {tkn_in.token_name}")
20.021734704865246 WETH was swapped into 11878.911104285744 DAI
[10]:
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 9999982.417204075, WETH = 67738.6361731024
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 100

Add liquidity (token amounts)

[11]:
tkn_in = weth
amt_tkn_in = float(pool_actions[336]['action']['token_in']['amount'])

res = lp.join_swap_extern_amount_in(amt_tkn_in, tkn_in, USER)

print(f"{amt_tkn_in} {tkn_in.token_name} was added resulting in anadditional {res['shares_in_amt']} LP shares")
26.741601415598677 WETH was added resulting in anadditional 0.03156505964916199 LP shares
[12]:
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 9999982.417204075, WETH = 67765.377774518
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 100.03156505964917

Add liquidity (LP share amounts)

[13]:
tkn_in = weth
amt_shares_in = 10

res = lp.join_swap_pool_amount_out(amt_shares_in, tkn_in, USER)

print(f"{amt_shares_in} LP shares were added resulting in an additional {res['tkn_in_amt']} {tkn_in.token_name}")
10 LP shares were added resulting in an additional 8575.568763821291 WETH
[14]:
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 9999982.417204075, WETH = 76340.94653833928
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 110.03156505964917

Remove liquidity (token amounts)

[15]:
tkn_out = weth
amt_tkn_out = float(pool_actions[664]['action']['token_out']['amount'])

res = lp.exit_swap_extern_amount_out(amt_tkn_out, tkn_out, USER)

print(f"{amt_tkn_out} {tkn_out.token_name} was removed resulting in the removal of {res['shares_out_amt']} LP shares")
27.036668416618735 WETH was removed resulting in the removal of 0.031191445644352424 LP shares
[16]:
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 9999982.417204075, WETH = 76313.90986992266
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 110.00037361400481

Remove liquidity (LP share amounts)

[17]:
tkn_out = weth
amt_shares_out = 10

res = lp.exit_swap_pool_amount_in(amt_shares_out, tkn_out, USER)

print(f"{amt_shares_out} LP shares were removed resulting in the removal of {res['tkn_out_amt']} {tkn_out.token_name}")
10 LP shares were removed resulting in the removal of 8566.8415530723 WETH
[18]:
lp.summary()
Balancer Exchange: DAI-WETH (LP)
Reserves: DAI = 9999982.417204075, WETH = 67747.06831685036
Weights: DAI = 0.2, WETH = 0.8
Pool Shares: 100.00037361400481