Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove bal_addresses deps #70

Merged
merged 4 commits into from
Jan 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions bal_tools/drpc.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from web3 import Web3
from bal_addresses import AddrBook

DRPC_NAME_OVERRIDES = {
"mainnet": "ethereum",
"zkevm": "polygon-zkevm",
}


class Web3RpcByChain:
def __init__(self, DRPC_KEY):
self.DRPC_KEY = DRPC_KEY
Expand Down Expand Up @@ -41,16 +41,25 @@ def values(self):
def items(self):
return self._w3_by_chain.items()


class Web3Rpc:
def __init__(self, chain, DRPC_KEY):
drpc_chain = DRPC_NAME_OVERRIDES.get(chain, chain)
self.w3 = Web3(Web3.HTTPProvider(f"https://lb.drpc.org/ogrpc?network={drpc_chain}&dkey={DRPC_KEY}"))
self.w3 = Web3(
Web3.HTTPProvider(
f"https://lb.drpc.org/ogrpc?network={drpc_chain}&dkey={DRPC_KEY}"
)
)
if not self.w3.is_connected():
raise ConnectionError(f"Unable to connect to {drpc_chain} network with provided DRPC_KEY.")
raise ConnectionError(
f"Unable to connect to {drpc_chain} network with provided DRPC_KEY."
)
try:
self.w3.eth.block_number
except Exception as e:
raise ConnectionError(f"Error fetching latest block number: {e}, chain: {chain}, url: {self.w3.provider.endpoint_uri}")
raise ConnectionError(
f"Error fetching latest block number: {e}, chain: {chain}, url: {self.w3.provider.endpoint_uri}"
)

def __getattr__(self, name):
return getattr(self.w3, name)
2 changes: 0 additions & 2 deletions bal_tools/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,3 @@ gql[requests]
python-dotenv
pydantic==2.7.4
json-fix

git+https://github.com/BalancerMaxis/[email protected]
5 changes: 1 addition & 4 deletions bal_tools/safe_tx_builder/safe_contract.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(
self.tx_builder = SafeTxBuilder()
if not self.tx_builder._initialized:
raise RuntimeError("SafeTxBuilder must be initialized before using SafeContract")
self.address = self.tx_builder._resolve_address(address)
self.address = address
self.abi = self._load_abi(abi, abi_file_path)

def __getattr__(self, attribute):
Expand Down Expand Up @@ -71,9 +71,6 @@ def call_function(self, func: ABIFunction, args: tuple, kwargs: dict = {}):
tx.contractInputsValues = None # type: ignore

for arg, input_type in zip(args, func.inputs):
if input_type.type == "address":
arg = self.tx_builder._resolve_address(arg)

input_template = self.tx_builder.load_template(TemplateType.INPUT_TYPE)
input_template.name = input_type.name
input_template.type = input_type.type
Expand Down
29 changes: 10 additions & 19 deletions bal_tools/safe_tx_builder/safe_tx_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@
from datetime import datetime, timezone
import os

from bal_addresses import AddrBook

from .models import *
from ..utils import is_address
from ..utils import is_address, chain_ids_by_name


class SafeTxBuilder:
Expand All @@ -23,17 +21,17 @@ def __new__(
if cls._instance is None:
cls._instance = super(SafeTxBuilder, cls).__new__(cls)
cls._instance._initialized = False

if safe_address is not None or cls._last_config is None:
cls._last_config = {
'safe_address': safe_address,
'chain_name': chain_name,
'version': version,
'timestamp': timestamp,
'tx_builder_version': tx_builder_version
"safe_address": safe_address,
"chain_name": chain_name,
"version": version,
"timestamp": timestamp,
"tx_builder_version": tx_builder_version,
}
cls._instance._initialize(**cls._last_config)

return cls._instance

def _initialize(
Expand All @@ -45,9 +43,8 @@ def _initialize(
tx_builder_version: str,
):
self.chain_name = chain_name
self.chain_id = str(AddrBook.chain_ids_by_name[chain_name])
self.addr_book = AddrBook(AddrBook.chain_names_by_id[int(self.chain_id)]).flatbook
self.safe_address = self._resolve_address(safe_address)
self.chain_id = str(chain_ids_by_name()[chain_name])
self.safe_address = safe_address
self.version = version
self.timestamp = timestamp if timestamp else datetime.now(timezone.utc)
self.tx_builder_version = tx_builder_version
Expand All @@ -68,12 +65,6 @@ def load_template(

return model.model_validate_json(file_content)

def _resolve_address(self, identifier: str) -> str:
if is_address(identifier):
return identifier

return self.addr_book[identifier]

def _load_payload_metadata(self):
self.base_payload.version = self.version
self.base_payload.chainId = self.chain_id
Expand Down
5 changes: 2 additions & 3 deletions bal_tools/subgraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
from gql import Client, gql
from gql.transport.requests import RequestsHTTPTransport
from web3 import Web3
from bal_addresses import AddrBook

from typing import Union, List, Callable, Dict
from .utils import get_abi, flatten_nested_dict
from .utils import get_abi, flatten_nested_dict, chain_ids_by_name
from .models import *
from .errors import NoPricesFoundError

Expand All @@ -35,7 +34,7 @@

class Subgraph:
def __init__(self, chain: str = "mainnet", silence_warnings: bool = False):
if chain not in AddrBook.chain_ids_by_name.keys():
if chain not in chain_ids_by_name().keys():
raise ValueError(f"Invalid chain: {chain}")
self.chain = chain
self.subgraph_url = {}
Expand Down
11 changes: 9 additions & 2 deletions bal_tools/utils.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
from web3 import Web3
from typing import Union, List, Dict
import json
import os
from importlib.resources import files

import requests


### These functions are to deal with differing web3 versions and the need to use 5.x for legacy brownie code
def to_checksum_address(address: str):
Expand All @@ -30,7 +31,13 @@ def flatten_nested_dict(d):
result = d.copy()
for key, value in list(result.items()):
if isinstance(value, dict):
if key not in ['dynamicData', 'staking']:
if key not in ["dynamicData", "staking"]:
result.pop(key)
result.update(value)
return result


def chain_ids_by_name():
chains_raw = "https://raw.githubusercontent.com/BalancerMaxis/bal_addresses/main/extras/chains.json"
chains = requests.get(chains_raw).json()
return chains["CHAIN_IDS_BY_NAME"]
24 changes: 5 additions & 19 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,20 @@
import json
import os

from bal_addresses import AddrBook
from bal_tools.pools_gauges import BalPoolsGauges
from bal_tools.subgraph import Subgraph
from bal_tools.ecosystem import Aura
from bal_tools.safe_tx_builder import SafeTxBuilder
from bal_tools.utils import chain_ids_by_name

from web3 import Web3
from dotenv import load_dotenv


load_dotenv()

exempt_chains = ["fantom", "goerli"]
chains = [
chain
for chain in list(AddrBook.chains["CHAIN_IDS_BY_NAME"])
if chain not in exempt_chains
]
exempt_chains = ["fantom", "goerli", "sonic"]
chains = [chain for chain in list(chain_ids_by_name()) if chain not in exempt_chains]


@pytest.fixture(scope="module")
Expand Down Expand Up @@ -54,18 +50,8 @@ def aura(chain):


@pytest.fixture(scope="module")
def addr_book():
return AddrBook("mainnet").flatbook


@pytest.fixture(scope="module")
def msig_name():
return "multisigs/maxi_omni"


@pytest.fixture(scope="module")
def safe_tx_builder(msig_name) -> SafeTxBuilder:
return SafeTxBuilder(msig_name)
def safe_tx_builder() -> SafeTxBuilder:
return SafeTxBuilder("0x10A19e7eE7d7F8a52822f6817de8ea18204F2e4f")


@pytest.fixture(scope="module")
Expand Down
20 changes: 9 additions & 11 deletions tests/test_safe_tx_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,25 @@
def test_safe_contract(
safe_tx_builder: SafeTxBuilder,
erc20_abi,
bribe_market_abi,
addr_book,
msig_name,
bribe_market_abi
):
usdc_address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
bribe_market_address = "0x45Bc37b18E73A42A4a826357a8348cDC042cCBBc"

usdc = SafeContract("tokens/USDC", erc20_abi)
usdc = SafeContract(usdc_address, erc20_abi)
usdc.approve(bribe_market_address, 100e18)

bribe_market = SafeContract(bribe_market_address, bribe_market_abi)
bribe_market.depositBribe(
"0x0000000000000000000000000000000000000000000000000000000000000000",
"tokens/USDC",
usdc_address,
1e18,
0,
2,
)

payload = safe_tx_builder.output_payload("tests/payload_outputs/bribe.json")

assert safe_tx_builder.safe_address == addr_book[msig_name]

assert payload.transactions[0].to == usdc_address
assert payload.transactions[0].contractMethod.name == "approve"
assert payload.transactions[0].contractMethod.inputs[0].type == "address"
Expand Down Expand Up @@ -57,10 +53,12 @@ def test_safe_contract(


def test_multiple_functions_with_same_name(bridge_abi):
builder = SafeTxBuilder("multisigs/dao")
usdc_address = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
dao_msig = "0x10A19e7eE7d7F8a52822f6817de8ea18204F2e4f"
builder = SafeTxBuilder(dao_msig)
bridge = SafeContract("0x88ad09518695c6c3712AC10a214bE5109a655671", bridge_abi)

bridge.relayTokens("tokens/USDC", "multisigs/dao", int(1e18))
bridge.relayTokens("tokens/USDC", int(1e18))
bridge.relayTokens(usdc_address, dao_msig, int(1e18))
bridge.relayTokens(usdc_address, int(1e18))

builder.output_payload("tests/payload_outputs/multiple_names.json")
Loading