Skip to main content
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:
WindowDefault cap (USDC)
Daily10,000
Weekly50,000
Monthly200,000
Higher tiers and partner-specific overrides are negotiated at onboarding. There is no self-service path to raise caps — contact your integration manager.

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

GET /api/me/deposit-limits
X-Api-Key: ps_live_<keyId>_<secret>   # needs `portfolio:read`
{
  "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 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

Deposits overview

Approve + depositERC20 lifecycle.

Backend auto-deploy

Caps are initialised in the same flow as vault deploy.