Skip to content

Commit

Permalink
feat: balancer
Browse files Browse the repository at this point in the history
  • Loading branch information
wavey0x committed Dec 28, 2022
1 parent 6665de6 commit 489a481
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 46 deletions.
46 changes: 0 additions & 46 deletions yearn/prices/balancer.py

This file was deleted.

26 changes: 26 additions & 0 deletions yearn/prices/balancer/balancer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import logging
from typing import Optional, Union
from yearn.prices.balancer.v1 import BalancerV1, balancer_v1
from yearn.prices.balancer.v2 import BalancerV2, balancer_v2
from yearn.typing import Address

logger = logging.getLogger(__name__)

BALANCERS = {
"v1": balancer_v1,
"v2": balancer_v2
}
class BalancerSelector:
def __init__(self) -> None:
self.balancers = {
version: balancer for version, balancer in BALANCERS.items() if balancer
}

def get_balancer_for_pool(self, address: Address) -> Optional[Union[BalancerV1, BalancerV2]]:
for b in BALANCERS.values():
if b and b.is_balancer_pool(address):
return b

return None

selector = BalancerSelector()
Empty file added yearn/prices/balancer/v1.py
Empty file.
56 changes: 56 additions & 0 deletions yearn/prices/balancer/v2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from typing import Any, Literal, Optional, List
from brownie import chain
from cachetools.func import ttl_cache

from yearn.cache import memory
from yearn.multicall2 import fetch_multicall
from yearn.prices import magic
from yearn.utils import contract, Singleton
from yearn.networks import Network
from yearn.typing import Address, Block
from yearn.exceptions import UnsupportedNetwork

networks = [ Network.Mainnet ]

@memory.cache()
def is_balancer_pool_cached(address: Address) -> bool:
pool = contract(address)
required = {"getVault", "getPoolId", "totalSupply"}
return required.issubset(set(pool.__dict__))

class BalancerV2(metaclass=Singleton):
def __init__(self) -> None:
if chain.id not in networks:
raise UnsupportedNetwork('Balancer is not supported on this network')

def __contains__(self, token: Any) -> Literal[False]:
return False

def is_balancer_pool(self, address: Address) -> bool:
return is_balancer_pool_cached(address)

def get_version(self) -> str:
return "v2"

def get_tokens(self, token: Address, block: Optional[Block] = None) -> List:
pool = contract(token)
pool_id = pool.getPoolId()
vault = contract(pool.getVault())
return vault.getPoolTokens(pool_id, block_identifier=block)[0]

@ttl_cache(ttl=600)
def get_price(self, token: Address, block: Optional[Block] = None) -> float:
pool = contract(token)
pool_id = pool.getPoolId()
vault = contract(pool.getVault())
tokens = vault.getPoolTokens(pool_id, block_identifier=block)
balances = [balance for t, balance in zip(tokens[0], tokens[1]) if t != token]
total = sum(balance * magic.get_price(t, block=block) for t, balance in zip(tokens[0], tokens[1]) if t != token)
supply = sum(balances)
return total / supply

balancer_v2 = None
try:
balancer_v2 = BalancerV2()
except UnsupportedNetwork:
pass

0 comments on commit 489a481

Please sign in to comment.