> For the complete documentation index, see [llms.txt](https://docs.ensemble.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ensemble.io/how-it-works/vault-lifecycle.md).

# Vault lifecycle

Deposits, maintenance, redemptions, and emergency recovery from start to finish.

An accepted deposit creates shares immediately. The vault then moves capital and adjusts trading positions through separate maintenance transactions. A normal withdrawal pays available USDC immediately; permanent emergency recovery has a different claim process.

```mermaid
sequenceDiagram
    participant U as User
    participant C as CircuitBreaker
    participant V as Vault
    participant H as HyperCore
    participant K as Permissionless keeper
    U->>C: Deposit USDC
    C->>V: Authorized deposit
    V-->>U: Mint shares immediately
    K->>V: deployCapital()
    V->>H: Submit bridge to Core
    K->>V: confirmBridge() after settlement is visible
    K->>V: rebalance() when eligible
    V->>H: Submit IOC orders
    K->>V: confirmRebalance() after progress is visible
    U->>C: Redeem shares
    C->>V: Authorized redeem
    V-->>C: Return buffered USDC
    C-->>U: Forward USDC immediately
```

The diagram shows the routed flow. Direct ERC-4626 `deposit`, `mint`, `withdraw`, and `redeem` calls also enforce CircuitBreaker policy. Direct entry attributes capacity to the receiver; direct exit attributes it to the share owner and supports owner allowances. Public routed flows use the caller identity, while trusted routes authenticate the forwarded account.

## States and pending work

Vault state describes which operations are allowed. Separate pending flags track maintenance that has been submitted but has not finished.

The contract exposes three `VaultState` values:

* `Normal`: deposits and ordinary permissionless maintenance may proceed when no bridge or rebalance is pending and the other eligibility checks pass.
* `Paused`: deposits are blocked, while ordinary redemptions may remain possible if there is no active emergency-close episode or pending work, Standard mode is confirmed, and margin is not stressed.
* `Emergency`: ordinary redemption is disabled; a separately enabled pro-rata emergency claim path may become available after recovery.

Bridge and rebalance pending flags are separate from the vault state. A vault can therefore be `Normal` while an asynchronous action temporarily prevents a new deposit, redemption, or maintenance action.

## Deposits

An accepted deposit transfers USDC and issues shares in one transaction.

CircuitBreaker first validates the route and consumes deposit capacity. The vault then:

1. requires `Normal` state, confirmed Standard account mode, and no pending bridge, bridge recovery, or rebalance;
2. accrues management fees and computes current NAV per share;
3. checks the total deposit cap and deposit-window capacity;
4. calculates the deposit fee and shares;
5. transfers USDC and mints shares to the receiver in the same transaction.

There is no request queue, epoch finalization, or later NAV submission for a normal deposit. "Epoch" in this system refers to an optional resetting deposit-cap window, not delayed settlement. When its interval elapses, the next enforcing action observes the reset and begins a new window; it is distinct from CircuitBreaker's current-plus-previous-bucket rolling limits.

When share supply is zero, the contract enforces `MIN_FIRST_DEPOSIT = 10e6`, or $10 USDC for a 6-decimal USDC token. This empty-vault bootstrap floor is distinct from product metadata, a CircuitBreaker route minimum, and the vault's total cap.

## Capital movement

Vaults retain a configured USDC buffer on HyperEVM. `deployCapital()` submits excess capital toward HyperCore; `withdrawCapital(amount)` submits a bounded return of capital when the buffer is short. Both functions are permissionless but revalidate state and sizing on-chain.

A submission is not settlement. The vault records direction, amount, block, and timestamp as pending. After HyperCore or EVM balances reflect the movement, `confirmBridge()` finalizes accounting. It rejects confirmation in the submit block and rejects if settlement is not yet observable.

If the configured timeout passes, `cancelStaleBridge()` either finalizes a late-visible settlement or reverses pending accounting and marks recovery state. `reconfirmBridge()` first attempts to prove late settlement. After the contract's recovery waiting period, it can also clear recovery state under guarded conditions without proving full settlement. Clearing that state does not prove that the original transfer succeeded.

```mermaid
stateDiagram-v2
    [*] --> Settled
    Settled --> BridgePending: deployCapital() or withdrawCapital()
    BridgePending --> Settled: confirmBridge()
    BridgePending --> RecoveryPending: cancelStaleBridge() without observed settlement
    RecoveryPending --> Settled: reconfirmBridge() proves settlement
    RecoveryPending --> Reconciled: guarded recovery completion
```

## Rebalancing

Submitting orders starts a rebalance. Confirmation depends on the progress the contract can observe afterward.

`rebalance()` checks cooldown, drift, spread, backoff, order-size, margin, and pending-state rules before submitting HyperCore IOC orders. A no-op can complete without leaving pending work; otherwise the vault records a nonce, submitted position sizes, and pending state.

`confirmRebalance()` clears pending state after on-chain reads prove the required progress. If the confirmation timeout passes, `cancelStaleRebalance()` rechecks progress and can record success when the submitted orders have already settled.

Otherwise it submits cancellation requests and keeps the cycle pending. A later call after the cancellation observation timeout records observed execution, clears the cycle, and records a failed attempt. One successful cancellation-submission transaction therefore does not mean the cycle has finished. Indexers must distinguish `RebalanceSubmitted`, `RebalanceConfirmed`, and `StaleRebalanceCancelled`.

## Redemptions

A normal exit either pays USDC in the transaction or reverts. The native CircuitBreaker `redeem` path pulls approved shares, calls the vault, and forwards the returned USDC to the receiver. The vault accrues fees, computes current NAV per share, burns shares, and transfers net USDC after the withdrawal fee.

Redemptions draw only from the lesser of the vault's physical USDC balance and its tracked `accountedBalance`. Donated or otherwise unaccounted tokens do not increase spendable redemption capacity. A valid value preview can therefore exceed current executable capacity.

Ordinary redemption is blocked during bridge, bridge-recovery, or rebalance pending work, in `Emergency`, while an emergency-close episode remains active, without confirmed Standard mode, or while the Core account meets the emergency margin condition. Elapsed cooldown alone does not clear the emergency episode. There is no implicit queued withdrawal if immediate liquidity is insufficient.

## Emergency claims

Emergency recovery can end in a fixed pro-rata USDC claim for each shareholder. It requires recovered funds and explicit enablement before holders can claim.

`emergencyClose()` attempts to flatten exposure and moves normal operation into paused emergency handling. Recovery and enabling claims are distinct privileged steps with contract-enforced preconditions.

After the vault reaches `Emergency` and emergency withdrawals are enabled, `emergencyWithdraw()` lets each holder make one pro-rata claim:

```
user USDC = emergency available USDC × user shares / emergency total shares
```

Enablement requires flat positions, no pending maintenance or retained bridge recovery, and recovered attributable Core principal. It fixes the share supply and available USDC after fees, using only tracked, physically held funds. Share transfers freeze at this permanent boundary.

The call burns the holder's full current balance and marks the address claimed. It is not the ordinary CircuitBreaker redemption path, and it should not be presented as available until compatible on-chain state proves it is enabled.
