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 |
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.
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
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 toDepositLimitRegistry 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 withDepositCapExceeded, the on-chain
transaction does not settle and no USDC moves — your EOA simply pays
gas for the revert. Recovery options:
- Wait for the rolling window to free up. The oldest deposit in
the window rolls out at the timestamp returned by
windowResetsAt.<window>fromGET /api/me/deposit-limits. - Deposit a smaller amount. Anything ≤
remaining.dailyis guaranteed to pass the daily check (and weekly / monthly are strictly looser). - 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-chainDepositLimitRegistry
implementation.
Next
Deposits overview
Approve + depositERC20 lifecycle.
Backend auto-deploy
Caps are initialised in the same flow as vault deploy.