Python implementation of mathematics for Balancer v3
Note: This is the Python implementation within the balancer-maths monorepo, which also contains TypeScript and Rust implementations.
pip install balancer-mathsgit clone https://github.com/balancer/balancer-maths.git
cd balancer-maths/python
pip install -e .- Create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activate # On Windows use: .venv\Scripts\activate- Install development dependencies:
pip install -e ".[dev]"Hooks are supported on a case by case basis.
When a pool has a hook type included in the pool data relevant hook data must also be passed as an input to any Vault operation. See Remove Liquidity example below.
Currently supported hooks:
- ExitFeeHook
- This hook implements the ExitFeeHookExample found in mono-repo
from src.vault import Vault
from src.swap import SwapInput, SwapKind
pool = {
"poolType": "WEIGHTED",
"chainId": "11155111",
"blockNumber": "5955145",
"poolAddress": "0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
"tokens": [
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
],
"scalingFactors": [1000000000000000000, 1000000000000000000],
"weights": [500000000000000000, 500000000000000000],
"swapFee": 100000000000000000,
"balancesLiveScaled18": [2000000000000000000, 2000000000000000000],
"tokenRates": [1000000000000000000, 1000000000000000000],
"totalSupply": 1000000000000000000,
"aggregateSwapFee": 500000000000000000,
}
swap_input = SwapInput(
amount_raw=100000000,
swap_kind=SwapKind.GIVENIN,
token_in=pool['tokens'][0],
token_out=pool['tokens'][1],
)
vault = Vault()
calculated_result = vault.swap(
swap_input,
pool,
)from src.vault import Vault
from src.add_liquidity import AddLiquidityInput, AddLiquidityKind
pool = {
"poolType": "WEIGHTED",
"chainId": "11155111",
"blockNumber": "5955145",
"poolAddress": "0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
"tokens": [
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
],
"scalingFactors": [1000000000000000000, 1000000000000000000],
"weights": [500000000000000000, 500000000000000000],
"swapFee": 100000000000000000,
"balancesLiveScaled18": [2000000000000000000, 2000000000000000000],
"tokenRates": [1000000000000000000, 1000000000000000000],
"totalSupply": 1000000000000000000,
"aggregateSwapFee": 500000000000000000,
}
add_liquidity_input = AddLiquidityInput(
pool="0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
max_amounts_in_raw=[200000000000000000, 100000000000000000],
min_bpt_amount_out_raw=0,
kind=AddLiquidityKind.UNBALANCED,
)
vault = Vault()
calculated_result = vault.add_liquidity(
add_liquidity_input,
pool,
)This example shows how to calculate the result of a remove liqudity operation when the pool is registered with the ExitFee hook.
from src.vault import Vault
from src.remove_liquidity import RemoveLiquidityInput, RemoveLiquidityKind
pool = {
"poolType": "WEIGHTED",
"hookType": "ExitFee",
"chainId": "11155111",
"blockNumber": "5955145",
"poolAddress": "0x03722034317d8fb16845213bd3ce15439f9ce136",
"tokens": [
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
],
"scalingFactors": [1000000000000000000, 1000000000000000000],
"weights": [500000000000000000, 500000000000000000],
"swapFee": 100000000000000000,
"balancesLiveScaled18": [5000000000000000, 5000000000000000000],
"tokenRates": [1000000000000000000, 1000000000000000000],
"totalSupply": 158113883008415798,
"aggregateSwapFee": 0,
}
remove_liquidity_input = RemoveLiquidityInput(
pool="0x03722034317d8fb16845213bd3ce15439f9ce136",
min_amounts_out_raw=[1, 1],
max_bpt_amount_in_raw=10000000000000,
kind=RemoveLiquidityKind.PROPORTIONAL,
)
input_hook_state = {
'removeLiquidityHookFeePercentage': 0,
'tokens': pool['tokens'],
}
vault = Vault()
calculated_result = vault.remove_liquidity(
remove_liquidity_input,
pool,
hook_state=input_hook_state
)To build the package locally for testing:
python build_and_release.py --allThis will:
- Clean previous build artifacts
- Install build dependencies
- Build the package
- Check the built package
- Test Release (recommended first):
python build_and_release.py --test-upload- Production Release:
python build_and_release.py --uploadNote: You'll need to have your PyPI credentials configured. You can set them up using:
pip install twine
twine configureIf you prefer to build manually:
# Install build tools
pip install build twine
# Build the package
python -m build
# Check the package
twine check dist/*
# Upload to TestPyPI
twine upload --repository testpypi dist/*
# Upload to PyPI
twine upload dist/*