From ffba98535434aacb2f9a70f1f4aec479a95674e2 Mon Sep 17 00:00:00 2001 From: Daniel Schiavini Date: Fri, 24 Nov 2023 13:47:52 +0100 Subject: [PATCH] Test updates, fix print_missing --- scripts/print_missing.py | 117 ++++++++++-------- tests/conftest.py | 1 - .../api/test_find_pool_for_coins.py | 10 +- .../api/test_get_admin_balances.py | 11 +- .../metaregistry/api/test_get_balances.py | 7 +- .../mainnet/metaregistry/api/test_get_fees.py | 2 +- .../metaregistry/api/test_get_gauge.py | 4 +- .../api/test_get_underlying_balances.py | 8 +- .../api/test_get_underlying_coins.py | 2 +- .../api/test_get_underlying_decimals.py | 8 +- .../api/test_get_virtual_price.py | 13 +- 11 files changed, 101 insertions(+), 82 deletions(-) diff --git a/scripts/print_missing.py b/scripts/print_missing.py index 3fbb4a1..8a4aa9e 100644 --- a/scripts/print_missing.py +++ b/scripts/print_missing.py @@ -1,56 +1,75 @@ +import json + import boa -from tabulate import tabulate - -MISSING = "\033[33m✖\033[0m" -PRESENT = "\033[32m✓\033[0m" - - -def main(): - def get_non_indexed_view_functions( - registry_selectors, registry_abi, fn_index - ): - view_fns = { - d["name"] - for d in registry_abi - if d.get("stateMutability") == "view" - } - non_indexed_fns = dict(registry_selectors.items() - fn_index.items()) - return { - k: registry_selectors[k] - for k, v in non_indexed_fns.items() - if registry_selectors[k] in view_fns - } - - metaregistry = boa.load_partial("contracts/mainnet/MetaRegistry.vy") - function_index = get_non_indexed_view_functions( - metaregistry.selectors, metaregistry.abi, {} +from rich.console import Console +from rich.table import Table +from vyper.compiler.output import build_abi_output + +MISSING = "[red]✖[/red]" +PRESENT = "[green]✓[/green]" +META_NAME = "MetaRegistry" + + +def get_view_functions(abi: list[dict]) -> set[str]: + """ + Get the view functions from an ABI. + :param abi: the ABI to get the view functions from + """ + return {d["name"] for d in abi if d.get("stateMutability") == "view"} + + +def main() -> None: + """ + Calculate the missing functions from the registry and print them in a table. + """ + console = Console() + metaregistry = boa.load_partial(f"contracts/mainnet/{META_NAME}.vy") + meta_functions = get_view_functions( + abi=build_abi_output(metaregistry.compiler_data) ) - registry_coverage = [[PRESENT] * len(function_index)] registry_names = [ - f"{a}{b}" - for a in ["Crypto", "Stable"] - for b in ["Factory", "Registry"] + "CryptoFactory", + "CryptoRegistry", + "StableFactory", + "StableRegistry", ] + registry_functions = {META_NAME: meta_functions} for registry_name in registry_names: - # registry = getattr(interface, registry_name) # TODO: fix this! - registry = None - non_indexed_view_fns = get_non_indexed_view_functions( - registry.selectors, registry.abi, function_index - ) - function_index.update(non_indexed_view_fns) - registry_coverage.append( - [ - PRESENT if fn in registry.selectors else MISSING - for fn in function_index.keys() - ] - ) - - registry_coverage = [ - coverage + [MISSING] * (len(function_index) - len(coverage)) - for coverage in registry_coverage - ] - res = sorted(zip(function_index.values(), *registry_coverage)) - print( - tabulate(res, headers=["Functions", "MetaRegistry"] + registry_names) + with open(f"contracts/interfaces/{registry_name}.json") as f: + registry_abi = json.load(f) + registry_functions[registry_name] = get_view_functions(registry_abi) + + table = create_table(registry_functions) + return console.print(table) + + +def create_table(registry_functions: dict[str, set[str]]) -> Table: + """ + Create a table with the missing functions. + :param registry_functions: the functions from the registries + :return: the table with the missing functions + """ + table = Table(title="Missing Functions") + all_functions = set.union(*registry_functions.values()) + registries = [META_NAME] + sorted( + registry_name + for registry_name in registry_functions + if registry_name != META_NAME ) + table.add_column("Function Name") + for registry_name in registries: + table.add_column(registry_name) + for function_name in sorted(all_functions): + cells = [ + PRESENT + if function_name in registry_functions[registry_name] + else MISSING + for registry_name in registries + ] + table.add_row(function_name, *cells) + return table + + +if __name__ == "__main__": + main() diff --git a/tests/conftest.py b/tests/conftest.py index 40fea7b..afc28ca 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,7 +8,6 @@ pytest_plugins = [ "fixtures.accounts", "fixtures.constants", - "fixtures.contracts", "fixtures.deployments", "fixtures.functions", ] diff --git a/tests/mainnet/metaregistry/api/test_find_pool_for_coins.py b/tests/mainnet/metaregistry/api/test_find_pool_for_coins.py index 7ef82fd..9f9d004 100644 --- a/tests/mainnet/metaregistry/api/test_find_pool_for_coins.py +++ b/tests/mainnet/metaregistry/api/test_find_pool_for_coins.py @@ -13,8 +13,8 @@ def _get_all_combinations(metaregistry, pool): pool_coins = [ coin for coin in metaregistry.get_coins(pool) if coin != ZERO_ADDRESS ] - base_combinations = list(itertools.combinations(pool_coins, 2)) - all_combinations = base_combinations + all_combinations = list(itertools.combinations(pool_coins, 2)) + first_coin = pool_coins[0] if metaregistry.is_meta(pool): underlying_coins = [ @@ -22,10 +22,10 @@ def _get_all_combinations(metaregistry, pool): for coin in metaregistry.get_underlying_coins(pool) if coin != ZERO_ADDRESS ] - all_combinations = all_combinations + [ - (pool_coins[0], coin) + all_combinations += [ + (first_coin, coin) for coin in underlying_coins - if pool_coins[0] != coin + if first_coin != coin ] return all_combinations diff --git a/tests/mainnet/metaregistry/api/test_get_admin_balances.py b/tests/mainnet/metaregistry/api/test_get_admin_balances.py index c35ecb8..65cbb28 100644 --- a/tests/mainnet/metaregistry/api/test_get_admin_balances.py +++ b/tests/mainnet/metaregistry/api/test_get_admin_balances.py @@ -1,5 +1,6 @@ import boa import pytest +from boa import BoaError from eth.codecs.abi.exceptions import DecodeError from tests.utils import get_deployed_token_contract @@ -10,14 +11,10 @@ def pre_test_checks(metaregistry, pool): pytest.skip("empty pool: skipping") try: - if ( - get_deployed_token_contract( - metaregistry.get_lp_token(pool) - ).totalSupply() - == 0 - ): + contract = get_deployed_token_contract(metaregistry.get_lp_token(pool)) + if contract.totalSupply() == 0: pytest.skip("LP token supply is zero") - except DecodeError as err: # TODO: Document why this happens + except (BoaError, DecodeError) as err: # TODO: Document why this happens pytest.skip( f"{type(err).__name__} for token {metaregistry.get_lp_token(pool)}: " f"Skipping because of {err.msg}" diff --git a/tests/mainnet/metaregistry/api/test_get_balances.py b/tests/mainnet/metaregistry/api/test_get_balances.py index 470aa70..96df2c2 100644 --- a/tests/mainnet/metaregistry/api/test_get_balances.py +++ b/tests/mainnet/metaregistry/api/test_get_balances.py @@ -1,3 +1,6 @@ +from boa import BoaError + + def test_stable_registry_pools( populated_metaregistry, stable_registry_pool, stable_registry ): @@ -28,7 +31,7 @@ def test_crypto_registry_pools( ): try: actual_output = crypto_registry.get_balances(crypto_registry_pool) - except KeyError: # TODO: Pick right exception + except BoaError: actual_output = [] pool = curve_pool_v2(crypto_registry_pool) for i in range( @@ -48,7 +51,7 @@ def test_crypto_factory_pools( ): try: actual_output = crypto_factory.get_balances(crypto_factory_pool) - except KeyError: # TODO: Pick right exception + except BoaError: actual_output = [] pool = curve_pool_v2(crypto_factory_pool) for i in range(2): diff --git a/tests/mainnet/metaregistry/api/test_get_fees.py b/tests/mainnet/metaregistry/api/test_get_fees.py index 5dbfdce..05acef9 100644 --- a/tests/mainnet/metaregistry/api/test_get_fees.py +++ b/tests/mainnet/metaregistry/api/test_get_fees.py @@ -62,7 +62,7 @@ def test_crypto_factory_pools( curve_pool_v2, ): if sum(crypto_factory.get_balances(crypto_factory_pool)) == 0: - with boa.env.anchor(): + with boa.reverts(): curve_pool_v2(crypto_factory_pool).fee() pytest.skip( f"crypto factory pool {crypto_factory_pool} is empty and factory pools tend to " diff --git a/tests/mainnet/metaregistry/api/test_get_gauge.py b/tests/mainnet/metaregistry/api/test_get_gauge.py index cedbdba..43b4ebc 100644 --- a/tests/mainnet/metaregistry/api/test_get_gauge.py +++ b/tests/mainnet/metaregistry/api/test_get_gauge.py @@ -1,10 +1,12 @@ +from boa import BoaError + from tests.utils import ZERO_ADDRESS def _is_dao_onboarded_gauge(_gauge, gauge_controller, liquidity_gauge): try: gauge_controller.gauge_types(_gauge) - except KeyError: # TODO: Pick the right exception + except BoaError: return False if liquidity_gauge(_gauge).is_killed(): diff --git a/tests/mainnet/metaregistry/api/test_get_underlying_balances.py b/tests/mainnet/metaregistry/api/test_get_underlying_balances.py index 2255473..dc2a290 100644 --- a/tests/mainnet/metaregistry/api/test_get_underlying_balances.py +++ b/tests/mainnet/metaregistry/api/test_get_underlying_balances.py @@ -1,6 +1,7 @@ import warnings import pytest +from boa import BoaError from tests.utils import ZERO_ADDRESS, get_deployed_token_contract @@ -21,7 +22,7 @@ def _get_underlying_balances( actual_output = registry.get_underlying_balances(pool) # registry getter borks, so we need to get balances the hard way: - except (KeyError, AttributeError): # TODO: Pick the right exception + except (BoaError, AttributeError): coins = metaregistry.get_coins(pool) balances = metaregistry.get_balances(pool) for idx, coin in enumerate(coins): @@ -32,10 +33,7 @@ def _get_underlying_balances( coin_contract = get_deployed_token_contract(coin) try: lp_token_supply = coin_contract.totalSupply() - except ( - KeyError, - AttributeError, - ): # TODO: Pick the right exception + except (BoaError, AttributeError): assert "totalSupply" not in [ i.name for i in coin_contract.contract_type.view_methods diff --git a/tests/mainnet/metaregistry/api/test_get_underlying_coins.py b/tests/mainnet/metaregistry/api/test_get_underlying_coins.py index e57af26..4c5a64e 100644 --- a/tests/mainnet/metaregistry/api/test_get_underlying_coins.py +++ b/tests/mainnet/metaregistry/api/test_get_underlying_coins.py @@ -40,7 +40,7 @@ def _check_fetched_underlying_coins(registry, pool, underlying_coins): warnings.warn(f"Pool {pool} might be a lending pool.") return registry_underlying_coins - except BoaError: # TODO: Make error more specific + except BoaError: # virtual machine errors prop up for registry.get_underlying_coins if pool # is completely depegged. We check this by setting up a revert check and # then returning underlying_coins:git diff --git a/tests/mainnet/metaregistry/api/test_get_underlying_decimals.py b/tests/mainnet/metaregistry/api/test_get_underlying_decimals.py index 6c6b2b2..264ef97 100644 --- a/tests/mainnet/metaregistry/api/test_get_underlying_decimals.py +++ b/tests/mainnet/metaregistry/api/test_get_underlying_decimals.py @@ -1,4 +1,5 @@ import pytest +from boa import BoaError from tests.utils import ZERO_ADDRESS, get_deployed_token_contract @@ -7,8 +8,7 @@ "0xA96A65c051bF88B4095Ee1f2451C2A9d43F53Ae2": [18, 18], # compound pools. ctokens are 8 decimals. underlying is dai usdc: "0xA2B47E3D5c44877cca798226B7B8118F9BFb7A56": [18, 6], - # cream-yearn cytokens are 8 decimals, whereas underlying is - # dai usdc usdt: + # cream-yearn cytokens are 8 decimals, whereas underlying is dai usdc usdt: "0x2dded6Da1BF5DBdF597C45fcFaa3194e53EcfeAF": [18, 6, 6], # usdt pool has cDAI, cUSDC and USDT (which is [8, 8, 6]): "0x52EA46506B9CC5Ef470C5bf89f17Dc28bB35D85C": [18, 6, 6], @@ -35,9 +35,9 @@ def _test_underlying_decimals_getter(metaregistry, registry, pool): underlying_coins[i] ) actual_output.append(token_contract.decimals()) - except KeyError: # TODO: Pick the right exception + except BoaError: pytest.skip("Unverified contract. Skipping test.") - except ZeroDivisionError: # TODO: Pick the right exception + except ZeroDivisionError: if ( underlying_coins[i] == "0x6810e776880C02933D47DB1b9fc05908e5386b96" diff --git a/tests/mainnet/metaregistry/api/test_get_virtual_price.py b/tests/mainnet/metaregistry/api/test_get_virtual_price.py index e52a765..cc6c858 100644 --- a/tests/mainnet/metaregistry/api/test_get_virtual_price.py +++ b/tests/mainnet/metaregistry/api/test_get_virtual_price.py @@ -2,6 +2,7 @@ import boa import pytest +from boa import BoaError from tests.utils import ZERO_ADDRESS, get_deployed_token_contract @@ -11,13 +12,13 @@ def _check_pool_has_no_liquidity(metaregistry, pool, pool_balances, lp_token): # skip if pool has little to no liquidity, since vprice queries will most likely bork: if sum(pool_balances) == 0: - with boa.env.anchor(): + with boa.reverts(): metaregistry.get_virtual_price_from_lp_token(lp_token) pytest.skip(f"empty pool: {pool}") elif sum(pool_balances) < 100: # tiny pool - with boa.env.anchor(): + with boa.reverts(): metaregistry.get_virtual_price_from_lp_token(lp_token) pytest.skip(f"tiny pool: {pool}") @@ -42,7 +43,7 @@ def _check_skem_tokens_with_weird_decimals( ).decimals() == 0 ): - with boa.env.anchor(): + with boa.reverts(): metaregistry.get_virtual_price_from_lp_token(lp_token) pytest.skip( f"skem token {coins[i]} in pool {pool} with zero decimals" @@ -68,7 +69,7 @@ def _check_pool_is_depegged( and min(pool_balances_float) < 1 ): try: - with boa.env.anchor(): + with boa.reverts(): metaregistry.get_virtual_price_from_lp_token(lp_token) pytest.skip( @@ -135,8 +136,8 @@ def test_stable_factory_pools( populated_metaregistry.get_virtual_price_from_lp_token(lp_token) ) assert actual_output == metaregistry_output - except KeyError: # TODO: Pick the right exception - with boa.env.anchor(): + except BoaError: + with boa.reverts(): populated_metaregistry.get_virtual_price_from_lp_token(lp_token)