Skip to content

Commit

Permalink
Merge pull request #307 from BalancerMaxis/add_rate_providers
Browse files Browse the repository at this point in the history
V0.9.5: Create rate provider class and add rate providers to bal_addresses
  • Loading branch information
gosuto-inzasheru authored May 23, 2024
2 parents b001357 + 5bc4f45 commit 9b2c72d
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
2 changes: 2 additions & 0 deletions bal_addresses/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@
ChecksumError,
UnexpectedListLengthError,
)

from .rate_providers import RateProviders
32 changes: 31 additions & 1 deletion bal_addresses/addresses.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
from .errors import MultipleMatchesError, NoResultError
from typing import Dict
from typing import Optional

from .rate_providers import RateProviders
import requests
from munch import Munch
from web3 import Web3
from collections import defaultdict

from .utils import to_checksum_address

Expand Down Expand Up @@ -68,6 +69,7 @@ def __init__(self, chain, jsonfile=False):
self._pools = None
self._gauges = None
self._root_gauges = None
self._rate_providers = None

@property
def deployments(self) -> Optional[Munch]:
Expand Down Expand Up @@ -146,6 +148,17 @@ def root_gauges(self) -> Optional[Munch]:
self.populate_root_gauges()
return self._root_gauges

@property
def rate_providers(self) -> Optional[Munch]:
"""
Get the rate_providers for all chains in a form of a Munch object
"""
if self._rate_providers is not None:
return self._rate_providers
else:
self.process_rate_providers()
return self._rate_providers

def populate_deployments(self) -> None:
chain_deployments = requests.get(
f"{GITHUB_DEPLOYMENTS_RAW}/addresses/{self.chain}.json"
Expand Down Expand Up @@ -256,6 +269,21 @@ def populate_root_gauges(self) -> None:
else:
self._root_gauges = Munch.fromDict({})

def process_rate_providers(self) -> Optional[Munch]:
"""
Parse rate_providers into an addressbook style munch
"""
rate_providers = defaultdict(dict)
r = RateProviders(self.chain)
for rate_provider, infodict in r.info_by_rate_provider.items():
name = infodict.get("name")
summary = infodict.get("summary")
token_address = infodict.get("asset")
## create a nested dict with name/summary/token_address as keys and rate_provider as value
rate_providers[summary] = {name: {token_address: rate_provider}}
self._rate_providers = Munch.fromDict(rate_providers)
return self._rate_providers

def search_unique(self, substr):
results = [s for s in self.flatbook.keys() if substr in s]
if len(results) > 1:
Expand Down Expand Up @@ -344,6 +372,7 @@ def generate_flatbook(self):
self.populate_gauges()
self.populate_root_gauges()
self.populate_extras()
self.process_rate_providers()
# write pools and gauges first, so they get overwritten by deployments later
# deployment label should take precedence over pool/gauge label
flatbook["pools"] = self.flatten_dict(self.pools)
Expand All @@ -355,6 +384,7 @@ def generate_flatbook(self):
flatbook = {**flatbook, **self.flatten_dict(self.extras)}
flatbook["multisigs"] = self.flatten_dict(self.multisigs)
flatbook["EOA"] = self.flatten_dict(self.EOAs)
flatbook["rate_providers"] = self.flatten_dict(self.rate_providers)
return self.flatten_dict(flatbook)


Expand Down
64 changes: 64 additions & 0 deletions bal_addresses/rate_providers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import json
import os.path
from .errors import MultipleMatchesError, NoResultError
from typing import Dict
from typing import Optional
import requests
from munch import Munch
from web3 import Web3

from .utils import to_checksum_address


GITHUB_CODEREVIEW_RAW = "https://raw.githubusercontent.com/balancer/code-review/main"
GITHUB_CODEREVIEW_NICE = "https://github.com/balancer/code-review/blob/main"


class RateProviders:

source_data = requests.get(
f"{GITHUB_CODEREVIEW_RAW}/rate-providers/registry.json"
).json()
SUPPORTED_CHAINS = source_data.keys()

def __init__(self, chain):
self.chain = "ethereum" if chain == "mainnet" else chain
if self.chain not in self.SUPPORTED_CHAINS:
print(f"WARNING: Chain {self.chain} has no reviewed rate providers")
self.info_by_rate_provider = {}
self.rate_providers_by_token = {}
else:
self.info_by_rate_provider = Munch(self.source_data.get(self.chain, {}))
self.rate_providers_by_token = Munch(
self.translate_source_data(self.info_by_rate_provider)
)

def get_review_for_safe_rate_provder(self, token_address) -> Optional[str]:
"""
Check if the token has a safe rate provider and return the link to the review.
return None if there is no safe rate provider found.
"""
token_info = self.rate_providers_by_token.get(
to_checksum_address(token_address)
)
if token_info and token_info.is_safe:
return token_info.review_link
return None

def translate_source_data(self, chain_data):
"""
Translate the source data into a more usable format
"""
translated_data = {}
for provider, infodict in chain_data.items():
token_address = to_checksum_address(infodict["asset"])
this = translated_data[token_address] = Munch({})
this.rate_provider = to_checksum_address(provider)
this.name = infodict.get("name")
this.is_safe = infodict.get("summary") == "safe"
this.warnings = infodict.get("warnings")
this.factory = infodict.get("factory")
this.review_link = infodict.get("review").replace(
"./", f"{GITHUB_CODEREVIEW_NICE}/rate-providers/"
)
return translated_data
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from setuptools import setup, find_packages

VERSION = "0.9.3"
VERSION = "0.9.5"
DESCRIPTION = "Balancer Maxi Addressbook"
LONG_DESCRIPTION = "Balancer Maxi Addressbook and Balancer Permissions helper"

Expand Down

0 comments on commit 9b2c72d

Please sign in to comment.