erc_7540.deposit_redeem

Documentation for eth_defi.erc_7540.deposit_redeem Python module.

Protocol-neutral ERC-7540 deposit and redemption flows.

Module Attributes

ERC7540_ANVIL_SETTLEMENT_UNSUPPORTED_REASON

Generic ERC-7540 cannot know a protocol's operator settlement action.

Classes

ERC7540DepositManager

Protocol-neutral asynchronous ERC-7540 deposit and redemption flow.

ERC7540DepositRequest

Asynchronous deposit request for ERC-7540 vaults.

ERC7540DepositTicket

Asynchronous deposit request for ERC-7540 vaults.

ERC7540RedemptionRequest

Asynchronous redemption request for ERC-7540 vaults.

ERC7540RedemptionTicket

Asynchronous redemption request for ERC-7540 vaults.

class ERC7540DepositManager

Bases: eth_defi.vault.deposit_redeem.VaultDepositManager

Protocol-neutral asynchronous ERC-7540 deposit and redemption flow.

Generic manager for ERC-7540 request-based vaults, where deposits and redemptions are two-phase: a request transaction registers the intent, an operator settles it off-interface, and a later claim transaction moves the tokens. Protocol adapters such as Lagoon subclass this manager to add their settlement driver and access policies; the generic manager only builds the standard request and claim calls.

Deposit process

Asynchronous. The owner first approve()``s the ERC-20 denomination token to the vault (the default :meth:`get_deposit_approval_target`). :meth:`create_deposit_request` builds the standard ``requestDeposit(assets, owner, owner) call (the request is controller-scoped, so owner is both controller and receiver — a separate to is unsupported). Broadcasting it emits a DepositRequest event whose requestId is parsed into an ERC7540DepositTicket. Once the operator settles, can_finish_deposit() (reading claimableDepositRequest) turns True and finish_deposit() builds the three-argument deposit(assets, to, owner) claim that mints the shares.

Redemption process

Asynchronous. create_redemption_request() builds the standard requestRedeem call (via vault.request_redeem), controller-scoped to owner; a separate to is unsupported. Broadcasting emits a RedeemRequest event whose requestId is parsed into an ERC7540RedemptionTicket. After operator settlement can_finish_redeem() (reading claimableRedeemRequest) turns True and finish_redemption() builds the three-argument redeem(shares, to, owner) claim. A request is identified by its ERC-7540 requestId carried on the ticket.

Queues and settlement

Requests are queued onchain and settled by the vault operator; the timing and mechanism are outside the ERC-7540 standard. Status is derived from the request-specific claimable views: get_deposit_request_status() and get_redemption_request_status() check the ticket’s claimable amount first (an aggregate pendingDepositRequest(0, owner)/pendingRedeemRequest(0, owner) query lumps all of an owner’s requests together), then fall back to the aggregate pending query, returning claimable/pending/none. The generic layer has no reclaim signal, so reclaimable is never returned. fetch_vault_flow_events() streams DepositRequest and RedeemRequest events from Hypersync.

Lockups and cooldowns

No deterministic protocol-level delay: settlement cadence is operator-driven. estimate_redemption_delay() returns zero and get_redemption_delay_over() returns the Unix epoch sentinel. can_create_deposit_request() and can_create_redemption_request() reflect only the vault’s optional paused() flag.

Whitelisting / access control

Deposit admission is checked in _assert_deposit_request_available(), called at the start of create_deposit_request(): it first rejects a paused vault with VaultFlowUnavailable, then runs the shared check_deposit_whitelist() preflight (raising WhitelistingRequired for an unpermitted owner). The pause flag is read defensively — a missing paused() view is treated as unpaused. Protocol-specific admission policies belong in subclasses.

Anvil settlement (force_settle)

Settlement is operator-specific, so the generic manager deliberately has no Anvil settlement driver: the inherited force_settle() raises UnsupportedVaultSimulation for an async ticket. Protocol subclasses (such as Lagoon) override it to drive settlement on a fork.

Initialise the manager for an ERC-7540 vault adapter.

Protocol-specific subclasses may reuse this constructor after validating a narrower vault type.

Parameters

vault – Protocol adapter implementing the ERC-7540 vault interface.

deposit_request_class

Request wrapper used for deposits. Protocol subclasses may replace it.

alias of eth_defi.erc_7540.deposit_redeem.ERC7540DepositRequest

redemption_request_class

Request wrapper used for redemptions. Protocol subclasses may replace it.

alias of eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionRequest

__init__(vault)

Initialise the manager for an ERC-7540 vault adapter.

Protocol-specific subclasses may reuse this constructor after validating a narrower vault type.

Parameters

vault (eth_defi.erc_7540.vault.ERC7540Vault) – Protocol adapter implementing the ERC-7540 vault interface.

fetch_vault_flow_events(hypersync_client, start_block, end_block)

Fetch standard ERC-7540 request events using Hypersync.

ERC-7540 vaults emit DepositRequest for deposit requests and RedeemRequest for redemption requests. Protocol-specific legacy events must be handled by a protocol manager subclass.

Parameters
  • hypersync_client – Configured Hypersync client for the vault chain.

  • start_block (int) – Inclusive start block.

  • end_block (int) – Inclusive end block.

Returns

Iterator of indexed pending vault flow events in chain order.

Return type

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

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

Build the standard ERC-7540 requestDeposit transaction.

Parameters
  • owner (eth_typing.evm.HexAddress) – Controller and owner of the request.

  • to (eth_typing.evm.HexAddress) – Unsupported separate receiver; ERC-7540 requests use owner.

  • amount (decimal.Decimal) – Human-readable denomination-token amount.

  • raw_amount (int) – Raw denomination-token amount, overriding amount.

  • check_max_deposit – Reserved for parity with the common manager API.

  • check_enough_token – Reserved for parity with the common manager API.

Returns

Request wrapper ready for signing and parsing.

Raises

VaultFlowUnavailable – If the vault’s optional pause view reports that requests are paused.

Return type

eth_defi.erc_7540.deposit_redeem.ERC7540DepositRequest

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

Build the standard ERC-7540 requestRedeem transaction.

Parameters
  • owner (eth_typing.evm.HexAddress) – Controller and owner of the request.

  • to (eth_typing.evm.HexAddress) – Unsupported separate receiver; ERC-7540 requests use owner.

  • shares (decimal.Decimal) – Human-readable vault-share amount.

  • raw_shares (int) – Raw vault-share amount, overriding shares.

  • check_max_deposit – Reserved for parity with the common manager API.

  • check_enough_token – Whether to verify that the owner still holds the requested shares.

Returns

Request wrapper ready for signing and parsing.

Return type

eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionRequest

finish_deposit(deposit_ticket)

Build the ERC-7540 transaction that claims deposit shares.

The request must already be settled. The ticket supplies the controller, receiver and settled asset amount.

Parameters

deposit_ticket (eth_defi.vault.deposit_redeem.DepositTicket) – Settled asynchronous deposit ticket.

Returns

Bound three-argument deposit claim function.

Return type

web3.contract.contract.ContractFunction

can_finish_deposit(deposit_ticket)

Check whether a deposit request is ready to claim.

The ERC-7540 claimableDepositRequest view returns a positive asset amount after the operator has settled the request.

Parameters

deposit_ticket (eth_defi.erc_7540.deposit_redeem.ERC7540DepositTicket) – Deposit request to inspect.

Returns

True when the request has claimable assets.

Return type

bool

can_finish_redeem(redemption_ticket)

Check whether a redemption request is ready to claim.

The ERC-7540 claimableRedeemRequest view returns a positive share amount after the operator has settled the request.

Parameters

redemption_ticket (eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionTicket) – Redemption request to inspect.

Returns

True when the request has claimable shares.

Return type

bool

serialize_deposit_ticket(ticket)

Serialise an ERC-7540 deposit ticket.

The generic base ticket payload is extended with the ERC-7540 request identifier needed for later status checks.

Parameters

ticket (eth_defi.erc_7540.deposit_redeem.ERC7540DepositTicket) – Deposit ticket to serialise.

Returns

Persistent ticket data including vault_request_id.

Return type

dict

reconstruct_deposit_ticket(data)

Reconstruct a deposit ticket from persistent data.

Both the current string form and the legacy integer form of raw token amounts are accepted for backwards compatibility.

Parameters

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

Returns

Reconstructed ERC-7540 deposit ticket.

Return type

eth_defi.erc_7540.deposit_redeem.ERC7540DepositTicket

serialize_redemption_ticket(ticket)

Serialise an ERC-7540 redemption ticket.

The ERC-7540 request identifier is retained so a restarted process can query the request-specific claimable amount.

Parameters

ticket (eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionTicket) – Redemption ticket to serialise.

Returns

Persistent ticket data including vault_request_id.

Return type

dict

reconstruct_redemption_ticket(data)

Reconstruct a redemption ticket from persistent data.

Both the current string form and the legacy integer form of raw share amounts are accepted for backwards compatibility.

Parameters

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

Returns

Reconstructed ERC-7540 redemption ticket.

Return type

eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionTicket

get_deposit_request_status(ticket)

Map ERC-7540 deposit state to the generic status enum.

Check the request-specific claimable amount first: an aggregate pendingDepositRequest(0, owner) query lumps together all of the owner’s requests, so probing it first would report an already-settled request as still pending whenever another request is outstanding. The generic interface has no reclaim signal, so reclaimable is never returned.

Parameters

ticket (eth_defi.erc_7540.deposit_redeem.ERC7540DepositTicket) – Deposit request to inspect.

Returns

Claimable, pending or empty request status.

Return type

eth_defi.vault.deposit_redeem.AsyncVaultRequestStatus

get_redemption_request_status(ticket)

Map ERC-7540 redemption state to the generic status enum.

Request-specific claimable is checked before the aggregate pending query for the same reason as get_deposit_request_status().

Parameters

ticket (eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionTicket) – Redemption request to inspect.

Returns

Claimable, pending or empty request status.

Return type

eth_defi.vault.deposit_redeem.AsyncVaultRequestStatus

can_create_deposit_request(owner)

Return whether the vault is currently open for a deposit request.

The generic ERC-7540 layer checks only the optional pause flag. Protocol-specific admission policies belong in manager subclasses.

Parameters

owner (eth_typing.evm.HexAddress) – Request owner and controller used by requestDeposit.

Returns

False when the vault reports that requests are paused.

Return type

bool

can_create_redemption_request(owner)

Return whether the vault is currently open for a redemption request.

The generic ERC-7540 layer checks only the optional pause flag; protocol-specific redemption rules belong in manager subclasses.

Parameters

owner (eth_typing.evm.HexAddress) – Request owner and controller.

Returns

False when the vault reports that requests are paused.

Return type

bool

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

Refuse generic ERC-7540 operator settlement before a fork broadcast.

ERC-7540 standardises request and claim interfaces but not the operator action which makes a particular ticket claimable. Protocol-specific managers must implement and prove that action before advertising an Anvil settlement capability.

Parameters
Returns

This method never returns because both generic ERC-7540 directions are asynchronous.

Raises

UnsupportedVaultSimulation – Always, with the generic capability’s stable reason.

Return type

eth_defi.vault.deposit_redeem.VaultForcedSettlementResult

has_synchronous_deposit()

Report that deposits use the asynchronous request lifecycle.

Returns

Always False for ERC-7540.

Return type

bool

has_synchronous_redemption()

Report that redemptions use the asynchronous request lifecycle.

Returns

Always False for ERC-7540.

Return type

bool

estimate_redemption_delay()

Return no deterministic protocol-level redemption delay.

Settlement timing is controlled by each vault operator and is outside the ERC-7540 standard.

Returns

Zero-duration sentinel for an unspecified delay.

Return type

datetime.timedelta

get_redemption_delay_over(address)

Return the legacy sentinel for an unknown account deadline.

Generic ERC-7540 vaults do not expose a deterministic per-account settlement deadline.

Parameters

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

Returns

Naive Unix epoch sentinel retained for backwards compatibility.

Return type

datetime.datetime

is_redemption_in_progress(owner)

Check whether a controller has pending redemption shares.

Request identifier zero aggregates the controller’s pending redemption shares under ERC-7540.

Parameters

owner (eth_typing.evm.HexAddress) – Controller address to inspect.

Returns

True if the controller has pending redemption shares.

Return type

bool

is_deposit_in_progress(owner)

Check pending ERC-7540 request.

Query pendingDepositRequest(0, owner) when the request identifier is not known. Per ERC-7540, request identifier zero aggregates the controller’s pending deposit assets. A value greater than zero means at least one request remains unsettled.

Parameters

owner (eth_typing.evm.HexAddress) – Controller address to inspect.

Returns

True if the controller has pending deposit assets.

Return type

bool

finish_redemption(redemption_ticket)

Build the ERC-7540 transaction that claims redeemed assets.

The request must already be settled. The ticket supplies the controller, receiver and settled share amount.

Parameters

redemption_ticket (eth_defi.vault.deposit_redeem.RedemptionTicket) – Settled asynchronous redemption ticket.

Returns

Bound three-argument redeem claim function.

Return type

web3.contract.contract.ContractFunction

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

Estimate shares for a denomination-token amount.

ERC-7540 retains the ERC-4626 convertToShares preview used here; the estimate does not imply that the request is currently admissible.

Parameters
  • owner (eth_typing.evm.HexAddress) – Request controller. The standard preview is not owner-specific.

  • amount (decimal.Decimal) – Human-readable denomination-token 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 the conversion rate.

Returns

Estimated human-readable share amount.

Return type

decimal.Decimal

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

Estimate denomination tokens for a vault-share amount.

ERC-7540 retains the ERC-4626 convertToAssets preview used here; the estimate does not imply that the request is currently admissible.

Parameters
  • owner (eth_typing.evm.HexAddress) – Request controller. The standard preview is not owner-specific.

  • shares (decimal.Decimal) – Human-readable vault-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 the conversion rate.

Returns

Estimated human-readable denomination-token amount.

Return type

decimal.Decimal

analyse_deposit(claim_tx_hash, deposit_ticket)

Analyse a completed ERC-7540 deposit claim.

The method decodes the ERC-4626 Deposit event emitted by the second-stage claim transaction. Protocol subclasses may extend the accepted event signatures for legacy deployments.

Parameters
Returns

Decoded token movement, or a failed-transaction diagnostic.

Raises

RuntimeError – If a successful receipt does not contain an accepted event.

Return type

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

get_deposit_event_signatures()

Return accepted claim-deposit event signatures.

ERC-7540 claims retain the ERC-4626 Deposit event shape.

Returns

Standard ERC-4626 Deposit topic emitted by ERC-7540 claims.

Return type

set[eth_typing.encoding.HexStr]

analyse_redemption(claim_tx_hash, redemption_ticket)

Analyse a completed ERC-7540 redemption claim.

The method decodes the ERC-4626 Withdraw event emitted by the second-stage claim transaction. Protocol subclasses may extend the accepted event signatures for legacy deployments.

Parameters
Returns

Decoded token movement, or a failed-transaction diagnostic.

Raises

RuntimeError – If a successful receipt does not contain an accepted event.

Return type

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

get_redemption_event_signatures()

Return accepted claim-redemption event signatures.

ERC-7540 claims retain the ERC-4626 Withdraw event shape.

Returns

Standard ERC-4626 Withdraw topic emitted by ERC-7540 claims.

Return type

set[eth_typing.encoding.HexStr]

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 deposit calldata for a closed-vault GuardV0 policy check.

This Anvil-only diagnostic path is for a consumer that has already received a typed deposit_closed or deposit_paused preflight result. Adapters must override it only after proving that their typed result represents a temporary vault closure rather than a capacity or amount restriction. The returned calls must be supplied individually to GuardV0.validateCall(); callers must never broadcast them to the closed protocol vault.

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

  • raw_amount (int) – Denomination-token amount in the selected asset’s raw unit.

Returns

Manager-generated deposit request suitable only for isolated GuardV0 validation.

Raises

UnsupportedVaultSimulation – Unless the protocol-specific manager implements this diagnostic path.

Return type

eth_defi.vault.deposit_redeem.DepositRequest

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]

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_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]

class ERC7540DepositRequest

Bases: eth_defi.vault.deposit_redeem.DepositRequest

Asynchronous deposit request for ERC-7540 vaults.

parse_deposit_transaction(tx_hashes)

Parse one standard ERC-7540 deposit-request transaction.

The final receipt must contain exactly one standard DepositRequest event from which the request identifier is read.

Parameters

tx_hashes (list[hexbytes.main.HexBytes]) – Transaction hashes belonging to the request.

Returns

Parsed request ticket with its ERC-7540 request identifier.

Raises

CannotParseRedemptionTransaction – If the receipt does not contain exactly one DepositRequest event.

Return type

eth_defi.erc_7540.deposit_redeem.ERC7540DepositTicket

__init__(vault, owner, to, amount, raw_amount, funcs, gas=None, value=None)
Parameters
Return type

None

broadcast(from_=None, gas=None, check_value=True)

Broadcast all the transactions in this request.

Parameters
Returns

List of transaction hashes

Raises

TransactionAssertionError – If any of the transactions revert

Return type

eth_defi.vault.deposit_redeem.RedemptionTicket

class ERC7540DepositTicket

Bases: eth_defi.vault.deposit_redeem.DepositTicket

Asynchronous deposit request for ERC-7540 vaults.

request_id: int

ERC-7540 request identifier.

__init__(vault_address, owner, to, raw_amount, tx_hash, gas_used, block_number, block_timestamp, request_id)
Parameters
Return type

None

class ERC7540RedemptionRequest

Bases: eth_defi.vault.deposit_redeem.RedemptionRequest

Asynchronous redemption request for ERC-7540 vaults.

parse_redeem_transaction(tx_hashes)

Parse one standard ERC-7540 redemption-request transaction.

The final receipt must contain exactly one standard RedeemRequest event from which the request identifier is read.

Parameters

tx_hashes (list[hexbytes.main.HexBytes]) – Transaction hashes belonging to the request.

Returns

Parsed request ticket with its ERC-7540 request identifier.

Raises

CannotParseRedemptionTransaction – If the receipt does not contain exactly one RedeemRequest event.

Return type

eth_defi.erc_7540.deposit_redeem.ERC7540RedemptionTicket

__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 ERC7540RedemptionTicket

Bases: eth_defi.vault.deposit_redeem.RedemptionTicket

Asynchronous redemption request for ERC-7540 vaults.

request_id: int

ERC-7540 request identifier.

__init__(vault_address, owner, to, raw_shares, tx_hash, request_id)
Parameters
Return type

None

abstract get_request_id()

Get the redemption request id.

  • If vault uses some sort of request ids to track the withdrawals

  • Needed for settlement

Return type

int