diff --git a/Makefile b/Makefile index 86301a59a..b47ebc8eb 100644 --- a/Makefile +++ b/Makefile @@ -124,7 +124,7 @@ console: build setup-network docker build -f Dockerfile.dev -t ghcr.io/yearn/yearn-exporter . $(compose_command) -p $$PROJECT_PREFIX run --rm --entrypoint "brownie console --network $$BROWNIE_NETWORK" exporter -shell: setup-network +shell: infra setup-network source set_network_envs.sh $(compose_command) -p $$PROJECT_PREFIX run --rm --entrypoint bash exporter diff --git a/yearn/entities.py b/yearn/entities.py index 449cdd352..dde099482 100644 --- a/yearn/entities.py +++ b/yearn/entities.py @@ -98,11 +98,28 @@ class Token(db.Entity): address = Required(Address, column="address_id") streams = Set('Stream', reverse="token") vesting_escrows = Set("VestingEscrow", reverse="token") + vault = Optional("Vault", column="vault_id") @property def scale(self) -> int: return 10 ** self.decimals +class Vault(db.Entity): + _table_ = "vaults" + vault_id = PrimaryKey(int, auto=True) + address = Required(str, index=True) + name = Required(str) + token = Required("Token", column="token_id", index=True) + strategy = Optional("Strategy", column="strategy_id") + version = Required(str) + +class Strategy(db.Entity): + _table_ = "strategies" + strategy_id = PrimaryKey(int, auto=True) + address = Required(str, index=True) + name = Required(str) + vault = Required("Vault", column="vault_id", index=True) + version = Required(str) # Used for wallet exporter and other analysis class UserTx(db.Entity): diff --git a/yearn/outputs/postgres/utils.py b/yearn/outputs/postgres/utils.py index eb083161f..0d98273f0 100644 --- a/yearn/outputs/postgres/utils.py +++ b/yearn/outputs/postgres/utils.py @@ -6,7 +6,7 @@ from pony.orm import db_session, select from y import Contract, ContractNotVerified, Network -from yearn.entities import (Address, Chain, Token, TreasuryTx, TxGroup, UserTx, +from yearn.entities import (Address, Chain, Token, TreasuryTx, TxGroup, UserTx, Vault, Strategy, db) from yearn.multicall2 import fetch_multicall from yearn.utils import hex_to_string, is_contract @@ -93,6 +93,22 @@ def cache_token(address: str) -> Token: logger.info(f'token {symbol} added to postgres') return token +@db_session +def cache_vault(address: str, name: str, version: str) -> Vault: + token = cache_token(address) + vault = Vault.get(token=token) + if not vault: + vault = Vault(token=token, address=address, name=name, version=version) + return vault + +@db_session +def cache_strategy(vault_address: str, vault_name: str, vault_version: str, strategy_address: str, strategy_name: str, strategy_version: str) -> Strategy: + vault = cache_vault(vault_address, vault_name, vault_version) + strategy = Strategy.get(vault=vault, address=strategy_address) + if not strategy: + strategy = Strategy(vault=vault, address=strategy_address, name=strategy_name, version=strategy_version) + return strategy + @db_session def cache_txgroup(name: str, parent: Optional[TxGroup] = None) -> TxGroup: _txgroup = TxGroup.get(name=name) diff --git a/yearn/v1/registry.py b/yearn/v1/registry.py index 41963e170..2f4dc1599 100644 --- a/yearn/v1/registry.py +++ b/yearn/v1/registry.py @@ -14,6 +14,7 @@ from yearn.typing import Block from yearn.utils import contract from yearn.v1.vaults import VaultV1 +from yearn.outputs.postgres.utils import cache_strategy logger = logging.getLogger(__name__) @@ -32,7 +33,17 @@ def vaults(self) -> List[VaultV1]: addresses_generator_v1_vaults = contract(addresses_provider.addressById("ADDRESSES_GENERATOR_V1_VAULTS")) # NOTE: we assume no more v1 vaults are deployed - return [VaultV1(vault_address, *self.registry.getVaultInfo(vault_address)) for vault_address in addresses_generator_v1_vaults.assetsAddresses()] + vaults = [VaultV1(vault_address, *self.registry.getVaultInfo(vault_address)) for vault_address in addresses_generator_v1_vaults.assetsAddresses()] + for v in vaults: + strategy_name = v.strategy._name + if hasattr(v.strategy, "name"): + strategy_name = v.strategy.name() + vault_name = v.vault._name + if hasattr(v.vault, "name"): + vault_name = v.vault.name() + cache_strategy(str(v.vault), vault_name, "v1", str(v.strategy), strategy_name, "v1") + + return vaults def __repr__(self) -> str: return f"" diff --git a/yearn/v2/registry.py b/yearn/v2/registry.py index 4d8741a1a..448fc2c42 100644 --- a/yearn/v2/registry.py +++ b/yearn/v2/registry.py @@ -23,6 +23,7 @@ from yearn.exceptions import UnsupportedNetwork from yearn.multicall2 import fetch_multicall_async from yearn.utils import Singleton, contract +from yearn.outputs.postgres.utils import cache_strategy from yearn.v2.vaults import Vault logger = logging.getLogger(__name__) @@ -106,7 +107,17 @@ def load_from_ens(self): @property @wait_or_exit_before def vaults(self) -> List[Vault]: - return list(self._vaults.values()) + vaults = list(self._vaults.values()) + for v in vaults: + for s in v.strategies: + strategy_name = s.strategy._name + if hasattr(s.strategy, "name"): + strategy_name = s.strategy.name() + vault_name = v.vault._name + if hasattr(v.vault, "name"): + vault_name = v.vault.name() + cache_strategy(str(v.vault), vault_name, v.vault.apiVersion(), str(s.strategy), strategy_name, s.strategy.apiVersion()) + return vaults @property @wait_or_exit_before