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

fix: use crypto swap registry if available #188

Merged
merged 2 commits into from
Dec 30, 2021
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
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