erc_4626.vault_protocol.upshift.deposit_redeem

Documentation for eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem Python module.

Upshift multi-asset deposit flow.

Classes

UpshiftMultiAssetDepositManager

Build and decode Upshift's direct multi-asset deposit flow.

UpshiftQueuedRedemptionRequest

Parse an Upshift requestRedeem into a dated redemption ticket.

UpshiftQueuedRedemptionTicket

Persist an Upshift request/claim withdrawal date and epoch identity.

class UpshiftQueuedRedemptionTicket

Bases: eth_defi.vault.deposit_redeem.RedemptionTicket

Persist an Upshift request/claim withdrawal date and epoch identity.

claimable_epoch: int

Epoch emitted by the verified requestRedeem return value.

year: int

Calendar date selecting the batched operator settlement and owner claim.

get_request_id()

Return the protocol claimable epoch as the request identity.

Returns

Upshift claimable epoch.

Return type

int

__init__(vault_address, owner, to, raw_shares, tx_hash, claimable_epoch, year, month, day)
Parameters
Return type

None

class UpshiftQueuedRedemptionRequest

Bases: eth_defi.vault.deposit_redeem.RedemptionRequest

Parse an Upshift requestRedeem into a dated redemption ticket.

parse_redeem_transaction(tx_hashes)

Validate the native request event and read its scheduled date.

The verified request event does not include the date returned by requestRedeem. The immediately-read getWithdrawalEpoch state is therefore persisted after the successful transaction, alongside the event’s holder, receiver and share count checks.

Parameters

tx_hashes (list[hexbytes.main.HexBytes]) – Broadcast request hashes; the final hash is requestRedeem.

Returns

Persistable queued-redemption ticket.

Raises

CannotParseRedemptionTransaction – If the receipt has no matching Upshift request event.

Return type

eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem.UpshiftQueuedRedemptionTicket

__init__(vault, owner, to, shares, raw_shares, funcs)
Parameters
Return type

None

broadcast(from_=None, gas=1000000)

Broadcast all the transactions in this request.

Parameters
Returns

List of transaction hashes

Return type

list[hexbytes.main.HexBytes]

class UpshiftMultiAssetDepositManager

Bases: eth_defi.erc_4626.deposit_redeem.ERC4626DepositManager

Build and decode Upshift’s direct multi-asset deposit flow.

Upshift multiAssetVault proxies are accounting contracts, not plain ERC-4626 share tokens: they accept a whitelist of deposit tokens through a protocol-specific deposit(asset, amount, receiver) entry point and expose share metadata on a separate LP token. This manager builds and decodes that synchronous deposit flow; it deliberately exposes no redemption, because the protocol’s request/claim redemption lifecycle is not yet fork-proven.

Deposit process

Synchronous and asset-aware. The caller must select a token from the vault’s onchain whitelist (fetch_accepted_assets(), resolved by _fetch_accepted_asset()); an unselected or non-whitelisted asset raises VaultFlowUnavailable. create_deposit_request() returns two calls — approve on the selected token followed by the vault’s deposit(asset, amount, receiver) — and rejects a zero-address receiver. Capacity is preflighted through fetch_max_deposit_for_asset(), which combines the per-deposit maxDepositAmount() cap and the vault-wide depositCap() minus getTotalAssets(), converted into the selected token’s units with the protocol’s asset-aware previewDeposit. Deposits are also gated vault-wide by UpshiftVault.fetch_deposit_closed_reason() (depositsPaused(), zero maxDepositAmount() or a reached depositCap()). There is no per-account minimum or whitelist; the amount must be strictly positive.

Redemption process

Two verified paths are exposed. The default is asynchronous: create_redemption_request() calls requestRedeem(shares, receiver) and persists its date/epoch in UpshiftQueuedRedemptionTicket. The vault operator later calls processAllClaimsByDate and the manager finishes with claim(year, month, day, receiver). Passing instant=True instead builds the atomic instantRedeem(shares, receiver) path. Both paths validate the live withdrawal pause/cap and the share balance before broadcast.

Queues and settlement

Queued redemptions are operator settled by date. processAllClaimsByDate is intentionally not a manager/GuardV0 call: it is an external operator action. force_settle() can invoke it only on a supplied local mock deployed at this manager’s vault address, never against a production fork.

Lockups and cooldowns

Not applicable to deposits (synchronous). At the vault level, UpshiftVault.get_estimated_lock_up() reports a nominal one-day redemption claim cycle, but this manager implements no redemption path to which that would apply.

Whitelisting / access control

Deposits are permissionless per account, but the deposit token must be on the vault’s onchain asset whitelist. Availability is otherwise controlled vault-wide by the pause flags and caps above, not by a per-account whitelist.

Anvil settlement (force_settle)

Deposits and instant redemptions are synchronous and use the shared force_settle(None) no-op. A queued ticket requires an explicit matching mock implementing processAllClaimsByDate; production operator authority is not impersonated.

fetch_accepted_assets()

Return every token currently accepted by the vault.

Returns

Accepted tokens in the protocol whitelist order.

Return type

tuple[eth_defi.token.TokenDetails, …]

fetch_max_deposit_for_asset(accepted_asset, block_identifier='latest')

Return current deposit capacity in selected-token raw units.

Upshift constrains both one deposit through maxDepositAmount and total vault assets through depositCap. The lower current reference capacity is converted with the protocol’s asset-aware preview.

Parameters
  • accepted_asset (eth_typing.evm.HexAddress) – Whitelisted token selected for the deposit.

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

Returns

Current maximum selected-token amount in native raw units.

Raises

ValueError – If the protocol reports a zero reference value for one token.

Return type

int

fetch_depositable_raw_assets(owner)

Answer the generic deposit-limit hook without ERC-4626 maxDeposit.

The multi-asset Upshift vault does not implement the standard ERC-4626 maxDeposit (its limit surface is maxDepositAmount / depositCap / asset-aware previewDeposit). Overriding the generic hook means a generic-path deposit preflight receives a real limit — for the vault’s first whitelisted asset, in that asset’s raw units — instead of the raw ABIFunctionNotFound the base implementation would raise. The protocol-specific create_deposit_request() still uses the per-selected-asset fetch_max_deposit_for_asset() for an actual deposit.

Parameters

owner (eth_typing.evm.HexAddress) – Unused; the multi-asset limit is not owner-specific.

Returns

Deposit limit for the vault’s first accepted asset in raw units, or None when the vault currently accepts no asset.

Return type

Optional[int]

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

Refuse an ambiguous estimate without an accepted-asset selection.

Parameters
  • owner (Optional[eth_typing.evm.HexAddress]) – Deposit owner used for structured error context.

  • amount (decimal.Decimal) – Ambiguous amount whose token is not specified.

  • 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 request is rejected before an onchain read.

Raises

VaultFlowUnavailable – Always, directing the caller to estimate_deposit_for_asset().

Return type

decimal.Decimal

estimate_deposit_for_asset(owner, amount, accepted_asset, block_identifier='latest')

Estimate LP shares for a selected accepted asset.

The estimate comes from Upshift’s asset-aware previewDeposit call, avoiding local assumptions about reference-asset conversion.

Parameters
  • owner (Optional[eth_typing.evm.HexAddress]) – Deposit owner used for structured error context.

  • amount (decimal.Decimal) – Selected accepted-asset amount.

  • accepted_asset (eth_typing.evm.HexAddress) – Whitelisted deposit-token address.

  • 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 share price.

Returns

Estimated LP shares rounded down to share-token precision.

Return type

decimal.Decimal

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

Estimate queued redemption assets through the verified vault preview.

Parameters
  • owner (Optional[eth_typing.evm.HexAddress]) – Share owner used for structured error context.

  • shares (decimal.Decimal) – Requested LP shares.

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

Returns

Estimated denomination assets after the queued redemption fee.

Return type

decimal.Decimal

can_create_deposit_request(owner)

Return whether the protocol-wide deposit gate is currently open.

Parameters

owner (eth_typing.evm.HexAddress) – Unused because Upshift’s pause and cap are vault-wide.

Returns

True when deposits are neither paused nor configured with a zero cap.

Return type

bool

can_create_redemption_request(owner)

Return whether the live vault gate and owner share balance permit redemption.

Parameters

owner (eth_typing.evm.HexAddress) – Share owner.

Returns

True when withdrawals are open and the owner has LP shares.

Return type

bool

has_synchronous_redemption()

Return false because the default redemption path is queued.

Returns

False; callers select the exceptional instant path explicitly.

Return type

bool

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

Create approval and deposit calls for one selected asset.

The returned synchronous request approves the vault and then calls its multi-asset deposit entry point.

Parameters
Returns

Synchronous approval and deposit request.

Raises

VaultFlowUnavailable – If the asset is invalid or current protocol state rejects the flow.

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, *, instant=False)

Build a verified Upshift instant or request/claim redemption.

Parameters
  • owner (eth_typing.evm.HexAddress) – Share owner used for structured error context.

  • to (Optional[eth_typing.evm.HexAddress]) – Asset receiver, defaulting to the share owner.

  • shares (Optional[decimal.Decimal]) – Decimal LP shares, exclusive with raw_shares.

  • raw_shares (Optional[int]) – Native LP shares, exclusive with shares.

  • check_max_deposit (bool) – Retained base-interface compatibility flag.

  • check_enough_token (bool) – Check the owner’s LP share balance.

  • instant (bool) – Build instantRedeem when True; otherwise build the queued requestRedeem lifecycle.

Returns

Synchronous standard request for instant redemption, or a queued request that parses a dated redemption ticket.

Return type

eth_defi.vault.deposit_redeem.RedemptionRequest

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

Settle a queued Upshift ticket through a matching local mock only.

Parameters
Returns

No-op result or pending-to-claimable mock settlement result.

Raises

UnsupportedVaultSimulation – If a production settlement or invalid mock is requested.

Return type

eth_defi.vault.deposit_redeem.VaultForcedSettlementResult

get_redemption_request_status(ticket)

Map the receiver’s dated burnable amount to a generic request status.

Parameters

ticket (eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem.UpshiftQueuedRedemptionTicket) – Upshift queued redemption ticket.

Returns

claimable after operator processing, otherwise pending.

Return type

eth_defi.vault.deposit_redeem.AsyncVaultRequestStatus

can_finish_redeem(redemption_ticket)

Return whether a queued ticket has an onchain claimable amount.

Parameters

redemption_ticket (eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem.UpshiftQueuedRedemptionTicket) – Upshift queued redemption ticket.

Returns

Whether the operator has processed the request.

Return type

bool

serialize_redemption_ticket(ticket)

Serialise the scheduled Upshift receiver/date aggregate identity.

Parameters

ticket (eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem.UpshiftQueuedRedemptionTicket) – Queued Upshift redemption ticket.

Returns

JSON-compatible base and calendar/epoch fields.

Return type

dict

reconstruct_redemption_ticket(data)

Restore a persisted Upshift receiver/date aggregate ticket.

Parameters

data (dict) – Data produced by serialize_redemption_ticket().

Returns

Queued Upshift redemption ticket.

Return type

eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem.UpshiftQueuedRedemptionTicket

finish_redemption(redemption_ticket)

Build the verified dated Upshift claim call.

Parameters

redemption_ticket (eth_defi.erc_4626.vault_protocol.upshift.deposit_redeem.UpshiftQueuedRedemptionTicket) – Claimable Upshift ticket.

Returns

claim(year, month, day, receiver) call.

analyse_deposit(claim_tx_hash, deposit_ticket)

Decode Upshift’s verified protocol deposit event.

Parameters
Returns

Executed deposit amounts or a structured transaction failure.

Raises

ValueError – If the receipt does not contain exactly one matching deposit event.

Return type

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

__init__(vault)
Parameters

vault (ERC4626Vault) –

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

estimate_redemption_delay()

Get the redemption delay for this vault.

  • What is overall redemption delay: not related to the current moment

  • How long it takes before a redemption request is allowed

  • This is not specific for any address, but the general vault rule

  • E.g. you get 0xa592703b is an IPOR Fusion error code AccountIsLocked, if you try to instantly redeem from IPOR vaults

Returns

Redemption delay as a datetime.timedelta

Raises

NotImplementedError – If not implemented for this vault protocoll.

Return type

datetime.timedelta

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_vault_flow_events(hypersync_client, start_block, end_block)

Fetch asynchronous vault request events from an indexed backend.

The base implementation returns no events for vault managers that do not have a two-phase deposit or redemption flow.

Parameters
  • hypersync_client – Configured Hypersync client for this vault’s chain.

  • start_block (int) – Inclusive start block.

  • end_block (int) – Inclusive end block.

Returns

Iterator of protocol-neutral pending vault flow events.

Return type

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

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]

get_redemption_delay_over(address)

Get the redemption timer left for an address.

  • How long it takes before a redemption request is allowed

  • This is not specific for any address, but the general vault rule

  • E.g. you get 0xa592703b is an IPOR Fusion error code AccountIsLocked, if you try to instantly redeem from IPOR vaults

Returns

UTC timestamp when the account can redeem.

Naive datetime, or None when the protocol has no deterministic onchain deadline.

Raises

NotImplementedError – If not implemented for this vault protocoll.

Parameters

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

Return type

datetime.datetime

has_synchronous_deposit()

Does this vault support synchronous deposits?

  • E.g. ERC-4626 vaults

Return type

bool

is_deposit_in_progress(owner)

Check if the owner has an active deposit request.

Parameters

owner (eth_typing.evm.HexAddress) – Owner of the shares

Returns

True if there is an active redemption request

Return type

bool

is_redemption_in_progress(owner)

Check if the owner has an active redemption request.

Parameters

owner (eth_typing.evm.HexAddress) – Owner of the shares

Returns

True if there is an active redemption request

Return type

bool

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