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.
Files changed (94) hide show
  1. balancer_maths-0.1.1/.gitignore +99 -0
  2. balancer_maths-0.1.1/.pylintrc +5 -0
  3. balancer_maths-0.1.1/.vscode/launch.json +25 -0
  4. balancer_maths-0.1.1/.vscode/settings.json +11 -0
  5. balancer_maths-0.1.1/LICENSE +21 -0
  6. balancer_maths-0.1.1/MANIFEST.in +12 -0
  7. balancer_maths-0.1.1/PKG-INFO +248 -0
  8. balancer_maths-0.1.1/README.md +231 -0
  9. balancer_maths-0.1.1/RELEASE_GUIDE.md +166 -0
  10. balancer_maths-0.1.1/build_and_release.py +106 -0
  11. balancer_maths-0.1.1/pyproject.toml +50 -0
  12. balancer_maths-0.1.1/src/__init__.py +60 -0
  13. balancer_maths-0.1.1/src/common/__init__.py +0 -0
  14. balancer_maths-0.1.1/src/common/base_pool_math.py +382 -0
  15. balancer_maths-0.1.1/src/common/base_pool_state.py +17 -0
  16. balancer_maths-0.1.1/src/common/bigint.py +108 -0
  17. balancer_maths-0.1.1/src/common/constants.py +5 -0
  18. balancer_maths-0.1.1/src/common/log_exp_math.py +423 -0
  19. balancer_maths-0.1.1/src/common/maths.py +98 -0
  20. balancer_maths-0.1.1/src/common/oz_math.py +53 -0
  21. balancer_maths-0.1.1/src/common/pool_base.py +33 -0
  22. balancer_maths-0.1.1/src/common/swap_params.py +13 -0
  23. balancer_maths-0.1.1/src/common/types.py +80 -0
  24. balancer_maths-0.1.1/src/common/utils.py +124 -0
  25. balancer_maths-0.1.1/src/hooks/__init__.py +0 -0
  26. balancer_maths-0.1.1/src/hooks/default_hook.py +95 -0
  27. balancer_maths-0.1.1/src/hooks/exit_fee/exit_fee_hook.py +63 -0
  28. balancer_maths-0.1.1/src/hooks/exit_fee/types.py +8 -0
  29. balancer_maths-0.1.1/src/hooks/stable_surge/stable_surge_hook.py +100 -0
  30. balancer_maths-0.1.1/src/hooks/stable_surge/types.py +17 -0
  31. balancer_maths-0.1.1/src/hooks/types.py +140 -0
  32. balancer_maths-0.1.1/src/pools/__init__.py +3 -0
  33. balancer_maths-0.1.1/src/pools/buffer/__init__.py +0 -0
  34. balancer_maths-0.1.1/src/pools/buffer/buffer_data.py +23 -0
  35. balancer_maths-0.1.1/src/pools/buffer/buffer_math.py +47 -0
  36. balancer_maths-0.1.1/src/pools/buffer/enums.py +6 -0
  37. balancer_maths-0.1.1/src/pools/buffer/erc4626_buffer_wrap_or_unwrap.py +28 -0
  38. balancer_maths-0.1.1/src/pools/gyro/__init__.py +0 -0
  39. balancer_maths-0.1.1/src/pools/gyro/gyro_2clp.py +213 -0
  40. balancer_maths-0.1.1/src/pools/gyro/gyro_2clp_data.py +53 -0
  41. balancer_maths-0.1.1/src/pools/gyro/gyro_2clp_math.py +310 -0
  42. balancer_maths-0.1.1/src/pools/gyro/gyro_eclp.py +129 -0
  43. balancer_maths-0.1.1/src/pools/gyro/gyro_eclp_data.py +76 -0
  44. balancer_maths-0.1.1/src/pools/gyro/gyro_eclp_math.py +809 -0
  45. balancer_maths-0.1.1/src/pools/gyro/gyro_pool_math.py +101 -0
  46. balancer_maths-0.1.1/src/pools/gyro/signed_fixed_point.py +234 -0
  47. balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/__init__.py +0 -0
  48. balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/liquidity_bootstrapping.py +41 -0
  49. balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/liquidity_bootstrapping_data.py +66 -0
  50. balancer_maths-0.1.1/src/pools/liquidity_bootstrapping/liquidity_bootstrapping_math.py +64 -0
  51. balancer_maths-0.1.1/src/pools/quantamm/__init__.py +3 -0
  52. balancer_maths-0.1.1/src/pools/quantamm/quantamm.py +206 -0
  53. balancer_maths-0.1.1/src/pools/quantamm/quantamm_data.py +78 -0
  54. balancer_maths-0.1.1/src/pools/quantamm/quantamm_math.py +81 -0
  55. balancer_maths-0.1.1/src/pools/reclamm/__init__.py +3 -0
  56. balancer_maths-0.1.1/src/pools/reclamm/reclamm.py +88 -0
  57. balancer_maths-0.1.1/src/pools/reclamm/reclamm_data.py +66 -0
  58. balancer_maths-0.1.1/src/pools/reclamm/reclamm_math.py +463 -0
  59. balancer_maths-0.1.1/src/pools/reclamm_v2/__init__.py +0 -0
  60. balancer_maths-0.1.1/src/pools/reclamm_v2/reclamm_v2.py +88 -0
  61. balancer_maths-0.1.1/src/pools/reclamm_v2/reclamm_v2_data.py +66 -0
  62. balancer_maths-0.1.1/src/pools/reclamm_v2/reclamm_v2_math.py +541 -0
  63. balancer_maths-0.1.1/src/pools/stable/__init__.py +3 -0
  64. balancer_maths-0.1.1/src/pools/stable/stable.py +75 -0
  65. balancer_maths-0.1.1/src/pools/stable/stable_data.py +50 -0
  66. balancer_maths-0.1.1/src/pools/stable/stable_math.py +191 -0
  67. balancer_maths-0.1.1/src/pools/weighted/__init__.py +3 -0
  68. balancer_maths-0.1.1/src/pools/weighted/weighted.py +65 -0
  69. balancer_maths-0.1.1/src/pools/weighted/weighted_data.py +48 -0
  70. balancer_maths-0.1.1/src/pools/weighted/weighted_math.py +148 -0
  71. balancer_maths-0.1.1/src/vault/__init__.py +0 -0
  72. balancer_maths-0.1.1/src/vault/add_liquidity.py +148 -0
  73. balancer_maths-0.1.1/src/vault/remove_liquidity.py +169 -0
  74. balancer_maths-0.1.1/src/vault/swap.py +236 -0
  75. balancer_maths-0.1.1/src/vault/vault.py +123 -0
  76. balancer_maths-0.1.1/test/__init__.py +0 -0
  77. balancer_maths-0.1.1/test/hooks/test_after_add_liquidity.py +139 -0
  78. balancer_maths-0.1.1/test/hooks/test_after_remove_liquidity.py +174 -0
  79. balancer_maths-0.1.1/test/hooks/test_after_swap.py +168 -0
  80. balancer_maths-0.1.1/test/hooks/test_before_add_liquidity.py +105 -0
  81. balancer_maths-0.1.1/test/hooks/test_before_remove_liquidity.py +137 -0
  82. balancer_maths-0.1.1/test/hooks/test_before_swap.py +95 -0
  83. balancer_maths-0.1.1/test/hooks/test_exit_fee.py +73 -0
  84. balancer_maths-0.1.1/test/hooks/test_hook.py +76 -0
  85. balancer_maths-0.1.1/test/hooks/test_stable_surge.py +73 -0
  86. balancer_maths-0.1.1/test/test_add_liquidity.py +34 -0
  87. balancer_maths-0.1.1/test/test_custom_pool.py +114 -0
  88. balancer_maths-0.1.1/test/test_reclamm.py +65 -0
  89. balancer_maths-0.1.1/test/test_remove_liquidity.py +34 -0
  90. balancer_maths-0.1.1/test/test_swaps.py +48 -0
  91. balancer_maths-0.1.1/test/utils/__init__.py +0 -0
  92. balancer_maths-0.1.1/test/utils/default_pool.py +32 -0
  93. balancer_maths-0.1.1/test/utils/map_pool_state.py +56 -0
  94. 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,5 @@
1
+ [MASTER]
2
+ init-hook='import sys; sys.path.append("src")'
3
+
4
+ [MESSAGES CONTROL]
5
+ disable=missing-module-docstring, missing-function-docstring, missing-class-docstring, too-few-public-methods, line-too-long
@@ -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
+