vault.curator
Documentation for eth_defi.vault.curator Python module.
Vault curator identification and metadata.
Vault curators are professional risk managers and strategy operators that brand their vaults by embedding their organisation name in the vault’s token name or display name. Examples include Gauntlet, RE7 Labs, Steakhouse Financial, and MEV Capital.
This module provides:
Curator identification — given a vault name, detect which curator manages it using word-boundary regex matching against known curator names loaded from YAML feeder files
Protocol-curated detection — some vaults are operated by the protocol itself (Ostium, Gains Network, Hyperliquid HLP, Lighter LLP) rather than a third-party curator; these are identified by address lookups against known system vault address sets
Curator metadata loading — load curator metadata from the shared feeder YAML files in
eth_defi/data/feeds/curators/R2 metadata export — upload per-curator metadata JSON and an aggregate index to Cloudflare R2 for frontend consumption
Curator YAML files use the shared feeder schema defined in
eth_defi.feed.sources. Each file lives under
eth_defi/data/feeds/curators/ and follows this format:
feeder-id: gauntlet
name: Gauntlet
role: curator
website: https://www.gauntlet.xyz
curatorwatch: https://curatorwatch.com/curator/gauntlet
twitter: gauntlet_xyz
linkedin: gauntlet-xyz
rss: https://medium.com/feed/gauntlet-networks
short_description: Gauntlet is a DeFi risk manager.
long_description: |
Gauntlet builds risk management systems for lending markets,
vaults and other on-chain financial applications.
Canonical feeder aliases
When the same organisation appears as both a curator and a stablecoin
issuer or vault protocol, duplicate feed fetching is avoided by using
canonical-feeder-id. An alias YAML file contains identity and
description metadata, but no feed source fields (twitter, linkedin, rss):
feeder-id: ethena
name: Ethena
role: curator
canonical-feeder-id: usde
The priority order determines which role keeps the feed sources:
Stablecoin — highest priority, always keeps feeds
Protocol — keeps feeds only when no stablecoin overlap exists
Curator — lowest priority, defers to stablecoin or protocol
Metadata inheritance happens at export time:
build_curator_metadata_json() resolves the canonical feeder
YAML by role priority and inherits website, twitter, linkedin and rss
from it.
Post resolution happens at consumption time — consumers use
resolve_feeder_id() to map an alias
feeder_id to the canonical feeder_id, then look up posts under that
canonical feeder’s tracked sources. The canonical_feeder_id field
is included in the exported CuratorMetadata JSON so that
frontends can resolve without accessing YAML files.
Identification approach
The curator name is matched against the vault display name using
word-boundary regular expressions (\b). This avoids false
positives such as bare "Gamma" matching "GammaSwap V1" or
"August" matching "Prize imToken August Campaign".
For curators whose YAML name field alone is insufficient (e.g.
"RE7 Labs" vaults often appear as just "RE7 …"), additional
short patterns are registered in CURATOR_NAME_PATTERNS.
Protocol-curated vaults are identified before name matching:
Ostium and Gains Network — all vaults on these protocols are protocol-curated (no external curator)
Frax — only vaults whose identified protocol is Frax are attributed to the Frax Finance curator; holding FRAX or frxUSD is not curator evidence
Hyperliquid — system vaults (HLP parent, HLP children, Liquidator) are identified by address against
eth_defi.hyperliquid.constants.HYPERLIQUID_SYSTEM_VAULT_ADDRESSESLighter — the LLP system pool is identified by address against
eth_defi.lighter.constants.LIGHTER_SYSTEM_POOL_ADDRESSES
Usage example:
from eth_defi.vault.curator import identify_curator, get_curator_name
slug = identify_curator(
chain_id=1,
vault_token_symbol="gtUSDC",
vault_name="Gauntlet USDC Core",
vault_address="0x1234…",
protocol_slug="morpho",
)
assert slug == "gauntlet"
assert get_curator_name(slug) == "Gauntlet"
# Protocol-curated vault — returns the protocol slug itself
slug = identify_curator(
chain_id=999,
vault_token_symbol="HLP",
vault_name="Hyperliquid Liquidity Pool",
vault_address="0xdfc24b077bc1425ad1dea75bcb6f8158e10df303",
protocol_slug="hyperliquid",
)
assert slug == "hyperliquid"
assert get_curator_name(slug) == "Hyperliquid"
assert is_protocol_curator(slug)
Module Attributes
Logo variants supported by the shared vault logo folder. |
|
Protocol slugs where all vaults are protocol-curated. |
|
Protocol slug aliases that should resolve to the canonical protocol-curator slug emitted by |
|
Complete set of protocol slugs that can appear as curator slugs. |
|
Human-readable names for protocol-curator slugs. |
|
Additional name patterns for curator matching. |
|
Distributor / sponsor curators whose brand is a white-label wrapper. |
|
Protocol curator slugs that must never be inferred from a name alone. |
|
Protocol-specific curator metadata fields in curator YAML files. |
|
Exact vault address to curator overrides from Dune dashboards. |
Functions
|
Build the aggregate curator metadata index. |
|
Build a |
Check which logo variants are available for a curator. |
|
|
Look up the human-readable name for a curator slug. |
|
Identify the curator managing a vault. |
|
Check whether a curator slug represents a protocol-curated vault. |
Load all curator metadata from YAML files. |
|
|
Process and upload a single curator's metadata and logos to R2. |
|
Build and upload the aggregate curator index to R2. |
|
Upload metadata entries for all protocol-curated slugs to R2. |
Classes
Metadata for a single curator loaded from YAML. |
|
Logo URLs for a vault curator. |
|
Curator metadata as exported to JSON for R2 upload. |
- VAULTS_DATA_DIR: pathlib.Path = PosixPath('/home/runner/work/web3-ethereum-defi/web3-ethereum-defi/eth_defi/data/vaults')
Base directory for shared vault protocol and curator data.
- FORMATTED_LOGOS_DIR: pathlib.Path = PosixPath('/home/runner/work/web3-ethereum-defi/web3-ethereum-defi/eth_defi/data/vaults/formatted_logos')
Directory containing formatted 256x256 PNG logos.
- LOGO_VARIANTS: tuple[str, ...] = ('generic', 'dark', 'light')
Logo variants supported by the shared vault logo folder.
- CURATORS_DATA_DIR: pathlib.Path = PosixPath('/home/runner/work/web3-ethereum-defi/web3-ethereum-defi/eth_defi/data/feeds/curators')
Path to the curator feeder YAML files.
These files use the shared feeder schema from
eth_defi.feed.sourcesand are also consumed by the feed post collector.
- PROTOCOL_CURATED_SLUGS: set[str] = {'3jane', 'atoma', 'd2-finance', 'domination-finance', 'frankencoin', 'frax-finance', 'gains-network', 'ondo', 'ostium', 'usyc', 'wstgbp'}
Protocol slugs where all vaults are protocol-curated.
For these protocols there is no external curator — the protocol itself operates every vault. Values use the canonical curator slug after applying
PROTOCOL_CURATOR_SLUG_ALIASES.
- PROTOCOL_CURATOR_SLUG_ALIASES: dict[str, str] = {'frax': 'frax-finance', 'gtrade': 'gains-network'}
Protocol slug aliases that should resolve to the canonical protocol-curator slug emitted by
identify_curator().
- ALL_PROTOCOL_CURATOR_SLUGS: set[str] = {'3jane', 'atoma', 'd2-finance', 'domination-finance', 'frankencoin', 'frax-finance', 'gains-network', 'grvt', 'hyperliquid', 'lighter', 'ondo', 'ostium', 'spiko-curator', 'theo-curator', 'usyc', 'wstgbp'}
Complete set of protocol slugs that can appear as curator slugs.
Includes both blanket protocol-curated slugs and protocols whose system vaults are protocol-curated (Hyperliquid HLP, Lighter LLP, GRVT GLP). Use
is_protocol_curator()to check membership.
- PROTOCOL_CURATOR_NAMES: dict[str, str] = {'3jane': '3Jane', 'atoma': 'Atoma', 'd2-finance': 'D2 Finance', 'domination-finance': 'Domination Finance', 'frankencoin': 'Frankencoin', 'frax-finance': 'Frax Finance', 'gains-network': 'Gains Network', 'grvt': 'GRVT', 'hyperliquid': 'Hyperliquid', 'lighter': 'Lighter', 'ondo': 'Ondo Finance', 'ostium': 'Ostium', 'spiko-curator': 'Spiko', 'theo-curator': 'Theo', 'usyc': 'Circle USYC', 'wstgbp': 'wstGBP'}
Human-readable names for protocol-curator slugs.
These names are used by
get_curator_name()when the curator slug matches a protocol rather than a third-party curator YAML file.
- CURATOR_NAME_PATTERNS: dict[str, list[str]] = {'9summits': ['9 Summits'], 'agora-finance': ['Agora'], 'apollo-crypto': ['mAPOLLO'], 'august-digital': ['August Digital', 'August USDC', 'August AUSD'], 'avantgarde-finance': ['Avantgarde'], 'b-cube-ai': ['B-CUBE', 'BCUBE'], 'b-protocol': ['B.Protocol'], 'bizantine': ['Bizantine'], 'clearstar-labs': ['Clearstar'], 'damm-capital': ['DAMM Capital', 'DAMM'], 'edge-and-hedge': ['Edge & Hedge', 'Edge and Hedge'], 'edge-capital': ['mEDGE'], 'fasanara': ['mF-ONE', 'mFONE'], 'felix': ['Felix'], 'fija': ['Fija'], 'fisher8-capital': ['Fisher8'], 'gamma-strategies': ['Gamma Strategies'], 'growi-finance': ['Growi'], 'harvest': ['Harvest'], 'ignight-capital': ['Ignight'], 'insertive-capital': ['Insertive'], 'ipor': ['IPOR', 'Autopilot'], 'k3-capital': ['K3 Capital', 'K3'], 'kappa-lab': ['Fire Liquidity Provider', 'FLP'], 'keyring-network': ['Keyring'], 'llama-risk': ['LlamaRisk', 'Llama Risk'], 'm11-credit': ['M11C'], 'pareto-technologies': ['Pareto'], 'pistachio': ['Pistachio'], 're7-labs': ['RE7'], 'reservoir': ['Reservoir'], 'rogue-traders': ['Rogue Traders'], 'sentora': ['IntoTheBlock'], 'singularity': ['Singularity'], 'stake-dao': ['StakeDAO'], 'steakhouse-financial': ['Steakhouse', 'Smokehouse'], 'strata': ['Strata-Money', 'Strata'], 'systemic-strategies': ['Systemic Strategies'], 'tangent-finance': ['Tangent'], 'tanken': ['Tanken'], 'tau': ['TAU'], 'telosc': ['TelosC'], 'tid-capital': ['TiD Capital', 'TiD'], 'tulipa-capital': ['Tulipa'], 'usdai': ['USD.AI', 'USDai'], 'varlamore-capital': ['Varlamore'], 'woo': ['Woo'], 'xerberus': ['Xerberus'], 'yo': ['yoUSD', 'yoETH', 'yoBTC', 'yoEUR', 'yoGOLD', 'yoUSDT', 'yUSD', 'YO Treasury']}
Additional name patterns for curator matching.
Maps curator slug to a list of extra patterns (beyond the YAML
namefield) that should also trigger a match. Each pattern is compiled as a word-boundary regex (\\bPATTERN\\b).Use full compound names to avoid false positives — e.g.
"Gamma Strategies"not"Gamma"(which would match"GammaSwap V1").
- SPONSOR_CURATOR_SLUGS: set[str] = {'cool-wallet', 'trust-wallet'}
Distributor / sponsor curators whose brand is a white-label wrapper.
These organisations brand a vault family (e.g. “Trust Wallet Morpho Smokehouse USDC”) but the underlying strategy is run by another curator named in the same vault title. Their name patterns are matched at the lowest priority so the real risk curator (Smokehouse/Steakhouse, Gauntlet, …) wins on co-branded vaults, while sponsor-only vaults (e.g. “Trust Wallet AAVE v3 USDT”, where the underlying is an uncurated Aave market) still resolve to the sponsor.
- PROTOCOL_BOUND_CURATOR_SLUGS: set[str] = {'frax-finance'}
Protocol curator slugs that must never be inferred from a name alone.
Frax assets are widely used by third-party protocols and curators. A vault name containing FRAX or frxUSD establishes its denomination or strategy, not that Frax operates the vault.
- PROTOCOL_MANAGER_YAML_FIELDS: dict[str, str] = {'accountable': 'accountable-company', 'asseto': 'asseto-role', 'euler': 'euler-entity', 'ipor-fusion': 'ipor-atomist', 'lagoon-finance': 'lagoon-curator', 'morpho': 'morpho-curator', 't3tris': 't3tris-curator', 'upshift': 'upshift-strategist'}
Protocol-specific curator metadata fields in curator YAML files.
- CURATOR_ADDRESS_OVERRIDES: dict[tuple[int, str], str] = {(1, '0x0324dd195d0cd53f9f07bee6a48ee7a20bad738f'): 'spice-vc', (1, '0x09864f52b035ae22ee739dfa5c748fa080d07bd8'): 'jpmorgan', (1, '0x098697ba3fee4ea76294c5d6a466a4e3b3e95fe6'): 'piku', (1, '0x0f0a9d3f0bc6006143c96e6995572b51413cb3c4'): 'rockawayx', (1, '0x17418038ecf73ba4026c4f428547bf099706f27b'): 'apollo', (1, '0x1b19c19393e2d034d8ff31ff34c81252fcbbee92'): 'ondo', (1, '0x1f41e42d0a9e3c0dd3ba15b527342783b43200a9'): 'blockchain-capital', (1, '0x1fecf3d9d4fee7f2c02917a66028a48c6706c179'): 'wisdomtree', (1, '0x2255718832bc9fd3be1caf75084f4803da14ff01'): 'vaneck', (1, '0x237c717df1b60501f8d029d3fe7385fd090df180'): 'bosera-asset-management-international', (1, '0x252739487c1fa66eaeae7ced41d6358ab2a6bca9'): 'arca', (1, '0x286d9f099587f567ece2b70ebb64b94acd672d76'): 'cncb-capital', (1, '0x2bf11d2e04bc40daa95c24b8b90ec4f5c57dd326'): 'piku', (1, '0x383730608d98b82470d733369a839f6b7e8cfda5'): 'dl-holdings', (1, '0x3be5dd4a34f1c6a112048b9df908ced4372d5049'): 'epoch-rwa', (1, '0x3ddc84940ab509c11b20b76b466933f40b750dc9'): 'franklin-templeton', (1, '0x42975aae7a124257e7fda7f5e8382f51449b784a'): 'blackrock', (1, '0x43415eb6ff9db7e26a15b704e7a3edce97d31c4e'): 'superstate', (1, '0x4867ad1a74b38b0aeff4fff251ed0dadae4f4630'): 'cms-asset-management-hk', (1, '0x48ab4e39ac59f4e88974804b04a991b3a402717f'): 'fidelity', (1, '0x498d9329555471bf6073a5f2d047f746d522a373'): 'cms-asset-management-hk', (1, '0x50293dd8889b931eb3441d2664dce8396640b419'): 'wellington-management', (1, '0x50bdaff4bceb852f006f657f47c68fcc417f7beb'): 'haitong-international-asset-management', (1, '0x51c2d74017390cbbd30550179a16a1c28f7210fc'): 'bny-investments', (1, '0x54a4fc78431f9201824643e99bec891bb7462a1d'): 'fidelity', (1, '0x5e17f6f450dcb0bc69b232ea554e224d7e88067a'): 'protos-asset-management', (1, '0x5f829b1b473cba86838e1b7bb7e144dbde228e21'): 'rockawayx', (1, '0x5fa487bca6158c64046b2813623e20755091da0b'): 'theo-curator', (1, '0x63e19fb814eb737730ac0afbb52b351695b97176'): 'gaoteng-global-asset-management', (1, '0x64c18dcc4ccb3b8d27877a4aebb4c3126cb39cb9'): 'rockawayx', (1, '0x67e1f506b148d0fc95a4e3ffb49068ceb6855c05'): 'rockawayx', (1, '0x682ef9cc637ef56577092b29ae9275a629aae7db'): 'science-inc', (1, '0x6a7c6aa2b8b8a6a891de552bdeffa87c3f53bd46'): 'jpmorgan', (1, '0x6a9da2d710bb9b700acde7cb81f10f1ff8c89041'): 'blackrock', (1, '0x6dc4674573380aff6c3359e19da5cbb6afceb5c3'): 'cms-asset-management-hk', (1, '0x7712c34205737192402172409a8f7ccef8aa2aec'): 'blackrock', (1, '0x78e80da0616887b46a31f39310c2a8b0fbd6a42d'): 'chinaamc-hong-kong', (1, '0x827ce7e8e35861d9ac7fe002755767b695a5594a'): 'piku', (1, '0x85d38585c3ac08268f598282a84b7c0ddfc0d04f'): 'chinaamc-hong-kong', (1, '0x8ac91877b93330f52b2979a31a4879506021475c'): 'rockawayx', (1, '0x8c213ee79581ff4984583c6a801e5263418c4b86'): 'janus-henderson-anemoy', (1, '0x90276e9d4a023b5229e0c2e9d4b2a83fe3a2b48c'): 'franklin-templeton', (1, '0x907c00d587daff16d028fe1e131d6dd3c6bf2f4b'): 'cms-asset-management-hk', (1, '0x953972ea0c1703c58f09fb6fd2477fdcf0fee074'): 'rockawayx', (1, '0x96f6ef951840721adbf46ac996b59e0235cb985c'): 'ondo', (1, '0x99351baed3d8ab544ccb08af96a105910fda71e7'): 'piku', (1, '0xb9c317cae7dd05ecb0c0925020e529934c96f84d'): 'rockawayx', (1, '0xc0c61c29ef8beabc694987c93e5fe4af647042e7'): 'cosimo-digital', (1, '0xc87dbbb8c67e4f19fcd2e297c05937567b2572ce'): 'rockawayx', (1, '0xcd69123b3fbbfc666e1f6a501da27b564c00de54'): 'rockawayx', (1, '0xd65d6e8dbc3cd3d12418199e6f4014db3aaa0097'): 'rockawayx', (1, '0xda2ffa104356688e74d9340519b8c17f00d7752e'): 'hamilton-lane', (1, '0xe0181090c22579b6a217f1522cbf8c9f1f0c1965'): 'rockawayx', (1, '0xe4880249745eac5f1ed9d8f7df844792d560e750'): 'spiko-curator', (1, '0xe99a27169c2aa26a8f2757949d09fa3f9a8f0b3b'): 'rockawayx', (1, '0xf0db6f529581e7f6ebac7a7f6882923c00fc3a66'): 'fidelity', (1, '0xf252c5bd43907a6cab079e990845a37a7c5730d9'): 'partners-group', (1, '0xf3a2a5de306b063d75c86b6352832639b7263a3b'): 'muzinich', (10, '0xa1cdab15bba75a80df4089cafba013e376957cf5'): 'blackrock', (56, '0x1775504c5873e179ea2f8abfce3861ec74d159bc'): 'cms-asset-management-hk', (56, '0x1ec3aa07e3898f1e6d4f23b5dce1bdbecb5c1fe1'): 'chinaamc-hong-kong', (56, '0x50bf2924cee59737ead76e881643ed8569bae6e8'): 'partners-group', (56, '0xb5a30e1fa2cf3c8dea882124b3ab5a47a27c5dd2'): 'rockawayx', (56, '0xfb8cb7630bc3cb34a6a9846ec03de3a32393ee65'): 'muzinich', (137, '0x2893ef551b6dd69f661ac00f11d93e5dc5dc0e99'): 'blackrock', (1329, '0x6137dcfdd3c83fe2922b1cba4105d2e92b327a06'): 'rockawayx', (5000, '0x671642ac281c760e34251d51bc9eef27026f3b7a'): 'mantle-guard', (8453, '0xae4181cfb5aaa08bbe77d269c6b595672b9f9edc'): 'rockawayx', (42161, '0xa6525ae43edcd03dc08e775774dcabd3bb925872'): 'blackrock', (42161, '0xc26af85ede9cc25d449bcebef866bb85afd5d346'): 'wellington-management', (43114, '0x53fc82f14f009009b440a706e31c9021e1196a2f'): 'blackrock', (43114, '0xb2ea3e7b80317c4e20d1927034162176e25834e2'): 'dfzq'}
Exact vault address to curator overrides from Dune dashboards.
Used when the public vault display name does not carry the curator brand, or carries a co-branded protocol/issuer name that would otherwise win fuzzy matching. Keys are
(chain_id, lowercase_vault_address).
- class CuratorInfo
Bases:
TypedDictMetadata for a single curator loaded from YAML.
Represents the in-memory view of a curator feeder file from
eth_defi/data/feeds/curators/.- slug: str
URL-safe slug identifier, matches the YAML filename stem and
feeder-idfield (e.g."gauntlet","re7-labs").
- twitter: Optional[str]
Twitter/X handle without
@prefix (e.g."gauntlet_xyz"), orNoneif not configured.
- linkedin: Optional[str]
LinkedIn company identifier (e.g.
"gauntlet-xyz"), orNoneif not configured.
- rss: Optional[str]
RSS or Atom feed URL for the curator’s blog or newsletter, or
Noneif not configured.
- protocol_curator: bool
Whether this is a protocol-native curator (the protocol itself acts as curator) rather than a third-party risk manager.
Truefor protocol-curated vaults (Ostium, Gains Network, HLP, LLP).Falsefor third-party curators (Gauntlet, RE7 Labs, etc.).
- canonical_feeder_id: Optional[str]
When set, this curator’s feed sources are provided by another feeder identified by this slug. The canonical feeder may be in a different role (e.g. a stablecoin feeder). Posts for this curator should be looked up under the canonical feeder’s sources.
Nonefor curators that have their own feed sources.
- protocol_manager_names: dict[str, str | tuple[str, ...]]
Exact protocol manager names keyed by protocol slug.
These values are sourced from protocol-specific YAML fields such as
euler-entity,lagoon-curatorandupshift-strategist.
- __init__(*args, **kwargs)
- __new__(**kwargs)
- clear()
Remove all items from the dict.
- copy()
Return a shallow copy of the dict.
- fromkeys(value=None, /)
Create a new dictionary with keys from iterable and values set to value.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items()
Return a set-like object providing a view on the dict’s items.
- keys()
Return a set-like object providing a view on the dict’s keys.
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- setdefault(key, default=None, /)
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- update([E, ]**F) None. Update D from mapping/iterable E and F.
If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values()
Return an object providing a view on the dict’s values.
- class CuratorLogos
Bases:
TypedDictLogo URLs for a vault curator.
Logo URLs point to 256x256 PNG files in R2 storage.
Noneif the logo variant is not available.- __init__(*args, **kwargs)
- __new__(**kwargs)
- clear()
Remove all items from the dict.
- copy()
Return a shallow copy of the dict.
- fromkeys(value=None, /)
Create a new dictionary with keys from iterable and values set to value.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items()
Return a set-like object providing a view on the dict’s items.
- keys()
Return a set-like object providing a view on the dict’s keys.
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- setdefault(key, default=None, /)
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- update([E, ]**F) None. Update D from mapping/iterable E and F.
If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values()
Return an object providing a view on the dict’s values.
- class CuratorMetadata
Bases:
TypedDictCurator metadata as exported to JSON for R2 upload.
This is the public API shape consumed by the frontend. Twitter and LinkedIn fields are expanded to full URLs rather than bare handles/identifiers.
- linkedin: Optional[str]
Full LinkedIn company URL (e.g.
"https://www.linkedin.com/company/gauntlet-xyz"), orNone.
- logos: eth_defi.vault.curator.CuratorLogos
Logo URLs for available 256x256 PNG variants.
- protocol_curator: bool
Whether this curator is the protocol itself (not a third party).
Truefor protocol-curated vaults (e.g. Ostium, Gains Network, HLP, LLP).Falsefor third-party curators (e.g. Gauntlet, RE7 Labs).
- canonical_feeder_id: Optional[str]
When this curator is an alias, the slug of the canonical feeder whose posts should be used.
Nonefor non-alias curators. Consumers should look up posts under this feeder_id instead.
- __init__(*args, **kwargs)
- __new__(**kwargs)
- clear()
Remove all items from the dict.
- copy()
Return a shallow copy of the dict.
- fromkeys(value=None, /)
Create a new dictionary with keys from iterable and values set to value.
- get(key, default=None, /)
Return the value for key if key is in the dictionary, else default.
- items()
Return a set-like object providing a view on the dict’s items.
- keys()
Return a set-like object providing a view on the dict’s keys.
- pop(k[, d]) v, remove specified key and return the corresponding value.
If the key is not found, return the default if given; otherwise, raise a KeyError.
- popitem()
Remove and return a (key, value) pair as a 2-tuple.
Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.
- setdefault(key, default=None, /)
Insert key with a value of default if key is not in the dictionary.
Return the value for key if key is in the dictionary, else default.
- update([E, ]**F) None. Update D from mapping/iterable E and F.
If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]
- values()
Return an object providing a view on the dict’s values.
- load_curator_map()
Load all curator metadata from YAML files.
Returns a dict mapping slug to
CuratorInfo. Cached in-process after first call (same pattern aseth_defi.stablecoin_metadata.load_all_stablecoin_metadata()).- Returns
Dict keyed by curator slug.
- Return type
- identify_curator(chain_id, vault_token_symbol, vault_name, vault_address, protocol_slug='', manager_name='', declared_curator_slug=None)
Identify the curator managing a vault.
Checks protocol-curated status first (by protocol slug and vault address), then falls back to word-boundary regex matching against the vault display name and the manager name.
Some native marketplace protocols (notably GRVT) brand the curator in a separate
manager_namefield rather than the vault display name — the vault name there is the strategy name (e.g."Ethereum Moving Average Long/Short") while the curator identity (e.g."Gerhard - Bitcoin Strategy") is the manager. Passmanager_nameso these curators are detected. Exact protocol manager metadata runs before ordinary vault-name and manager-name fuzzy matching. Protocol-bound curators such as Frax are never inferred from asset names.- Parameters
chain_id (int) – Chain ID where the vault is deployed.
vault_token_symbol (str) – The vault’s share token symbol (e.g.
"gtUSDC").vault_name (str) – The vault’s human-readable display name, which curators typically brand with their organisation name.
vault_address (str) – The vault’s on-chain address (hex or synthetic format).
protocol_slug (str) – Slugified protocol name from
eth_defi.research.vault_metrics.slugify_protocol()(e.g."morpho","hyperliquid","lighter").manager_name (Optional[str]) – Optional name of the vault manager/operator, used by native marketplace protocols (e.g. GRVT) where the curator brand lives in the manager field rather than the vault name. Empty string or
Nonewhen unknown.declared_curator_slug (Optional[str]) – Optional curator slug exported directly by a reviewed vault adapter. Exact chain/address overrides still take precedence so corrected attribution also applies to stale cached scan metadata.
- Returns
Curator slug (e.g.
"gauntlet","ostium","hyperliquid"), orNoneif no curator could be identified. For protocol-curated vaults the protocol slug itself is returned. Useis_protocol_curator()to distinguish protocol-curated from third-party curators.- Return type
- is_protocol_curator(slug)
Check whether a curator slug represents a protocol-curated vault.
Protocol-curated means the protocol itself operates the vault rather than a third-party risk manager.
- Parameters
slug (str) – Curator slug as returned by
identify_curator().- Returns
Trueif the slug identifies a protocol acting as its own curator.- Return type
- get_curator_name(slug)
Look up the human-readable name for a curator slug.
Handles both third-party curators (looked up from YAML) and protocol-curated slugs (looked up from
PROTOCOL_CURATOR_NAMES).- Parameters
slug (str) – Curator slug as returned by
identify_curator().- Returns
Human-readable curator name, or
Noneif not found.- Return type
- get_curator_available_logos(slug)
Check which logo variants are available for a curator.
Curator and vault protocol logos share
eth_defi/data/vaults/formatted_logos/{slug}/.
- build_curator_metadata_json(yaml_path, public_url='')
Build a
CuratorMetadatadict from a curator YAML file.Twitter handles are expanded to full
https://x.com/{handle}URLs. LinkedIn company identifiers are expanded to fullhttps://www.linkedin.com/company/{id}URLs.- Parameters
yaml_path (pathlib.Path) – Path to a curator YAML file.
public_url (str) – Public base URL for constructing logo URLs.
- Returns
Metadata dict ready for JSON serialisation.
- Return type
- process_and_upload_curator_metadata(yaml_path, bucket_name, endpoint_url, access_key_id, secret_access_key, public_url='', key_prefix='')
Process and upload a single curator’s metadata and logos to R2.
Uploads:
curator-metadata/{key_prefix}{slug}/metadata.json— JSON metadatacurator-metadata/{key_prefix}{slug}/{variant}.png— 256x256 logo
- Parameters
yaml_path (pathlib.Path) – Path to the curator YAML file.
bucket_name (str) – R2 bucket name.
endpoint_url (str) – R2 API endpoint URL.
access_key_id (str) – R2 access key ID.
secret_access_key (str) – R2 secret access key.
public_url (str) – Public base URL for constructing logo URLs in metadata.
key_prefix (str) – Optional prefix for R2 keys (e.g.
"test-"for testing).
- Returns
The processed
CuratorMetadata.- Return type
- upload_protocol_curator_metadata(bucket_name, endpoint_url, access_key_id, secret_access_key, public_url='', key_prefix='')
Upload metadata entries for all protocol-curated slugs to R2.
Ensures that
curator-metadata/{slug}/metadata.jsonexists for every protocol inALL_PROTOCOL_CURATOR_SLUGSso that frontend slug lookups never 404.- Parameters
- Returns
List of uploaded
CuratorMetadataentries.- Return type
- build_curator_index(public_url='')
Build the aggregate curator metadata index.
Loads all curator YAML files and appends synthetic entries for protocol-curated slugs. The result is suitable for JSON serialisation and R2 upload as
curator-metadata/index.json.- Parameters
public_url (str) – Public base URL for constructing logo URLs.
- Returns
List of
CuratorMetadatadicts for all known curators.- Return type
- upload_curator_index(bucket_name, endpoint_url, access_key_id, secret_access_key, public_url='', key_prefix='')
Build and upload the aggregate curator index to R2.
Uploads to
curator-metadata/{key_prefix}index.json.- Parameters
- Returns
The full index list.
- Return type