Skip to content

Commit

Permalink
fix: use crypto swap registry if available (#188)
Browse files Browse the repository at this point in the history
* fix: use crypto swap registry if available

* fix: make boolean check more explicit
  • Loading branch information
jstashh authored Dec 30, 2021
1 parent 92d4c87 commit 4afe6cd
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 6 deletions.
5 changes: 4 additions & 1 deletion scripts/apy.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,4 +126,7 @@ def dai():


def old_dai():
calculate_apy("0x19D3364A399d251E894aC732651be8B0E4e85001")
calculate_apy("0x19D3364A399d251E894aC732651be8B0E4e85001")

def eurs_usdc():
calculate_apy("0x801Ab06154Bf539dea4385a39f5fa8534fB53073")
23 changes: 22 additions & 1 deletion tests/prices/test_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import numpy as np
import pytest
import requests
from brownie import chain, multicall, web3
from brownie import ZERO_ADDRESS, chain, multicall, web3
from tabulate import tabulate
from yearn.prices import curve
from yearn.exceptions import PriceError
from yearn.utils import contract, contract_creation_block
from yearn.prices.magic import get_price

pooldata = json.load(open('tests/fixtures/pooldata.json'))

Expand Down Expand Up @@ -161,6 +162,11 @@

metapools = new_metapools + old_metapools

eur_usd_crypto_pool_tokens = [
"0x3b6831c0077a1e44ED0a21841C3bC4dC11bCE833",
"0x3D229E1B4faab62F621eF2F6A610961f7BD7b23B"
]


@pytest.fixture(scope='session')
def convex_gauge_map():
Expand Down Expand Up @@ -288,3 +294,18 @@ def test_get_balances_fallback(name):
if curve.curve.get_factory(pool):
pytest.skip('not applicable to metapools')
print(name, curve.curve.get_balances(pool, block=registry_deploy))


@pytest.mark.parametrize('pool', range(len(eur_usd_crypto_pool_tokens)))
def test_crypto_pool_eur_usd_assets(pool):
lp_token = eur_usd_crypto_pool_tokens[pool]
pool = curve.curve.crypto_swap_registry.get_pool_from_lp_token(lp_token)
coins = curve.curve.crypto_swap_registry.get_coins(pool)
non_zero_coins = list(filter(lambda coin: coin != ZERO_ADDRESS, coins))
underlying_coin_prices = map(lambda coin: get_price(coin), non_zero_coins)
summed_coin_prices = sum(underlying_coin_prices)

price = curve.curve.get_price(lp_token)
# the price of the crypto pool token should be approximately equal to the sum of the
# underlying coins, provided they are roughly equally balanced in the pool
assert price == pytest.approx(summed_coin_prices, rel=2e-1)
44 changes: 40 additions & 4 deletions yearn/prices/curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,14 +78,15 @@ def __init__(self):

self.pools = set()
self.identifiers = defaultdict(list)
self.addres_provider = contract(addrs['address_provider'])
self.address_provider = contract(addrs['address_provider'])
self.crypto_swap_registry = contract(self.address_provider.get_address(5))
self.watch_events()

def watch_events(self):
# TODO keep fresh in background

# fetch all registries and factories from address provider
log_filter = create_filter(str(self.addres_provider))
log_filter = create_filter(str(self.address_provider))
for event in decode_logs(log_filter.get_new_entries()):
if event.name == 'NewAddressIdentifier':
self.identifiers[event['id']].append(event['addr'])
Expand All @@ -98,6 +99,11 @@ def watch_events(self):
if event.name == 'PoolAdded':
self.pools.add(event['pool'])

log_filter = create_filter(str(self.crypto_swap_registry))
for event in decode_logs(log_filter.get_new_entries()):
if event.name == 'PoolAdded':
self.pools.add(event['pool'])

logger.info(f'loaded {len(self.pools)} pools')

@property
Expand Down Expand Up @@ -128,6 +134,12 @@ def metapools_by_factory(self):
str(factory): list(islice(pool_lists, pool_count))
for factory, pool_count in zip(metapool_factories, pool_counts)
}

def crypto_swap_registry_supports_pool(self, pool):
if self.crypto_swap_registry.get_pool_name(pool):
return True
else:
return False

def get_factory(self, pool):
"""
Expand All @@ -144,6 +156,11 @@ def get_factory(self, pool):

@lru_cache(maxsize=None)
def _pool_from_lp_token(self, token):
crypto_swap_registry_result = self.crypto_swap_registry.get_pool_from_lp_token(token)

if crypto_swap_registry_result != ZERO_ADDRESS:
return crypto_swap_registry_result

return self.registry.get_pool_from_lp_token(token)

def __contains__(self, token):
Expand Down Expand Up @@ -173,6 +190,11 @@ def get_gauge(self, pool):
if gauge != ZERO_ADDRESS:
return gauge

if self.crypto_swap_registry_supports_pool(pool):
gauges, types = self.crypto_swap_registry.get_gauges(pool)
if gauges[0] != ZERO_ADDRESS:
return gauges[0]

gauges, types = self.registry.get_gauges(pool)
if gauges[0] != ZERO_ADDRESS:
return gauges[0]
Expand All @@ -186,6 +208,8 @@ def get_coins(self, pool):

if factory:
coins = contract(factory).get_coins(pool)
elif self.crypto_swap_registry_supports_pool(pool):
coins = self.crypto_swap_registry.get_coins(pool)
else:
coins = self.registry.get_coins(pool)

Expand Down Expand Up @@ -220,7 +244,13 @@ def get_underlying_coins(self, pool):
@lru_cache(maxsize=None)
def get_decimals(self, pool):
factory = self.get_factory(pool)
source = contract(factory) if factory else self.registry
if factory:
source = contract(factory)
elif self.crypto_swap_registry_supports_pool(pool):
source = self.crypto_swap_registry
else:
source = source = self.registry

decimals = source.get_decimals(pool)

# pool not in registry
Expand All @@ -241,7 +271,13 @@ def get_balances(self, pool, block=None):
decimals = self.get_decimals(pool)

try:
source = contract(factory) if factory else self.registry
if factory:
source = contract(factory)
elif self.crypto_swap_registry_supports_pool(pool):
source = self.crypto_swap_registry
else:
source = self.registry

balances = source.get_balances(pool, block_identifier=block)
# fallback for historical queries
except ValueError:
Expand Down

0 comments on commit 4afe6cd

Please sign in to comment.