vault.top_vaults_json
Documentation for eth_defi.vault.top_vaults_json Python module.
Multi-chain vault analysis + safe JSON export.
Features: - Performs lifetime metric analysis for all available chains. - Filters and formats results for the top-performing vaults. - Safely exports to JSON with NaN/Inf -> null sanitization. - Normalizes column keys into snake_case. - Uses column-wise .map(parse_value) to comply with modern pandas. - Uses allow_nan=False to guarantee strict JSON validity.
To test out:
OUTPUT_JSON=/tmp/top-vaults.json VAULT_EXPORT_STATE_PATH=/tmp/vault-export-state.json python -m eth_defi.vault.top_vaults_json
The legacy wrapper also works:
OUTPUT_JSON=/tmp/top-vaults.json VAULT_EXPORT_STATE_PATH=/tmp/vault-export-state.json python scripts/erc-4626/vault-analysis-json.py
To test out Pandas warning issues in calculate_lifetime_metrics(), enable strict warnings:
Module Attributes
Per-protocol peak-NAV export threshold overrides, keyed by protocol slug. |
|
Default output filename when no |
Functions
|
Add a vault export row with deterministic deduplication. |
|
Annotate an exported current row. |
|
Annotate a stale fallback export. |
|
Annotate a sticky current-row export. |
|
Apply append-biased sticky export state to lifetime metrics. |
|
Build provenance metadata shared by all vault metrics JSON outputs. |
|
Create a detached copy of an exported row. |
|
Recursively traverses a Python object (dict or list) and collects paths to non-serializable values or invalid keys. |
Format a naive UTC timestamp for sticky export state. |
|
|
Check if an exported vault row is blacklisted. |
|
Check if a row or exported record risk means hard blacklist. |
|
Check if a current row can replace the stored export record. |
|
Check if a stored exported row has the key fields needed for replay. |
|
Check if an exported current row is inside the freshness warning window. |
|
Load sticky export state or create a new empty state. |
|
Main execution function for vault analysis and JSON export. |
|
Normalise one metrics dataframe row for sticky processing. |
Create an empty sticky export state document. |
|
|
Create or update sticky state for an exported current row. |
|
Create a canonical sticky export state key. |
Create a sticky export state key from an exported vault record. |
|
|
Persist structural suppression for a vault. |
Normalise timestamp-like values to naive UTC datetimes. |
|
|
Resolve the peak-NAV export threshold for one vault row. |
|
Resolve the sticky export state path. |
|
Atomically write sticky export state. |
|
Validate sticky export state structure. |
Validate JSON serialisability with strict NaN handling. |
Classes
Normalised current dataframe row for sticky export processing. |
|
Result of applying sticky vault export state. |
|
Counters emitted by sticky vault export state processing. |
- PROTOCOL_MIN_TVL_OVERRIDES: dict[str, float] = {'apex': 499.0}
Per-protocol peak-NAV export threshold overrides, keyed by protocol slug.
A vault normally has to reach
THRESHOLD_TVLpeak NAV to enter the exported dataset. Some protocols warrant a different bar. The value here replacesTHRESHOLD_TVLfor matching rows.ApeX Omni native vaults are small retail copy-trading leader accounts and, at launch, none have yet gathered meaningful TVL (the largest currently holds roughly USDT 14k, and only about two dozen clear the default USDT 5k export bar). With the default USDT 5k bar the ApeX protocol page is almost empty, so during the rollout period we deliberately lower the ApeX threshold to USDT 499 to give the page a usable set of vaults. Revisit and raise this back towards the default once ApeX vaults gain real traction.
- resolve_export_threshold_tvl(record, default_threshold)
Resolve the peak-NAV export threshold for one vault row.
Most vaults use the global
THRESHOLD_TVL, but protocols listed inPROTOCOL_MIN_TVL_OVERRIDESuse their own bar. The lookup is by exportedprotocol_slugso it does not depend on any protocol package.
- DEFAULT_OUTPUT_FILENAME = 'stablecoin-vault-metrics.json'
Default output filename when no
OUTPUT_JSONoverride is supplied and nooutput_pathis passed tomain().
- class StickyExportStats
Bases:
objectCounters emitted by sticky vault export state processing.
The counters are intentionally small and line-oriented, because this script is often run from cron and pipeline logs are the first place operators diagnose data gaps.
- current_row_structural_fallbacks: int
Current rows that could not replace the stored fallback record.
- missing_curator_slugs: int
Exported sticky rows whose curator slug no longer resolves in curator export.
- __init__(loaded_state_entries=0, current_filter_passed=0, sticky_additions=0, sticky_fallback_exports=0, current_row_structural_fallbacks=0, structurally_suppressed_vaults=0, stale_warning_vaults=0, missing_protocol_slugs=0, missing_curator_slugs=0, previous_current_filter_count=None)
- Parameters
- Return type
None
- class StickyExportResult
Bases:
objectResult of applying sticky vault export state.
- stats: eth_defi.vault.top_vaults_json.StickyExportStats
Operator-facing counters.
- format_state_timestamp(ts)
Format a naive UTC timestamp for sticky export state.
State files use
Zsuffixes for readability, while comparisons use naive UTC datetimes internally.- Parameters
ts (datetime.datetime) – Naive UTC datetime.
- Returns
ISO 8601 string with
Zsuffix.- Return type
- normalise_datetime_to_naive_utc(value)
Normalise timestamp-like values to naive UTC datetimes.
Tz-aware Pandas and Python timestamps are converted to UTC first and only then stripped of tzinfo. This avoids both
TypeErrorwhen comparing aware and naive values, and silent wall-clock shifts from dropping tzinfo before conversion.- Parameters
value –
datetime,pd.Timestamp, ISO string, or null-like value.- Returns
Naive UTC datetime, or
Nonefor null-like values.- Return type
- make_vault_export_state_key(chain_id, address)
Create a canonical sticky export state key.
State, dataframe rows, exported rows, and deduplication all use the same
chain_id-lowercase_addressshape.
- make_vault_export_state_key_from_record(record)
Create a sticky export state key from an exported vault record.
- resolve_sticky_export_state_path(data_dir)
Resolve the sticky export state path.
VAULT_EXPORT_STATE_PATHis an explicit override. Otherwise all vault metric JSON outputs share one state file under the pipeline data directory.- Parameters
data_dir (pathlib.Path) – Pipeline data directory.
- Returns
State file path.
- Return type
- make_empty_sticky_export_state(now)
Create an empty sticky export state document.
- Parameters
now (datetime.datetime) – Current naive UTC datetime.
- Returns
Empty state mapping.
- Return type
- validate_sticky_export_state(state)
Validate sticky export state structure.
- Parameters
state (dict) – Decoded state JSON.
- Return type
None
- load_sticky_export_state(path, now)
Load sticky export state or create a new empty state.
Corrupt existing state raises instead of being reset, because the sticky qualification history is production state.
- Parameters
path (pathlib.Path) – State file path.
now (datetime.datetime) – Current naive UTC datetime.
- Returns
Loaded state mapping.
- Return type
- save_sticky_export_state(state, path)
Atomically write sticky export state.
- Parameters
state (dict) – State mapping.
path (pathlib.Path) – Destination path.
- Return type
None
- build_export_metadata(version_info=None)
Build provenance metadata shared by all vault metrics JSON outputs.
- Parameters
version_info (Optional[eth_defi.version_info.VersionInfo]) – Optional Docker image version stamp. When omitted, read the stamp from the running image.
- Returns
JSON-serialisable metadata containing the exporter version information.
- Return type
- find_non_serializable_paths(obj, path=None, results=None)
Recursively traverses a Python object (dict or list) and collects paths to non-serializable values or invalid keys.
- Args:
obj: The object to check (dict, list, or nested combination). path: Current path (list of keys/indices; internal use). results: List to collect issues (internal use).
- Returns:
List of tuples: (path_list, issue_description) for each problem found. Empty list if everything is serializable.
- is_blacklisted_risk_value(value)
Check if a row or exported record risk means hard blacklist.
Exported records serialise
VaultTechnicalRisk.blacklistedas"Blacklisted"throughget_risk_level_name(). Current dataframe rows may still carry the enum before export.- Parameters
value – Risk enum or serialised risk value.
- Returns
Trueif the value is the exact blacklist marker.- Return type
- is_blacklisted_record(record)
Check if an exported vault row is blacklisted.
- is_export_record_key_safe(record)
Check if a stored exported row has the key fields needed for replay.
- is_current_record_export_safe(record)
Check if a current row can replace the stored export record.
Missing non-key fields are treated as a transient metadata gap for sticky vaults. The caller can still replay a previous
last_exported_record.
- is_row_fresh(record, now, stale_warning_age_days)
Check if an exported current row is inside the freshness warning window.
- Parameters
record (dict) – Exported current row.
now (datetime.datetime) – Current naive UTC datetime.
stale_warning_age_days (int) – Warning age in days.
- Returns
Truewhen the row is fresh.- Return type
- copy_export_record(record)
Create a detached copy of an exported row.
- make_current_vault_row(row, now, stale_warning_age_days)
Normalise one metrics dataframe row for sticky processing.
- Parameters
row (pandas.Series) – Lifetime metrics dataframe row.
now (datetime.datetime) – Current naive UTC datetime.
stale_warning_age_days (int) – Warning age in days.
- Returns
Normalised current row wrapper.
- Return type
- annotate_current_record(record, state_entry, fresh)
Annotate an exported current row.
- annotate_sticky_record(record, state_entry, fresh)
Annotate a sticky current-row export.
- annotate_fallback_record(record, state_entry, fallback_reason=None)
Annotate a stale fallback export.
- make_state_entry_from_current_row(current_row, now_text, threshold_tvl, existing_entry=None)
Create or update sticky state for an exported current row.
- Parameters
current_row (eth_defi.vault.top_vaults_json.CurrentVaultRow) – Current row wrapper.
now_text (str) – Current timestamp formatted for state.
threshold_tvl (float) – Active
MIN_TVLthreshold.
- Returns
Updated state entry.
- Return type
- mark_state_entry_suppressed(state, key, reason, now_text, current_row=None, threshold_tvl=None)
Persist structural suppression for a vault.
- Parameters
state (dict) – Sticky export state.
key (str) – Canonical vault key.
reason (str) – Suppression reason.
now_text (str) – Current timestamp formatted for state.
current_row (Optional[eth_defi.vault.top_vaults_json.CurrentVaultRow]) – Current row, if available.
threshold_tvl (Optional[float]) – Active
MIN_TVLthreshold, if the current row qualified.
- Return type
None
- add_exported_vault(vaults_by_key, key, priority, record)
Add a vault export row with deterministic deduplication.
Higher priority wins. The priority rule is a safety net for malformed duplicate inputs, because normal current/sticky paths are intended to be mutually exclusive.
- apply_sticky_export_state(lifetime_data_df, state, *, now, threshold_tvl, stale_warning_age_days)
Apply append-biased sticky export state to lifetime metrics.
Current rows passing the peak TVL filter qualify a vault forever. Later missing, stale, below-threshold, or structurally incomplete rows do not make a previously qualified vault disappear unless exact invalid-fallback suppression applies.
- Parameters
lifetime_data_df (pandas.DataFrame) – Calculated lifetime metrics.
state (dict) – Mutable sticky export state.
now (datetime.datetime) – Current naive UTC datetime.
threshold_tvl (float) – Active default peak TVL export threshold. Per-protocol overrides may apply per row via
resolve_export_threshold_tvl().stale_warning_age_days (int) – Warning age in days.
- Returns
Final vault rows, mutated state, and counters.
- Return type
- validate_strict_json_serialisable(obj)
Validate JSON serialisability with strict NaN handling.
- Parameters
obj (dict) – Object to validate.
- Return type
None
- main(data_dir=None, vault_db_path=None, parquet_path=None, output_path=None, core3_db_path=None, xerberus_db_path=None, feed_db_path=None)
Main execution function for vault analysis and JSON export.
All four arguments are independently overridable. When a path argument is
None, it is derived fromdata_dirso that a caller passing onlydata_dirreads and writes under that directory consistently — never a mix ofdata_dirfor reads and~/.tradingstrategy/vaultsfor writes.- Parameters
data_dir (Optional[pathlib.Path]) – Pipeline data directory. When
None, falls back to theDATA_DIRenv var (default~/.tradingstrategy/vaults). Acts as the anchor for bothparquet_pathandoutput_pathdefaults when those are alsoNone.vault_db_path (Optional[pathlib.Path]) – Path to the vault metadata pickle. When
None,VaultDatabase.read()useseth_defi.vault.vaultdb.DEFAULT_VAULT_DATABASE.parquet_path (Optional[pathlib.Path]) – Path to the cleaned vault prices parquet. When
None, defaults todata_dir / "cleaned-vault-prices-1h.parquet".output_path (Optional[pathlib.Path]) – Destination JSON path. When
None, defaults todata_dir / DEFAULT_OUTPUT_FILENAME. TheOUTPUT_JSONenv var is honoured by_resolve_defaults_from_env()in the__main__entrypoint, not bymain()itself, so in-process callers get deterministic path anchoring with no env var surprises.core3_db_path (Optional[pathlib.Path]) – Path to the Core3 risk intelligence DuckDB database. When
None, resolved fromCORE3_DATABASE_PATHenv var, then the default constant. The database is only opened if the resolved file exists on disk.xerberus_db_path (Optional[pathlib.Path]) – Path to the Xerberus risk DuckDB database. When
None, resolved fromXERBERUS_DATABASE_PATHenv var, then the default constant. Opened read-only when the file exists.feed_db_path (Optional[pathlib.Path]) – Path to the vault post feed DuckDB database. When
None, resolved fromFEED_DB_PATHenv var, falling back toDB_PATH(used by the feed collector), thenDEFAULT_VAULT_POST_DATABASE. The database is only opened if the resolved file exists on disk.
- Return type