OdaFactVault

Documentation for eth_defi.tokenised_fund.kinexys.vault.OdaFactVault Python class.

class OdaFactVault

Bases: eth_defi.vault.base.VaultBase

Scan-only adapter for ODA-FACT tokenised fund contracts.

The adapter reads ERC-20 supply from the ODA-FACT token itself. For the initial JLTXX integration, share price is an explicitly labelled 1.00 USD estimate until an official NAV feed is available.

Create an ODA-FACT vault adapter.

Parameters
  • web3 – Web3 connection.

  • spec – Chain and ODA-FACT token address.

  • token_cache – Token metadata cache used by fetch_erc20_details().

  • features – Shared pipeline feature flags. Expected to contain ERC4626Feature.oda_fact_like.

  • default_block_identifier – Default block for metadata reads.

  • require_denomination_token – Whether missing denomination token should raise through VaultBase.denomination_token.

Attributes summary

address

ODA-FACT token and diamond address.

chain_id

EVM chain id for this ODA-FACT contract.

denomination_token

Get the token which denominates the vault valuation

deposit_manager

Deposit manager assocaited with this vault

description

Human-readable product description.

flow_manager

Flow manager associated with this vault

info

Get info dictionary related to this vault deployment.

manager_name

Issuer or platform display name.

name

Token name, falling back to static product metadata.

share_token

ERC-20 that presents vault shares.

short_description

Short product description.

symbol

Token symbol.

vault_address

Compatibility alias for scanner code that expects vault_address.

Methods summary

__init__(web3, spec[, token_cache, ...])

Create an ODA-FACT vault adapter.

fetch_available_liquidity([block_identifier])

Get the amount of denomination token available for immediate withdrawal.

fetch_denomination_token()

Fetch ERC-20 denomination token metadata.

fetch_denomination_token_address()

Return the ERC-20 denomination token address.

fetch_deposit_closed_reason()

Return the Kinexys public deposit availability status.

fetch_deposit_next_open()

Get when deposits will next be open.

fetch_info()

Return ODA-FACT metadata for this scan-only adapter.

fetch_nav([block_identifier])

Fetch ODA-FACT NAV.

fetch_portfolio(universe[, block_identifier])

Return an empty portfolio for the scan-only adapter.

fetch_redemption_closed_reason()

Return the Kinexys public redemption availability status.

fetch_redemption_next_open()

Get when withdrawals/redemptions will next be open.

fetch_scan_record_extra_data()

Return ODA-FACT-specific scan-row diagnostics.

fetch_share_price([block_identifier])

Fetch ODA-FACT share price when an authorised source is available.

fetch_share_token()

Fetch ERC-20 metadata for the ODA-FACT token.

fetch_share_token_address([block_identifier])

Return the ODA-FACT token address.

fetch_total_assets([block_identifier])

Fetch ODA-FACT TVL when a share NAV is available.

fetch_total_supply([block_identifier])

Fetch total outstanding ODA-FACT token supply.

fetch_utilisation_percent([block_identifier])

Get the percentage of assets currently lent out.

get_deposit_fee(block_identifier)

Deposit fee is set to zero by default as vaults usually do not have deposit fees.

get_deposit_manager()

Get deposit manager.

get_deposit_manager_capability()

Return static public transaction-adapter support, if any.

get_estimated_lock_up()

Return unknown lock-up.

get_fee_data()

Return hardcoded JLTXX prospectus fee data.

get_fee_mode()

Get how this vault accounts its fees.

get_flags()

Get various vault state flags from the smart contract.

get_flow_manager()

Get flow manager.

get_historical_reader(stateful)

Get ODA-FACT historical reader.

get_link([referral])

Return product/platform link.

get_management_fee(block_identifier)

Return JLTXX net annual expense ratio.

get_notes()

Return markdown notes for the known ODA-FACT vault.

get_performance_fee(block_identifier)

Return JLTXX performance fee.

get_protocol_name()

Return the name of the vault protocol.

get_risk()

Get risk profile of this vault.

get_spec()

get_withdraw_fee(block_identifier)

Withdraw fee is set to zero by default as vaults usually do not have withdraw fees.

has_block_range_event_support()

Whether event-based deposit/redemption flow accounting is implemented.

has_custom_fees()

Does this vault have fees outside the shared fee model.

has_deposit_distribution_to_all_positions()

Whether deposits are automatically distributed to positions.

__init__(web3, spec, token_cache=None, features=None, default_block_identifier=None, require_denomination_token=False)

Create an ODA-FACT vault adapter.

Parameters
  • web3 (web3.main.Web3) – Web3 connection.

  • spec (eth_defi.vault.base.VaultSpec) – Chain and ODA-FACT token address.

  • token_cache (Optional[dict]) – Token metadata cache used by fetch_erc20_details().

  • features (Optional[set[eth_defi.erc_4626.core.ERC4626Feature]]) – Shared pipeline feature flags. Expected to contain ERC4626Feature.oda_fact_like.

  • default_block_identifier (Optional[Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]]) – Default block for metadata reads.

  • require_denomination_token (bool) – Whether missing denomination token should raise through VaultBase.denomination_token.

property chain_id: int

EVM chain id for this ODA-FACT contract.

property address: eth_typing.evm.HexAddress

ODA-FACT token and diamond address.

property vault_address: eth_typing.evm.HexAddress

Compatibility alias for scanner code that expects vault_address.

property name: str

Token name, falling back to static product metadata.

property symbol: str

Token symbol.

property description: Optional[str]

Human-readable product description.

property short_description: Optional[str]

Short product description.

property manager_name: Optional[str]

Issuer or platform display name.

fetch_share_token_address(block_identifier='latest')

Return the ODA-FACT token address.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Accepted for compatibility with the shared historical scanner.

Returns

ODA-FACT token address.

Return type

eth_typing.evm.HexAddress

fetch_share_token()

Fetch ERC-20 metadata for the ODA-FACT token.

Returns

Token details for the ODA-FACT share token.

Return type

eth_defi.token.TokenDetails

fetch_denomination_token_address()

Return the ERC-20 denomination token address.

ODA-FACT fund accounting is USD-denominated but does not expose an ERC-4626 asset() token or any other ERC-20 denomination token. Exporting a surrogate token would make the vault appear to accept or redeem that asset, so this adapter reports no denomination token.

Returns

Always None.

Return type

Optional[eth_typing.evm.HexAddress]

fetch_denomination_token()

Fetch ERC-20 denomination token metadata.

Returns

Always None because ODA-FACT instruments do not expose a denomination token.

Return type

Optional[eth_defi.token.TokenDetails]

fetch_share_price(block_identifier='latest')

Fetch ODA-FACT share price when an authorised source is available.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Historical or latest block identifier. The current implementation does not have block-specific NAV data.

Returns

Estimated JLTXX NAV per one human-readable share, or None for MONY because its FACT Diamond has no on-chain price or NAV view.

Return type

Optional[decimal.Decimal]

fetch_total_supply(block_identifier='latest')

Fetch total outstanding ODA-FACT token supply.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Historical or latest block identifier.

Returns

Human-readable token supply.

Return type

decimal.Decimal

fetch_total_assets(block_identifier='latest')

Fetch ODA-FACT TVL when a share NAV is available.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Historical or latest block identifier.

Returns

Estimated total assets in USD-denomination units, or None when the product provides no verified NAV.

Return type

Optional[decimal.Decimal]

fetch_nav(block_identifier='latest')

Fetch ODA-FACT NAV.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Historical or latest block identifier.

Returns

Estimated total assets in USD-denomination units, or None when the product provides no verified NAV.

Return type

Optional[decimal.Decimal]

fetch_info()

Return ODA-FACT metadata for this scan-only adapter.

Returns

Token and NAV-source metadata.

Return type

eth_defi.tokenised_fund.kinexys.vault.OdaFactVaultInfo

fetch_scan_record_extra_data()

Return ODA-FACT-specific scan-row diagnostics.

Returns

Private scan-row fields that make the temporary NAV and denomination assumptions explicit.

Return type

dict[str, object]

fetch_portfolio(universe, block_identifier=None)

Return an empty portfolio for the scan-only adapter.

ODA-FACT fund assets are not represented as on-chain ERC-20 holdings of the token contract. Portfolio composition requires an off-chain fund accounting feed and is intentionally out of scope.

Parameters
Returns

Empty spot portfolio.

Return type

eth_defi.vault.base.VaultPortfolio

has_block_range_event_support()

Whether event-based deposit/redemption flow accounting is implemented.

Return type

bool

has_deposit_distribution_to_all_positions()

Whether deposits are automatically distributed to positions.

Return type

bool

get_flow_manager()

Get flow manager.

Raises

NotImplementedError – Always, because ODA-FACT flow accounting is not implemented yet.

Return type

eth_defi.vault.base.VaultFlowManager

get_deposit_manager()

Get deposit manager.

Raises

NotImplementedError – Always, because active ODA-FACT subscription and redemption are not implemented.

Return type

eth_defi.vault.deposit_redeem.VaultDepositManager

fetch_deposit_closed_reason()

Return the Kinexys public deposit availability status.

Kinexys ODA-FACT contracts are permissioned tokenised fund contracts. On-chain subscriptions are available only to whitelisted parties and are not exposed through a public ERC-4626-style deposit flow.

Returns

Human-readable reason why public deposits are closed.

Return type

Optional[str]

fetch_redemption_closed_reason()

Return the Kinexys public redemption availability status.

Kinexys ODA-FACT contracts are permissioned tokenised fund contracts. On-chain redemptions are available only to whitelisted parties and are not exposed through a public ERC-4626-style redemption flow.

Returns

Human-readable reason why public redemptions are closed.

Return type

Optional[str]

get_historical_reader(stateful)

Get ODA-FACT historical reader.

Parameters

stateful (bool) – Whether to attach adaptive reader state.

Returns

Historical reader.

Return type

eth_defi.vault.base.VaultHistoricalReader

get_fee_data()

Return hardcoded JLTXX prospectus fee data.

ODA-FACT product fees are not available from the on-chain token surface. J.P. Morgan’s JLTXX prospectus advertises 0.71% gross total annual fund operating expenses and 0.16% net total annual fund operating expenses after waivers through JLTXX_PROSPECTUS_FEE_WAIVER_UNTIL. The shared vault fee model has only one annual management-like field, so the current net expense ratio is exposed as management. performance, deposit and withdraw are reported as zero because they are not advertised as separate Token Class fees.

Returns

Hardcoded fee data for the known ODA-FACT contract, or broken fee data for unknown ODA-FACT addresses.

Return type

eth_defi.vault.fee.FeeData

get_management_fee(block_identifier)

Return JLTXX net annual expense ratio.

The fee is hardcoded from the JLTXX prospectus, because it is not readable from the ODA-FACT token contract.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Ignored. Prospectus fee disclosure is not block-specific.

Returns

0.0016 for JLTXX, representing 0.16% net annual fund operating expenses after waivers.

Return type

Optional[float]

get_performance_fee(block_identifier)

Return JLTXX performance fee.

Parameters

block_identifier (Union[Literal['latest', 'earliest', 'pending', 'safe', 'finalized'], eth_typing.evm.BlockNumber, eth_typing.evm.Hash32, eth_typing.encoding.HexStr, int]) – Ignored. Prospectus fee disclosure is not block-specific.

Returns

0 because the JLTXX Token Class prospectus does not advertise a separate performance fee.

Return type

Optional[float]

get_notes()

Return markdown notes for the known ODA-FACT vault.

The notes are stored in the shared vault notes matrix so both direct adapter users and downstream vault metric exports see the same vault-specific description.

Returns

Markdown note for JLTXX, or None for unknown ODA-FACT addresses.

Return type

Optional[str]

get_estimated_lock_up()

Return unknown lock-up.

Returns

None because subscription/redemption terms are off-chain.

Return type

Optional[datetime.timedelta]

get_link(referral=None)

Return product/platform link.

Parameters

referral (Optional[str]) – Ignored.

Returns

Kinexys platform URL.

Return type

str

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

fetch_available_liquidity(block_identifier='latest')

Get the amount of denomination token available for immediate withdrawal.

Only applicable to lending protocol vaults (IPOR, Euler, Morpho, Gearbox, etc.). Non-lending protocols should leave this method unimplemented.

Note: maxRedeem(address(0)) does NOT work as a proxy for available liquidity because it requires a specific address that has already deposited shares. For address(0), balanceOf is always 0, so maxRedeem returns 0 regardless of actual liquidity.

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”.

Raises

NotImplementedError – For non-lending protocol vaults.

Returns

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

Return type

Optional[decimal.Decimal]

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_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_utilisation_percent(block_identifier='latest')

Get the percentage of assets currently lent out.

Only applicable to lending protocol vaults (IPOR, Euler, Morpho, Gearbox, etc.). Non-lending protocols should leave this method unimplemented.

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”.

Raises

NotImplementedError – For non-lending protocol vaults.

Returns

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

Return type

Optional[float]

property flow_manager: eth_defi.vault.base.VaultFlowManager

Flow manager associated with this vault

get_deposit_fee(block_identifier)

Deposit fee is set to zero by default as vaults usually do not have deposit fees.

Internal: Use get_fee_data().

Parameters

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

Return type

Optional[float]

get_deposit_manager_capability()

Return static public transaction-adapter support, if any.

This method deliberately does not attempt to construct a manager or query live pause, cap, epoch, balance, allow-list, or liquidity state. Adapters opt in only after their complete deposit and redemption lifecycles have focused coverage. None is therefore the safe default for unknown and protocol-specific vaults.

Returns

Adapter-specific capability object, or None when unsupported.

Return type

Optional[eth_defi.vault.deposit_redeem.VaultDepositManagerCapability]

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_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_withdraw_fee(block_identifier)

Withdraw fee is set to zero by default as vaults usually do not have withdraw fees.

Internal: Use get_fee_data().

Parameters

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

Return type

float

has_custom_fees()

Does this vault have fees outside the shared fee model.

Custom fees cause risk in vault comparison because the shared management/performance/deposit/withdraw fee fields cannot describe the full fee structure.

Do not return True merely because a vault implements custom accessors for ordinary management, performance, deposit, or withdraw fees. Return True only when some vault fee cannot be reflected in those standard fields as a fee-like value.

Returns

True if the vault has fees outside the shared fee model.

Return type

bool

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

property share_token: eth_defi.token.TokenDetails

ERC-20 that presents vault shares.

  • User gets shares on deposit and burns them on redemption

first_seen_at_block: Optional[int]

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.