midas.registry
Documentation for eth_defi.midas.registry Python module.
Midas deployed contract registry.
This module is a Pythonised snapshot of the public Midas TypeScript address registry. The upstream source is:
https://raw.githubusercontent.com/midas-apps/contracts/main/config/constants/addresses.ts
Snapshot metadata:
Repository:
midas-apps/contractsBranch:
mainCommit:
9151f86df2af21f41f6f0efa0bd361c6d3dc3adfCommit timestamp:
2026-07-09T14:26:21Z
How this file was generated
This registry has two data sources.
The address snapshot is generated from the upstream Midas contract repository.
The MIDAS_ADDRESSES_PER_NETWORK data comes from addresses.ts by
evaluating the exported TypeScript object literals as JavaScript and
serialising them as Python dictionaries. TypeScript undefined values are
converted to None. The companion MIDAS_CHAIN_IDS mapping is generated
from:
https://raw.githubusercontent.com/midas-apps/contracts/main/config/networks/index.ts
The deployment metadata in MIDAS_PRODUCT_DEPLOYMENTS is generated by a
live archive-node scan over each product token address. The scanner performs
binary search with historical eth_getCode calls to find the first block
where the product token bytecode exists, then reads that block timestamp. This
step only covers products whose registry entry has both token and
dataFeed and whose Midas network has a configured local JSON-RPC
environment variable in MIDAS_NETWORK_RPC_ENV_VARS.
Manual update process
Fetch the latest upstream TypeScript files:
curl -L https://raw.githubusercontent.com/midas-apps/contracts/main/config/constants/addresses.ts -o /tmp/midas-addresses.ts curl -L https://raw.githubusercontent.com/midas-apps/contracts/main/config/networks/index.ts -o /tmp/midas-networks.ts
Convert the exported
midasAddressesPerNetwork,sanctionListContractsandustbContractsobjects to Python dictionaries. TypeScriptundefinedvalues should becomeNone. Computed[chainIds.*]keys in the smaller maps should become integer chain ids.Replace only the upstream-generated constants in this file and update
MIDAS_REGISTRY_SOURCE_COMMITandMIDAS_REGISTRY_SOURCE_COMMIT_DATE.Refresh deployment blocks and timestamps from archive nodes:
source .local-test.env && UPDATE_REGISTRY=true poetry run python scripts/midas/scan-deployments.py
The scan output is a
tabulateaudit table. Products on networks without a configured RPC environment variable are skipped instead of guessed.Run:
poetry run ruff format eth_defi/midas/registry.py poetry run ruff check eth_defi/midas/registry.py
The active vault scanner allow-list is generated from this registry. A product
is promoted to the shared scanner once it has an mToken, a Midas datafeed and
deployment metadata. Products without a local RPC mapping or deployment scan
remain visible here, but are not used by the scanner until the missing metadata
is generated. If a product’s registry feeds cannot currently produce a positive
NAV/share, record it in MIDAS_PRODUCT_SCAN_EXCLUSIONS with the observed
reason instead of silently letting production scans fail.
Module Attributes
Registry networks and their local JSON-RPC environment variable names. |
|
Scanned deployment blocks for Midas products. |
|
Non-product registry sections. |
|
Redemption vault fields in preference order for scanner diagnostics. |
|
Custom oracle fields in preference order for share price fallback reads. |
|
Deposit vault fields in preference order for scanner diagnostics. |
|
Products whose registry entries are intentionally not promoted to scanning. |
Functions
|
Group Midas registry products by chain id. |
|
Iterate product-like entries from the Pythonised Midas registry. |
Classes
Scanner-friendly Midas product entry. |
- MIDAS_NETWORK_RPC_ENV_VARS: Final[dict[str, str]] = {'arbitrum': 'JSON_RPC_ARBITRUM', 'base': 'JSON_RPC_BASE', 'bsc': 'JSON_RPC_BINANCE', 'hyperevm': 'JSON_RPC_HYPERLIQUID', 'katana': 'JSON_RPC_KATANA', 'main': 'JSON_RPC_ETHEREUM', 'monad': 'JSON_RPC_MONAD', 'optimism': 'JSON_RPC_OPTIMISM', 'plasma': 'JSON_RPC_PLASMA', 'tac': 'JSON_RPC_TAC'}
Registry networks and their local JSON-RPC environment variable names.
Keep this map explicit because Midas network names do not always match
eth_defi.chain.CHAIN_NAMESaliases.
- MIDAS_PRODUCT_DEPLOYMENTS: Final[dict[tuple[str, str], tuple[int, datetime.datetime]]] = {('arbitrum', 'mBASIS'): (310831851, datetime.datetime(2025, 2, 28, 15, 55, 55)), ('arbitrum', 'mEDGE'): (311756173, datetime.datetime(2025, 3, 3, 8, 39, 59)), ('arbitrum', 'mMEV'): (311756840, datetime.datetime(2025, 3, 3, 8, 42, 45)), ('arbitrum', 'mRE7'): (311757192, datetime.datetime(2025, 3, 3, 8, 44, 13)), ('arbitrum', 'mTBILL'): (310814679, datetime.datetime(2025, 2, 28, 14, 44, 25)), ('base', 'mBASIS'): (21444525, datetime.datetime(2024, 10, 23, 10, 13, 17)), ('base', 'mEDGE'): (26499551, datetime.datetime(2025, 2, 17, 10, 34, 9)), ('base', 'mEVUSD'): (37775645, datetime.datetime(2025, 11, 5, 11, 3, 57)), ('base', 'mLIQUIDITY'): (30256530, datetime.datetime(2025, 5, 15, 9, 46, 47)), ('base', 'mMEV'): (26500311, datetime.datetime(2025, 2, 17, 10, 59, 29)), ('base', 'mRE7'): (26499775, datetime.datetime(2025, 2, 17, 10, 41, 37)), ('base', 'mSL'): (29566149, datetime.datetime(2025, 4, 29, 10, 14, 5)), ('base', 'mTBILL'): (19975742, datetime.datetime(2024, 9, 19, 10, 13, 51)), ('bsc', 'cUSDO'): (64016550, datetime.datetime(2025, 10, 9, 12, 10, 43)), ('bsc', 'mXRP'): (63687212, datetime.datetime(2025, 10, 6, 15, 32, 6)), ('hyperevm', 'dnETH'): (15226933, datetime.datetime(2025, 9, 30, 11, 2)), ('hyperevm', 'dnFART'): (13375947, datetime.datetime(2025, 9, 9, 9, 14)), ('hyperevm', 'dnHYPE'): (11445176, datetime.datetime(2025, 8, 18, 9, 28)), ('hyperevm', 'dnPUMP'): (12423459, datetime.datetime(2025, 8, 29, 12, 57)), ('hyperevm', 'dnTEST'): (15230410, datetime.datetime(2025, 9, 30, 11, 59)), ('hyperevm', 'hbUSDC'): (10226740, datetime.datetime(2025, 8, 4, 12, 29)), ('hyperevm', 'hbUSDT'): (3270801, datetime.datetime(2025, 5, 2, 10, 28, 32)), ('hyperevm', 'hbXAUt'): (5474555, datetime.datetime(2025, 6, 11, 8, 27, 34)), ('hyperevm', 'kitBTC'): (13021617, datetime.datetime(2025, 9, 5, 8, 24)), ('hyperevm', 'kitHYPE'): (13017103, datetime.datetime(2025, 9, 5, 7, 10)), ('hyperevm', 'kitUSD'): (12955859, datetime.datetime(2025, 9, 4, 14, 26)), ('hyperevm', 'liquidHYPE'): (8725211, datetime.datetime(2025, 7, 18, 9, 3)), ('hyperevm', 'lstHYPE'): (8115617, datetime.datetime(2025, 7, 11, 10, 25)), ('hyperevm', 'obeatUSD'): (15403040, datetime.datetime(2025, 10, 2, 11, 9)), ('hyperevm', 'wNLP'): (15223761, datetime.datetime(2025, 9, 30, 10, 10)), ('hyperevm', 'wVLP'): (10921614, datetime.datetime(2025, 8, 12, 10, 23)), ('katana', 'kmiUSD'): (9366730, datetime.datetime(2025, 8, 25, 8, 12, 21)), ('katana', 'mHYPER'): (22684661, datetime.datetime(2026, 1, 26, 11, 37, 52)), ('katana', 'mRE7SOL'): (4540503, datetime.datetime(2025, 6, 30, 11, 35, 14)), ('main', 'JIV'): (23274808, datetime.datetime(2025, 9, 2, 10, 25, 11)), ('main', 'acremBTC1'): (23367405, datetime.datetime(2025, 9, 15, 8, 52, 23)), ('main', 'bondBTC'): (24869298, datetime.datetime(2026, 4, 13, 7, 16, 23)), ('main', 'bondETH'): (24850328, datetime.datetime(2026, 4, 10, 15, 49, 35)), ('main', 'bondUSD'): (24849841, datetime.datetime(2026, 4, 10, 14, 11, 59)), ('main', 'carryTradeUSDTRYLeverage'): (25128195, datetime.datetime(2026, 5, 19, 8, 53, 35)), ('main', 'hypeBTC'): (22517088, datetime.datetime(2025, 5, 19, 12, 44, 47)), ('main', 'hypeETH'): (22516836, datetime.datetime(2025, 5, 19, 11, 54, 11)), ('main', 'hypeUSD'): (22530554, datetime.datetime(2025, 5, 21, 10, 4, 23)), ('main', 'mAPOLLO'): (22924553, datetime.datetime(2025, 7, 15, 12, 22, 35)), ('main', 'mBASIS'): (20068373, datetime.datetime(2024, 6, 11, 11, 46, 11)), ('main', 'mBTC'): (20991269, datetime.datetime(2024, 10, 18, 8, 31, 47)), ('main', 'mEDGE'): (21665964, datetime.datetime(2025, 1, 20, 13, 20, 35)), ('main', 'mEVETH'): (25172925, datetime.datetime(2026, 5, 25, 14, 30, 23)), ('main', 'mEVUSD'): (23496808, datetime.datetime(2025, 10, 3, 10, 58, 35)), ('main', 'mFARM'): (23073881, datetime.datetime(2025, 8, 5, 9, 11, 11)), ('main', 'mFONE'): (22437927, datetime.datetime(2025, 5, 8, 9, 27, 23)), ('main', 'mHYPER'): (22924118, datetime.datetime(2025, 7, 15, 10, 55, 11)), ('main', 'mHyperBTC'): (23576630, datetime.datetime(2025, 10, 14, 14, 46, 59)), ('main', 'mHyperETH'): (23547132, datetime.datetime(2025, 10, 10, 11, 47, 59)), ('main', 'mKRalpha'): (24083710, datetime.datetime(2025, 12, 24, 16, 35, 35)), ('main', 'mLIQUIDITY'): (22466394, datetime.datetime(2025, 5, 12, 9, 43, 59)), ('main', 'mM1USD'): (24534309, datetime.datetime(2026, 2, 25, 13, 44, 35)), ('main', 'mMEV'): (21771599, datetime.datetime(2025, 2, 4, 7, 19, 11)), ('main', 'mPortofino'): (23675979, datetime.datetime(2025, 10, 28, 12, 40, 11)), ('main', 'mRE7'): (21786049, datetime.datetime(2025, 2, 6, 7, 44, 47)), ('main', 'mRE7BTC'): (23288661, datetime.datetime(2025, 9, 4, 8, 48, 59)), ('main', 'mROX'): (24425757, datetime.datetime(2026, 2, 10, 10, 24, 35)), ('main', 'mSL'): (22274978, datetime.datetime(2025, 4, 15, 14, 28, 23)), ('main', 'mTBILL'): (18691255, datetime.datetime(2023, 12, 1, 11, 25, 59)), ('main', 'mWIN'): (25236860, datetime.datetime(2026, 6, 3, 12, 27, 23)), ('main', 'mWildUSD'): (23432101, datetime.datetime(2025, 9, 24, 9, 48, 11)), ('main', 'mevBTC'): (22867636, datetime.datetime(2025, 7, 7, 13, 32, 47)), ('main', 'msyrupUSD'): (23232613, datetime.datetime(2025, 8, 27, 12, 59, 35)), ('main', 'msyrupUSDp'): (23339333, datetime.datetime(2025, 9, 11, 10, 50, 47)), ('main', 'qHVNUSD'): (25286287, datetime.datetime(2026, 6, 10, 9, 55, 35)), ('main', 'sGold'): (25338248, datetime.datetime(2026, 6, 17, 15, 45, 11)), ('main', 'stockMarketTRBasisTrade'): (25122809, datetime.datetime(2026, 5, 18, 14, 52, 35)), ('main', 'tBTC'): (22594563, datetime.datetime(2025, 5, 30, 9, 9, 23)), ('main', 'tETH'): (22594497, datetime.datetime(2025, 5, 30, 8, 55, 59)), ('main', 'tUSDe'): (22594324, datetime.datetime(2025, 5, 30, 8, 21, 11)), ('main', 'turtlePST'): (25387099, datetime.datetime(2026, 6, 24, 11, 12, 47)), ('main', 'zeroGBTCV'): (23274478, datetime.datetime(2025, 9, 2, 9, 18, 47)), ('main', 'zeroGETHV'): (23274171, datetime.datetime(2025, 9, 2, 8, 16, 47)), ('main', 'zeroGUSDV'): (23269210, datetime.datetime(2025, 9, 1, 15, 34, 35)), ('monad', 'mEDGE'): (41557850, datetime.datetime(2025, 12, 12, 13, 16, 35)), ('monad', 'mHYPER'): (48387891, datetime.datetime(2026, 1, 13, 6, 43, 5)), ('monad', 'mHyperBTC'): (61813077, datetime.datetime(2026, 3, 16, 13, 57, 2)), ('optimism', 'liquidRESERVE'): (149938537, datetime.datetime(2026, 4, 6, 11, 44, 11)), ('optimism', 'liquidRWA'): (152185362, datetime.datetime(2026, 5, 28, 11, 58, 21)), ('optimism', 'mRe7ETH'): (149716831, datetime.datetime(2026, 4, 1, 8, 33, 59)), ('optimism', 'weEUR'): (149935744, datetime.datetime(2026, 4, 6, 10, 11, 5)), ('plasma', 'mHYPER'): (2828525, datetime.datetime(2025, 10, 6, 13, 35, 7)), ('plasma', 'plUSD'): (2210548, datetime.datetime(2025, 9, 29, 9, 55, 30)), ('plasma', 'splUSD'): (2213033, datetime.datetime(2025, 9, 29, 10, 36, 55)), ('tac', 'mRE7'): (12121424, datetime.datetime(2026, 1, 8, 10, 29, 38)), ('tac', 'tacTON'): (6292451, datetime.datetime(2025, 9, 26, 11, 14, 55))}
Scanned deployment blocks for Midas products.
This table is maintained by live archive-node scans over the product token addresses, not by the upstream TypeScript registry. To refresh it, run:
source .local-test.env && UPDATE_REGISTRY=true poetry run python scripts/midas/scan-deployments.py
Keys are
(Midas network key, product symbol)and values are(first bytecode block, first bytecode block timestamp). Timestamps are naive UTC datetimes.
- MIDAS_REGISTRY_NON_PRODUCT_KEYS: Final[frozenset[str]] = frozenset({'accessControl', 'paymentTokens', 'timelock'})
Non-product registry sections.
- MIDAS_REDEMPTION_VAULT_FIELDS: Final[tuple[str, ...]] = ('redemptionVault', 'redemptionVaultSwapper', 'redemptionVaultMToken', 'redemptionVaultUstb', 'redemptionVaultAave', 'redemptionVaultMorpho', 'redemptionVaultBuidl')
Redemption vault fields in preference order for scanner diagnostics.
- MIDAS_CUSTOM_FEED_FIELDS: Final[tuple[str, ...]] = ('customFeed', 'customFeedGrowth', 'customFeedDv', 'customFeedRv')
Custom oracle fields in preference order for share price fallback reads.
- MIDAS_DEPOSIT_VAULT_FIELDS: Final[tuple[str, ...]] = ('depositVault', 'depositVaultMToken', 'depositVaultUstb', 'depositVaultAave', 'depositVaultMorpho')
Deposit vault fields in preference order for scanner diagnostics.
- MIDAS_PRODUCT_SCAN_EXCLUSIONS: Final[dict[tuple[str, str], str]] = {('base', 'mRE7'): 'dataFeed is deprecated and customFeed.latestRoundData() returns a zero answer'}
Products whose registry entries are intentionally not promoted to scanning.
These rows stay in
MIDAS_ADDRESSES_PER_NETWORK, but the shared vault adapter cannot produce a reliable NAV/share from their current on-chain feeds. Re-check this list with:source .local-test.env && DAYS=4 REQUIRE_ALL_SUCCESS=true poetry run python scripts/midas/scan-history.py
- class MidasRegistryProduct
Bases:
objectScanner-friendly Midas product entry.
- first_seen_at_block: Optional[int]
First block where the product token bytecode exists, when scanned.
- first_seen_at: Optional[datetime.datetime]
Timestamp of
first_seen_at_blockas naive UTC datetime, when scanned.
- property rpc_env_var: Optional[str]
Get the local JSON-RPC environment variable for this product chain.
- property has_required_historical_contracts: bool
Can this product be read with the Midas historical datafeed scanner.
- property has_required_adapter_data: bool
Can this product be promoted to the shared vault scanner adapter.
- iter_midas_registry_products(*, require_historical_contracts=False, require_adapter_data=False)
Iterate product-like entries from the Pythonised Midas registry.
Payment token and access-control sections are skipped. If
require_historical_contractsis true, only entries with bothtokenanddataFeedare yielded. These are the minimum contracts needed for historical share price and TVL reads. Ifrequire_adapter_datais true, deployment metadata is also required so the shared scanner can create a historical lead with a deterministic start block.- Parameters
- Returns
Iterator of typed registry product entries.
- Return type
collections.abc.Iterator[eth_defi.midas.registry.MidasRegistryProduct]
- get_midas_registry_products_by_chain(*, require_historical_contracts=False, require_adapter_data=False)
Group Midas registry products by chain id.
- Parameters
- Returns
Mapping of chain id to products.
- Return type
dict[int, list[eth_defi.midas.registry.MidasRegistryProduct]]