GithubHelp home page GithubHelp logo

balancer / balpy Goto Github PK

View Code? Open in Web Editor NEW
64.0 5.0 47.0 10.27 MB

Tools for interacting with Balancer Protocol V2 in Python.

License: GNU General Public License v3.0

Python 96.19% Jupyter Notebook 3.52% Shell 0.29%

balpy's Introduction

balpy

balpy

Python tools for interacting with Balancer Protocol V2 in Python.

DISCLAIMER: While balpy is intended to be a useful tool to simplify interacting with Balancer V2 Smart Contracts, this package is an ALPHA-build and should be considered as such. Use at your own risk! This package is capable of sending Ethereum (or EVM compatible) tokens controlled by whatever private key you provide. User assumes all liability for using this software; contributors to this package are not liable for any undesirable results. Users are STRONGLY encouraged to experiment with this package on testnets before using it on mainnet with valuable assets.

Usage

balpy has been tested on:

  • MacOS using Python 3.9.0
  • Linux using Python 3.9-dev
  • Windows using Python 3.9.5

Install

Install from PiP

Local installation of the latest balpy release can be done simply using:

pip install balpy

However, for reliability and isolation, we recommend creating a package through poetry

# If you do not have poetry installed, install it using the following commands:
# pip install poetry
poetry new package-name
cd package-name
poetry add balpy

See release on PyPI: https://pypi.org/project/balpy/

Install from source

# Install in virtual environment using poetry
git clone https://github.com/balancer-labs/balpy.git
cd balpy
poetry install # Install dependencies and package
# You can enter the virtual environment using
poetry shell
# You can run a file using the environment
poetry run ./samples/misc/vaultWethRead.py

Locally building wheels

You can also create a wheel (.whl) file to build the library for platform-specific distribution

git clone https://github.com/balancer-labs/balpy.git
cd balpy
poetry build
# You can find the wheels here
cd dist/
# Wheel name will depend on version
pip install ./balpy-X.X.X.whl

Environment Variables

You must set these two environment variables in order to use the balpy module

  • KEY_API_ETHERSCAN: API key for Etherscan for gas prices
  • KEY_PRIVATE: Plain text private key for signing transactions

You also must set AT LEAST one of these environment variables to connect to the network

  • KEY_API_INFURA: API key for Infura for sending transactions
  • BALPY_CUSTOM_RPC: Custom RPC URL (like localhost or Polygon RPC)

Samples

See README.md in samples/ for more information.

balpy's People

Contributors

0xspraggins avatar danielmkm avatar elnilz avatar endymionjkb avatar gerrrg avatar kumar-ish avatar mitpitt avatar officialnico avatar rabmarut avatar ribeirojose avatar scooprinder avatar wewecalibrate avatar yvesfracari avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

balpy's Issues

getPools fails

$python samples/theGraph/getPools.py

Usage: python samples/theGraph/getPools.py <network>
No network given; defaulting to mainnet Ethereum
Querying number of pools...
Got response from the Subgraph
Querying 953 pools...
Querying pools # 0 through # 5 ...
Got pools.
Querying tokens for pool with ID: 0x0017c363b29d8f86d82e9681552685f68f34b7e4000200000000000000000209
Traceback (most recent call last):
  File "/home/ygg/Workspace/Forks/balpy/samples/theGraph/getPools.py", line 33, in <module>
    main();
  File "/home/ygg/Workspace/Forks/balpy/samples/theGraph/getPools.py", line 29, in main
    pools = bg.getV2Pools(batch_size, verbose=verbose)
  File "/home/ygg/Workspace/Forks/balpy/balpy/graph/graph.py", line 190, in getV2Pools
    curr_pool_token_data = self.getPoolTokens(curr_id, verbose=verbose);
  File "/home/ygg/Workspace/Forks/balpy/balpy/graph/graph.py", line 111, in getPoolTokens
    response = self.client.execute(gql(formatted_query_string))
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/gql/client.py", line 78, in execute
    raise Exception(str(result.errors[0]))
Exception: {'locations': [{'column': 5, 'line': 12}], 'message': 'Type `PoolToken` has no field `invested`'}

Add Single Swaps

A relatively easy addition would be pure single swaps (currently it can only do a one-swap BatchSwap; I actually already have code for this that should be trivial to integrate, it's just not in balpy itself yet [https://github.com/gerrrg/balancer-tutorials/blob/master/python/swaps/single_swap.py ])

The type checks in these two lines of Python can probably be removed.

if(not isinstance(weights[key],Decimal)):

https://github.com/balancer/balpy/blob/77d787a06b147aab40c0d08d22af11846b5e989b/balpy/balancerv2cad/src/balancerv2cad/WeightedPool.py#L46C16-L46C16

If the user of the library wants to ensure that the input integers do not lose precision, they must pass in a string of a floating-point number to trigger the logic of factory_fees.update. This approach is quite unintuitive, as externally one could directly pass in a Decimal data

Make use of web3py gas strategies

Web3.py does have a gas_strategies sub-package that I haven't looked at yet. Could be a better system to use instead of querying Etherscan.

Fails to run on Kovan, Goerli, Mainnet

Kovan is deprecated and no longer supported by infura.

I tried running the following:

python3 samples/poolCreation/poolCreationSample.py samples/poolCreation/sampleLBPool.json

on both mainnet and goerli. I get the following error:

Missing contracts on mainnet: [ChildChainStreamer, ChildChainLiquidityGaugeFactory]

==============================================================

==============================================================
================ Step 1: Check Token Balances ================
==============================================================

Traceback (most recent call last):
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/web3/contract.py", line 1507, in call_contract_function
    output_data = web3.codec.decode_abi(output_types, return_data)
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_abi/codec.py", line 181, in decode_abi
    return decoder(stream)
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_abi/decoding.py", line 127, in __call__
    return self.decode(stream)
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_utils/functional.py", line 45, in inner
    return callback(fn(*args, **kwargs))
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_abi/decoding.py", line 173, in decode
    yield decoder(stream)
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_abi/decoding.py", line 127, in __call__
    return self.decode(stream)
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_abi/decoding.py", line 198, in decode
    raw_data = self.read_data_from_stream(stream)
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/eth_abi/decoding.py", line 305, in read_data_from_stream
    raise InsufficientDataBytes(
eth_abi.exceptions.InsufficientDataBytes: Tried to read 32 bytes.  Only got 0 bytes

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/ygg/Workspace/Forks/balpy/samples/poolCreation/poolCreationSample.py", line 112, in <module>
    main();
  File "/home/ygg/Workspace/Forks/balpy/samples/poolCreation/poolCreationSample.py", line 39, in main
    if not bal.erc20HasSufficientBalances(tokens, initialBalances):
  File "/home/ygg/Workspace/Forks/balpy/balpy/balpy.py", line 618, in erc20HasSufficientBalances
    currentHasSufficientBalance = self.erc20HasSufficientBalance(token, amount);
  File "/home/ygg/Workspace/Forks/balpy/balpy/balpy.py", line 595, in erc20HasSufficientBalance
    balance = self.erc20GetBalanceStandard(tokenAddress);
  File "/home/ygg/Workspace/Forks/balpy/balpy/balpy.py", line 564, in erc20GetBalanceStandard
    decimals = self.erc20GetDecimals(tokenAddress);
  File "/home/ygg/Workspace/Forks/balpy/balpy/balpy.py", line 557, in erc20GetDecimals
    decimals = token.functions.decimals().call();
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/web3/contract.py", line 954, in call
    return call_contract_function(
  File "/home/ygg/.cache/pypoetry/virtualenvs/balpy-yyw1STJO-py3.10/lib/python3.10/site-packages/web3/contract.py", line 1528, in call_contract_function
    raise BadFunctionCallOutput(msg) from e
web3.exceptions.BadFunctionCallOutput: Could not transact with/call contract function, is contract deployed correctly and chain synced?

Allow passing of keys/RPC URLs as initialization arguments

Currently, the following arguments must be set as environment variables:

  • KEY_API_ETHERSCAN
  • KEY_API_INFURA
  • KEY_PRIVATE
  • BALPY_CUSTOM_RPC

While this functionality is useful, it can also be tedious for specific use cases. For example, scripts that might want to query/execute items on different networks need to automatically set environment variables. While this is possible, it would be cleaner to allow passing these as constructors args.

exitPool

Hey,

Thank you for this repo, helps a bit understand how to interact with BAL contracts, which tbh aren't that straightforward to work with...
One thing i'm trying to do is remove some tokens from one of the pools... And I've used the code you provided here to figure out the userDataEncoded part

    		userDataEncoded = eth_abi.encode_abi(['uint256', 'uint256[]'],[2,[amountOut,0]])

    		txPrep = self.balancerContract.functions.exitPool(poolId=self.bs["poolId"],
                                                        sender=self.pid["address"],
                                                        recipient=self.pid["address"],
                                                        request={'assets':[self.bs["assets"]["bal"],
                                                                           self.bs["assets"]["weth"]],
                                                                 'minAmountsOut':[amountOut,0],
                                                                 'userData': userDataEncoded.hex(),
                                                                 'toInternalBalance':False})

tbh I am not sure how to proceed, if I need to get one sided 0.002 BAL tokens out of the WETH/BAL pool , wouldn't amountOut need to be int(2e15)
Or is there some other configuration. Also would the joinKind be 2 in this case?

Tried to hit it on chain and it did give back an error BAL#207
https://etherscan.io/tx/0x2d9c272484255bd7d7fdaaac069634704c0442191ead43c392895e9d5b0b6b83

Tests

There are no tests written for this library. That seems dangerous. I would be happy to start contributing tests. I'm still trying to get a sample running.

Getting price of swap before doing a swap.

Sorry, just getting started to connect Balancer to my Python trading program.
Could you direct me how to see the price of a swap before I do it?
I have a hard time finding docs on that.

Add pool exits

Currently the library does not support pool exits, which would be a nice addition! The code for joins should be relatively similar, so looking at those could be a good starting point

Integrate Liquidity mining claims contracts

If you're looking for something more intense, it would be cool to have claiming from the MerkleRedeem contract (and eventually the proper staking contracts once those are live)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.