> For the complete documentation index, see [llms.txt](https://docs.anchored.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.anchored.finance/trading-api/cash-operations/buffer-mechanism.md).

# Buffer Mechanism

The stock contracts use a dual-buffer design so small deposits and withdrawals can settle instantly without waiting for the full asynchronous cash settlement path. This page explains the mechanism from an API integration perspective.

## Why Buffers Exist

Deposits and withdrawals may need asynchronous cash settlement. Waiting for that full path on every operation would add latency to every API flow, so `Cashier` can use pre-funded liquidity to apply the result first and let final settlement catch up later.

The Cashier therefore keeps pre-funded buffers:

| Buffer             | Unit                             | Used for            | API-visible result                |
| ------------------ | -------------------------------- | ------------------- | --------------------------------- |
| `creditBuffer`     | `mUSD`, 18-decimal WAD           | Instant deposits    | `mUsdBalance` updates immediately |
| `withdrawalBuffer` | Per-token amount, token decimals | Instant withdrawals | Cash token transfers immediately  |

If the relevant buffer can cover the operation safely, the operation is instant. Otherwise it is queued and settled later.

## Deposit Path

```mermaid
sequenceDiagram
    participant U as User
    participant R as StockRouter
    participant C as Cashier

    U->>R: deposit token
    R->>C: deposit(user, token, amount)
    alt creditBuffer available and withdrawalBuffer has room
        C->>C: reduce creditBuffer
        C->>C: increase withdrawalBuffer
        C->>U: credit mUsdBalance instantly
    else buffer criteria not met
        C->>C: record pending deposit
        Note over C: final settlement completes later
        C->>U: credit mUsdBalance later
    end
```

On an instant deposit:

* Cash token moves in from the wallet.
* Cashier consumes `creditBuffer`.
* `mUsdBalance` updates immediately.
* The token amount, net of fee, replenishes that token's `withdrawalBuffer` up to capacity.

On a queued deposit:

* Cashier records a pending deposit operation.
* `mUSD` is not credited immediately.
* Cashier credits `mUSD` after final settlement.

## Withdrawal Path

```mermaid
sequenceDiagram
    participant U as User
    participant R as StockRouter
    participant C as Cashier

    U->>R: withdraw credit
    R->>C: withdraw(user, token, creditAmount)
    C->>C: deduct mUsdBalance
    alt withdrawalBuffer available
        C->>C: reduce withdrawalBuffer
        C->>C: replenish creditBuffer
        C->>U: transfer token instantly
    else buffer criteria not met
        C->>C: record pending withdrawal
        Note over C: final settlement completes later
        C->>U: transfer token later
    end
```

On an instant withdrawal:

* `mUsdBalance` is deducted first.
* Cashier pays the token from `withdrawalBuffer`.
* The deducted credit replenishes `creditBuffer` up to capacity.

On a queued withdrawal:

* `mUsdBalance` is deducted when the withdrawal is requested.
* Cashier records a pending withdrawal operation.
* Cashier transfers tokens after final settlement.

## Instant Eligibility

The contracts intentionally avoid draining buffers in one operation. An operation must be small enough relative to the current buffer and the buffer must have enough available capacity.

| Operation  | Instant requirements, simplified                                                                                                               |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Deposit    | Deposit credit is no more than `creditBuffer / instantThresholdDivisor`, `creditBuffer` can cover it, and the token withdrawal buffer has room |
| Withdrawal | Withdrawal token value is no more than `withdrawalBuffer / instantThresholdDivisor`, and `withdrawalBuffer` can cover it                       |

Anchored production uses `instantThresholdDivisor = 5`, so an instant operation is normally limited to at most 20% of the relevant current buffer. Operators can configure this value.

## Cross-Buffer Replenishment

The two buffers feed each other:

| Operation          | Consumes                 | Replenishes              |
| ------------------ | ------------------------ | ------------------------ |
| Instant deposit    | `creditBuffer`           | Token `withdrawalBuffer` |
| Instant withdrawal | Token `withdrawalBuffer` | `creditBuffer`           |

This is why deposits help future withdrawals and withdrawals help future deposits. Buffer manager operations can also rebalance or bootstrap buffers without changing the API flow.

## API-Visible Results

| Result                         | Likely meaning                                          | Integration guidance                      |
| ------------------------------ | ------------------------------------------------------- | ----------------------------------------- |
| `isInstant = true`             | Operation used available buffer                         | Treat operation as instantly applied      |
| `operationStatus = processing` | Operation is queued or settlement path is still running | Continue polling; do not treat as failure |
| `operationStatus = settled`    | Cashier has applied final credit or payout              | Refresh portfolio state                   |

For deposits, track when `mUsdBalance` updates. For withdrawals, track when tokens arrive in the wallet. The buffer mechanism only changes timing, not the eventual accounting path.

## Integration Guidance

* Do not assume every deposit or withdrawal is instant.
* Treat queued cash operations as normal product behavior.
* Poll the operation detail endpoint and refresh portfolio after final status.
* If a large operation is queued, retrying the same amount does not make it instant; it is constrained by current buffer size and capacity.

Related docs:

| Need                       | Doc                                                                                                |
| -------------------------- | -------------------------------------------------------------------------------------------------- |
| Live buffer and fee config | [../market/on-chain-config.md](/trading-api/market-data/on-chain-config.md) (`GET /api/v1/config`) |
| Deposit endpoints          | [deposits.md](/trading-api/cash-operations/deposits.md)                                            |
| Withdrawal endpoints       | [withdrawals.md](/trading-api/cash-operations/withdrawals.md)                                      |
| Cash status fields         | [operation-status.md](/trading-api/cash-operations/operation-status.md)                            |
| Status model               | [../reference/status-model.md](/trading-api/reference/status-model.md)                             |
