From da53e7b90e2c7dfbdb58dc1267d8d996ff253c10 Mon Sep 17 00:00:00 2001 From: bout3fiddy <11488427+bout3fiddy@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:15:18 +0200 Subject: [PATCH] remove unnecessary registry ... --- .../mainnet/registries/BasePoolRegistryNG.vy | 469 ------------------ .../ng/CurveStableSwapFactoryNGHandler.vy | 99 ++-- ...nd_setup_stableswap_factory_ng_handler.py} | 0 scripts/utils/constants.py | 16 + 4 files changed, 58 insertions(+), 526 deletions(-) delete mode 100644 contracts/mainnet/registries/BasePoolRegistryNG.vy rename scripts/{deploy_and_setup_base_pool_registry.py => deploy_and_setup_stableswap_factory_ng_handler.py} (100%) diff --git a/contracts/mainnet/registries/BasePoolRegistryNG.vy b/contracts/mainnet/registries/BasePoolRegistryNG.vy deleted file mode 100644 index d17f560..0000000 --- a/contracts/mainnet/registries/BasePoolRegistryNG.vy +++ /dev/null @@ -1,469 +0,0 @@ -#pragma version ^0.3.7 -""" -@title CurveBasePoolRegistryv2 -@license MIT -@author Curve.Fi -""" -MAX_COINS: constant(uint256) = 8 - - -struct BasePool: - lp_token: address - n_coins: uint256 - is_v2: bool - is_legacy: bool - is_lending: bool - -struct NGBasePoolArray: - lp_token: address - coins: DynArray[address, MAX_COINS] - decimals: uint256 - n_coins: uint256 - asset_types: DynArray[uint8, MAX_COINS] - - -interface AddressProvider: - def admin() -> address: view - -interface ERC20: - def decimals() -> uint256: view - -interface CurvePoolLegacy: - def coins(i: int128) -> address: view - -interface CurvePool: - def coins(i: uint256) -> address: view - def N_COINS() -> uint256: view - -interface CurveStableswapNGFactory: - def base_pool_count() -> uint256: view - def base_pool_list(i: uint256) -> address: view - def get_coins(_pool: address) -> DynArray[address, MAX_COINS]: view - def base_pool_data(_pool: address) -> NGBasePoolArray: view - - -event BasePoolAdded: - basepool: indexed(address) - - -event BasePoolRemoved: - basepool: indexed(address) - - -stableswap_ng_factory: public(immutable(CurveStableswapNGFactory)) -admin: public(address) -future_admin: public(address) - -manually_added_base_pool: HashMap[address, BasePool] -manually_added_base_pool_list: DynArray[address, 10000] -is_active_manually_added_pool: HashMap[address, bool] -manually_added_base_pool_for_lp_token: HashMap[address, address] -manually_added_base_pool_count: uint256 -last_updated: public(uint256) # last manual update! - - -@external -def __init__(_stableswap_ng_factory: address): - self.admin = msg.sender - stableswap_ng_factory = CurveStableswapNGFactory(_stableswap_ng_factory) - - -@internal -@view -def _pool_is_ng(_pool: address) -> bool: - - # Check if pool is from stableswap ng factory: - return raw_call( - stableswap_ng_factory.address, - concat( - method_id('get_n_coins(address)'), - convert(_pool, bytes32), - ), - revert_on_failure=False, - is_static_call=True, - ) - - -@internal -@view -def _pool_is_ng_basepool(_pool: address) -> bool: - - # Check if pool is a base pool on stableswap ng factory: - if stableswap_ng_factory.base_pool_data(_pool).n_coins > 0: - return True - - return False - - -@internal -@view -def _get_basepool_coins(_pool: address) -> DynArray[address, MAX_COINS]: - - if self._pool_is_ng(_pool): - return stableswap_ng_factory.get_coins(_pool) - - _coins: DynArray[address, MAX_COINS] = [] - _n_coins: uint256 = self.manually_added_base_pool[_pool].n_coins - _is_legacy: bool = self.manually_added_base_pool[_pool].is_legacy - for i in range(_n_coins, bound=MAX_COINS): - - if _is_legacy: - _coins.append(CurvePoolLegacy(_pool).coins(convert(i, int128))) - else: - _coins.append(CurvePool(_pool).coins(i)) - - return _coins - - -@internal -@view -def _get_base_pools() -> DynArray[address, 10000]: - - # manually added base pools are listed first: - __base_pool_list: DynArray[address, 10000] = [] - __manually_removed_pools: DynArray[address, 10000] = [] - - for i in range(len(self.manually_added_base_pool_list), bound=10000): - _pool: address = self.manually_added_base_pool_list[i] - if self.is_active_manually_added_pool[_pool]: - __base_pool_list.append(self.manually_added_base_pool_list[i]) - else: - __manually_removed_pools.append(_pool) - - print(__base_pool_list) - print(__manually_removed_pools) - - for j in range(stableswap_ng_factory.base_pool_count(), bound=10000): - stableswap_factory_ng_base_pool: address = stableswap_ng_factory.base_pool_list(j) - if ( - stableswap_factory_ng_base_pool not in __base_pool_list and - stableswap_factory_ng_base_pool not in __manually_removed_pools - ): - print(stableswap_factory_ng_base_pool) - __base_pool_list.append(stableswap_factory_ng_base_pool) - - return __base_pool_list - - -@internal -@view -def _base_pool_list(i: uint256) -> address: - base_pool_list: DynArray[address, 10000] = self._get_base_pools() - if i < len(base_pool_list): - return base_pool_list[i] - else: - return empty(address) - - -@internal -@view -def _base_pool_count() -> uint256: - return len(self._get_base_pools()) - - -@internal -@view -def _get_base_pool_for_lp_token(_lp_token: address) -> address: - - base_pool: address = self.manually_added_base_pool_for_lp_token[_lp_token] - - if base_pool != empty(address): - - return base_pool - - elif ( - base_pool == empty(address) and - self._pool_is_ng(_lp_token) and - self._pool_is_ng_basepool(_lp_token) - ): - return _lp_token - - return empty(address) - - -@internal -@view -def _get_basepools_for_coin(_coin: address) -> DynArray[address, 1000]: - """ - @notice Gets the base pool for a coin - @dev Some coins can be in multiple base pools, this function returns - the base pool with the input coin as an underlying asset - @param _coin Address of the coin - @return basepool addresses - """ - _base_pools: DynArray[address, 10000] = self._get_base_pools() - _base_pools_for_coin: DynArray[address, 1000] = [] - for _pool in _base_pools: - _coins: DynArray[address, MAX_COINS] = self._get_basepool_coins(_pool) - if _coin in _coins: - _base_pools_for_coin.append(_pool) - - return _base_pools_for_coin - - -# ------- public view methods -------- - - -@external -@view -def base_pool_list(i: uint256) -> address: - return self._base_pool_list(i) - - -@external -@view -def base_pool_count() -> uint256: - return self._base_pool_count() - - - -@external -@view -def get_base_pool_for_lp_tokens(_lp_token: address) -> address: - """ - @notice Gets pool address for lp token - @param _pool Address of the base pool - @return address address of the base pool - """ - return self._get_base_pool_for_lp_token(_lp_token) - - -@external -@view -def get_n_coins(_pool: address) -> uint256: - """ - @notice Gets the number of coins in a base pool - @param _pool Address of the base pool - @return uint256 number of coins - """ - - n_coins: uint256 = self.manually_added_base_pool[_pool].n_coins - - if not n_coins == 0: - - return n_coins - - elif ( - n_coins == 0 and - self._pool_is_ng(_pool) and - self._pool_is_ng_basepool(_pool) - ): - - return CurvePool(_pool).N_COINS() - - else: # pool is not registered, so register it first - - return 0 - - -@external -@view -def get_coins(_pool: address) -> address[MAX_COINS]: - """ - @notice Gets coins in a base pool - @param _pool Address of the base pool - @return address[MAX_COINS] with coin addresses - """ - coins: DynArray[address, MAX_COINS] = self._get_basepool_coins(_pool) - _coins: address[MAX_COINS] = empty(address[MAX_COINS]) - for i in range(len(coins), bound=MAX_COINS): - _coins[i] = coins[i] - return _coins - - -@external -@view -def get_basepool_for_coin(_coin: address, _idx: uint256 = 0) -> address: - """ - @notice Gets the base pool for a coin - @dev Some coins can be in multiple base pools, this function returns - the base pool for a coin at a specific index - @param _coin Address of the coin - @param _idx Index of base pool that holds the coin - @return basepool address - """ - return self._get_basepools_for_coin(_coin)[_idx] - - -@external -@view -def get_basepools_for_coin(_coin: address) -> DynArray[address, 1000]: - """ - @notice Gets the base pool for a coin - @dev Some coins can be in multiple base pools, this function returns - the base pool for a coin at a specific index - @param _coin Address of the coin - @return basepool addresses - """ - return self._get_basepools_for_coin(_coin) - - -@external -@view -def get_decimals(_pool: address) -> uint256[MAX_COINS]: - """ - @notice Gets decimals of coins in a base pool - @param _pool Address of the base pool - @return uint256[MAX_COINS] containing coin decimals - """ - _coins: DynArray[address, MAX_COINS] = self._get_basepool_coins(_pool) - _decimals: uint256[MAX_COINS] = empty(uint256[MAX_COINS]) - for i in range(MAX_COINS): - if _coins[i] == empty(address): - break - if _coins[i] == 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE: - _decimals[i] = 18 - else: - _decimals[i] = ERC20(_coins[i]).decimals() - - return _decimals - - -@external -@view -def get_lp_token(_pool: address) -> address: - """ - @notice Gets the LP token of a base pool - @param _pool Address of the base pool - @return address of the LP token - """ - lp_token: address = self.manually_added_base_pool[_pool].lp_token - if lp_token != empty(address): - return lp_token - - if self._pool_is_ng_basepool(_pool): - return stableswap_ng_factory.base_pool_data(_pool).lp_token - - return empty(address) - - -@external -@view -def is_legacy(_pool: address) -> bool: - """ - @notice Checks if a base pool uses Curve's legacy abi - @dev Legacy abi includes int128 indices whereas the newer - abi uses uint256 indices - @param _pool Address of the base pool - @return bool True if legacy abi is used - """ - # Will return false if it is an ng pool (not manually registered) - return self.manually_added_base_pool[_pool].is_legacy - - -@external -@view -def is_v2(_pool: address) -> bool: - """ - @notice Checks if a base pool is a Curve CryptoSwap pool - @param _pool Address of the base pool - @return bool True if the pool is a Curve CryptoSwap pool - """ - # Will return false if it is an ng pool (not manually registered) - return self.manually_added_base_pool[_pool].is_v2 - - -@external -@view -def is_lending(_pool: address) -> bool: - """ - @notice Checks if a base pool is a Curve Lending pool - @param _pool Address of the base pool - @return bool True if the pool is a Curve Lending pool - """ - # Will return false if it is an ng pool (not manually registered) - return self.manually_added_base_pool[_pool].is_lending - - -# ----------- Admin methods ---------- - -@external -def add_custom_base_pool( - _pool: address, - _lp_token: address, - _n_coins: uint256, - _is_legacy: bool, - _is_lending: bool, - _is_v2: bool -): - """ - @notice Add a base pool to the registry - @param _pool Address of the base pool - @param _lp_token Address of the LP token - @param _n_coins Number of coins in the base pool - @param _is_legacy True if the base pool uses legacy abi - @param _is_lending True if the base pool is a Curve Lending pool - @param _is_v2 True if the base pool is a Curve CryptoSwap pool - """ - assert msg.sender == self.admin # dev: admin-only function - assert self.manually_added_base_pool[_pool].lp_token == empty(address) # dev: pool exists - - # add pool to base_pool_list - self.manually_added_base_pool[_pool].lp_token = _lp_token - self.manually_added_base_pool[_pool].n_coins = _n_coins - self.manually_added_base_pool[_pool].is_v2 = _is_v2 - self.manually_added_base_pool[_pool].is_legacy = _is_legacy - self.manually_added_base_pool[_pool].is_lending = _is_lending - - # for reverse lookup: - self.manually_added_base_pool_for_lp_token[_lp_token] = _pool - - # set base pool as active - self.is_active_manually_added_pool[_pool] = True - - self.last_updated = block.timestamp - if _pool not in self.manually_added_base_pool_list: - self.manually_added_base_pool_list.append(_pool) - self.manually_added_base_pool_count += 1 - log BasePoolAdded(_pool) - - -@external -def remove_custom_base_pool(_pool: address): - """ - @notice Remove a base pool from the registry - @param _pool Address of the base pool - """ - assert msg.sender == self.admin # dev: admin-only function - assert _pool != empty(address) - assert self.manually_added_base_pool[_pool].lp_token != empty(address) # dev: pool doesn't exist - - # reset pool <> lp_token mappings - self.manually_added_base_pool_for_lp_token[self.manually_added_base_pool[_pool].lp_token] = empty(address) - self.manually_added_base_pool[_pool].lp_token = empty(address) - self.manually_added_base_pool[_pool].n_coins = 0 - self.manually_added_base_pool[_pool].is_legacy = False - self.manually_added_base_pool[_pool].is_lending = False - self.manually_added_base_pool[_pool].is_v2 = False - - # reduce count - self.manually_added_base_pool_count -= 1 - - # remove from active manually-added base pool hashmap - self.is_active_manually_added_pool[_pool] = False - - self.last_updated = block.timestamp - log BasePoolRemoved(_pool) - - -@external -def commit_transfer_ownership(_addr: address): - """ - @notice Transfer ownership of this contract to `addr` - @param _addr Address of the new owner - """ - assert msg.sender == self.admin # dev: admin only - self.future_admin = _addr - - -@external -def accept_transfer_ownership(): - """ - @notice Accept a pending ownership transfer - @dev Only callable by the new owner - """ - _admin: address = self.future_admin - assert msg.sender == _admin # dev: future admin only - - self.admin = _admin - self.future_admin = empty(address) diff --git a/contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy b/contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy index 55d279e..1f7c206 100644 --- a/contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy +++ b/contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy @@ -13,7 +13,6 @@ interface BaseRegistry: def get_admin_balances(_pool: address) -> DynArray[uint256, MAX_METAREGISTRY_COINS]: view def get_A(_pool: address) -> uint256: view def get_balances(_pool: address) -> DynArray[uint256, MAX_METAREGISTRY_COINS]: view - def get_base_pool(_pool: address) -> address: view def get_coins(_pool: address) -> DynArray[address, MAX_METAREGISTRY_COINS]: view def get_coin_indices(_pool: address, _from: address, _to: address) -> (int128, int128): view def get_decimals(_pool: address) -> DynArray[uint256, MAX_METAREGISTRY_COINS]: view @@ -29,13 +28,9 @@ interface BaseRegistry: def is_meta(_pool: address) -> bool: view def pool_count() -> uint256: view def pool_list(pool_id: uint256) -> address: view - -interface BasePoolRegistry: - def get_base_pool_for_lp_token(_lp_token: address) -> address: view - def get_n_coins(_pool: address) -> uint256: view - def get_coins(_pool: address) -> DynArray[address, MAX_METAREGISTRY_COINS]: view - def get_lp_token(_pool: address) -> address: view - def is_legacy(_pool: address) -> bool: view + def base_pool_data(_pool: address) -> BasePoolArray: view + def base_pool_count() -> uint256: view + def get_base_pool(_pool: address) -> address: view def base_pool_list(i: uint256) -> address: view interface CurveLegacyPool: @@ -45,6 +40,9 @@ interface CurvePool: def admin_balances(i: uint256) -> uint256: view def balances(i: uint256) -> uint256: view def get_virtual_price() -> uint256: view + def fee() -> uint256: view + def admin_fee() -> uint256: view + def offpeg_fee_multiplier() -> uint256: view interface ERC20: def balanceOf(_addr: address) -> uint256: view @@ -52,35 +50,44 @@ interface ERC20: def name() -> String[64]: view def totalSupply() -> uint256: view -interface GaugeController: - def gauge_types(gauge: address) -> int128: view - def gauges(i: uint256) -> address: view - interface Gauge: def is_killed() -> bool: view -interface MetaRegistry: - def registry_length() -> uint256: view + +struct BasePoolArray: + lp_token: address + coins: DynArray[address, MAX_METAREGISTRY_COINS] + decimals: uint256 + n_coins: uint256 + asset_types: DynArray[uint8, MAX_METAREGISTRY_COINS] # ---- constants ---- # GAUGE_CONTROLLER: constant(address) = 0x2F50D538606Fa9EDD2B11E2446BEb18C9D5846bB MAX_METAREGISTRY_COINS: constant(uint256) = 8 - +legacy_pool: constant(address) = 0x7fC77b5c7614E1533320Ea6DDc2Eb61fa00A9714 # ---- storage variables ---- # base_registry: public(BaseRegistry) -base_pool_registry: public(BasePoolRegistry) # ---- constructor ---- # @external -def __init__(_registry_address: address, _base_pool_registry: address): +def __init__(_registry_address: address): self.base_registry = BaseRegistry(_registry_address) - self.base_pool_registry = BasePoolRegistry(_base_pool_registry) # ---- internal methods ---- # +@internal +@view +def _get_base_pool_lp_token(_lp_token: address) -> address: + for i in range(self.base_registry.base_pool_count(), bound=10000): + base_pool: address = self.base_registry.base_pool_list(i) + if self.base_registry.base_pool_data(base_pool).lp_token == _lp_token: + return base_pool + return empty(address) + + @internal @view def _get_coins(_pool: address) -> address[MAX_METAREGISTRY_COINS]: @@ -105,20 +112,12 @@ def _get_underlying_coins(_pool: address) -> address[MAX_METAREGISTRY_COINS]: return _padded_coins -@internal -@view -def _get_n_coins(_pool: address) -> uint256: - if self.base_registry.is_meta(_pool): - return 2 - return self.base_registry.get_n_coins(_pool) - - @view @internal def _get_meta_underlying_balances(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: - base_coin_idx: uint256 = self._get_n_coins(_pool) - 1 + base_coin_idx: uint256 = self.base_registry.get_n_coins(_pool) - 1 base_pool: address = self.base_registry.get_base_pool(_pool) - base_total_supply: uint256 = ERC20(self.base_pool_registry.get_lp_token(base_pool)).totalSupply() + base_total_supply: uint256 = ERC20(self._get_base_pool_lp_token(base_pool)).totalSupply() ul_balance: uint256 = 0 underlying_pct: uint256 = 0 @@ -138,7 +137,7 @@ def _get_meta_underlying_balances(_pool: address) -> uint256[MAX_METAREGISTRY_CO else: - if self.base_pool_registry.is_legacy(base_pool): + if base_pool == legacy_pool: ul_balance = CurveLegacyPool(base_pool).balances(convert(i - base_coin_idx, int128)) else: ul_balance = CurvePool(base_pool).balances(i - base_coin_idx) @@ -174,18 +173,6 @@ def _pad_addr_dynarray(_array: DynArray[address, MAX_METAREGISTRY_COINS]) -> add return _padded_array -@internal -@view -def _get_balances(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: - return self._pad_uint_dynarray(self.base_registry.get_balances(_pool)) - - -@internal -@view -def _get_decimals(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: - return self._pad_uint_dynarray(self.base_registry.get_decimals(_pool)) - - @internal @view def _get_gauge_type(_gauge: address) -> int128: @@ -226,7 +213,7 @@ def get_admin_balances(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: @param _pool address of the pool @return balances of the admin of the pool """ - n_coins: uint256 = self._get_n_coins(_pool) + n_coins: uint256 = self.base_registry.get_n_coins(_pool) admin_balances: uint256[MAX_METAREGISTRY_COINS] = empty(uint256[MAX_METAREGISTRY_COINS]) for i in range(MAX_METAREGISTRY_COINS): if i == n_coins: @@ -243,7 +230,7 @@ def get_balances(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: @param _pool address of the pool @return balances of the pool """ - return self._get_balances(_pool) + return self._pad_uint_dynarray(self.base_registry.get_balances(_pool)) @external @@ -304,7 +291,7 @@ def get_decimals(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: @param _pool address of the pool @return decimals of coins in the pool """ - return self._get_decimals(_pool) + return self._pad_uint_dynarray(self.base_registry.get_decimals(_pool)) @external @@ -316,9 +303,9 @@ def get_fees(_pool: address) -> uint256[10]: @return fees of the pool """ fees: uint256[10] = empty(uint256[10]) - pool_fees: uint256[2] = self.base_registry.get_fees(_pool) - for i in range(2): - fees[i] = pool_fees[i] + fees[0] = CurvePool(_pool).fee() + fees[1] = CurvePool(_pool).admin_fee() + fees[2] = CurvePool(_pool).offpeg_fee_multiplier() return fees @@ -368,7 +355,7 @@ def get_n_coins(_pool: address) -> uint256: @param _pool address of the pool @return number of coins in the pool """ - return self._get_n_coins(_pool) + return self.base_registry.get_n_coins(_pool) @external @@ -390,13 +377,11 @@ def get_n_underlying_coins(_pool: address) -> uint256: if coins[i] == empty(address): break - # TODO: accommodate ng base pools here: - base_pool = self.base_pool_registry.get_base_pool_for_lp_token(coins[i]) + base_pool = self.base_registry.get_base_pool(coins[i]) if base_pool == empty(address) and coins[i] != empty(address): num_coins += 1 else: - # TODO: accommodate ng base pools here: - num_coins += self.base_pool_registry.get_n_coins(base_pool) + num_coins += self.base_registry.base_pool_data(base_pool).n_coins return num_coins @@ -423,7 +408,7 @@ def get_pool_from_lp_token(_lp_token: address) -> address: @param _lp_token address of the lp token (which is also the pool) @return pool of the lp token """ - if self._get_n_coins(_lp_token) > 0: + if self.base_registry.get_n_coins(_lp_token) > 0: return _lp_token return empty(address) @@ -436,7 +421,7 @@ def get_pool_name(_pool: address) -> String[64]: @dev stable factory pools are ERC20 tokenized @return name of the pool """ - if self._get_n_coins(_pool) == 0: + if self.base_registry.get_n_coins(_pool) == 0: # _pool is not in base registry, so we ignore: return "" return ERC20(_pool).name() @@ -464,7 +449,7 @@ def get_underlying_balances(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: @return underlying balances of the pool """ if not self.base_registry.is_meta(_pool): - return self._get_balances(_pool) + return self._pad_uint_dynarray(self.base_registry.get_balances(_pool)) return self._get_meta_underlying_balances(_pool) @@ -494,7 +479,7 @@ def get_underlying_decimals(_pool: address) -> uint256[MAX_METAREGISTRY_COINS]: @return underlying decimals of the pool """ if not self.base_registry.is_meta(_pool): - return self._get_decimals(_pool) + return self._pad_uint_dynarray(self.base_registry.get_decimals(_pool)) return self._pad_uint_dynarray(self.base_registry.get_underlying_decimals(_pool)) @@ -517,7 +502,7 @@ def is_registered(_pool: address) -> bool: @param _pool The address of the pool @return A bool corresponding to whether the pool belongs or not """ - return self._get_n_coins(_pool) > 0 + return self.base_registry.get_n_coins(_pool) > 0 @external diff --git a/scripts/deploy_and_setup_base_pool_registry.py b/scripts/deploy_and_setup_stableswap_factory_ng_handler.py similarity index 100% rename from scripts/deploy_and_setup_base_pool_registry.py rename to scripts/deploy_and_setup_stableswap_factory_ng_handler.py diff --git a/scripts/utils/constants.py b/scripts/utils/constants.py index 128b307..bcca530 100644 --- a/scripts/utils/constants.py +++ b/scripts/utils/constants.py @@ -36,6 +36,22 @@ "is_lending": False, "is_v2": False, }, + "fraxusdp": { + "pool": "0xaE34574AC03A15cd58A92DC79De7B1A0800F1CE3", + "lp_token": "0xFC2838a17D8e8B1D5456E0a351B0708a09211147", + "num_coins": 2, + "is_legacy": False, + "is_lending": False, + "is_v2": False, + }, + "sbtcv2": { + "pool": "0xf253f83AcA21aAbD2A20553AE0BF7F65C755A07F", + "lp_token": "0x051d7e5609917Bd9b73f04BAc0DED8Dd46a74301", + "num_coins": 2, + "is_legacy": False, + "is_lending": False, + "is_v2": False, + }, } CRYPTO_REGISTRY_POOLS = {