From 9ac8e946fc0f08aea66a9d29f658712141a5ddf6 Mon Sep 17 00:00:00 2001 From: bout3fiddy <11488427+bout3fiddy@users.noreply.github.com> Date: Fri, 17 May 2024 22:26:19 +0200 Subject: [PATCH] l2 metaregistry --- contracts/{mainnet => }/MetaRegistry.vy | 0 contracts/MetaRegistryL2.vy | 593 ++++++++++++++++++ .../registries/BasePoolRegistry.vy | 0 .../registries/CryptoRegistryV1.vy | 0 .../registry_handlers/CryptoFactoryHandler.vy | 0 .../CryptoRegistryHandler.vy | 0 .../registry_handlers/StableFactoryHandler.vy | 0 .../StableRegistryHandler.vy | 0 .../ng/CurveStableSwapFactoryNGHandler.vy | 0 .../ng/CurveTricryptoFactoryHandler.vy | 0 .../ng/CurveTwocryptoFactoryHandler.vy | 0 requirements.in | 2 +- scripts/address_provider_constants.py | 16 + scripts/deploy.py | 16 +- scripts/deploy_addressprovider_and_setup.py | 13 +- scripts/deploy_and_setup_crypto_ng_handler.py | 4 +- ...and_setup_stableswap_factory_ng_handler.py | 2 +- scripts/deploy_crypto_registry_handler.py | 2 +- scripts/deploy_metaregistry_sidechain_l2s.py | 128 ++++ scripts/utils/print_missing.py | 2 +- tests/unitary/conftest.py | 6 +- tests/utils.py | 4 +- 22 files changed, 762 insertions(+), 26 deletions(-) rename contracts/{mainnet => }/MetaRegistry.vy (100%) create mode 100644 contracts/MetaRegistryL2.vy rename contracts/{mainnet => }/registries/BasePoolRegistry.vy (100%) rename contracts/{mainnet => }/registries/CryptoRegistryV1.vy (100%) rename contracts/{mainnet => }/registry_handlers/CryptoFactoryHandler.vy (100%) rename contracts/{mainnet => }/registry_handlers/CryptoRegistryHandler.vy (100%) rename contracts/{mainnet => }/registry_handlers/StableFactoryHandler.vy (100%) rename contracts/{mainnet => }/registry_handlers/StableRegistryHandler.vy (100%) rename contracts/{mainnet => }/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy (100%) rename contracts/{mainnet => }/registry_handlers/ng/CurveTricryptoFactoryHandler.vy (100%) rename contracts/{mainnet => }/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy (100%) create mode 100644 scripts/deploy_metaregistry_sidechain_l2s.py diff --git a/contracts/mainnet/MetaRegistry.vy b/contracts/MetaRegistry.vy similarity index 100% rename from contracts/mainnet/MetaRegistry.vy rename to contracts/MetaRegistry.vy diff --git a/contracts/MetaRegistryL2.vy b/contracts/MetaRegistryL2.vy new file mode 100644 index 0000000..03f45c2 --- /dev/null +++ b/contracts/MetaRegistryL2.vy @@ -0,0 +1,593 @@ +# pragma version 0.3.10 +# pragma evm-version paris +""" +@title CurveMetaRegistry +""" + +# ---- interfaces ---- # +interface AddressProvider: + def admin() -> address: view + + +# registry and registry handlers are considered to be the same here. +# registry handlers are just wrapper contracts that simplify/fix underlying registries +# for integrating it into the Metaregistry. +interface RegistryHandler: + def find_pool_for_coins(_from: address, _to: address, i: uint256 = 0) -> address: view + def get_admin_balances(_pool: address) -> uint256[MAX_COINS]: view + def get_balances(_pool: address) -> uint256[MAX_COINS]: view + def get_base_pool(_pool: address) -> address: view + def get_coins(_pool: address) -> address[MAX_COINS]: view + def get_coin_indices(_pool: address, _from: address, _to: address) -> (int128, int128, bool): view + def get_decimals(_pool: address) -> uint256[MAX_COINS]: view + def get_fees(_pool: address) -> uint256[10]: view + def get_lp_token(_pool: address) -> address: view + def get_n_coins(_pool: address) -> uint256: view + def get_n_underlying_coins(_pool: address) -> uint256: view + def get_pool_asset_type(_pool: address) -> uint256: view + def get_pool_from_lp_token(_lp_token: address) -> address: view + def get_pool_name(_pool: address) -> String[64]: view + def get_pool_params(_pool: address) -> uint256[20]: view + def get_underlying_balances(_pool: address) -> uint256[MAX_COINS]: view + def get_underlying_coins(_pool: address) -> address[MAX_COINS]: view + def get_underlying_decimals(_pool: address) -> uint256[MAX_COINS]: view + def is_meta(_pool: address) -> bool: view + def is_registered(_pool: address) -> bool: view + def pool_count() -> uint256: view + def pool_list(_index: uint256) -> address: view + def get_virtual_price_from_lp_token(_addr: address) -> uint256: view + def base_registry() -> address: view + +interface GaugeFactory: + def get_gauge_from_lp_token(_lp_token: address) -> address: view + + +# ---- events ---- # +event CommitNewAdmin: + deadline: indexed(uint256) + admin: indexed(address) + +event NewAdmin: + admin: indexed(address) + + +# ---- constants ---- # +MAX_REGISTRIES: constant(uint256) = 10 +MAX_COINS: constant(uint256) = 8 +MAX_POOL_PARAMS: constant(uint256) = 20 +ADMIN_ACTIONS_DELAY: constant(uint256) = 3 * 86400 + + +# ---- storage variables ---- # +admin: public(address) +future_admin: public(address) + +# get registry/registry_handler by index, index starts at 0: +get_registry: public(HashMap[uint256, address]) +registry_length: public(uint256) +gauge_factory: public(GaugeFactory) +gauge_type: public(int128) + + +# ---- constructor ---- # +@external +def __init__(_gauge_factory: address, _gauge_type: int128): + self.admin = msg.sender + self.gauge_factory = GaugeFactory(_gauge_factory) + self.gauge_type = _gauge_type + + +# ---- internal methods ---- # +@internal +def _update_single_registry(_index: uint256, _registry_handler: address): + assert _index <= self.registry_length + + if _index == self.registry_length: + self.registry_length += 1 + + self.get_registry[_index] = _registry_handler + + +@internal +@view +def _get_pool_from_lp_token(_token: address) -> address: + for i in range(MAX_REGISTRIES): + if i == self.registry_length: + break + handler: address = self.get_registry[i] + pool: address = RegistryHandler(handler).get_pool_from_lp_token(_token) + if pool != empty(address): + return pool + return empty(address) + + +@internal +@view +def _get_registry_handlers_from_pool(_pool: address) -> address[MAX_REGISTRIES]: + """ + @notice Get registry handler that handles the registry api for a pool + @dev sometimes a factory pool can be registered in a manual registry + because of this, we always take the last registry a pool is + registered in and not the first, as manual registries are first + and factories come later + @param _pool address of the pool + @return registry_handlers: address[MAX_REGISTRIES] + """ + + pool_registry_handler: address[MAX_REGISTRIES] = empty(address[MAX_REGISTRIES]) + c: uint256 = 0 + for i in range(MAX_REGISTRIES): + + if i == self.registry_length: + break + handler: address = self.get_registry[i] + + if RegistryHandler(handler).is_registered(_pool): + pool_registry_handler[c] = handler + c += 1 + + if pool_registry_handler[0] == empty(address): + raise "no registry" + return pool_registry_handler + + +# ---- most used methods: Admin / DAO privileged methods ---- # +@external +def add_registry_handler(_registry_handler: address): + """ + @notice Adds a registry from the address provider entry + @param _registry_handler Address of the handler contract + """ + assert msg.sender == self.admin # dev: only admin + + self._update_single_registry(self.registry_length, _registry_handler) + + +@external +def update_registry_handler(_index: uint256, _registry_handler: address): + """ + @notice Updates the contract used to handle a registry + @param _index The index of the registry in get_registry + @param _registry_handler Address of the new handler contract + """ + assert msg.sender == self.admin # dev: only admin + assert _index < self.registry_length + + self._update_single_registry(_index, _registry_handler) + + +@external +def update_gauge_data(_gauge_factory: address, _gauge_type: int128): + assert msg.sender == self.admin + self.gauge_factory = GaugeFactory(_gauge_factory) + self.gauge_type = _gauge_type + + +# ---- view methods (API) of the contract ---- # + + +@external +@view +def get_registry_handlers_from_pool(_pool: address) -> address[MAX_REGISTRIES]: + """ + @notice Get the registry handlers associated with a pool + @param _pool Pool address + @return List of registry handlers + """ + return self._get_registry_handlers_from_pool(_pool) + + +@external +@view +def get_base_registry(registry_handler: address) -> address: + """ + @notice Get the registry associated with a registry handler + @param registry_handler Registry Handler address + @return Address of base registry + """ + return RegistryHandler(registry_handler).base_registry() + + +@view +@external +def find_pool_for_coins( + _from: address, _to: address, i: uint256 = 0 +) -> address: + """ + @notice Find the ith available pool containing the input pair + @param _from Address of coin to be sent + @param _to Address of coin to be received + @param i Index of the pool to return + @return Pool address + """ + pools_found: uint256 = 0 + pool: address = empty(address) + registry: address = empty(address) + + for registry_index in range(MAX_REGISTRIES): + + registry = self.get_registry[registry_index] + if registry == empty(address): + break + + for j in range(0, 65536): + + pool = RegistryHandler(registry).find_pool_for_coins(_from, _to, j) + if pool == empty(address): + break + pools_found += 1 + if pools_found > i: + return pool + + return pool + + +@view +@external +def find_pools_for_coins(_from: address, _to: address) -> DynArray[address, 1000]: + """ + @notice Find all pools that contain the input pair + @param _from Address of coin to be sent + @param _to Address of coin to be received + @return Pool addresses + """ + pools_found: DynArray[address, 1000]= empty(DynArray[address, 1000]) + pool: address = empty(address) + registry: address = empty(address) + + for registry_index in range(MAX_REGISTRIES): + + registry = self.get_registry[registry_index] + if registry == empty(address): + break + + for j in range(0, 65536): + + pool = RegistryHandler(registry).find_pool_for_coins(_from, _to, j) + if pool == empty(address): + break + pools_found.append(pool) + + return pools_found + + +@external +@view +def get_admin_balances(_pool: address, _handler_id: uint256 = 0) -> uint256[MAX_COINS]: + """ + @notice Get the current admin balances (uncollected fees) for a pool + @dev _handler_id < 1 if pool is registry in one handler, more than 0 otherwise + @param _pool Pool address + @param _handler_id id of registry handler + @return List of uint256 admin balances + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_admin_balances(_pool) + + +@external +@view +def get_balances(_pool: address, _handler_id: uint256 = 0) -> uint256[MAX_COINS]: + """ + @notice Get balances for each coin within a pool + @dev For metapools, these are the wrapped coin balances + @param _pool Pool address + @param _handler_id id of registry handler + @return uint256 list of balances + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_balances(_pool) + + +@external +@view +def get_base_pool(_pool: address, _handler_id: uint256 = 0) -> address: + """ + @notice Get the base pool for a given factory metapool + @dev Will return empty(address) if pool is not a metapool + @param _pool Metapool address + @param _handler_id id of registry handler + @return Address of base pool + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_base_pool(_pool) + + +@view +@external +def get_coin_indices(_pool: address, _from: address, _to: address, _handler_id: uint256 = 0) -> (int128, int128, bool): + """ + @notice Convert coin addresses to indices for use with pool methods + @param _pool Pool address + @param _from Coin address to be used as `i` within a pool + @param _to Coin address to be used as `j` within a pool + @param _handler_id id of registry handler + @return from index, to index, is the market underlying ? + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_coin_indices(_pool, _from, _to) + + +@external +@view +def get_coins(_pool: address, _handler_id: uint256 = 0) -> address[MAX_COINS]: + """ + @notice Get the coins within a pool + @dev For metapools, these are the wrapped coin addresses + @param _pool Pool address + @param _handler_id id of registry handler + @return List of coin addresses + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_coins(_pool) + + +@external +@view +def get_decimals(_pool: address, _handler_id: uint256 = 0) -> uint256[MAX_COINS]: + """ + @notice Get decimal places for each coin within a pool + @dev For metapools, these are the wrapped coin decimal places + @param _pool Pool address + @param _handler_id id of registry handler + @return uint256 list of decimals + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_decimals(_pool) + + +@external +@view +def get_fees(_pool: address, _handler_id: uint256 = 0) -> uint256[10]: + """ + @notice Get pool fees + @dev Fees are expressed as integers + @param _pool Pool address + @param _handler_id id of registry handler + @return Pool fee as uint256 with 1e10 precision + Admin fee as 1e10 percentage of pool fee + Mid fee + Out fee + 6 blank spots for future use cases + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_fees(_pool) + + +@external +@view +def get_gauge(_pool: address, gauge_idx: uint256 = 0, _handler_id: uint256 = 0) -> address: + """ + @notice Get a single liquidity gauge contract associated with a pool + @param _pool Pool address + @param gauge_idx Index of gauge to return + @param _handler_id id of registry handler + @return Address of gauge + """ + lp_token: address = RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_lp_token(_pool) + return self.gauge_factory.get_gauge_from_lp_token(lp_token) + + +@external +@view +def get_gauge_type(_pool: address, gauge_idx: uint256 = 0, _handler_id: uint256 = 0) -> int128: + """ + @notice Get gauge_type of a single liquidity gauge contract associated with a pool + @param _pool Pool address + @param gauge_idx Index of gauge to return + @param _handler_id id of registry handler + @return Address of gauge + """ + return self.gauge_type + + +@external +@view +def get_lp_token(_pool: address, _handler_id: uint256 = 0) -> address: + """ + @notice Get the address of the LP token of a pool + @param _pool Pool address + @param _handler_id id of registry handler + @return Address of the LP token + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_lp_token(_pool) + + +@external +@view +def get_n_coins(_pool: address, _handler_id: uint256 = 0) -> uint256: + """ + @notice Get the number of coins in a pool + @dev For metapools, it is tokens + wrapping/lending token (no underlying) + @param _pool Pool address + @return Number of coins + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_n_coins(_pool) + + +@external +@view +def get_n_underlying_coins(_pool: address, _handler_id: uint256 = 0) -> uint256: + """ + @notice Get the number of underlying coins in a pool + @dev For non metapools, returns the same as get_n_coins + @param _pool Pool address + @return Number of coins + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_n_underlying_coins(_pool) + + +@external +@view +def get_pool_asset_type(_pool: address, _handler_id: uint256 = 0) -> uint256: + """ + @notice Query the asset type of `_pool` + @param _pool Pool Address + @return The asset type as an unstripped string + @dev 0 : USD, 1: ETH, 2: BTC, 3: Other, 4: CryptoSwap + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_pool_asset_type(_pool) + + +@external +@view +def get_pool_from_lp_token(_token: address, _handler_id: uint256 = 0) -> address: + """ + @notice Get the pool associated with an LP token + @param _token LP token address + @return Pool address + """ + return self._get_pool_from_lp_token(_token) + + +@external +@view +def get_pool_params(_pool: address, _handler_id: uint256 = 0) -> uint256[MAX_POOL_PARAMS]: + """ + @notice Get the parameters of a pool + @param _pool Pool address + @param _handler_id id of registry handler + @return Pool parameters + """ + registry_handler: address = self._get_registry_handlers_from_pool(_pool)[_handler_id] + return RegistryHandler(registry_handler).get_pool_params(_pool) + + +@external +@view +def get_pool_name(_pool: address, _handler_id: uint256 = 0) -> String[64]: + """ + @notice Get the given name for a pool + @param _pool Pool address + @return The name of a pool + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_pool_name(_pool) + + +@external +@view +def get_underlying_balances(_pool: address, _handler_id: uint256 = 0) -> uint256[MAX_COINS]: + """ + @notice Get balances for each underlying coin within a pool + @dev For non metapools, returns the same value as `get_balances` + @param _pool Pool address + @param _handler_id id of registry handler + @return uint256 List of underlyingbalances + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_underlying_balances(_pool) + + +@external +@view +def get_underlying_coins(_pool: address, _handler_id: uint256 = 0) -> address[MAX_COINS]: + """ + @notice Get the underlying coins within a pool + @dev For non metapools, returns the same value as `get_coins` + @param _pool Pool address + @param _handler_id id of registry handler + @return List of coin addresses + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_underlying_coins(_pool) + + +@external +@view +def get_underlying_decimals(_pool: address, _handler_id: uint256 = 0) -> uint256[MAX_COINS]: + """ + @notice Get decimal places for each underlying coin within a pool + @dev For non metapools, returns the same value as `get_decimals` + @param _pool Pool address + @param _handler_id id of registry handler + @return uint256 list of decimals + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).get_underlying_decimals(_pool) + + +@external +@view +def get_virtual_price_from_lp_token(_token: address, _handler_id: uint256 = 0) -> uint256: + """ + @notice Get the virtual price of a pool LP token + @param _token LP token address + @param _handler_id id of registry handler + @return uint256 Virtual price + """ + pool: address = self._get_pool_from_lp_token(_token) + registry_handler: address = self._get_registry_handlers_from_pool(pool)[_handler_id] + return RegistryHandler(registry_handler).get_virtual_price_from_lp_token(_token) + + +@external +@view +def is_meta(_pool: address, _handler_id: uint256 = 0) -> bool: + """ + @notice Verify `_pool` is a metapool + @param _pool Pool address + @param _handler_id id of registry handler + @return True if `_pool` is a metapool + """ + return RegistryHandler(self._get_registry_handlers_from_pool(_pool)[_handler_id]).is_meta(_pool) + + +@external +@view +def is_registered(_pool: address, _handler_id: uint256 = 0) -> bool: + """ + @notice Check if a pool is in the metaregistry using get_n_coins + @param _pool The address of the pool + @param _handler_id id of registry handler + @return A bool corresponding to whether the pool belongs or not + """ + return self._get_registry_handlers_from_pool(_pool)[_handler_id] != empty(address) + + +@external +@view +def pool_count() -> uint256: + """ + @notice Return the total number of pools tracked by the metaregistry + @return uint256 The number of pools in the metaregistry + """ + total_pools: uint256 = 0 + for i in range(MAX_REGISTRIES): + if i == self.registry_length: + break + handler: address = self.get_registry[i] + total_pools += RegistryHandler(handler).pool_count() + return total_pools + + +@external +@view +def pool_list(_index: uint256) -> address: + """ + @notice Return the pool at a given index in the metaregistry + @param _index The index of the pool in the metaregistry + @return The address of the pool at the given index + """ + pools_skip: uint256 = 0 + for i in range(MAX_REGISTRIES): + if i == self.registry_length: + break + handler: address = self.get_registry[i] + count: uint256 = RegistryHandler(handler).pool_count() + if _index - pools_skip < count: + return RegistryHandler(handler).pool_list(_index - pools_skip) + pools_skip += count + return empty(address) + + +@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/registries/BasePoolRegistry.vy b/contracts/registries/BasePoolRegistry.vy similarity index 100% rename from contracts/mainnet/registries/BasePoolRegistry.vy rename to contracts/registries/BasePoolRegistry.vy diff --git a/contracts/mainnet/registries/CryptoRegistryV1.vy b/contracts/registries/CryptoRegistryV1.vy similarity index 100% rename from contracts/mainnet/registries/CryptoRegistryV1.vy rename to contracts/registries/CryptoRegistryV1.vy diff --git a/contracts/mainnet/registry_handlers/CryptoFactoryHandler.vy b/contracts/registry_handlers/CryptoFactoryHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/CryptoFactoryHandler.vy rename to contracts/registry_handlers/CryptoFactoryHandler.vy diff --git a/contracts/mainnet/registry_handlers/CryptoRegistryHandler.vy b/contracts/registry_handlers/CryptoRegistryHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/CryptoRegistryHandler.vy rename to contracts/registry_handlers/CryptoRegistryHandler.vy diff --git a/contracts/mainnet/registry_handlers/StableFactoryHandler.vy b/contracts/registry_handlers/StableFactoryHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/StableFactoryHandler.vy rename to contracts/registry_handlers/StableFactoryHandler.vy diff --git a/contracts/mainnet/registry_handlers/StableRegistryHandler.vy b/contracts/registry_handlers/StableRegistryHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/StableRegistryHandler.vy rename to contracts/registry_handlers/StableRegistryHandler.vy diff --git a/contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy b/contracts/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy rename to contracts/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy diff --git a/contracts/mainnet/registry_handlers/ng/CurveTricryptoFactoryHandler.vy b/contracts/registry_handlers/ng/CurveTricryptoFactoryHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/ng/CurveTricryptoFactoryHandler.vy rename to contracts/registry_handlers/ng/CurveTricryptoFactoryHandler.vy diff --git a/contracts/mainnet/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy b/contracts/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy similarity index 100% rename from contracts/mainnet/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy rename to contracts/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy diff --git a/requirements.in b/requirements.in index 12a8a59..1dd8c9d 100644 --- a/requirements.in +++ b/requirements.in @@ -1,4 +1,4 @@ -titanoboa[forking-recommended] @ git+https://github.com/vyperlang/titanoboa@e85ab24 +titanoboa[forking-recommended] @ git+https://github.com/vyperlang/titanoboa@69c68d6dbb60b8f8782b5bfca336f5dc838a7719 black flake8 isort diff --git a/scripts/address_provider_constants.py b/scripts/address_provider_constants.py index 0761c81..9e813e9 100644 --- a/scripts/address_provider_constants.py +++ b/scripts/address_provider_constants.py @@ -255,6 +255,22 @@ 23: "0xA177D2bd2BD723878bD95982c0855291953f74C9", 25: "0x98B4029CaBEf7Fd525A36B0BF8555EC1d42ec0B6", # crvUSD }, + "xlayer": { + 2: "0x4f37A9d177470499A2dD084621020b023fcffc1F", # 2: "Exchange Router", + 4: "0xf3A431008396df8A8b2DF492C913706BDB0874ef", # 4: "Fee Distributor", + 11: "0xd3B17f862956464ae4403cCF829CE69199856e1e", # 11: "TricryptoNG Factory", + 12: "0x5eeE3091f747E60a045a2E715a4c71e600e31F6E", # 12: "StableswapNG Factory", + 13: "0x0c59d36b23f809f8b6C7cb4c8C590a0AC103baEf", # 13: "TwocryptoNG Factory", + 14: "0x0fE38dCC905eC14F6099a83Ac5C93BF2601300CF", # 14: "Stableswap Calculations Contract", + 15: "0x69522fb5337663d3B4dFB0030b881c1A750Adb4f", # 15: "Cryptoswap calculations Contract", + 19: "0x3d5320821bfca19fb0b5428f2c79d63bd5246f89", # 19: "CRV Token", + 20: "0xeF672bD94913CB6f1d2812a6e18c1fFdEd8eFf5c", # 20: "Gauge Factory", + 21: "0x6628b9e7c0029cea234b382be17101648f32cd8f", # 21: "Ownership Admin", + 22: "0xccc4864762412f3273bf7ca9264295909504ebb5", # 22: "Parameter Admin", + 23: "0x9ffc6f671d88593aae56d9d34f2b40d7a56d467f", # 23: "Emergency Admin", + 24: "0x0848F3800F04b3ad4309A5f27814be7FC4740cB9", # 24: "CurveDAO Vault", # Holds funds + 25: "0xdA8f4Eb4503ACF5dec5420523637bb5b33a846f6", # 25: "crvUSD Token" + }, # No UI: "linea": { 4: "0xf3A431008396df8A8b2DF492C913706BDB0874ef", diff --git a/scripts/deploy.py b/scripts/deploy.py index 880a193..0636f9d 100644 --- a/scripts/deploy.py +++ b/scripts/deploy.py @@ -36,9 +36,7 @@ def main(): setup_environment(console) # deploy basepool registry: - base_pool_registry = boa.load( - "contracts/mainnet/registries/BasePoolRegistry.vy" - ) + base_pool_registry = boa.load("contracts/registries/BasePoolRegistry.vy") # deploy crypto registry: console.log( @@ -46,7 +44,7 @@ def main(): encode(["address", "address"], [ADDRESS_PROVIDER, base_pool_registry]), ) crypto_registry = boa.load( - "contracts/mainnet/registries/CryptoRegistryV1.vy", + "contracts/registries/CryptoRegistryV1.vy", ADDRESS_PROVIDER, base_pool_registry, ) @@ -57,7 +55,7 @@ def main(): encode(["address"], [STABLE_REGISTRY_ADDRESS]).hex(), ) boa.load( - "contracts/mainnet/registry_handlers/StableRegistryHandler.vy", + "contracts/registry_handlers/StableRegistryHandler.vy", STABLE_REGISTRY_ADDRESS, ) @@ -70,7 +68,7 @@ def main(): ).hex(), ) boa.load( - "contracts/mainnet/registry_handlers/StableFactoryHandler.vy", + "contracts/registry_handlers/StableFactoryHandler.vy", STABLE_FACTORY_ADDRESS, base_pool_registry, ) @@ -81,7 +79,7 @@ def main(): encode(["address"], [crypto_registry]).hex(), ) boa.load( - "contracts/mainnet/registry_handlers/CryptoRegistryHandler.vy", + "contracts/registry_handlers/CryptoRegistryHandler.vy", crypto_registry, ) @@ -94,7 +92,7 @@ def main(): ).hex(), ) boa.load( - "contracts/mainnet/registry_handlers/CryptoFactoryHandler.vy", + "contracts/registry_handlers/CryptoFactoryHandler.vy", CRYPTO_FACTORY_ADDRESS, base_pool_registry, ) @@ -104,7 +102,7 @@ def main(): "MetaRegistry constructor arguments: ", encode(["address"], [ADDRESS_PROVIDER]).hex(), ) - boa.load("contracts/mainnet/MetaRegistry.vy", ADDRESS_PROVIDER) + boa.load("contracts/MetaRegistry.vy", ADDRESS_PROVIDER) if __name__ == "__main__": diff --git a/scripts/deploy_addressprovider_and_setup.py b/scripts/deploy_addressprovider_and_setup.py index a682550..9482430 100644 --- a/scripts/deploy_addressprovider_and_setup.py +++ b/scripts/deploy_addressprovider_and_setup.py @@ -34,23 +34,25 @@ def deploy_via_create2_factory(deployment_bytecode, salt, create2deployer): create2deployer.deploy(0, salt, deployment_bytecode) -def main(network, fork): +def main(network, fork, url=""): """ Deploy the AddressProvider to the network. """ console = RichConsole() + if not url: + url = fetch_url(network) if not fork: # Prodmode console.log("Running script in prod mode...") - boa.set_env(NetworkEnv(fetch_url(network))) + boa.set_env(NetworkEnv(url)) boa.env.add_account(Account.from_key(os.environ["FIDDYDEPLOYER"])) else: # Forkmode console.log("Simulation Mode. Writing to mainnet-fork.") - boa.env.fork(url=fetch_url(network)) + boa.env.fork(url=url) boa.env.eoa = FIDDY_DEPLOYER CREATE2DEPLOYER = boa.load_abi("abi/create2deployer.json").at( @@ -82,11 +84,12 @@ def main(network, fork): if len(ids) > 20: raise + console.log("Adding new ids ...") address_provider.add_new_ids(ids, addresses_for_id, descriptions) if __name__ == "__main__": - network = "kava" + network = "xlayer" fork = False - main(network, fork) + main(network, fork, url="https://xlayerrpc.okx.com") diff --git a/scripts/deploy_and_setup_crypto_ng_handler.py b/scripts/deploy_and_setup_crypto_ng_handler.py index 80b50ca..e1ce87c 100644 --- a/scripts/deploy_and_setup_crypto_ng_handler.py +++ b/scripts/deploy_and_setup_crypto_ng_handler.py @@ -30,11 +30,11 @@ def main(network: str = "ethereum", fork: bool = True): # deploy handlers: registry = boa.load( - "contracts/mainnet/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy", + "contracts/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy", "0x98EE851a00abeE0d95D08cF4CA2BdCE32aeaAF7F", ) registry = boa.load( - "contracts/mainnet/registry_handlers/ng/CurveTricryptoFactoryHandler.vy", + "contracts/registry_handlers/ng/CurveTricryptoFactoryHandler.vy", "0x0c0e5f2fF0ff18a3be9b835635039256dC4B4963", ) console.log(f"Deployed Factory Handlers.") diff --git a/scripts/deploy_and_setup_stableswap_factory_ng_handler.py b/scripts/deploy_and_setup_stableswap_factory_ng_handler.py index 82d025a..1c6bb00 100644 --- a/scripts/deploy_and_setup_stableswap_factory_ng_handler.py +++ b/scripts/deploy_and_setup_stableswap_factory_ng_handler.py @@ -30,7 +30,7 @@ def main(network: str = "ethereum", fork: bool = True): # deploy basepool registry: registry = boa.load( - "contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy", + "contracts/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy", "0x6A8cbed756804B16E05E741eDaBd5cB544AE21bf", # stableswap factory ng ) console.log( diff --git a/scripts/deploy_crypto_registry_handler.py b/scripts/deploy_crypto_registry_handler.py index 5a9cc3c..c869516 100644 --- a/scripts/deploy_crypto_registry_handler.py +++ b/scripts/deploy_crypto_registry_handler.py @@ -21,7 +21,7 @@ def main(): console = RichConsole() console.log("Deploying Crypto Registry Handler contract...") setup_environment(console) - boa.load("contracts/mainnet/registry_handlers/CryptoRegistryHandler.vy") + boa.load("contracts/registry_handlers/CryptoRegistryHandler.vy") if __name__ == "__main__": diff --git a/scripts/deploy_metaregistry_sidechain_l2s.py b/scripts/deploy_metaregistry_sidechain_l2s.py new file mode 100644 index 0000000..531358b --- /dev/null +++ b/scripts/deploy_metaregistry_sidechain_l2s.py @@ -0,0 +1,128 @@ +import os +import sys + +import boa +from eth_account import Account +from rich.console import Console as RichConsole + +sys.path.append("./") + +FIDDY_DEPLOYER = "" +ADDRESS_PROVIDER = "0x5ffe7FB82894076ECB99A30D6A32e969e6e35E98" +GAUGE_TYPE = { + "arbitrum": 7, + "optimism": 11, + "polygon": 2, + "base": 0, + "fraxtal": 11, + "bsc": 12, + "gnosis": 4, + "fantom": 1, + "avalanche": 8, + "aurora": -1, + "celo": -1, + "kava": 9, + "mantle": -1, + "linea": -1, + "scroll": -1, + "polygon-zkevm": -1, + "xlayer": -1, +} + + +def fetch_url(network): + return os.getenv("DRPC_URL") % (network, os.getenv("DRPC_KEY")) + + +def main(network, fork, url=""): + """ + Deploy the AddressProvider to the network. + """ + assert "ethereum" not in network + console = RichConsole() + if not url: + url = fetch_url(network) + + if not fork: + # Prodmode + console.log("Running script in prod mode...") + boa.set_network_env(url) + boa.env.add_account(Account.from_key(os.environ["FIDDYDEPLOYER"])) + boa.env.suppress_debug_tt(True) + + else: + # Forkmode + console.log("Simulation Mode. Writing to mainnet-fork.") + boa.env.fork(url=url) + boa.env.eoa = FIDDY_DEPLOYER + + address_provider = boa.load_partial("contracts/AddressProviderNG.vy").at( + ADDRESS_PROVIDER + ) + + # deploy metaregistry + # console.log("Deploying Metaregistry ...") + # gauge_factory = address_provider.get_address(20) # 20 is for Gauge Factory + # gauge_type = GAUGE_TYPE[network] + # metaregistry = boa.load("contracts/MetaregistryL2.vy", gauge_factory, gauge_type) + # console.log( + # "Constructor arguments: ", + # encode(["address", "int128"], [gauge_factory, gauge_type]).hex(), + # ) + + # xlayer + metaregistry = boa.load_partial("contracts/MetaregistryL2.vy").at( + "0x87DD13Dd25a1DBde0E1EdcF5B8Fa6cfff7eABCaD" + ) + + # set up tricrypto ng factory handler + console.log("Deploy Tricrypto Factory Handler ...") + tricrypto_ng_factory = address_provider.get_address(11) + tricrypto_ng_factory_handler = boa.load( + "contracts/registry_handlers/ng/CurveTricryptoFactoryHandler.vy", + tricrypto_ng_factory, + ) + + # set up stableswap ng factory handler + console.log("Deploy Stableswap Factory Handler ...") + stableswap_ng_factory = address_provider.get_address(12) + stableswap_ng_factory_handler = boa.load( + "contracts/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy", + stableswap_ng_factory, + ) + + # set up twocrypto ng factory handler + console.log("Deploy Twocrypto Factory Handler ...") + twocrypto_ng_factory = address_provider.get_address(13) + twocrypto_ng_factory_handler = boa.load( + "contracts/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy", + twocrypto_ng_factory, + ) + + # Add registry handlers to the metaregistry + console.log("Add Factory Handlers to Metaregistry ...") + metaregistry.add_registry_handler(stableswap_ng_factory_handler.address) + metaregistry.add_registry_handler(twocrypto_ng_factory_handler.address) + metaregistry.add_registry_handler(tricrypto_ng_factory_handler.address) + + # add metaregistry to address provider + console.log("Add Metaregistry to AddressProvider ...") + address_provider.add_new_id(7, metaregistry.address, "Metaregistry") + + console.log("Deployment and integration of the Metaregistry completed.") + + +if __name__ == "__main__": + # not deployed: + # aurora + + network = "" + fork = False + url = "" + + if network == "xlayer": + url = "https://rpc.xlayer.tech" + elif network == "fraxtal": + url = "https://rpc.frax.com" + + main(network, fork, url=url) diff --git a/scripts/utils/print_missing.py b/scripts/utils/print_missing.py index e7630d8..b254497 100644 --- a/scripts/utils/print_missing.py +++ b/scripts/utils/print_missing.py @@ -37,7 +37,7 @@ def get_functions_from_source(name: str) -> set[str]: :param name: the name of the source file :return: the view functions from the source file """ - deployer = boa.load_partial(f"contracts/mainnet/{name}.vy") + deployer = boa.load_partial(f"contracts/{name}.vy") meta_functions = get_view_functions( abi=build_abi_output(deployer.compiler_data) ) diff --git a/tests/unitary/conftest.py b/tests/unitary/conftest.py index f6138f3..4824947 100644 --- a/tests/unitary/conftest.py +++ b/tests/unitary/conftest.py @@ -39,7 +39,7 @@ def stable_ng_factory_handler( ): with boa.env.prank(ng_owner): return boa.load( - "contracts/mainnet/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy", + "contracts/registry_handlers/ng/CurveStableSwapFactoryNGHandler.vy", stableswap_ng_factory.address, populated_base_pool_registry.address, ) @@ -49,7 +49,7 @@ def stable_ng_factory_handler( def twocrypto_ng_factory_handler(twocrypto_ng_factory, ng_owner): with boa.env.prank(ng_owner): return boa.load( - "contracts/mainnet/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy", + "contracts/registry_handlers/ng/CurveTwocryptoFactoryHandler.vy", twocrypto_ng_factory.address, ) @@ -58,7 +58,7 @@ def twocrypto_ng_factory_handler(twocrypto_ng_factory, ng_owner): def tricrypto_ng_factory_handler(tricrypto_ng_factory, ng_owner): with boa.env.prank(ng_owner): return boa.load( - "contracts/mainnet/registry_handlers/ng/CurveTricryptoFactoryHandler.vy", + "contracts/registry_handlers/ng/CurveTricryptoFactoryHandler.vy", tricrypto_ng_factory.address, ) diff --git a/tests/utils.py b/tests/utils.py index d26117a..e158188 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -27,9 +27,7 @@ def deploy_contract( directory: str = ".", **kwargs, ) -> VyperContract: - file_name = path.join( - BASE_DIR, f"contracts/mainnet/{directory}/{contract}.vy" - ) + file_name = path.join(BASE_DIR, f"contracts/{directory}/{contract}.vy") with boa.env.sender(sender): return boa.load(file_name, *args, **kwargs)