EulerEarnVaultHistoricalReader

Documentation for eth_defi.erc_4626.vault_protocol.euler.vault.EulerEarnVaultHistoricalReader Python class.

class EulerEarnVaultHistoricalReader

Bases: eth_defi.erc_4626.vault.ERC4626HistoricalReader

Read EulerEarn vault core data + utilisation metrics.

For EulerEarn (metavault): - Idle assets = asset().balanceOf(vault) - Utilisation = (totalAssets - idle) / totalAssets

Warning

EulerEarn vaults have maxDeposit() disabled because it uses excessive gas.

Research notes on TelosC Surge vault (0xa9C251F8304b1B3Fc2b9e8fcae78D94Eff82Ac66):

The EulerEarn architecture (based on Metamorpho) has loop-heavy operations that cause maxDeposit(address(0)) to consume 21-36M gas - nearly the entire Plasma block gas limit of 36M.

The gas consumption comes from:

  1. _maxDeposit() in EulerEarnVaultModule.sol iterates through supplyQueue to calculate maxTotalDeposit for each strategy

  2. _convertToShares() in EulerEarnBase.sol triggers _accruedFeeAndAssets() which loops through the entire withdrawQueue to calculate accrued fees

  3. Maximum queue length of 30 strategies (defined in ConstantsLib.MAX_QUEUE_LENGTH) means up to 60 external contract calls per maxDeposit() invocation

Source code references:

  • EulerEarnVaultModule.sol: _maxDeposit() at supplyQueue iteration

  • EulerEarnBase.sol: _accruedFeeAndAssets() at withdrawQueue iteration

  • ConstantsLib.sol: MAX_QUEUE_LENGTH = 30

Plasmascan: https://plasmascan.to/address/0xa9C251F8304b1B3Fc2b9e8fcae78D94Eff82Ac66

Since Multicall3 does not support per-call gas limits, and calling maxDeposit() would consume the entire block gas limit, we unconditionally skip this call for all EulerEarn vaults.

Attributes summary

address

first_block

one_raw_share

Methods summary

__init__(vault, stateful)

construct_core_erc_4626_multicall()

Polling endpoints defined in ERC-4626 spec.

construct_fee_calls()

Add EulerEarn fee call.

construct_multicalls()

Get the onchain calls that are needed to read the share price.

construct_utilisation_calls()

Add idle assets call for utilisation calculation.

dictify_multicall_results(block_number, ...)

Convert batch of multicalls made for this vault to more digestible dict.

get_warmup_calls()

Yield warmup calls for EulerEarn vaults.

process_core_erc_4626_result(call_by_name)

Decode common ERC-4626 calls.

process_result(block_number, timestamp, ...)

Process the result of mult

process_utilisation_result(call_by_name, ...)

Decode EulerEarn utilisation data.

should_skip_call(function_name)

Check if a specific function call should be skipped.

should_skip_call(function_name)

Check if a specific function call should be skipped.

EulerEarn vaults always skip maxDeposit due to excessive gas usage. See class docstring for detailed research notes.

Parameters

function_name (str) –

Return type

bool

get_warmup_calls()

Yield warmup calls for EulerEarn vaults.

Includes base ERC-4626 calls (except maxDeposit) plus idle_assets and fee calls. maxDeposit is excluded because EulerEarn vaults use excessive gas for this call.

Return type

Iterable[tuple[str, callable, any]]

construct_multicalls()

Get the onchain calls that are needed to read the share price.

Return type

Iterable[eth_defi.event_reader.multicall_batcher.EncodedCall]

construct_utilisation_calls()

Add idle assets call for utilisation calculation.

Note: We use the asset token’s balanceOf to get idle assets. This requires an additional call to the asset token contract.

Return type

Iterable[eth_defi.event_reader.multicall_batcher.EncodedCall]

construct_fee_calls()

Add EulerEarn fee call.

Return type

Iterable[eth_defi.event_reader.multicall_batcher.EncodedCall]

process_utilisation_result(call_by_name, total_assets)

Decode EulerEarn utilisation data.

Utilisation = (totalAssets - idle) / totalAssets

Parameters
Return type

tuple[decimal.Decimal | None, float | None]

process_result(block_number, timestamp, call_results)

Process the result of mult

  • Calls are created in construct_multicalls()

  • This method combines result of this calls to a easy to manage historical record VaultHistoricalRead

Parameters
Return type

eth_defi.vault.base.VaultHistoricalRead

__init__(vault, stateful)
Parameters
construct_core_erc_4626_multicall()

Polling endpoints defined in ERC-4626 spec.

  • Does not include fee calls which do not have standard

Return type

Iterable[eth_defi.event_reader.multicall_batcher.EncodedCall]

dictify_multicall_results(block_number, call_results, allow_failure=True)

Convert batch of multicalls made for this vault to more digestible dict.

  • Assert that all multicalls succeed

Returns

Dictionary where each multicall is keyed by its EncodedCall.extra_data["function"]

Parameters
Return type

dict[str, eth_defi.event_reader.multicall_batcher.EncodedCallResult]

process_core_erc_4626_result(call_by_name)

Decode common ERC-4626 calls.

Parameters

call_by_name (dict[str, eth_defi.event_reader.multicall_batcher.EncodedCallResult]) –

Return type

tuple