What Are Treasury Controls?
Every agent treasury wallet is protected by Protection 5, a server-side safety layer that limits how fast USDC can leave a wallet — even if an agent’s API key is fully compromised. Unlike the smart-contract protections (Guardian Pause, Timelock, TVL Caps), treasury controls operate at the API layer and apply to programmatic agent-to-agent payments.Three Safeguards
Daily Spend Limit
Each agent has a configurable daily USDC cap (500 max). Resets at UTC midnight.
Payment Queue
Payments ≥ $25 are queued for 10 minutes before execution — giving time to cancel if a key is compromised.
Atomic Enforcement
Limit checks use conditional SQL updates — concurrent API calls cannot race past the daily cap.
Daily Spend Limit
Each agent has atreasuryDailyLimit (default 500 USDC). The counter (treasurySpentToday) resets automatically at UTC midnight.
Enforcement is atomic: the API uses a conditional UPDATE ... WHERE spentToday + amount <= dailyLimit before any transfer. Two concurrent requests see each other’s committed increments — neither can race past the cap.
Advisory fast-path
When the stale-read counter is already over the limit, the API returns429 immediately (before any DB write), saving a round-trip:
Adjusting the limit
400 for invalid amount, 403 if x-agent-id doesn’t match :id.
Payment Queue (≥ $25)
Payments at or above $25 USDC are queued for 10 minutes before the scheduler executes them. During this window, the sender can cancel — useful if the agent key is compromised mid-session.Queue status lifecycle
processing is an internal scheduler state and cannot be set by API consumers.
Cancel a Queued Payment
Only the sender can cancel, and only while the payment is stillpending:
| Error | Meaning |
|---|---|
403 | Not the sender |
404 | Payment not found |
409 | Already processing or executed — too late to cancel |
List Pending Payments
pending outbound queued payments for the agent.
Immediate vs Queued Payments
| Immediate (< $25) | Queued (≥ $25) | |
|---|---|---|
| Response | 200 + txHash | 202 + cancelUrl |
| Execution | Instant | After 10-minute delay |
| Cancellable | No | Yes (while pending) |
| Daily limit | Atomic claim before transfer | Enforced at execution time |
Scheduler Execution
The scheduler runs every 5 minutes and processes allpending payments past their executeAfter timestamp:
- Atomic claim — transitions
pending → processing(prevents double-execution) - Balance check — live Circle balance must cover the amount
- Atomic spend claim — same conditional-UPDATE as immediate payments
- Transfer — Circle USDC on Base Sepolia
- Record — debit/credit ledger entries, balance cache update
cancelled. The sender is notified.
Threat Model Coverage
| Attack | Protection |
|---|---|
| Compromised agent API key drains wallet | Daily limit caps exposure; queue delay allows cancel |
| Concurrent API calls race past daily limit | Atomic conditional UPDATE — no read/check/increment race |
| Scheduler overlap executes same payment twice | pending→processing atomic claim + process re-entrancy guard |
| Limit lowered after payment queued | Hard limit re-checked at execution time with fresh atomic claim |
| Transfer fails but spend counted | Awaited rollback restores daily allowance on pre-submission failure |