Balancer
Python implementation of Balancer Weighted Pools ‘broadly’ consists of two main components
BalancerMath.py: refactor of Balancer V1 Math solidity contract code, and was copied from BalancerPools_Model GH repos
BalancerExchange.py: refactor of Balancer Pool solidity contract code
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
Tests extracted from BalancerPools_Model GH repos
[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
Denorm weights are loosely selected as target percentages by the contract deployer
Percentage weights are normalized (to sum to 1) and are calculated based on denormalized weights
Shares are typically initialized to 100
[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
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