balancer-maths 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- balancer_maths-0.1.1/.gitignore +99 -0
- balancer_maths-0.1.1/.pylintrc +5 -0
- balancer_maths-0.1.1/.vscode/launch.json +25 -0
- balancer_maths-0.1.1/.vscode/settings.json +11 -0
- balancer_maths-0.1.1/LICENSE +21 -0
- balancer_maths-0.1.1/MANIFEST.in +12 -0
- balancer_maths-0.1.1/PKG-INFO +248 -0
- balancer_maths-0.1.1/README.md +231 -0
- balancer_maths-0.1.1/RELEASE_GUIDE.md +166 -0
- balancer_maths-0.1.1/build_and_release.py +106 -0
- balancer_maths-0.1.1/pyproject.toml +50 -0
- balancer_maths-0.1.1/src/__init__.py +60 -0
- balancer_maths-0.1.1/src/common/__init__.py +0 -0
- balancer_maths-0.1.1/src/common/base_pool_math.py +382 -0
- balancer_maths-0.1.1/src/common/base_pool_state.py +17 -0
- balancer_maths-0.1.1/src/common/bigint.py +108 -0
- balancer_maths-0.1.1/src/common/constants.py +5 -0
- balancer_maths-0.1.1/src/common/log_exp_math.py +423 -0
- balancer_maths-0.1.1/src/common/maths.py +98 -0
- balancer_maths-0.1.1/src/common/oz_math.py +53 -0
- balancer_maths-0.1.1/src/common/pool_base.py +33 -0
- balancer_maths-0.1.1/src/common/swap_params.py +13 -0
- balancer_maths-0.1.1/src/common/types.py +80 -0
- balancer_maths-0.1.1/src/common/utils.py +124 -0
- balancer_maths-0.1.1/src/hooks/__init__.py +0 -0
- balancer_maths-0.1.1/src/hooks/default_hook.py +95 -0
- balancer_maths-0.1.1/src/hooks/exit_fee/exit_fee_hook.py +63 -0
- balancer_maths-0.1.1/src/hooks/exit_fee/types.py +8 -0
- balancer_maths-0.1.1/src/hooks/stable_surge/stable_surge_hook.py +100 -0
- balancer_maths-0.1.1/src/hooks/stable_surge/types.py +17 -0
- balancer_maths-0.1.1/src/hooks/types.py +140 -0
- balancer_maths-0.1.1/src/pools/__init__.py +3 -0
- balancer_maths-0.1.1/src/pools/buffer/__init__.py +0 -0
- balancer_maths-0.1.1/src/pools/buffer/buffer_data.py +23 -0
- balancer_maths-0.1.1/src/pools/buffer/buffer_math.py +47 -0
- balancer_maths-0.1.1/src/pools/buffer/enums.py +6 -0
- balancer_maths-0.1.1/src/pools/buffer/erc4626_buffer_wrap_or_unwrap.py +28 -0
- balancer_maths-0.1.1/src/pools/gyro/__init__.py +0 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_2clp.py +213 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_2clp_data.py +53 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_2clp_math.py +310 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_eclp.py +129 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_eclp_data.py +76 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_eclp_math.py +809 -0
- balancer_maths-0.1.1/src/pools/gyro/gyro_pool_math.py +101 -0
- balancer_maths-0.1.1/src/pools/gyro/signed_fixed_point.py +234 -0
- balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/__init__.py +0 -0
- balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/liquidity_bootstrapping.py +41 -0
- balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/liquidity_bootstrapping_data.py +66 -0
- balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/liquidity_bootstrapping_math.py +64 -0
- balancer_maths-0.1.1/src/pools/quantamm/__init__.py +3 -0
- balancer_maths-0.1.1/src/pools/quantamm/quantamm.py +206 -0
- balancer_maths-0.1.1/src/pools/quantamm/quantamm_data.py +78 -0
- balancer_maths-0.1.1/src/pools/quantamm/quantamm_math.py +81 -0
- balancer_maths-0.1.1/src/pools/reclamm/__init__.py +3 -0
- balancer_maths-0.1.1/src/pools/reclamm/reclamm.py +88 -0
- balancer_maths-0.1.1/src/pools/reclamm/reclamm_data.py +66 -0
- balancer_maths-0.1.1/src/pools/reclamm/reclamm_math.py +463 -0
- balancer_maths-0.1.1/src/pools/reclamm_v2/__init__.py +0 -0
- balancer_maths-0.1.1/src/pools/reclamm_v2/reclamm_v2.py +88 -0
- balancer_maths-0.1.1/src/pools/reclamm_v2/reclamm_v2_data.py +66 -0
- balancer_maths-0.1.1/src/pools/reclamm_v2/reclamm_v2_math.py +541 -0
- balancer_maths-0.1.1/src/pools/stable/__init__.py +3 -0
- balancer_maths-0.1.1/src/pools/stable/stable.py +75 -0
- balancer_maths-0.1.1/src/pools/stable/stable_data.py +50 -0
- balancer_maths-0.1.1/src/pools/stable/stable_math.py +191 -0
- balancer_maths-0.1.1/src/pools/weighted/__init__.py +3 -0
- balancer_maths-0.1.1/src/pools/weighted/weighted.py +65 -0
- balancer_maths-0.1.1/src/pools/weighted/weighted_data.py +48 -0
- balancer_maths-0.1.1/src/pools/weighted/weighted_math.py +148 -0
- balancer_maths-0.1.1/src/vault/__init__.py +0 -0
- balancer_maths-0.1.1/src/vault/add_liquidity.py +148 -0
- balancer_maths-0.1.1/src/vault/remove_liquidity.py +169 -0
- balancer_maths-0.1.1/src/vault/swap.py +236 -0
- balancer_maths-0.1.1/src/vault/vault.py +123 -0
- balancer_maths-0.1.1/test/__init__.py +0 -0
- balancer_maths-0.1.1/test/hooks/test_after_add_liquidity.py +139 -0
- balancer_maths-0.1.1/test/hooks/test_after_remove_liquidity.py +174 -0
- balancer_maths-0.1.1/test/hooks/test_after_swap.py +168 -0
- balancer_maths-0.1.1/test/hooks/test_before_add_liquidity.py +105 -0
- balancer_maths-0.1.1/test/hooks/test_before_remove_liquidity.py +137 -0
- balancer_maths-0.1.1/test/hooks/test_before_swap.py +95 -0
- balancer_maths-0.1.1/test/hooks/test_exit_fee.py +73 -0
- balancer_maths-0.1.1/test/hooks/test_hook.py +76 -0
- balancer_maths-0.1.1/test/hooks/test_stable_surge.py +73 -0
- balancer_maths-0.1.1/test/test_add_liquidity.py +34 -0
- balancer_maths-0.1.1/test/test_custom_pool.py +114 -0
- balancer_maths-0.1.1/test/test_reclamm.py +65 -0
- balancer_maths-0.1.1/test/test_remove_liquidity.py +34 -0
- balancer_maths-0.1.1/test/test_swaps.py +48 -0
- balancer_maths-0.1.1/test/utils/__init__.py +0 -0
- balancer_maths-0.1.1/test/utils/default_pool.py +32 -0
- balancer_maths-0.1.1/test/utils/map_pool_state.py +56 -0
- balancer_maths-0.1.1/test/utils/read_test_data.py +65 -0
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# local tests
|
|
2
|
+
local
|
|
3
|
+
|
|
4
|
+
# build output
|
|
5
|
+
dist
|
|
6
|
+
|
|
7
|
+
# Logs
|
|
8
|
+
logs
|
|
9
|
+
*.log
|
|
10
|
+
npm-debug.log*
|
|
11
|
+
yarn-debug.log*
|
|
12
|
+
yarn-error.log*
|
|
13
|
+
lerna-debug.log*
|
|
14
|
+
|
|
15
|
+
# Diagnostic reports (https://nodejs.org/api/report.html)
|
|
16
|
+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
|
17
|
+
|
|
18
|
+
# Runtime data
|
|
19
|
+
pids
|
|
20
|
+
*.pid
|
|
21
|
+
*.seed
|
|
22
|
+
*.pid.lock
|
|
23
|
+
|
|
24
|
+
# Directory for instrumented libs generated by jscoverage/JSCover
|
|
25
|
+
lib-cov
|
|
26
|
+
|
|
27
|
+
# Coverage directory used by tools like istanbul
|
|
28
|
+
coverage
|
|
29
|
+
*.lcov
|
|
30
|
+
|
|
31
|
+
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
|
32
|
+
build/Release
|
|
33
|
+
|
|
34
|
+
# Dependency directories
|
|
35
|
+
node_modules/
|
|
36
|
+
jspm_packages/
|
|
37
|
+
|
|
38
|
+
# TypeScript cache
|
|
39
|
+
*.tsbuildinfo
|
|
40
|
+
|
|
41
|
+
# Optional npm cache directory
|
|
42
|
+
.npm
|
|
43
|
+
|
|
44
|
+
# Optional eslint cache
|
|
45
|
+
.eslintcache
|
|
46
|
+
|
|
47
|
+
# Optional REPL history
|
|
48
|
+
.node_repl_history
|
|
49
|
+
|
|
50
|
+
# Output of 'npm pack'
|
|
51
|
+
*.tgz
|
|
52
|
+
|
|
53
|
+
# Yarn Integrity file
|
|
54
|
+
.yarn-integrity
|
|
55
|
+
|
|
56
|
+
# dotenv environment variables file
|
|
57
|
+
.env
|
|
58
|
+
.env.test
|
|
59
|
+
|
|
60
|
+
# parcel-bundler cache (https://parceljs.org/)
|
|
61
|
+
.cache
|
|
62
|
+
.parcel-cache
|
|
63
|
+
|
|
64
|
+
# yarn v2
|
|
65
|
+
.yarn/cache
|
|
66
|
+
.yarn/unplugged
|
|
67
|
+
.yarn/build-state.yml
|
|
68
|
+
.yarn/install-state.gz
|
|
69
|
+
.pnp.*
|
|
70
|
+
|
|
71
|
+
# hardhat
|
|
72
|
+
node_modules
|
|
73
|
+
.env
|
|
74
|
+
coverage
|
|
75
|
+
coverage.json
|
|
76
|
+
typechain
|
|
77
|
+
typechain-types
|
|
78
|
+
|
|
79
|
+
# Hardhat files
|
|
80
|
+
cache
|
|
81
|
+
artifacts
|
|
82
|
+
|
|
83
|
+
#IDE
|
|
84
|
+
.idea
|
|
85
|
+
|
|
86
|
+
.DS_Store
|
|
87
|
+
|
|
88
|
+
python/.venv/
|
|
89
|
+
*.pyc
|
|
90
|
+
__pycache__
|
|
91
|
+
pip*
|
|
92
|
+
.travis.yml
|
|
93
|
+
.coveragerc
|
|
94
|
+
|
|
95
|
+
# Rust
|
|
96
|
+
target/
|
|
97
|
+
**/*.rs.bk
|
|
98
|
+
rust/Cargo.lock
|
|
99
|
+
*.pdb
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Use IntelliSense to learn about possible attributes.
|
|
3
|
+
// Hover to view descriptions of existing attributes.
|
|
4
|
+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
|
5
|
+
"version": "0.2.0",
|
|
6
|
+
"configurations": [
|
|
7
|
+
{
|
|
8
|
+
"name": "Pytest Current File",
|
|
9
|
+
"type":"debugpy",
|
|
10
|
+
"request":"launch",
|
|
11
|
+
"module":"pytest",
|
|
12
|
+
"args":[
|
|
13
|
+
"${workspaceFolder}/${relativeFile}",
|
|
14
|
+
],
|
|
15
|
+
"justMyCode": true,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Pytest",
|
|
19
|
+
"type": "debugpy",
|
|
20
|
+
"request": "launch",
|
|
21
|
+
"module": "pytest",
|
|
22
|
+
"console": "integratedTerminal"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"editor.defaultFormatter": "ms-python.black-formatter",
|
|
3
|
+
"editor.formatOnSave": true,
|
|
4
|
+
"notebook.defaultFormatter": "ms-python.black-formatter",
|
|
5
|
+
"notebook.formatOnSave": true,
|
|
6
|
+
"python.analysis.typeCheckingMode": "basic",
|
|
7
|
+
"python.analysis.diagnosticMode": "workspace",
|
|
8
|
+
"python.analysis.autoImportCompletions": true,
|
|
9
|
+
"python.analysis.autoSearchPaths": true,
|
|
10
|
+
"python.analysis.extraPaths": [".", "src"]
|
|
11
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Balancer Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
include README.md
|
|
2
|
+
include LICENSE
|
|
3
|
+
include pyproject.toml
|
|
4
|
+
recursive-include src *.py
|
|
5
|
+
recursive-include test *.py
|
|
6
|
+
global-exclude __pycache__
|
|
7
|
+
global-exclude *.pyc
|
|
8
|
+
global-exclude *.pyo
|
|
9
|
+
global-exclude *.pyd
|
|
10
|
+
global-exclude .git*
|
|
11
|
+
global-exclude .DS_Store
|
|
12
|
+
global-exclude *.so
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: balancer-maths
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Python implementation of mathematics for Balancer v3
|
|
5
|
+
Project-URL: Homepage, https://github.com/balancer/balancer-maths
|
|
6
|
+
Project-URL: Repository, https://github.com/balancer/balancer-maths
|
|
7
|
+
Project-URL: Documentation, https://github.com/balancer/balancer-maths/tree/main/python#readme
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/balancer/balancer-maths/issues
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: amm,balancer,defi,liquidity,mathematics,pools
|
|
12
|
+
Requires-Python: >=3.10
|
|
13
|
+
Provides-Extra: dev
|
|
14
|
+
Requires-Dist: black>=22.0.0; extra == 'dev'
|
|
15
|
+
Requires-Dist: pytest>=7.0.0; extra == 'dev'
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
|
|
18
|
+
# Balancer Maths Python
|
|
19
|
+
|
|
20
|
+
Python implementation of mathematics for Balancer v3
|
|
21
|
+
|
|
22
|
+
> **Note**: This is the Python implementation within the [balancer-maths](https://github.com/balancer/balancer-maths) monorepo, which also contains TypeScript and Rust implementations.
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
### From PyPI (recommended)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install balancer-maths
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### From source
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/balancer/balancer-maths.git
|
|
36
|
+
cd balancer-maths/python
|
|
37
|
+
pip install -e .
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Development Setup
|
|
41
|
+
|
|
42
|
+
1. Create and activate a virtual environment:
|
|
43
|
+
```bash
|
|
44
|
+
python -m venv .venv
|
|
45
|
+
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
2. Install development dependencies:
|
|
49
|
+
```bash
|
|
50
|
+
pip install -e ".[dev]"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Hooks Support
|
|
54
|
+
|
|
55
|
+
Hooks are supported on a case by case basis.
|
|
56
|
+
|
|
57
|
+
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](#remove-liquidity) below.
|
|
58
|
+
|
|
59
|
+
Currently supported hooks:
|
|
60
|
+
|
|
61
|
+
* ExitFeeHook
|
|
62
|
+
* This hook implements the ExitFeeHookExample found in [mono-repo](https://github.com/balancer/balancer-v3-monorepo/blob/c848c849cb44dc35f05d15858e4fba9f17e92d5e/pkg/pool-hooks/contracts/ExitFeeHookExample.sol)
|
|
63
|
+
|
|
64
|
+
## Examples
|
|
65
|
+
|
|
66
|
+
### Swap
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
from src.vault import Vault
|
|
70
|
+
from src.swap import SwapInput, SwapKind
|
|
71
|
+
|
|
72
|
+
pool = {
|
|
73
|
+
"poolType": "WEIGHTED",
|
|
74
|
+
"chainId": "11155111",
|
|
75
|
+
"blockNumber": "5955145",
|
|
76
|
+
"poolAddress": "0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
|
|
77
|
+
"tokens": [
|
|
78
|
+
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
79
|
+
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
|
|
80
|
+
],
|
|
81
|
+
"scalingFactors": [1000000000000000000, 1000000000000000000],
|
|
82
|
+
"weights": [500000000000000000, 500000000000000000],
|
|
83
|
+
"swapFee": 100000000000000000,
|
|
84
|
+
"balancesLiveScaled18": [2000000000000000000, 2000000000000000000],
|
|
85
|
+
"tokenRates": [1000000000000000000, 1000000000000000000],
|
|
86
|
+
"totalSupply": 1000000000000000000,
|
|
87
|
+
"aggregateSwapFee": 500000000000000000,
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
swap_input = SwapInput(
|
|
92
|
+
amount_raw=100000000,
|
|
93
|
+
swap_kind=SwapKind.GIVENIN,
|
|
94
|
+
token_in=pool['tokens'][0],
|
|
95
|
+
token_out=pool['tokens'][1],
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
vault = Vault()
|
|
99
|
+
|
|
100
|
+
calculated_result = vault.swap(
|
|
101
|
+
swap_input,
|
|
102
|
+
pool,
|
|
103
|
+
)
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### Add Liquidity
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from src.vault import Vault
|
|
110
|
+
from src.add_liquidity import AddLiquidityInput, AddLiquidityKind
|
|
111
|
+
|
|
112
|
+
pool = {
|
|
113
|
+
"poolType": "WEIGHTED",
|
|
114
|
+
"chainId": "11155111",
|
|
115
|
+
"blockNumber": "5955145",
|
|
116
|
+
"poolAddress": "0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
|
|
117
|
+
"tokens": [
|
|
118
|
+
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
119
|
+
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
|
|
120
|
+
],
|
|
121
|
+
"scalingFactors": [1000000000000000000, 1000000000000000000],
|
|
122
|
+
"weights": [500000000000000000, 500000000000000000],
|
|
123
|
+
"swapFee": 100000000000000000,
|
|
124
|
+
"balancesLiveScaled18": [2000000000000000000, 2000000000000000000],
|
|
125
|
+
"tokenRates": [1000000000000000000, 1000000000000000000],
|
|
126
|
+
"totalSupply": 1000000000000000000,
|
|
127
|
+
"aggregateSwapFee": 500000000000000000,
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
add_liquidity_input = AddLiquidityInput(
|
|
132
|
+
pool="0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
|
|
133
|
+
max_amounts_in_raw=[200000000000000000, 100000000000000000],
|
|
134
|
+
min_bpt_amount_out_raw=0,
|
|
135
|
+
kind=AddLiquidityKind.UNBALANCED,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
vault = Vault()
|
|
139
|
+
|
|
140
|
+
calculated_result = vault.add_liquidity(
|
|
141
|
+
add_liquidity_input,
|
|
142
|
+
pool,
|
|
143
|
+
)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Remove Liquidity
|
|
147
|
+
|
|
148
|
+
This example shows how to calculate the result of a remove liqudity operation when the pool is registered with the ExitFee hook.
|
|
149
|
+
|
|
150
|
+
```python
|
|
151
|
+
from src.vault import Vault
|
|
152
|
+
from src.remove_liquidity import RemoveLiquidityInput, RemoveLiquidityKind
|
|
153
|
+
|
|
154
|
+
pool = {
|
|
155
|
+
"poolType": "WEIGHTED",
|
|
156
|
+
"hookType": "ExitFee",
|
|
157
|
+
"chainId": "11155111",
|
|
158
|
+
"blockNumber": "5955145",
|
|
159
|
+
"poolAddress": "0x03722034317d8fb16845213bd3ce15439f9ce136",
|
|
160
|
+
"tokens": [
|
|
161
|
+
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
162
|
+
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
|
|
163
|
+
],
|
|
164
|
+
"scalingFactors": [1000000000000000000, 1000000000000000000],
|
|
165
|
+
"weights": [500000000000000000, 500000000000000000],
|
|
166
|
+
"swapFee": 100000000000000000,
|
|
167
|
+
"balancesLiveScaled18": [5000000000000000, 5000000000000000000],
|
|
168
|
+
"tokenRates": [1000000000000000000, 1000000000000000000],
|
|
169
|
+
"totalSupply": 158113883008415798,
|
|
170
|
+
"aggregateSwapFee": 0,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
remove_liquidity_input = RemoveLiquidityInput(
|
|
174
|
+
pool="0x03722034317d8fb16845213bd3ce15439f9ce136",
|
|
175
|
+
min_amounts_out_raw=[1, 1],
|
|
176
|
+
max_bpt_amount_in_raw=10000000000000,
|
|
177
|
+
kind=RemoveLiquidityKind.PROPORTIONAL,
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
input_hook_state = {
|
|
181
|
+
'removeLiquidityHookFeePercentage': 0,
|
|
182
|
+
'tokens': pool['tokens'],
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
vault = Vault()
|
|
186
|
+
|
|
187
|
+
calculated_result = vault.remove_liquidity(
|
|
188
|
+
remove_liquidity_input,
|
|
189
|
+
pool,
|
|
190
|
+
hook_state=input_hook_state
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Building and Releasing
|
|
195
|
+
|
|
196
|
+
### Local Development
|
|
197
|
+
|
|
198
|
+
To build the package locally for testing:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
python build_and_release.py --all
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
This will:
|
|
205
|
+
- Clean previous build artifacts
|
|
206
|
+
- Install build dependencies
|
|
207
|
+
- Build the package
|
|
208
|
+
- Check the built package
|
|
209
|
+
|
|
210
|
+
### Releasing to PyPI
|
|
211
|
+
|
|
212
|
+
1. **Test Release** (recommended first):
|
|
213
|
+
```bash
|
|
214
|
+
python build_and_release.py --test-upload
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
2. **Production Release**:
|
|
218
|
+
```bash
|
|
219
|
+
python build_and_release.py --upload
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
**Note**: You'll need to have your PyPI credentials configured. You can set them up using:
|
|
223
|
+
```bash
|
|
224
|
+
pip install twine
|
|
225
|
+
twine configure
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Manual Build
|
|
229
|
+
|
|
230
|
+
If you prefer to build manually:
|
|
231
|
+
|
|
232
|
+
```bash
|
|
233
|
+
# Install build tools
|
|
234
|
+
pip install build twine
|
|
235
|
+
|
|
236
|
+
# Build the package
|
|
237
|
+
python -m build
|
|
238
|
+
|
|
239
|
+
# Check the package
|
|
240
|
+
twine check dist/*
|
|
241
|
+
|
|
242
|
+
# Upload to TestPyPI
|
|
243
|
+
twine upload --repository testpypi dist/*
|
|
244
|
+
|
|
245
|
+
# Upload to PyPI
|
|
246
|
+
twine upload dist/*
|
|
247
|
+
```
|
|
248
|
+
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# Balancer Maths Python
|
|
2
|
+
|
|
3
|
+
Python implementation of mathematics for Balancer v3
|
|
4
|
+
|
|
5
|
+
> **Note**: This is the Python implementation within the [balancer-maths](https://github.com/balancer/balancer-maths) monorepo, which also contains TypeScript and Rust implementations.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
### From PyPI (recommended)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install balancer-maths
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
### From source
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
git clone https://github.com/balancer/balancer-maths.git
|
|
19
|
+
cd balancer-maths/python
|
|
20
|
+
pip install -e .
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Development Setup
|
|
24
|
+
|
|
25
|
+
1. Create and activate a virtual environment:
|
|
26
|
+
```bash
|
|
27
|
+
python -m venv .venv
|
|
28
|
+
source .venv/bin/activate # On Windows use: .venv\Scripts\activate
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
2. Install development dependencies:
|
|
32
|
+
```bash
|
|
33
|
+
pip install -e ".[dev]"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Hooks Support
|
|
37
|
+
|
|
38
|
+
Hooks are supported on a case by case basis.
|
|
39
|
+
|
|
40
|
+
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](#remove-liquidity) below.
|
|
41
|
+
|
|
42
|
+
Currently supported hooks:
|
|
43
|
+
|
|
44
|
+
* ExitFeeHook
|
|
45
|
+
* This hook implements the ExitFeeHookExample found in [mono-repo](https://github.com/balancer/balancer-v3-monorepo/blob/c848c849cb44dc35f05d15858e4fba9f17e92d5e/pkg/pool-hooks/contracts/ExitFeeHookExample.sol)
|
|
46
|
+
|
|
47
|
+
## Examples
|
|
48
|
+
|
|
49
|
+
### Swap
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
from src.vault import Vault
|
|
53
|
+
from src.swap import SwapInput, SwapKind
|
|
54
|
+
|
|
55
|
+
pool = {
|
|
56
|
+
"poolType": "WEIGHTED",
|
|
57
|
+
"chainId": "11155111",
|
|
58
|
+
"blockNumber": "5955145",
|
|
59
|
+
"poolAddress": "0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
|
|
60
|
+
"tokens": [
|
|
61
|
+
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
62
|
+
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
|
|
63
|
+
],
|
|
64
|
+
"scalingFactors": [1000000000000000000, 1000000000000000000],
|
|
65
|
+
"weights": [500000000000000000, 500000000000000000],
|
|
66
|
+
"swapFee": 100000000000000000,
|
|
67
|
+
"balancesLiveScaled18": [2000000000000000000, 2000000000000000000],
|
|
68
|
+
"tokenRates": [1000000000000000000, 1000000000000000000],
|
|
69
|
+
"totalSupply": 1000000000000000000,
|
|
70
|
+
"aggregateSwapFee": 500000000000000000,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
swap_input = SwapInput(
|
|
75
|
+
amount_raw=100000000,
|
|
76
|
+
swap_kind=SwapKind.GIVENIN,
|
|
77
|
+
token_in=pool['tokens'][0],
|
|
78
|
+
token_out=pool['tokens'][1],
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
vault = Vault()
|
|
82
|
+
|
|
83
|
+
calculated_result = vault.swap(
|
|
84
|
+
swap_input,
|
|
85
|
+
pool,
|
|
86
|
+
)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Add Liquidity
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
from src.vault import Vault
|
|
93
|
+
from src.add_liquidity import AddLiquidityInput, AddLiquidityKind
|
|
94
|
+
|
|
95
|
+
pool = {
|
|
96
|
+
"poolType": "WEIGHTED",
|
|
97
|
+
"chainId": "11155111",
|
|
98
|
+
"blockNumber": "5955145",
|
|
99
|
+
"poolAddress": "0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
|
|
100
|
+
"tokens": [
|
|
101
|
+
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
102
|
+
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
|
|
103
|
+
],
|
|
104
|
+
"scalingFactors": [1000000000000000000, 1000000000000000000],
|
|
105
|
+
"weights": [500000000000000000, 500000000000000000],
|
|
106
|
+
"swapFee": 100000000000000000,
|
|
107
|
+
"balancesLiveScaled18": [2000000000000000000, 2000000000000000000],
|
|
108
|
+
"tokenRates": [1000000000000000000, 1000000000000000000],
|
|
109
|
+
"totalSupply": 1000000000000000000,
|
|
110
|
+
"aggregateSwapFee": 500000000000000000,
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
add_liquidity_input = AddLiquidityInput(
|
|
115
|
+
pool="0xb2456a6f51530053bc41b0ee700fe6a2c37282e8",
|
|
116
|
+
max_amounts_in_raw=[200000000000000000, 100000000000000000],
|
|
117
|
+
min_bpt_amount_out_raw=0,
|
|
118
|
+
kind=AddLiquidityKind.UNBALANCED,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
vault = Vault()
|
|
122
|
+
|
|
123
|
+
calculated_result = vault.add_liquidity(
|
|
124
|
+
add_liquidity_input,
|
|
125
|
+
pool,
|
|
126
|
+
)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Remove Liquidity
|
|
130
|
+
|
|
131
|
+
This example shows how to calculate the result of a remove liqudity operation when the pool is registered with the ExitFee hook.
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from src.vault import Vault
|
|
135
|
+
from src.remove_liquidity import RemoveLiquidityInput, RemoveLiquidityKind
|
|
136
|
+
|
|
137
|
+
pool = {
|
|
138
|
+
"poolType": "WEIGHTED",
|
|
139
|
+
"hookType": "ExitFee",
|
|
140
|
+
"chainId": "11155111",
|
|
141
|
+
"blockNumber": "5955145",
|
|
142
|
+
"poolAddress": "0x03722034317d8fb16845213bd3ce15439f9ce136",
|
|
143
|
+
"tokens": [
|
|
144
|
+
"0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9",
|
|
145
|
+
"0xb19382073c7A0aDdbb56Ac6AF1808Fa49e377B75",
|
|
146
|
+
],
|
|
147
|
+
"scalingFactors": [1000000000000000000, 1000000000000000000],
|
|
148
|
+
"weights": [500000000000000000, 500000000000000000],
|
|
149
|
+
"swapFee": 100000000000000000,
|
|
150
|
+
"balancesLiveScaled18": [5000000000000000, 5000000000000000000],
|
|
151
|
+
"tokenRates": [1000000000000000000, 1000000000000000000],
|
|
152
|
+
"totalSupply": 158113883008415798,
|
|
153
|
+
"aggregateSwapFee": 0,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
remove_liquidity_input = RemoveLiquidityInput(
|
|
157
|
+
pool="0x03722034317d8fb16845213bd3ce15439f9ce136",
|
|
158
|
+
min_amounts_out_raw=[1, 1],
|
|
159
|
+
max_bpt_amount_in_raw=10000000000000,
|
|
160
|
+
kind=RemoveLiquidityKind.PROPORTIONAL,
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
input_hook_state = {
|
|
164
|
+
'removeLiquidityHookFeePercentage': 0,
|
|
165
|
+
'tokens': pool['tokens'],
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
vault = Vault()
|
|
169
|
+
|
|
170
|
+
calculated_result = vault.remove_liquidity(
|
|
171
|
+
remove_liquidity_input,
|
|
172
|
+
pool,
|
|
173
|
+
hook_state=input_hook_state
|
|
174
|
+
)
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Building and Releasing
|
|
178
|
+
|
|
179
|
+
### Local Development
|
|
180
|
+
|
|
181
|
+
To build the package locally for testing:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
python build_and_release.py --all
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This will:
|
|
188
|
+
- Clean previous build artifacts
|
|
189
|
+
- Install build dependencies
|
|
190
|
+
- Build the package
|
|
191
|
+
- Check the built package
|
|
192
|
+
|
|
193
|
+
### Releasing to PyPI
|
|
194
|
+
|
|
195
|
+
1. **Test Release** (recommended first):
|
|
196
|
+
```bash
|
|
197
|
+
python build_and_release.py --test-upload
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
2. **Production Release**:
|
|
201
|
+
```bash
|
|
202
|
+
python build_and_release.py --upload
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
**Note**: You'll need to have your PyPI credentials configured. You can set them up using:
|
|
206
|
+
```bash
|
|
207
|
+
pip install twine
|
|
208
|
+
twine configure
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### Manual Build
|
|
212
|
+
|
|
213
|
+
If you prefer to build manually:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Install build tools
|
|
217
|
+
pip install build twine
|
|
218
|
+
|
|
219
|
+
# Build the package
|
|
220
|
+
python -m build
|
|
221
|
+
|
|
222
|
+
# Check the package
|
|
223
|
+
twine check dist/*
|
|
224
|
+
|
|
225
|
+
# Upload to TestPyPI
|
|
226
|
+
twine upload --repository testpypi dist/*
|
|
227
|
+
|
|
228
|
+
# Upload to PyPI
|
|
229
|
+
twine upload dist/*
|
|
230
|
+
```
|
|
231
|
+
|