midas.historical

Documentation for eth_defi.midas.historical Python module.

Historical reader for Midas tokenised products.

Classes

MidasVaultHistoricalReader

Read historical supply and NAV/share for Midas products.

MidasVaultReaderState

Persist adaptive Midas history scan state.

class MidasVaultReaderState

Bases: eth_defi.erc_4626.vault.VaultReaderState

Persist adaptive Midas history scan state.

Midas datafeeds publish share prices in USD and the historical reader already calculates TVL in USD. Unlike ERC-4626 vaults, an mToken does not expose an ERC-20 denomination token, so the generic exchange-rate lookup cannot be used here.

Parameters
  • vault – The vault we are reading historical data for

  • tvl_threshold_1d_read – If the TVL is below this threshold, we will not read it more than once per day, otherwise hourly.

  • down_hard – Stop reading the vault if the TVL is down by this percentage from the peak.

  • min_tvl_threshold – If the vault never reaches this TVL, we stop reading it after the traction period.

  • traction_period – How long we wait for the vault to get traction before we stop reading it.

Parm peaked_tvl_threshold

The TVL value we first need to reach to trigger down hard condition.

property exchange_rate: decimal.Decimal

Return the USD exchange rate for Midas’ USD-denominated NAV.

Returns

One, because Midas reader total_assets is already in USD.

__init__(vault, tvl_threshold_1d_read=Decimal('10000'), tiny_tvl_threshold_rare_read=Decimal('1000'), peaked_tvl_threshold=Decimal('200000'), min_tvl_threshold=Decimal('1500'), down_hard=0.98, traction_period=datetime.timedelta(days=60))
Parameters
  • vault (eth_defi.erc_4626.vault.ERC4626Vault) – The vault we are reading historical data for

  • tvl_threshold_1d_read – If the TVL is below this threshold, we will not read it more than once per day, otherwise hourly.

  • down_hard – Stop reading the vault if the TVL is down by this percentage from the peak.

  • min_tvl_threshold – If the vault never reaches this TVL, we stop reading it after the traction period.

  • traction_period (datetime.timedelta) – How long we wait for the vault to get traction before we stop reading it.

Parm peaked_tvl_threshold

The TVL value we first need to reach to trigger down hard condition.

get_broken_calls()

Get all calls marked as broken.

Returns

Dict of function_name -> check_block for broken calls

Return type

dict[str, int]

get_call_status(function_name)

Get the status of a function call.

Parameters

function_name (str) – The function name to check

Returns

Tuple of (check_block, reverts) or None if not checked yet

Return type

Optional[tuple[int, bool]]

get_frequency()

How fast we are reading this vault or should the further reading be skipped.

Return type

tuple[Literal[‘peaked’, ‘faded’, ‘large_tvl’, ‘small_tvl’, ‘tiny_tvl’, ‘first_read’, ‘not_started’, ‘early’], datetime.timedelta | None]

load(data)

Load the state from a dictionary.

Parameters

data (dict) –

on_called(result, total_assets=None, share_price=None)
Parameters
on_unpriced_call(result)

Update adaptive scan state for a successful supply-only read.

Some tokenised funds expose their share supply but no reviewed scalar NAV or TVL. They still need persistent reader state so the stateful scanner can cache token metadata, advance its last-read block and throttle historical calls. Zero values are internal scheduling sentinels only; the exported historical row must continue to expose None for its share price and total assets.

Parameters

result (eth_defi.event_reader.multicall_batcher.EncodedCallResult) – Successful supply call carrying a block number and timestamp.

Return type

None

pformat()

Pretty print the current state.

Return type

str

save()

Persist state across multiple runs.

Returns

Pickleable Python object

Return type

dict

set_call_status(function_name, check_block, reverts)

Record the status of a function call.

Parameters
  • function_name (str) – The function name to record

  • check_block (int) – The block number when we checked

  • reverts (bool) – True if the call reverted

Return type

None

should_invoke(call, block_identifier, timestamp)

Check the condition if this multicall is good to go.

Parameters
Return type

bool

should_skip_call(function_name)

Check if a specific function call should be skipped for this vault.

Part of the warmup system to detect and skip broken contract calls. See README-reader-states.md for documentation.

Parameters

function_name (str) – The function name as stored in extra_data[“function”]

Returns

True if the call was marked as reverting

Return type

bool

first_seen_at_block

Passed from the vault discovery reader, pass the block number as args when we know this vault popped in to the existing

last_tvl: decimal.Decimal

TVL from the last read

first_read_at: datetime.datetime

Timestamp of the block of the first successful read of this vault.

max_tvl: decimal.Decimal

Start with zero TVL

last_share_price: decimal.Decimal

Start with zero share price

last_call_at: Optional[datetime.datetime]

When this vault received its last eth_call update

last_block: Optional[int]

When this vault received its last eth_call update

peaked_at: datetime.datetime

Disable reading if the vault has peaked (TVL too much down) and is no longer active

peaked_tvl: float

What was TVL when we disabled reading due to peaking

faded_at: datetime.datetime

Disable reading if the vault has never gotten any traction

traction_period

How much time after deployment we allow to get traction

min_tvl_threshold

Minimum TVL traction threshold to start reading the vault

tiny_tvl_threshold_rare_read

Vaults we do no really care about

entry_count

How many on_called() invocations have we had

invoke_count_passed

How many should_invoke() invocations have we had

invoke_count_first_read

How many should_invoke() invocations have we had

invoke_count_missing_freq

How many should_invoke() invocations have we had

invoke_count_throttled

How many should_invoke() invocations have we had

rpc_error_count

Track RPCc errors

denomination_token_address

Cache denomination token address when preparing readers

share_token_address

Cache share token address when preparing readers

one_raw_share

One share in its raw units

one

Cache denomination token address when preparing readers

chain_id

Copy for state debuggin

vault_poll_frequency

Cache for how often we are polling this vault, the mode name

token_symbol

Cache for debuggin

unsupported_token

Cache for debuggin

call_status: dict[str, tuple[int, bool]]

Map of function names to their call status for warmup system Key is the function name from extra_data[“function”] Value is tuple (check_block: int, reverts: bool) Example: {“maxDeposit”: (12345678, True)} means maxDeposit reverts, detected at block 12345678

class MidasVaultHistoricalReader

Bases: eth_defi.vault.base.VaultHistoricalReader

Read historical supply and NAV/share for Midas products.

Midas does not expose ERC-4626 convertToAssets() or totalAssets(). The canonical on-chain share price is the Midas IDataFeed value exposed through getDataInBase18(). Historical total assets are therefore calculated as totalSupply() * getDataInBase18().

Create a Midas historical reader.

Parameters
  • vault – Midas vault adapter.

  • stateful – Whether to attach adaptive reader state used by the shared historical multicaller.

__init__(vault, stateful)

Create a Midas historical reader.

Parameters
  • vault (MidasVault) – Midas vault adapter.

  • stateful (bool) – Whether to attach adaptive reader state used by the shared historical multicaller.

construct_multicalls()

Construct Midas historical multicalls.

Returns

Multicall batch reading ERC-20 totalSupply() and Midas getDataInBase18() NAV/share.

Return type

collections.abc.Iterable[eth_defi.event_reader.multicall_batcher.EncodedCall]

process_result(block_number, timestamp, call_results)

Convert Midas multicall results to a vault price row.

Parameters
Returns

VaultHistoricalRead with Midas NAV/share and supply.

Return type

eth_defi.vault.base.VaultHistoricalRead