> ## Documentation Index
> Fetch the complete documentation index at: https://docs.testnet.dev.adipredictstreet.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Deposit limits

> Per-EOA daily / weekly / monthly caps enforced on-chain by DepositLimitRegistry. Defaults, rolling windows, and how to read your current usage.

Every deposit is gated by three rolling caps recorded against the
depositing EOA: a **daily** cap, a **weekly** cap, and a **monthly**
cap. The caps are **on-chain** in the `DepositLimitRegistry`
contract — the platform initialises them automatically alongside
vault deploy, and `vault.depositERC20(...)` consults the registry on
every call.

## Defaults

KYC tier 1 wallets are seeded with the following caps on auto-deploy:

| Window  | Default cap (USDC) |
| ------- | ------------------ |
| Daily   | 10,000             |
| Weekly  | 50,000             |
| Monthly | 200,000            |

Higher tiers and partner-specific overrides are negotiated at
onboarding. There is **no self-service** path to raise caps — contact
your integration manager.

### Partner-backed sub-accounts

Sub-accounts under a `multi_wallet` partner with
`requirePerWalletKyc=false` (see [Partner kinds](/auth/api-keys#partner-kinds))
are seeded with **100,000 USDC** across all three windows the moment
the first request for the sub-account hits the API. Deposit / trade /
withdraw restrictions are cleared in the same auto-onboarding step.
No admin call required after the partner key is issued — the four
on-chain ops (`setCustomCaps`, `setDepositsRestricted(false)`,
`setTradingRestricted(false)`, `setWithdrawalsRestricted(false)`) are
enqueued automatically and confirmed by match-submitter within
\~30 sec.

The partner has taken KYB-level responsibility for its sub-accounts at
the partner record; the 100k envelope is the ops-chosen per-sub-account
starting ceiling. Need higher? Contact your integration manager — the
value is a single backend constant today, configurable per-partner on
roadmap.

## Rolling-window semantics

Caps are enforced over **rolling windows**, not calendar buckets:

* **Daily:** sum of deposits within the last 24h must stay ≤ daily cap.
* **Weekly:** sum within the last 7 days ≤ weekly cap.
* **Monthly:** sum within the last 30 days ≤ monthly cap.

A deposit that would push any window over its cap is **rejected
on-chain** with revert reason `DepositCapExceeded(window, cap, used)` —
the user transaction does not settle and no USDC moves. Wait for the
oldest deposit in the offending window to roll out, or split the
deposit into smaller chunks across days.

The order of checks is daily → weekly → monthly; the first cap that
would be exceeded is the one reported in the revert reason.

## Reading your current usage

```http theme={null}
GET /api/me/deposit-limits
X-Api-Key: ps_live_<keyId>_<secret>   # needs `portfolio:read`
```

```json theme={null}
{
  "walletAddress": "0x...",
  "initialized": true,
  "caps": {
    "daily":   "10000",
    "weekly":  "50000",
    "monthly": "200000"
  },
  "used": {
    "daily":   "300",
    "weekly":  "300",
    "monthly": "300"
  },
  "remaining": {
    "daily":   "9700",
    "weekly":  "49700",
    "monthly": "199700"
  },
  "windowResetsAt": {
    "daily":   "2026-04-26T12:34:15Z",
    "weekly":  "2026-05-02T12:34:15Z",
    "monthly": "2026-05-25T12:34:15Z"
  }
}
```

`initialized` is `false` until the platform's auto-init pass for
`DepositLimitRegistry` lands — see [Initialisation timing](#initialisation-timing)
below. While it's `false`, caps are still reported (the registry
returns the tier defaults under the hood) but `vault.depositERC20`
will revert with `NotInitialized()` until the back-office init tx
mines.

`windowResetsAt.<window>` is `windowStart + WINDOW` while the
recorded window is open (the moment the next deposit's window-edge
would roll, assuming no further activity). Once `now ≥ windowStart +
WINDOW`, the registry's lazy-reset semantics kick in — the next
deposit will start a fresh window at its own block timestamp — so we
report `used = 0` and `windowResetsAt.<window> = null` for that
window. Treat `null` as "no live window; full cap is available right
now."

## Initialisation timing

Caps are written to `DepositLimitRegistry` by the back-office wallet
in the same broad workflow as `VaultFactory.deployVault` — by the
time `GET /api/me/vault` returns `deployed: true`, the user is
already initialised in the registry and can deposit up to their tier
cap.

If your code path bypasses the platform and deploys the vault
manually in the same block as the first deposit, the deposit can
briefly revert with selector `0x87138d5c` = `NotInitialized()` because
the back-office cap-init tx hasn't been mined yet. Wait one block
and retry.

## Exceeding the cap

When a deposit reverts with `DepositCapExceeded`, the on-chain
transaction does not settle and no USDC moves — your EOA simply pays
gas for the revert. Recovery options:

1. **Wait for the rolling window to free up.** The oldest deposit in
   the window rolls out at the timestamp returned by
   `windowResetsAt.<window>` from `GET /api/me/deposit-limits`.
2. **Deposit a smaller amount.** Anything ≤ `remaining.daily` is
   guaranteed to pass the daily check (and weekly / monthly are
   strictly looser).
3. **Request a higher tier.** Contact your integration manager;
   onboarding has a tier-2 process that takes the cap to a
   partner-negotiated level.

## Withdrawals are not symmetric

Cap accounting is **deposit-only** — withdrawing USDC from the vault
does not "free up" deposit cap retroactively. The window is a sliding
view of inflow, not a net-flow accounting. This matches the regulatory
intent (AML deposit ceilings) and the on-chain `DepositLimitRegistry`
implementation.

## Next

<CardGroup cols={2}>
  <Card title="Deposits overview" icon="arrow-down-to-bracket" href="/concepts/deposits/overview">
    Approve + depositERC20 lifecycle.
  </Card>

  <Card title="Backend auto-deploy" icon="bolt" href="/concepts/vaults/auto-deploy">
    Caps are initialised in the same flow as vault deploy.
  </Card>
</CardGroup>
