AccountableDepositManager

Documentation for eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableDepositManager Python class.

class AccountableDepositManager

Bases: eth_defi.erc_4626.deposit_redeem.ERC4626DepositManager

Accountable adapter with synchronous deposits and claimed redemptions.

Accountable Capital vaults are ERC-4626 vaults whose capital is deployed into an external strategy. Deposits settle immediately, but redemptions follow the ERC-7540 async pattern: a requestRedeem escrows the shares into a queue, the strategy operator settles it, and the owner later claims the settled assets through the standard redeem entry point. The contract exposes only controller-level aggregate pending/claimable balances, not per-request balances, which shapes several limitations below.

Deposit process

Fully synchronous ERC-4626. create_deposit_request() builds a single deposit(assets, receiver) call (via deposit_4626()) after enforcing a minimum and a capacity check. The binding minimum is the greater of the vault-level MIN_AMOUNT_WEI and the strategy’s per-loan loan().minDeposit (_fetch_strategy_loan_min_deposit(); open-term strategies revert InsufficientAmount() (0x5945ea56) inside strategy.onDeposit for a deposit that clears only the vault minimum). A sub-minimum or over-maxDeposit request raises VaultFlowUnavailable. Estimation uses convertToShares because this deployment makes previewDeposit revert.

Redemption process

Asynchronous. create_redemption_request() builds a single requestRedeem(shares, owner, owner) call; the owner acts as its own ERC-7540 controller and no share-token allowance is needed because requestRedeem itself escrows the shares. The receiver must equal the owner. The vault-level MIN_AMOUNT_WEI (in shares) is enforced; the strategy minRedeem is deliberately not applied because its unit is unconfirmed for this deployment. Because claimability is a controller aggregate, an existing pending or claimable request blocks a further request for the same owner (is_redemption_in_progress()). Settled shares are claimed with finish_redemption(), which calls redeem for the current claimable amount.

Queues and settlement

ERC-7540-style queue. Pending and claimable state is read as controller aggregates through pendingRedeemRequest(0, controller) and claimableRedeemRequest(0, controller) (_pending_redeem_shares() / _claimable_redeem_shares()), not per request id. Settlement is performed off-band by the strategy operator; timing is not deterministic. The manager only auto-claims self-controlled tickets back to their share owner — it never directs an aggregate claim to a custom receiver or auto-claims a delegated-controller ticket. Multiple concurrent controller requests, partial claims and repeated settlement rounds are not modelled beyond claiming the current aggregate.

Lockups and cooldowns

No deterministic window. estimate_redemption_delay() returns zero and get_redemption_delay_over() returns None because settlement timing is strategy-controlled; AccountableVault.get_estimated_lock_up() is likewise None.

Whitelisting / access control

Accountable exposes a constructor-selected vault-wide permissionLevel. Mode None is permissionless, KYC requires signed per-call authorisation, and Whitelist checks persistent allowed(address) membership. The manager performs this admission check independently from minimum amount, loan state, and maxDeposit(owner) capacity. Hyperithm uses None.

Anvil settlement (force_settle)

Deposits use the shared force_settle(None) no-op. Redemptions have no safe generic Anvil settlement driver, so force_settle(ticket) raises UnsupportedVaultSimulation; settlement must be driven by the real strategy operator.

Attributes summary

web3

Methods summary

__init__(vault)

analyse_deposit(claim_tx_hash, deposit_ticket)

Analyse a mined ERC-4626 deposit or guarded SimpleVault wrapper.

analyse_redemption(claim_tx_hash, ...)

Analyse a mined ERC-4626 redemption or guarded SimpleVault wrapper.

can_create_deposit_request(owner)

Return the advisory standard ERC-4626 deposit availability.

can_create_redemption_request(owner)

Check that no aggregate request exists and the owner has shares.

can_finish_deposit(deposit_ticket)

Synchronous deposits can be finished immediately.

can_finish_redeem(redemption_ticket)

Check current aggregate claimability.

check_deposit_whitelist(owner)

Reject a deposit when the vault's whitelist excludes the owner.

create_deposit_request(owner[, to, amount, ...])

Build one standard ERC-4626 deposit with an explicit receiver.

create_deposit_request_for_guard_validation(...)

Build ERC-4626 deposit calldata after a proven global closure.

create_redemption_request(owner[, to, ...])

Build a request that transfers shares into Accountable's queue.

estimate_deposit(owner, amount[, ...])

Estimate Accountable shares without calling previewDeposit.

estimate_redeem(owner, shares[, ...])

Estimate assets using Accountable's non-reverting conversion method.

estimate_redemption_delay()

Return no deterministic Accountable queue deadline.

fetch_completed_redemption_tx_hash(ticket)

Find an operator-owned terminal redemption transaction when available.

fetch_depositable_raw_assets(owner)

Read the vault's current raw deposit limit for an owner.

fetch_vault_flow_events(hypersync_client, ...)

Fetch historical Accountable RedeemRequest logs.

finish_deposit(deposit_ticket)

Can we finish the deposit process in async vault.

finish_redemption(redemption_ticket)

Build a self-controlled claim for current claimable shares.

force_redemption_liquidity(owner, ...)

Provision an unavailable synchronous redemption on an Anvil fork.

force_settle(ticket, *[, mock, ignore_liquidity])

Refuse Accountable asynchronous settlement before any fork broadcast.

get_deposit_approval_target()

Return the ERC-20 spender required for a deposit request.

get_deposit_delay_over(address)

Estimate when a pending async deposit request will settle.

get_deposit_request_status(ticket)

Query the current status of an async deposit request.

get_max_deposit(owner)

How much we can deposit

get_redemption_delay_over(address)

Return no deterministic claimability deadline.

get_redemption_request_status(ticket)

Map Accountable aggregate balances to the generic request status.

has_synchronous_deposit()

Return Accountable deposit completion mode.

has_synchronous_redemption()

Return Accountable redemption completion mode.

is_deposit_in_progress(owner)

Report Accountable deposit queue state.

is_redemption_in_progress(owner)

Check aggregate pending or claimable shares for a controller.

reclaim_deposit(ticket)

Return a function to recover funds after a failed async deposit settlement.

reclaim_withdrawal(ticket)

Return a function to recover shares after a failed async withdrawal settlement.

reconstruct_deposit_ticket(data)

Reconstruct a deposit ticket from a serialised dict.

reconstruct_redemption_ticket(data)

Rebuild an Accountable ticket from persisted data.

serialize_deposit_ticket(ticket)

Serialise a deposit ticket to a dict for persistence.

serialize_redemption_ticket(ticket)

Serialise Accountable request identity for restart-safe claims.

estimate_deposit(owner, amount, block_identifier='latest')

Estimate Accountable shares without calling previewDeposit.

The reported Hyperithm deployment rejects the generic ERC-4626 preview call even though its conversion function remains available. convertToShares is the value used by the contract’s synchronous deposit path and gives callers a non-reverting estimate.

Parameters
  • owner (Optional[eth_typing.evm.HexAddress]) – Deposit owner. Accountable’s conversion is owner-independent.

  • amount (decimal.Decimal) – Denomination-token amount to deposit.

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

Returns

Estimated decimal share amount.

Raises

ValueError – If the vault reports a zero share estimate.

Return type

decimal.Decimal

create_deposit_request(owner, to=None, amount=None, raw_amount=None, check_max_deposit=True, check_enough_token=True)

Build one standard ERC-4626 deposit with an explicit receiver.

Parameters
Returns

One-call synchronous deposit request.

Return type

eth_defi.erc_4626.deposit_redeem.ERC4626DepositRequest

create_redemption_request(owner, to=None, shares=None, raw_shares=None, check_max_deposit=True, check_enough_token=True)

Build a request that transfers shares into Accountable’s queue.

Accountable uses owner as controller and does not require a share-token allowance: requestRedeem itself escrows the shares. Its aggregate getters make two concurrent tickets ambiguous, so an existing pending or claimable request blocks a further request for this owner.

Parameters
Returns

One-call redemption request.

Return type

eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableRedemptionRequest

force_settle(ticket, *, mock=None, ignore_liquidity=False)

Refuse Accountable asynchronous settlement before any fork broadcast.

The selected deposit direction is synchronous and retains the base no-op result. Accountable redemption settlement is controlled by a strategy operator and does not expose a safe Anvil driver.

Parameters
Returns

Shared synchronous no-op outcome for None.

Raises

UnsupportedVaultSimulation – For an asynchronous redemption ticket with the stable capability reason.

Return type

eth_defi.vault.deposit_redeem.VaultForcedSettlementResult

has_synchronous_deposit()

Return Accountable deposit completion mode.

Returns

Always True.

Return type

bool

has_synchronous_redemption()

Return Accountable redemption completion mode.

Returns

Always False because claims wait for settlement.

Return type

bool

is_deposit_in_progress(owner)

Report Accountable deposit queue state.

Parameters

owner (eth_typing.evm.HexAddress) – Ignored because deposits are synchronous.

Returns

Always False.

Return type

bool

is_redemption_in_progress(owner)

Check aggregate pending or claimable shares for a controller.

Parameters

owner (eth_typing.evm.HexAddress) – Accountable controller address.

Returns

True when an aggregate request or claim remains.

Return type

bool

can_create_deposit_request(owner)

Return the advisory standard ERC-4626 deposit availability.

Parameters

owner (eth_typing.evm.HexAddress) – Prospective deposit receiver.

Returns

Whether the current maximum deposit is positive.

Return type

bool

can_create_redemption_request(owner)

Check that no aggregate request exists and the owner has shares.

Parameters

owner (eth_typing.evm.HexAddress) – Prospective controller and share owner.

Returns

True when a new request is not locally precluded.

Return type

bool

estimate_redemption_delay()

Return no deterministic Accountable queue deadline.

Returns

Zero duration because settlement timing is strategy controlled.

Return type

datetime.timedelta

get_redemption_delay_over(address)

Return no deterministic claimability deadline.

Parameters

address (Union[eth_typing.evm.HexAddress, str]) – Ignored controller address.

Returns

Always None.

Return type

Optional[datetime.datetime]

get_redemption_request_status(ticket)

Map Accountable aggregate balances to the generic request status.

Claimability must be checked before pending status, because immediate settlement may leave a request id of zero and a non-zero claimable aggregate in the same transaction.

Parameters

ticket (eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableRedemptionTicket) – Persisted Accountable ticket.

Returns

Claimable, pending, or absent aggregate state.

Return type

eth_defi.vault.deposit_redeem.AsyncVaultRequestStatus

can_finish_redeem(redemption_ticket)

Check current aggregate claimability.

Parameters

redemption_ticket (eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableRedemptionTicket) – Accountable request ticket.

Returns

Whether this safe self-controlled ticket has claimable shares.

Return type

bool

finish_redemption(redemption_ticket)

Build a self-controlled claim for current claimable shares.

Accountable exposes a controller aggregate rather than a per-request claim balance. The public manager therefore only claims self-controlled tickets back to their share owner. It never directs an aggregate claim to a custom receiver or auto-claims a delegated-controller ticket. A settlement can make only part of the ticket claimable; claim the current amount, then repeat after the remaining shares settle.

Parameters

redemption_ticket (eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableRedemptionTicket) – Accountable request ticket.

Returns

Current-claimable redeem function call.

Raises

ValueError – If this ticket is delegated, has a custom receiver, or has no claimable shares.

Return type

web3.contract.contract.ContractFunction

estimate_redeem(owner, shares, block_identifier='latest')

Estimate assets using Accountable’s non-reverting conversion method.

Accountable intentionally makes previewRedeem revert, while convertToAssets reflects its current share price.

Parameters
  • owner (eth_typing.evm.HexAddress) – Ignored owner retained for the common manager API.

  • shares (decimal.Decimal) – Decimal share amount.

  • 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 conversion.

Returns

Estimated denomination assets.

Return type

decimal.Decimal

serialize_redemption_ticket(ticket)

Serialise Accountable request identity for restart-safe claims.

Parameters

ticket (eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableRedemptionTicket) – Ticket to serialise.

Returns

JSON-compatible ticket data.

Return type

dict

reconstruct_redemption_ticket(data)

Rebuild an Accountable ticket from persisted data.

Parameters

data (dict) – JSON-compatible serialised ticket data.

Returns

Restored Accountable ticket.

Return type

eth_defi.erc_4626.vault_protocol.accountable.deposit_redeem.AccountableRedemptionTicket

fetch_vault_flow_events(hypersync_client, start_block, end_block)

Fetch historical Accountable RedeemRequest logs.

Parameters
  • hypersync_client (hypersync.HypersyncClient) – Configured Monad Hypersync client.

  • start_block (int) – Inclusive request-event range start.

  • end_block (int) – Inclusive request-event range end.

Returns

Event-derived pending redemption discovery hints.

Return type

collections.abc.Iterator[eth_defi.vault.flow_events.PendingVaultFlow]

__init__(vault)
Parameters

vault (ERC4626Vault) –

analyse_deposit(claim_tx_hash, deposit_ticket)

Analyse a mined ERC-4626 deposit or guarded SimpleVault wrapper.

A ticket permits a settlement call through a non-vault wrapper, such as a SimpleVault Safe or its module. The event analyser still filters events by the underlying vault address.

Parameters
Returns

Decoded executed deposit quantities or a revert description.

Return type

Union[eth_defi.vault.deposit_redeem.DepositRedeemEventAnalysis, eth_defi.vault.deposit_redeem.DepositRedeemEventFailure]

analyse_redemption(claim_tx_hash, redemption_ticket)

Analyse a mined ERC-4626 redemption or guarded SimpleVault wrapper.

A ticket permits a non-vault transaction target for a guarded settlement; the decoded Withdraw event must still originate from this vault.

Parameters
Returns

Decoded executed redemption quantities or a revert description.

Return type

Union[eth_defi.vault.deposit_redeem.DepositRedeemEventAnalysis, eth_defi.vault.deposit_redeem.DepositRedeemEventFailure]

can_finish_deposit(deposit_ticket)

Synchronous deposits can be finished immediately.

Parameters

deposit_ticket (eth_defi.erc_4626.deposit_redeem.ERC4626DepositTicket) –

check_deposit_whitelist(owner)

Reject a deposit when the vault’s whitelist excludes the owner.

Shared deposit-preflight helper implementing the whitelisting contract every manager must honour: when a vault applies a deposit whitelist policy that is applicable and queryable, and owner is not a member of it, raise WhitelistingRequired before any transaction is broadcast so the caller can surface a “whitelisting required” state instead of paying gas for a guaranteed revert.

The check is intentionally conservative — it only raises when the whitelist information can be obtained and is applicable:

  • if is_whitelisted_deposit() raises NotImplementedError, the vault-wide policy cannot be determined for this adapter/version, so no exception is raised;

  • if the vault is permissionless, no exception is raised;

  • if is_account_whitelisted() raises NotImplementedError, per-account membership cannot be queried, so no exception is raised;

  • only when the policy is applicable and the owner is provably not admitted is WhitelistingRequired raised.

Adapters that need a stricter fail-closed policy for an unknown admission state should override their own preflight and raise VaultFlowUnavailable in addition to calling this helper (see the Lagoon manager for an example).

Parameters

owner (eth_typing.evm.HexAddress) – Deposit owner and controller whose whitelist membership is checked.

Raises

WhitelistingRequired – When the vault applies an applicable, queryable whitelist policy and owner is not permitted to deposit.

Return type

None

create_deposit_request_for_guard_validation(owner, raw_amount)

Build ERC-4626 deposit calldata after a proven global closure.

This Anvil-only diagnostic path is available only when the selected vault’s authoritative global closure reader reports that deposits are unavailable to every account. It preserves the normal protocol admission preflight and all permanent amount constraints, while omitting the temporary closed-deposit capacity and token-balance checks needed to encode the production-equivalent deposit call.

Parameters
  • owner (eth_typing.evm.HexAddress) – Safe/SimpleVault address that would own the minted shares.

  • raw_amount (int) – Raw denomination-token amount from the rejected real-deposit attempt.

Returns

Single ERC-4626 deposit request for isolated GuardV0 validation.

Raises
Return type

eth_defi.erc_4626.deposit_redeem.ERC4626DepositRequest

fetch_completed_redemption_tx_hash(ticket)

Find an operator-owned terminal redemption transaction when available.

Claim-based protocols finish through finish_redemption() and do not need this lookup. Operator-finalised protocols override the hook to find and validate the transaction that paid the requested receiver.

Parameters

ticket (eth_defi.vault.deposit_redeem.RedemptionTicket) – Persisted redemption request to locate.

Returns

Terminal transaction hash, or None if the protocol has not observed one yet.

Return type

Optional[hexbytes.main.HexBytes]

fetch_depositable_raw_assets(owner)

Read the vault’s current raw deposit limit for an owner.

Overridable deposit-limit hook. The base implementation reads the standard ERC-4626 maxDeposit(). Multi-asset or non-standard vaults that do not implement maxDeposit (for example Upshift’s multi-asset vault) override this to answer from their own limit reader, so the deposit preflight does not depend on the ERC-4626 method being present.

Parameters

owner (eth_typing.evm.HexAddress) – Account the deposit limit is queried for.

Returns

Raw deposit limit, or None when the vault exposes no limit. A zero maxDeposit is omitted from this owner-specific capacity hook (EIP-4626 is not universally honoured), consistent with eth_defi.erc_4626.flow.deposit_4626(). The normal deposit preflight separately recognises a meaningful global zero through ERC4626Vault.fetch_deposit_closed_reason().

Raises

VaultFlowUnavailable – When the vault does not expose a readable ERC-4626 maxDeposit and no protocol-specific override is provided, instead of leaking a raw web3 ABI/read error.

Return type

Optional[int]

finish_deposit(deposit_ticket)

Can we finish the deposit process in async vault.

  • We can claim our shares from the vault now

Parameters

deposit_ticket (eth_defi.vault.deposit_redeem.DepositTicket) –

Return type

web3.contract.contract.ContractFunction

force_redemption_liquidity(owner, raw_shares, failure)

Provision an unavailable synchronous redemption on an Anvil fork.

Concrete managers may implement this only for a source-proven liquidity failure. The default is deliberately unsupported: this hook must never bypass admission, minimums, maturity or time locks.

Parameters
Returns

Structured intervention evidence from a concrete manager.

Raises

UnsupportedVaultSimulation – Always for managers without a protocol-specific implementation.

Return type

eth_defi.vault.deposit_redeem.VaultRedemptionSimulationIntervention

get_deposit_approval_target()

Return the ERC-20 spender required for a deposit request.

Standard ERC-4626 and the currently supported async adapters pull denomination tokens from the vault address itself. An adapter using a different router or silo must override this method; guarded callers use it to whitelist and validate the exact approval calldata.

Returns

ERC-20 approval spender address.

Return type

eth_typing.evm.HexAddress

get_deposit_delay_over(address)

Estimate when a pending async deposit request will settle.

  • Mirror of get_redemption_delay_over() for the deposit side.

  • Used to show an estimated settlement time for unsettled deposits (e.g. in the trade-executor trade-ui table).

  • Default returns None: the protocol has no deterministic onchain settlement schedule (e.g. operator-driven ERC-7540 vaults like Lagoon). Subclasses with a predictable settlement cadence (e.g. Ostium V1.5) override this to return an estimated UTC timestamp.

Parameters

address (Union[eth_typing.evm.HexAddress, str]) – Owner of the pending deposit request.

Returns

Naive UTC timestamp when the deposit is expected to settle, or None when no onchain estimate is available.

Return type

Optional[datetime.datetime]

get_deposit_request_status(ticket)

Query the current status of an async deposit request.

Default implementation probes via can_finish_deposit(). Subclasses should override for more accurate status reporting (e.g. distinguishing reclaimable from pending).

Parameters

ticket (eth_defi.vault.deposit_redeem.DepositTicket) –

Return type

eth_defi.vault.deposit_redeem.AsyncVaultRequestStatus

get_max_deposit(owner)

How much we can deposit

Parameters

owner (eth_typing.evm.HexAddress) –

Return type

Optional[decimal.Decimal]

reclaim_deposit(ticket)

Return a function to recover funds after a failed async deposit settlement.

Returns None if the protocol does not support reclaim.

Parameters

ticket (eth_defi.vault.deposit_redeem.DepositTicket) –

Return type

Optional[web3.contract.contract.ContractFunction]

reclaim_withdrawal(ticket)

Return a function to recover shares after a failed async withdrawal settlement.

Returns None if the protocol does not support reclaim.

Parameters

ticket (eth_defi.vault.deposit_redeem.RedemptionTicket) –

Return type

Optional[web3.contract.contract.ContractFunction]

reconstruct_deposit_ticket(data)

Reconstruct a deposit ticket from a serialised dict.

Default returns a base DepositTicket. Subclasses override for protocol-specific ticket types.

Parameters

data (dict) –

Return type

eth_defi.vault.deposit_redeem.DepositTicket

serialize_deposit_ticket(ticket)

Serialise a deposit ticket to a dict for persistence.

The trade-executor stores this in trade.other_data so that the settlement retry module can reconstruct the ticket after a process restart.

Default implementation stores base DepositTicket fields. Subclasses override to add protocol-specific fields (e.g. settlement_id for Ostium, requestId for ERC-7540).

Parameters

ticket (eth_defi.vault.deposit_redeem.DepositTicket) –

Return type

dict