erc_4626.vault_protocol.accountable.vault

Documentation for eth_defi.erc_4626.vault_protocol.accountable.vault Python module.

Accountable Capital vault support.

Classes

AccountableFeeData

Snapshot all Accountable fee-manager terms for one vault.

AccountableHistoricalReader

Read Accountable vault core data with corrected NAV and available liquidity.

AccountablePermissionLevel

Accountable vault access modes from IAccess.PermissionLevel.

AccountableVault

Accountable Capital vault support.

class AccountablePermissionLevel

Bases: enum.IntEnum

Accountable vault access modes from IAccess.PermissionLevel.

none = 0

No account admission check.

kyc = 1

Accountable-signed authorisation appended to each call.

whitelist = 2

Persistent membership exposed through allowed(address).

__new__(value)
as_integer_ratio()

Return a pair of integers, whose ratio is equal to the original int.

The ratio is in lowest terms and has a positive denominator.

>>> (10).as_integer_ratio()
(10, 1)
>>> (-10).as_integer_ratio()
(-10, 1)
>>> (0).as_integer_ratio()
(0, 1)
bit_count()

Number of ones in the binary representation of the absolute value of self.

Also known as the population count.

>>> bin(13)
'0b1101'
>>> (13).bit_count()
3
bit_length()

Number of bits necessary to represent self in binary.

>>> bin(37)
'0b100101'
>>> (37).bit_length()
6
conjugate()

Returns self, the complex conjugate of any int.

denominator

the denominator of a rational number in lowest terms

from_bytes(byteorder='big', *, signed=False)

Return the integer represented by the given array of bytes.

bytes

Holds the array of bytes to convert. The argument must either support the buffer protocol or be an iterable object producing bytes. Bytes and bytearray are examples of built-in objects that support the buffer protocol.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use ‘big’.

signed

Indicates whether two’s complement is used to represent the integer.

imag

the imaginary part of a complex number

is_integer()

Returns True. Exists for duck type compatibility with float.is_integer.

numerator

the numerator of a rational number in lowest terms

real

the real part of a complex number

to_bytes(length=1, byteorder='big', *, signed=False)

Return an array of bytes representing an integer.

length

Length of bytes object to use. An OverflowError is raised if the integer is not representable with the given number of bytes. Default is length 1.

byteorder

The byte order used to represent the integer. If byteorder is ‘big’, the most significant byte is at the beginning of the byte array. If byteorder is ‘little’, the most significant byte is at the end of the byte array. To request the native byte order of the host system, use sys.byteorder as the byte order value. Default is to use ‘big’.

signed

Determines whether two’s complement is used to represent the integer. If signed is False and a negative integer is given, an OverflowError is raised.

class AccountableFeeData

Bases: object

Snapshot all Accountable fee-manager terms for one vault.

Accountable has two deployed fee-manager interfaces. The legacy interface supports establishment and performance fees; the current interface also supports an annualised management fee and separate manager/protocol splits for management and performance charges. All percentages use the manager’s runtime BASIS_POINTS() denominator, which is currently one million.

Establishment and prepayment fees are loan terms paid by the borrower. They are included here for a complete native view, but are not ERC-4626 LP deposit or withdrawal fees. minimum_deposit is decimalised using the vault denomination token while minimum_deposit_raw preserves the effective maximum of the vault and strategy contract thresholds.

block_identifier: Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]

Block tag or number shared by every read in this snapshot.

vault_address: eth_typing.evm.HexAddress

ERC-4626 vault whose fee terms were read.

strategy_address: eth_typing.evm.HexAddress

Accountable loan/strategy configured by the vault.

fee_manager_address: eth_typing.evm.HexAddress

Fee-manager contract configured by the strategy.

treasury_address: eth_typing.evm.HexAddress

Address receiving the protocol share of collected fees.

manager_fee_recipient_address: eth_typing.evm.HexAddress

Address receiving the manager share of collected fees.

basis_points: int

Runtime percentage denominator returned by BASIS_POINTS().

supports_management_fee: bool

Whether the deployed fee manager supports annual management fees.

establishment_fee_raw: int

Borrower establishment fee in Accountable percentage units.

management_fee_raw: int

Annualised management fee in Accountable percentage units.

Legacy fee managers structurally have no management fee, represented as zero together with supports_management_fee=False.

performance_fee_raw: int

Performance fee in Accountable percentage units.

manager_performance_fee_split_raw: int

Manager share of the performance fee in Accountable percentage units.

protocol_performance_fee_split_raw: int

Protocol share of the performance fee in Accountable percentage units.

manager_management_fee_split_raw: Optional[int]

Manager share of the management fee, or None on the legacy ABI.

protocol_management_fee_split_raw: Optional[int]

Protocol share of the management fee, or None on the legacy ABI.

prepayment_fee_raw: int

Borrower prepayment fee in Accountable percentage units.

vault_minimum_deposit_raw: Optional[int]

Vault-level dust threshold returned by MIN_AMOUNT_WEI(), if exposed.

strategy_minimum_deposit_raw: Optional[int]

Strategy-level configured loan.minDeposit, if exposed.

minimum_deposit_raw: Optional[int]

Effective ERC-20 base-unit minimum accepted by deposit().

This is the maximum of the vault and strategy thresholds when present.

minimum_deposit: Optional[decimal.Decimal]

Human-readable minimum deposit in denomination-token units, if exposed.

property establishment_fee: float

Return the borrower establishment fee as a fraction.

property management_fee: float

Return the annualised management fee as a fraction.

property performance_fee: float

Return the performance fee as a fraction.

property manager_performance_fee_split: float

Return the manager’s share of performance fees as a fraction.

property protocol_performance_fee_split: float

Return the protocol’s share of performance fees as a fraction.

property manager_management_fee_split: Optional[float]

Return the manager’s share of management fees when supported.

property protocol_management_fee_split: Optional[float]

Return the protocol’s share of management fees when supported.

property prepayment_fee: float

Return the borrower prepayment fee as a fraction.

as_generic_fee_data()

Map investor-facing Accountable fees to the shared fee schema.

Accountable deducts management and performance charges before updating the value backing vault shares, so both are internalised skimming fees. Establishment and prepayment charges apply to the underlying borrower, not an LP entering or leaving the ERC-4626 vault. Generic deposit and withdrawal fees are therefore known to be zero.

Returns

Shared fee data suitable for vault metadata and comparisons.

Return type

eth_defi.vault.fee.FeeData

__init__(block_identifier, vault_address, strategy_address, fee_manager_address, treasury_address, manager_fee_recipient_address, basis_points, supports_management_fee, establishment_fee_raw, management_fee_raw, performance_fee_raw, manager_performance_fee_split_raw, protocol_performance_fee_split_raw, manager_management_fee_split_raw, protocol_management_fee_split_raw, prepayment_fee_raw, vault_minimum_deposit_raw, strategy_minimum_deposit_raw, minimum_deposit_raw, minimum_deposit)
Parameters
Return type

None

class AccountableHistoricalReader

Bases: eth_defi.erc_4626.vault.ERC4626HistoricalReader

Read Accountable vault core data with corrected NAV and available liquidity.

Accountable’s totalAssets() only returns idle liquidity in the vault contract, excluding capital deployed by the strategy via lockAssets(). This means the standard ERC-4626 totalAssets() severely underreports the true vault NAV.

This reader:

  • Computes the true NAV as share_price * total_supply (derived from convertToAssets which uses sharePrice())

  • Exposes the raw totalAssets() value as available_liquidity since it represents the idle capital available for immediate withdrawals

construct_multicalls()

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

Return type

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

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]

get_warmup_calls()

Yield (function_name, callable, contract_call) tuples for warmup testing.

Each callable should execute a single contract call. If it raises, the function is marked as broken.

The optional contract_call is used for gas estimation to detect expensive calls before executing them. If provided, calls using excessive gas (>1M gas) will be marked as broken without execution.

Override in subclasses to add protocol-specific calls.

Returns

Iterable of (function_name, test_callable, contract_call) tuples. contract_call may be None if gas estimation is not needed.

Return type

Iterable[tuple[str, callable, Any]]

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

should_skip_call(function_name)

Check if a specific function call should be skipped.

Uses the reader state’s call_status map if available.

Parameters

function_name (str) – The function name to check

Returns

True if the call should be skipped

Return type

bool

class AccountableVault

Bases: eth_defi.erc_4626.vault.ERC4626Vault

Accountable Capital vault support.

Accountable Capital develops blockchain-based financial verification technology that enables organisations and investors to demonstrate solvency, liquidity, and compliance through transparent, verifiable attestations. The platform combines cryptographic proofs with auditable financial data to enhance trust across Web3 and traditional finance.

Accountable vaults implement ERC-7540 async redemption pattern with a queue system for processing withdrawal requests.

Accountable’s totalAssets() only returns the idle liquidity held by the vault contract. When the strategy deploys capital via lockAssets(), those assets are subtracted from totalAssets(). This means totalAssets() severely underreports the true vault value.

The true NAV is computed as convertToAssets(totalSupply()), which uses sharePrice() — the oracle/strategy-set price that reflects all capital including deployed positions. Both fetch_total_assets() and AccountableHistoricalReader use this corrected calculation.

The raw totalAssets() value is exposed via fetch_idle_capital() and fetch_available_liquidity() as it represents capital available for immediate withdrawals.

Key contract functions for NAV:

  • sharePrice() — current price per share (reflects deployed capital)

  • totalSupply() — total shares outstanding

  • convertToAssets(shares) — converts shares to assets using share price

  • totalAssets() — idle liquidity only (excludes deployed capital)

  • lockAssets(assets, sender) — strategy deploys capital (reduces totalAssets)

  • releaseAssets(assets, receiver) — strategy returns capital (increases totalAssets)

  • reservedLiquidity() — assets reserved for pending redemptions

  • Homepage: https://www.accountable.capital/

  • Twitter: https://x.com/AccountableData

  • No public GitHub repository available for smart contracts

  • Example contract: https://monadscan.com/address/0x58ba69b289De313E66A13B7D1F822Fc98b970554

Parameters
  • web3 – Connection we bind this instance to

  • spec – Chain, address tuple

  • token_cache

    Cache used with fetch_erc20_details() to avoid multiple calls to the same token.

    Reduces the number of RPC calls when scanning multiple vaults.

  • features – Pass vault feature flags along, externally detected.

  • default_block_identifier

    Override block identifier for on-chain metadata reads.

    When None, use get_safe_cached_latest_block_number() (the default, safe for broken RPCs). Set to "latest" for freshly deployed vaults whose contracts do not exist at the safe-cached block.

  • require_denomination_token – If True, accessing denomination_token will raise RuntimeError when the on-chain lookup returns None.

property vault_contract: web3.contract.contract.Contract

Get vault deployment with Accountable-specific ABI.

get_historical_reader(stateful)

Get share price reader to fetch historical returns.

Parameters

stateful – If True, use a stateful reading strategy.

Returns

None if unsupported

Return type

eth_defi.vault.base.VaultHistoricalReader

fetch_idle_capital(block_identifier='latest')

Fetch idle capital held by the vault contract.

This is the raw totalAssets() value — assets sitting in the vault that have not been deployed by the strategy via lockAssets(). This is the capital available for immediate withdrawals.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block number to read.

Returns

Idle capital in underlying token, or None if denomination token is unavailable.

Return type

Optional[decimal.Decimal]

fetch_total_assets(block_identifier)

Fetch the true vault NAV including deployed capital.

Accountable’s totalAssets() only returns idle liquidity. We compute the true NAV as convertToAssets(totalSupply()), which uses the strategy-set sharePrice() to account for all capital including deployed positions.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block number to read.

Returns

The vault NAV in underlying token, or None if denomination token is unavailable.

Return type

Optional[decimal.Decimal]

fetch_nav(block_identifier=None)

Fetch the most recent onchain NAV value.

Uses convertToAssets(totalSupply()) instead of totalAssets() because Accountable’s totalAssets() excludes deployed capital.

Returns

Vault NAV, denominated in denomination_token()

Return type

decimal.Decimal

fetch_available_liquidity(block_identifier='latest')

Get the amount of denomination token available for immediate withdrawal.

For Accountable vaults, this is totalAssets() which returns only idle capital not deployed by the strategy.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block to query. Defaults to “latest”.

Returns

Amount in denomination token units (human-readable Decimal).

Return type

Optional[decimal.Decimal]

fetch_utilisation_percent(block_identifier='latest')

Get the percentage of assets currently deployed by the strategy.

Utilisation = (true NAV - idle capital) / true NAV

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block to query. Defaults to “latest”.

Returns

Utilisation as float between 0.0 and 1.0 (0% to 100%).

Return type

Optional[float]

get_deposit_manager()

Create Accountable’s synchronous-deposit async-redeem manager.

Returns

Protocol-specific request and claim manager.

Return type

eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableDepositManager

fetch_permission_level(block_identifier=None)

Read Accountable’s explicit vault-wide admission mode.

Verified Accountable source defines None = 0, KYC = 1 and Whitelist = 2. The vault’s onlyAuth modifier permits every account in mode zero, requires a signed per-call authorisation in KYC mode, and reads allowed(account) in whitelist mode.

Parameters

block_identifier (Optional[Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]]) – Block at which to inspect the configured permission mode.

Returns

Typed Accountable permission level.

Raises

NotImplementedError – If a future deployment returns an unknown enum value.

Return type

eth_defi.erc_4626.vault_protocol.accountable.vault.AccountablePermissionLevel

is_whitelisted_deposit()

Report whether Accountable requires identity-based admission.

Minimum deposits, strategy capacity, loan state, and redemption queues are independent lifecycle conditions and do not affect this result.

Returns

False for Accountable’s None mode and True for KYC or explicit whitelist modes.

Return type

bool

is_account_whitelisted(address, permission_level=None)

Check whether a bare account can use the configured admission mode.

Whitelist mode has persistent membership through allowed(address). KYC mode instead requires Accountable-signed authorisation appended to each call; the standard ERC-4626 transaction builder supplies no such payload, so an address-only request is not admitted.

Parameters
Returns

Whether the standard adapter call is admitted for this account.

Return type

bool

get_deposit_manager_capability()

Declare Accountable’s public request lifecycle.

Returns

Synchronous deposit and asynchronous redemption capability.

Return type

eth_defi.vault.deposit_redeem.VaultDepositManagerCapability

property accountable_metadata: Optional[eth_defi.erc_4626.vault_protocol.accountable.offchain_metadata.AccountableVaultMetadata]

Offchain metadata from Accountable’s yield app API.

Fetched from yield.accountable.capital/api/loan. Cached on disk and in-process to avoid repeated API calls.

property description: Optional[str]

Full vault strategy description from Accountable’s offchain metadata.

property short_description: Optional[str]

First sentence of the vault strategy from Accountable’s offchain metadata.

property manager_name: Optional[str]

Curator company name from Accountable’s public vault API.

Accountable separates the ERC-4626 share-token name from the strategy manager. Its company_name metadata therefore provides the canonical curator identity for the generic vault scan and export.

Returns

Accountable’s manager display name, or None when the vault is not present in the public metadata API.

fetch_minimum_deposit(block_identifier='latest')

Fetch Accountable’s effective minimum deposit in token units.

Accountable checks both the vault’s MIN_AMOUNT_WEI() threshold and the strategy’s configured loan.minDeposit. The larger value is the amount an LP must satisfy.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block tag or number shared by both reads.

Returns

Human-readable denomination-token amount, or None when the getter or denomination token is unavailable.

Return type

Optional[decimal.Decimal]

fetch_minimum_redemption(block_identifier='latest')

Fetch Accountable’s request-redemption dust threshold in shares.

loan().minRedeem intentionally remains excluded until its unit is source-proven for the selected strategy deployment.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block at which to read the threshold.

Returns

Decimal share minimum, or None when unavailable.

Return type

Optional[decimal.Decimal]

fetch_accountable_fees(block_identifier='latest')

Fetch every Accountable fee-manager term and the minimum deposit.

The vault points to its strategy, and the strategy points to the fee manager. The reader first tries the current ABI’s managementFee() getter. A missing selector identifies the legacy ABI, where management fees are structurally unsupported and therefore known to be zero.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block tag or number shared by all onchain reads.

Returns

Complete Accountable-native fee snapshot.

Return type

eth_defi.erc_4626.vault_protocol.accountable.vault.AccountableFeeData

get_fee_data()

Fetch Accountable fees using the shared fee-data representation.

Returns

Investor-facing management and performance fees with zero LP deposit and withdrawal charges.

Return type

eth_defi.vault.fee.FeeData

get_management_fee(block_identifier)

Fetch the annualised onchain management fee.

Legacy fee managers cannot charge a management fee, so they return a known zero instead of the previous unknown None.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block tag or number at which to read the fee.

Returns

Fractional management fee, such as 0.01 for 1%.

Return type

float

get_performance_fee(block_identifier)

Fetch the onchain performance fee.

This replaces the previous offchain API value with the fee manager as the authoritative source.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Block tag or number at which to read the fee.

Returns

Fractional performance fee, such as 0.20 for 20%.

Return type

float

get_deposit_fee(block_identifier)

Return zero because Accountable has no ERC-4626 LP deposit fee.

establishmentFee is collected from the underlying borrower during loan repayment and must not be presented as an investor entry fee.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Unused because the LP deposit fee is structurally zero.

Returns

Always 0.0.

Return type

float

get_withdraw_fee(block_identifier)

Return zero because Accountable has no ERC-4626 LP withdrawal fee.

prepaymentFee applies when an underlying borrower repays early and must not be presented as an investor redemption fee.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Unused because the LP withdrawal fee is structurally zero.

Returns

Always 0.0.

Return type

float

has_custom_fees()

Report native borrower fee terms outside the shared fee schema.

Accountable establishment, prepayment and recipient-split fields are preserved in AccountableFeeData, but the shared fee schema cannot represent them without mislabelling borrower charges as LP entry or exit charges.

Returns

Always True for Accountable vaults.

Return type

bool

get_estimated_lock_up()

Accountable vaults use async redemption queue.

Lock-up period depends on the vault strategy and available liquidity.

Return type

Optional[datetime.timedelta]

Return the yield app link.

Accountable’s yield app URLs use the loan/strategy contract address, not the ERC-4626 vault (share token) address. Falls back to the vault address if metadata is unavailable.

Parameters

referral (Optional[str]) –

Return type

str

__init__(web3, spec, token_cache=None, features=None, default_block_identifier=None, require_denomination_token=False)
Parameters
  • web3 (web3.main.Web3) – Connection we bind this instance to

  • spec (eth_defi.vault.base.VaultSpec) – Chain, address tuple

  • token_cache (Optional[dict]) –

    Cache used with fetch_erc20_details() to avoid multiple calls to the same token.

    Reduces the number of RPC calls when scanning multiple vaults.

  • features (Optional[set[eth_defi.erc_4626.core.ERC4626Feature]]) – Pass vault feature flags along, externally detected.

  • default_block_identifier (Optional[Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, hexbytes.main.HexBytes, int]]) –

    Override block identifier for on-chain metadata reads.

    When None, use get_safe_cached_latest_block_number() (the default, safe for broken RPCs). Set to "latest" for freshly deployed vaults whose contracts do not exist at the safe-cached block.

  • require_denomination_token (bool) – If True, accessing denomination_token will raise RuntimeError when the on-chain lookup returns None.

property address: eth_typing.evm.HexAddress

Get the vault smart contract address.

can_check_deposit()

Check if maxDeposit(address(0)) can be used to check global deposit availability.

Most ERC-4626 vaults implement maxDeposit in a way that returns meaningful values when called with address(0):

  • Returns 0 when deposits are globally closed/capped

  • Returns a positive value indicating maximum deposit allowed

Override to return False in subclasses where maxDeposit(address(0)) doesn’t provide meaningful global availability information.

Returns

True if maxDeposit(address(0)) returns meaningful values for global deposit availability checking.

Return type

bool

can_check_redeem()

Check if maxRedeem(address(0)) can be used to check global redemption availability.

Most protocols return 0 for maxRedeem(address(0)) because that address has no balance/shares, not because redemptions are closed:

  • Gearbox: maxRedeem returns min(balanceOf(owner), convertToShares(availableLiquidity))

  • Most vaults: Return 0 because address(0) has no shares

Some protocols do use maxRedeem(address(0)) meaningfully:

  • Morpho, IPOR, Plutus: Return 0 when redemptions are globally blocked

Override to return True in subclasses that support address(0) redemption checks.

Returns

True if maxRedeem(address(0)) returns meaningful values for global redemption availability checking.

Return type

bool

property chain_id: int

Chain this vault is on

property denomination_token: Optional[eth_defi.token.TokenDetails]

Get the token which denominates the vault valuation

  • Used in deposits and redemptions

  • Used in NAV calculation

  • Used in profit benchmarks

  • Usually USDC

Returns

Token wrapper instance.

Maybe None for broken vaults like https://arbiscan.io/address/0x9d0fbc852deccb7dcdd6cb224fa7561efda74411#code

Note

None results are not cached — the next access will retry the on-chain call. This avoids permanently caching a transient RPC failure.

property deposit_manager: eth_defi.vault.deposit_redeem.VaultDepositManager

Deposit manager assocaited with this vault

property erc_7540: bool

Is this ERC-7540 vault with asynchronous deposits.

  • For example previewDeposit() function and other functions will revert

fetch_denomination_token()

Read denomination token from onchain.

Use denomination_token() for cached access.

Return type

Optional[eth_defi.token.TokenDetails]

fetch_denomination_token_address()

Get the asset() denomination token address of this vault.

Results are disk-cached per (chain_id, vault_address) via eth_defi.erc_4626.vault_token when the vault was constructed with a eth_defi.token.TokenDiskCache and no pinned default_block_identifier. The denomination token is immutable post-deployment, so the cached value is correct regardless of which block the caller would have asked for.

Only a definitive non-null answer is persisted. The None path taken on revert / broken contract is never cached, matching the behaviour of eth_defi.vault.base.VaultBase.denomination_token() which explicitly avoids memoising None so transient failures can be retried.

To disable the cache, pass token_cache=None (or any non- TokenDiskCache dict) when constructing the vault, or construct with a pinned default_block_identifier.

Returns

Denomination token address, or None if the vault contract is broken and did not return a valid address.

Return type

Optional[eth_typing.evm.HexAddress]

fetch_deposit_closed_reason()

Check if deposits are closed using maxDeposit(address(0)).

Uses the ERC-4626 standard maxDeposit function to determine if deposits are available. Returns a human-readable reason with the max deposit amount if deposits are restricted.

Returns

Human-readable string if deposits are closed/restricted, or None if deposits are open (maxDeposit > 0).

Return type

Optional[str]

fetch_deposit_next_open()

Get when deposits will next be open.

  • For epoch-based vaults (Ostium, D2), return calculated window open time

  • For non-epoch vaults (Plutus, IPOR, Morpho), return None

  • Override in protocol-specific subclasses

Returns

Naive UTC datetime when deposits will next be available, or None if:

  • Deposits are currently open

  • Timing is unpredictable (manually controlled)

  • Protocol does not support timing information

Return type

Optional[datetime.datetime]

fetch_info()

Use info() property for cached access.

Returns

See LagoonVaultInfo

Return type

eth_defi.erc_4626.vault.ERC4626VaultInfo

fetch_portfolio(universe, block_identifier=None, allow_fallback=True)

Read the current token balances of a vault.

  • SHould be supported by all implementations

Parameters
Return type

eth_defi.vault.base.VaultPortfolio

fetch_redemption_closed_reason()

Check if redemptions are closed using maxRedeem(address(0)).

Only works for protocols that implement maxRedeem in a way that returns meaningful values for address(0). Most protocols return 0 because address(0) has no shares, not because redemptions are closed.

Returns

Human-readable string if redemptions are closed, or None if redemptions are open or check is not supported.

Return type

Optional[str]

fetch_redemption_next_open()

Get when withdrawals/redemptions will next be open.

  • For epoch-based vaults (Ostium, D2), return calculated window open time

  • For non-epoch vaults (Plutus, IPOR, Morpho), return None

  • Override in protocol-specific subclasses

Returns

Naive UTC datetime when withdrawals will next be available, or None if:

  • Withdrawals are currently open

  • Timing is unpredictable (manually controlled)

  • Protocol does not support timing information

Return type

Optional[datetime.datetime]

fetch_scan_record_extra_data()

Fetch protocol-specific private scan row columns.

Some vault protocols expose structured metadata that is useful for the raw scanner output but does not fit the shared human-readable columns. Override this hook in protocol-specific subclasses instead of adding a separate branch to eth_defi.erc_4626.scan.create_vault_scan_record().

Returns

Mapping of private scan-row column names, usually prefixed with _. The default implementation returns no extra data.

Return type

dict[str, object]

fetch_share_price(block_identifier)

Get the current share price.

Returns

The share price in underlying token.

If supply is zero return zero.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, hexbytes.main.HexBytes, int]) –

Return type

decimal.Decimal

fetch_share_token()

Read share token details onchain.

Use share_token() for cached access.

Return type

eth_defi.token.TokenDetails

fetch_share_token_address(block_identifier='latest')

Get share token of this vault.

  • Vault itself (ERC-4626)

  • share() accessor (ERC-7575)

Results are disk-cached per (chain_id, vault_address) via eth_defi.erc_4626.vault_token when the vault was constructed with a eth_defi.token.TokenDiskCache. Under normal circumstances the block_identifier argument is effectively ignored on cache hits — ERC-4626 share tokens are immutable post-deployment, so the cached value is correct regardless of which block the caller asked for.

Only a definitive answer from the chain is ever persisted: a successful call, or a revert matching KNOWN_SHARE_TOKEN_ERROR_MESSAGES (which positively classifies the contract as non-ERC-7575). Transient RPC failures (ProbablyNodeHasNoBlock, HTTP 502) fall back to self.vault_address but are not written to the cache, so a flaky node cannot poison a real ERC-7575 vault’s entry.

To disable the cache, pass token_cache=None (or any non- TokenDiskCache dict) when constructing the vault, or construct with a pinned default_block_identifier to force the uncached historical-read path on every call.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, hexbytes.main.HexBytes, int]) – Block to query. Cache is only consulted/written when the caller passes the default "latest" and the vault instance has no pinned default_block_identifier.

Return type

eth_typing.evm.HexAddress

fetch_total_supply(block_identifier)

What is the current outstanding shares.

Example:

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, hexbytes.main.HexBytes, int]) –

Block number to read.

Use web3.eth.block_number for the last block.

Returns

The vault value in underlyinh token

Return type

decimal.Decimal

fetch_vault_info()

Get all information we can extract from the vault smart contracts.

Return type

eth_defi.erc_4626.vault.ERC4626VaultInfo

property flow_manager: eth_defi.vault.base.VaultFlowManager

Flow manager associated with this vault

get_fee_mode()

Get how this vault accounts its fees.

Return type

Optional[eth_defi.vault.fee.VaultFeeMode]

get_flags()

Get various vault state flags from the smart contract.

Returns

Flag set.

Do not modify in place.

Return type

set[eth_defi.vault.flag.VaultFlag]

get_flow_manager()

Get flow manager to read indiviaul settle events.

Return type

eth_defi.vault.base.VaultFlowManager

get_notes()

Get a human readable message if we know somethign special is going on with this vault.

Return type

Optional[str]

get_protocol_name()

Return the name of the vault protocol.

Return type

str

get_risk()

Get risk profile of this vault.

Return type

Optional[eth_defi.vault.risk.VaultTechnicalRisk]

get_share_price_source()

Return the standard ERC-4626 share-price source.

ERC-4626 prices are calculated from vault accounting values read at a specific block, including protocol-specific overrides that expose the same state through another contract view.

Returns

Smart-contract state source.

Return type

eth_defi.vault.price_source.PriceSource

get_synchronous_deposit_manager_capability()

Build static metadata for a verified synchronous manager.

A caller must already have established the reader class’ guarded fork evidence. This deliberately performs no RPC reads: the capability is static library metadata, not a live vault availability check.

Returns

Synchronous two-way capability.

Return type

eth_defi.vault.deposit_redeem.VaultDepositManagerCapability

get_whitelist_notes()

Return an export caveat for the vault-wide whitelist status.

Adapters may attach a concise, stable explanation when a classification is an explicitly requested operating assumption or excludes an integration-specific permission mechanism. The note describes the policy classification only; it must not be used to report temporary deposit availability.

Returns

Export note, or None when the classification needs no caveat.

Return type

Optional[str]

has_block_range_event_support()

Does this vault support block range-based event queries for deposits and redemptions.

  • If not we use chain balance polling-based approach

has_deposit_distribution_to_all_positions()

Deposits go automatically to all open positions.

  • Deposits do not land into the vault as cash

  • Instead, smart contracts automatically increase all open positions

  • The behaviour of Velvet Capital

property info: eth_defi.vault.base.VaultInfo

Get info dictionary related to this vault deployment.

  • Get cached data on the various vault parameters

Returns

Vault protocol specific information dictionary

is_valid()

Check if this vault is valid.

  • Call a known smart contract function to verify the function exists

Return type

bool

property name: str

Vault name.

property share_token: eth_defi.token.TokenDetails

ERC-20 that presents vault shares.

  • User gets shares on deposit and burns them on redemption

supports_generic_deposit_manager()

Check whether the live vault exposes the standard ERC-4626 surface.

This is deliberately an interface check, not a public support claim. Callers must still execute a guarded fork probe before relying on the generic manager for a protocol-specific adapter.

Returns

True when asset succeeds with a non-zero asset address. Deposit and redemption availability is established only by a guarded fork transaction, not by ERC-4626 max* advisory values.

Return type

bool

property symbol: str

Vault share token symbol

property underlying_token: eth_defi.token.TokenDetails

Alias for denomination_token()

first_seen_at_block: int | None

Block number hint when this vault was deployed.

Must be set externally, as because of shitty Ethereum RPC we cannot query this. Allows us to avoid unnecessary work when scanning historical price data.