EulerEarnVaultHistoricalReader
Documentation for eth_defi.erc_4626.vault_protocol.euler.vault.EulerEarnVaultHistoricalReader Python class.
- class EulerEarnVaultHistoricalReader
Bases:
eth_defi.erc_4626.vault.ERC4626HistoricalReaderRead 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:
_maxDeposit() in EulerEarnVaultModule.sol iterates through supplyQueue to calculate maxTotalDeposit for each strategy
_convertToShares() in EulerEarnBase.sol triggers _accruedFeeAndAssets() which loops through the entire withdrawQueue to calculate accrued fees
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
addressfirst_blockone_raw_shareMethods summary
__init__(vault, stateful)Polling endpoints defined in ERC-4626 spec.
Add EulerEarn fee call.
Get the onchain calls that are needed to read the share price.
Add idle assets call for utilisation calculation.
dictify_multicall_results(block_number, ...)Convert batch of multicalls made for this vault to more digestible dict.
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.
- 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.
- construct_multicalls()
Get the onchain calls that are needed to read the share price.
- 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.
- construct_fee_calls()
Add EulerEarn fee call.
- process_utilisation_result(call_by_name, total_assets)
Decode EulerEarn utilisation data.
Utilisation = (totalAssets - idle) / totalAssets
- Parameters
call_by_name (dict[str, eth_defi.event_reader.multicall_batcher.EncodedCallResult]) –
total_assets (decimal.Decimal | None) –
- 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
block_number (int) –
timestamp (datetime.datetime) –
call_results (list[eth_defi.event_reader.multicall_batcher.EncodedCallResult]) –
- Return type
- __init__(vault, stateful)
- Parameters
vault (eth_defi.erc_4626.vault.ERC4626Vault) –
stateful (bool) –
- construct_core_erc_4626_multicall()
Polling endpoints defined in ERC-4626 spec.
Does not include fee calls which do not have standard
- 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
block_number (int) –
call_results (list[eth_defi.event_reader.multicall_batcher.EncodedCallResult]) –
- 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