> For the complete documentation index, see [llms.txt](https://gotts.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gotts.gitbook.io/docs/gotts-vaults/vault/04-architecture.md).

# Architecture

> **Part of**: [Vault PRD](/docs/gotts-vaults/vault.md) | **Last Updated**: 2026-02-16

***

## System Architecture

### High-Level Architecture

```
┌─────────────────────────────────────────────────────────────────────────┐
│                        AGENT LAYER (MCP Clients)                         │
│                                                                          │
│  Vault Creator    Vault Manager    Vault Participant    External Agent   │
│  (deploys vaults) (executes strategy) (deposits capital)  (queries/reads) │
└──────┬────────────────┬──────────────────┬──────────────────┬────────────┘
       │                │                  │                  │
       └────────────────┴────────┬─────────┴──────────────────┘
                                 │
                  ┌──────────────┴──────────────┐
                  │  TIME-DELAYED PROXY LAYER    │  ← Optional (packages/agent-proxy/)
                  │  (announce → delay → execute) │
                  │                               │
                  │  AgentProxy: queues txs       │
                  │  Monitor Bot: watches events  │
                  │  Cancel Auth: vetoes bad txs  │
                  └──────────────┬──────────────┘
                                 │
                          MCP Transport Layer
                    (stdio / HTTP+SSE / WebSocket)
                                 │
┌────────────────────────────────┴────────────────────────────────────────┐
│              VAULT MCP SERVER (standalone, packages/vault/)              │
│                                                                          │
│  ┌───────────────────────────────────────────────────────────────────┐  │
│  │            MCP TOOLS (24 core + 6 optional proxy)                   │  │
│  │                                                                     │  │
│  │  FACTORY:  create_vault, list_vaults, get_vault_config              │  │
│  │  DEPOSIT:  vault_deposit, vault_withdraw, vault_simulate_deposit    │  │
│  │  STRATEGY: vault_rebalance, vault_collect_fees                      │  │
│  │  READ:     vault_get_state, vault_get_strategy, vault_get_positions,│  │
│  │            vault_get_agent_shares, vault_get_performance,           │  │
│  │            vault_get_risk_metrics                                   │  │
│  │  IDENTITY: vault_register_agent, vault_get_agent_reputation,        │  │
│  │            vault_get_tier_limits, vault_enroll_reputation,          │  │
│  │            vault_get_milestones, vault_claim_milestone              │  │
│  │  MARKET:   get_vault_rankings                                       │  │
│  └──────────────────────────────┬────────────────────────────────────┘  │
│                                  │                                       │
│  ┌──────────────────────────────┴────────────────────────────────────┐  │
│  │                    TypeScript SDK                                    │  │
│  │                                                                     │  │
│  │  VaultFactoryClient │ VaultClient │ StrategyEngine │ SharePoolClient │  │
│  │  CCABidder │ HookDeployer │ x402Gateway │ ReputationReader           │  │
│  └──────────────────────────────┬────────────────────────────────────┘  │
│                                  │                                       │
│  ┌──────────────────────────────┴────────────────────────────────────┐  │
│  │              Safety Pipeline (standalone or mcp-server peer)        │  │
│  │                                                                     │  │
│  │  Layer 0: ERC-8004 Identity Verification                           │  │
│  │  Layers 1-7: Token allowlist, spending limits, rate limiter,       │  │
│  │              circuit breaker, slippage guard, simulation, nonce     │  │
│  │  Layer 8: NAV circuit breaker + position monitoring                │  │
│  └──────────────────────────────┬────────────────────────────────────┘  │
│                                  │                                       │
│  ┌──────────────────────────────┴────────────────────────────────────┐  │
│  │              Memory Layer (DeFi Brain, optional)                     │  │
│  │                                                                     │  │
│  │  LanceDB (episodic) + SQLite (semantic)                            │  │
│  │  Active when TOOL_PROFILE includes learning                        │  │
│  └──────────────────────────────┬────────────────────────────────────┘  │
└─────────────────────────────────┼────────────────────────────────────────┘
                                  │
┌─────────────────────────────────┴────────────────────────────────────────┐
│                   ON-CHAIN CONTRACTS (Solidity / Foundry)                  │
│                                                                           │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  AgentVaultFactory  │  │  AgentVaultCore   │  │  VaultHook          │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Permissionless     │  │  ERC-4626 vault   │  │  V4 hook: agent-   │ │
│  │  vault deployment   │  │  + ERC-8004 gate  │  │  gated swaps +     │ │
│  │  via CREATE2.       │  │  + circuit breaker │  │  dynamic fees +    │ │
│  │  Registry of all    │  │  + tiered access   │  │  ERC-4626 yield    │ │
│  │  deployed vaults.   │  │  + CCA integration │  │  wrapping          │ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  CCABidAdapter      │  │  FeeModule        │  │  AgentGatedPool     │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Adapter for vault  │  │  Management fee,   │  │  Pool creation      │ │
│  │  collective CCA     │  │  performance fee,  │  │  factory with       │ │
│  │  bidding. Wraps     │  │  reputation-based  │  │  hook deployment    │ │
│  │  submitBid/exit/    │  │  discounts, creator│  │  via CREATE2 +     │ │
│  │  claim lifecycle.   │  │  fee share.        │  │  HookMiner.         │ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  V4 INTEGRATION MODULES (auto-market + volume flywheel):                 │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  NAVAwareHook       │  │  LaunchFeeHook    │  │  RehypothecationAd  │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Prices vault shares│  │  Descending-fee   │  │  Deploys idle out-  │ │
│  │  at NAV via NoOp.   │  │  MEV protection   │  │  of-range liquidity │ │
│  │  Asymmetric fees.   │  │  on share pool    │  │  to lending venues  │ │
│  │  Discrete snapshots │  │  creation. Fees   │  │  (Morpho, Aave,     │ │
│  │  + rate clamp +     │  │  deposited back   │  │  Seamless). JIT     │ │
│  │  staleness gates    │  │  as vault yield.  │  │  withdrawal on swap.│ │
│  │  (D-062).           │  │                   │  │                     │ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  RISK AND GOVERNANCE (unified on-chain risk + parameter governance):     │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  RiskEngine         │  │  ParamDecisionTbl │  │  HookKillSwitch     │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Single source of   │  │  Per-parameter    │  │  Sentinel-callable  │ │
│  │  truth: adapter caps│  │  authority, bounds,│  │  break-glass toggle │ │
│  │  drawdown, oracle   │  │  timelocks, and   │  │  for V4 hooks.      │ │
│  │  freshness, leverage│  │  justification    │  │  Re-enable requires │ │
│  │  ERC-7265 interface │  │  hash registry    │  │  Owner+Curator +    │ │
│  │  (D-056).           │  │  (D-059).         │  │  longTimelock(D-058)│ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  RESEARCH-BACKED MODULES (dynamic fees + activeness + reputation):        │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  DynamicFeeEngine   │  │  ActivenessCntrl  │  │  VaultReputation    │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Three-regime       │  │  PA-AMM lambda    │  │  Milestone auto-    │ │
│  │  threshold fees     │  │  parameter for    │  │  attestation +      │ │
│  │  + LVR-theta floor  │  │  active/passive   │  │  endgame defection  │ │
│  │  + fee-implied vol. │  │  reserve split.   │  │  detection.         │ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  STRATEGY ADAPTERS (pluggable yield sources, D-019):                    │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  RecursiveLending   │  │  PendleAdapter    │  │  CreditDelegation   │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Atomic flash-loan  │  │  PT/YT yield      │  │  Reputation-gated   │ │
│  │  leverage loops via │  │  tokenization +   │  │  uncollateralized    │ │
│  │  Morpho/Aave. 5-8x  │  │  fixed-rate       │  │  borrowing via Aave │ │
│  │  max on Base (D-048)│  │  capture (D-051). │  │  delegation (D-052).│ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  STRUCTURED PRODUCT MODULES (optional depositor risk segmentation):     │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  TrancheModule      │  │  PolicyCage       │  │  BondMMHook         │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  PYT: Senior (AA)   │  │  On-chain hard    │  │  V4 hook for fixed- │ │
│  │  + Junior (BB) share│  │  boundaries for   │  │  rate lending across│ │
│  │  tokens. Adaptive   │  │  AI agent strategy│  │  arbitrary maturities│ │
│  │  yield split (D-049)│  │  (D-053).         │  │  in one pool (D-055)│ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│                                                                           │
│  FACTORY-LEVEL COORDINATION (cross-vault optimization + automation):     │
│  ┌─────────────────────┐  ┌──────────────────┐  ┌─────────────────────┐ │
│  │  CrossVaultCoord    │  │  OptimalExitOrcl  │  │  LiquidityRouter    │ │
│  │  ────────────────── │  │  ──────────────── │  │  ────────────────── │ │
│  │  Convex optimizer   │  │  Longstaff-       │  │  Inter-vault lending│ │
│  │  for cross-vault    │  │  Schwartz Monte   │  │  of idle capital.   │ │
│  │  arbitrage-free     │  │  Carlo exit       │  │  Utilization-curve  │ │
│  │  state (D-032).     │  │  boundaries       │  │  rates. Reduces     │ │
│  │  Defensive rebal.   │  │  (D-031).         │  │  idle waste (D-054).│ │
│  └─────────────────────┘  └──────────────────┘  └─────────────────────┘ │
│  ┌─────────────────────┐                                                 │
│  │  ExecutionMarket    │                                                 │
│  │  ────────────────── │                                                 │
│  │  Native on-chain    │                                                 │
│  │  keeper registry.   │                                                 │
│  │  Bonded executors,  │                                                 │
│  │  job conditions,    │                                                 │
│  │  rewards + slashing │                                                 │
│  │  (D-057).           │                                                 │
│  └─────────────────────┘                                                 │
│                                                                           │
│  GOVERNANCE MODULE (optional, post-v1):                                  │
│  ┌─────────────────────┐                                                 │
│  │  veVAULT Module     │                                                 │
│  │  ────────────────── │                                                 │
│  │  Vote-escrowed token│                                                 │
│  │  governance. Gauge  │                                                 │
│  │  voting, bribe mkt, │                                                 │
│  │  agent bonding      │                                                 │
│  │  (D-050).           │                                                 │
│  └─────────────────────┘                                                 │
│                                                                           │
│  STRATEGY MARKETPLACE (expansion-track, D-089–D-093):                    │
│  ┌─────────────────────┐  ┌──────────────────┐                          │
│  │  StrategyMarket     │  │  StrategyEscrow   │                          │
│  │  Registry           │  │  ──────────────── │                          │
│  │  ──────────────── │  │  Seller stake lock │                          │
│  │  Publish, purchase, │  │  + 7-day dispute  │                          │
│  │  slash, royalties.  │  │  window + commit- │                          │
│  │  keccak256 strategy │  │  reveal voting.   │                          │
│  │  IDs + IPFS URIs.   │  │  Burns slashed    │                          │
│  │  EZKL proof gate.   │  │  stake (D-089).   │                          │
│  └─────────────────────┘  └──────────────────┘                          │
│                                                                           │
│  EXTERNAL CONTRACTS:                                                      │
│  ERC-8004 IdentityRegistry (0x8004...BD9e)                               │
│  ERC-8004 ReputationRegistry (0x8004...8713)                             │
│  Uniswap V4 PoolManager │ PositionManager │ Universal Router             │
│  Uniswap V4 TWAMM Hook │ Permit2                                        │
│  ContinuousClearingAuction │ ContinuousClearingAuctionFactory            │
│  LiquidityLauncher │ FullRangeLBPStrategy │ AdvancedLBPStrategy          │
└──────────────────────────────────────────────────────────────────────────┘
```

### Learning Economy Layer

The learning economy layer sits between the Memory Layer (DeFi Brain) and the on-chain contracts. It converts accumulated episodic memories into tradeable strategies, connects to the x402 marketplace for strategy distribution, and optionally generates ZK performance proofs.

```
VaultOperation (on-chain event)
  │
  ├─→ Episode Capture (LanceDB, TypeScript)
  │       packages/vault/sdk/src/learning/episode.ts
  │       Embeds: operation + regimeState + reflection (nomic-embed-text-v1.5)
  │
  ├─→ Reflexion Inner Loop (claude-opus-4-6 reflection, per-operation)
  │       packages/vault/sdk/src/learning/reflexion.ts
  │       Stores: prediction vs. actual gap, confidence score
  │
  ├─→ [Every 50 episodes] ExpeL Outer Loop (cross-episode distillation)
  │       packages/vault/sdk/src/learning/expel.ts
  │       Outputs: Insight pool (SQLite) with ADD/UPVOTE/DOWNVOTE/EDIT
  │       Categories: rebalance_timing, fee_optimization, regime_transition,
  │                   gas_execution, range_selection, jit_defense
  │
  ├─→ [Confidence > 0.8 AND sampleSize > 30] Strategy Generation
  │       packages/vault/sdk/src/learning/strategy.ts
  │       Fits: VaultStrategy JSON with parameters, featureImportance,
  │             regimeClassifier (4-state HMM), performance attestation
  │
  ├─→ [price > $1.00] EZKL Proof Generation (@ezkljs/engine, optional)
  │       packages/vault/sdk/src/learning/zkml.ts
  │       Proves: model M with hash H produced claimed Sharpe/drawdown/winRate
  │       Verification: ~0.5 seconds on Base via deployed Halo2 verifier
  │
  ├─→ EAS Attestation (via EAS SDK on Base, all strategies)
  │       Attests: performance metrics on-chain with tamper evidence
  │
  ├─→ StrategyMarketplaceRegistry (on-chain, publishStrategy())
  │       Stores: strategyId, priceUsdc, stakedAmount, zkProofHash, metadataURI
  │       StrategyEscrow: locks seller stake (slashable on underperformance)
  │
  ├─→ x402-gated Express server (buyers pay via HTTP 402 micropayments)
  │       packages/vault/src/marketplace/server.ts
  │       Routes: GET /strategies ($0.10), /signals/regime ($0.02), /signals/alpha ($1.00)
  │
  └─→ Bazaar Discovery (.well-known/x402.json manifest, indexed by x402 Facilitators)
        Revenue → claim_strategy_royalties → treasury-manager → vault stakes
```

**Alpha decay**: Strategy prices follow `P(t) = P_base × e^(-λt)`. λ is calibrated per strategy family (lp\_optimization: 0.05/day → \~14-day half-life). See [17-learning-economy.md §11](/docs/gotts-vaults/vault/17-learning-economy.md) for the full decay table.

**Federated regime detection**: Vaults share only 4-float probability vectors + Gaussian DP noise. Consensus at 66% of weighted agents triggers strategy adjustments. Raw market data and positions never leave the contributing vault.

**Full spec**: [17-learning-economy.md](/docs/gotts-vaults/vault/17-learning-economy.md)

***

### Package Structure

```
packages/
├── mcp-server/                        # Gotts Safe (57 tools)
├── vault/                             # Vault protocol (composes agent-proxy)
└── agent-proxy/                       # Standalone time-delay proxy module
    ├── contracts/
    │   ├── src/
    │   │   ├── AgentProxy.sol         # Time-delayed proxy with proxy types
    │   │   ├── AgentProxyFactory.sol   # Factory with CREATE2 + default whitelists
    │   │   └── interfaces/
    │   │       └── IMonitoringOracle.sol  # Pluggable evaluation interface
    │   └── test/
    │       ├── AgentProxy.t.sol
    │       ├── AgentProxyFactory.t.sol
    │       └── Integration.t.sol
    ├── sdk/
    │   ├── src/
    │   │   ├── proxy-client.ts        # ProxyClient: announce, execute, cancel
    │   │   ├── monitor.ts             # MonitorBot: event watching + evaluation
    │   │   ├── cancel-authority.ts    # CancelAuthority: KMS-backed cancel key
    │   │   ├── delay-engine.ts        # DelayEngine: risk-tiered delay computation
    │   │   ├── proxy-type-registry.ts # ProxyTypeRegistry: whitelist management
    │   │   └── types.ts
    │   └── __tests__/
    ├── src/
    │   ├── server.ts                  # Standalone proxy MCP server
    │   └── tools/                     # 6 MCP tools for proxy management
    │       ├── proxy-announce.ts
    │       ├── proxy-execute.ts
    │       ├── proxy-cancel.ts
    │       ├── proxy-get-pending.ts
    │       ├── proxy-get-config.ts
    │       └── proxy-configure.ts
    └── monitor/                       # Standalone monitoring bot
        ├── src/
        │   ├── index.ts               # Bot entry point
        │   ├── evaluator.ts           # Transaction evaluation policy
        │   ├── alerter.ts             # Multi-channel alerting (Telegram, Discord)
        │   └── config.ts              # Evaluation rules configuration
        └── Dockerfile
```

#### Vault Package Structure

```
packages/vault/
├── contracts/
│   ├── src/
│   │   ├── AgentVaultFactory.sol       # Permissionless vault deployment
│   │   ├── AgentVaultCore.sol          # ERC-4626 + ERC-8004 + tiered access
│   │   ├── VaultHook.sol               # V4: agent-gate + dynamic fees + yield wrap
│   │   ├── CCABidAdapter.sol           # Collective CCA participation
│   │   ├── FeeModule.sol               # Reputation-weighted fees
│   │   ├── AgentGatedPool.sol          # Pool creation with hook deployment
│   │   ├── NAVAwareHook.sol            # V4: NAV-priced share pool (auto-market)
│   │   ├── LaunchFeeHook.sol           # V4: descending-fee MEV protection
│   │   ├── RehypothecationAdapter.sol  # Idle liquidity → lending venues
│   │   ├── RecursiveLendingAdapter.sol # Flash-loan leverage loops (D-048)
│   │   ├── PendleAdapter.sol          # PT/YT yield tokenization (D-051)
│   │   ├── CreditDelegationAdapter.sol # Reputation-gated delegation (D-052)
│   │   ├── TrancheModule.sol          # PYT Senior/Junior shares (D-049)
│   │   ├── PolicyCage.sol             # On-chain agent strategy bounds (D-053)
│   │   ├── LiquidityRouter.sol        # Cross-vault idle capital lending (D-054)
│   │   ├── BondMMHook.sol             # Fixed-rate multi-maturity hook (D-055)
│   │   ├── RiskEngine.sol             # Unified risk params + ERC-7265 breaker (D-056)
│   │   ├── ExecutionMarket.sol        # Bonded keeper registry + job system (D-057)
│   │   ├── ParameterDecisionTable.sol # Per-param authority/bounds/timelock (D-059)
│   │   └── interfaces/
│   │       ├── IAgentVaultFactory.sol
│   │       ├── IAgentVaultCore.sol
│   │       ├── ICCABidAdapter.sol
│   │       ├── IFeeModule.sol
│   │       ├── IIdentityRegistry.sol
│   │       └── IReputationRegistry.sol
│   ├── test/
│   │   ├── AgentVaultFactory.t.sol
│   │   ├── AgentVaultCore.t.sol
│   │   ├── VaultHook.t.sol
│   │   ├── CCABidAdapter.t.sol
│   │   ├── FeeModule.t.sol
│   │   ├── Integration.t.sol           # Full lifecycle tests
│   │   └── Invariants.t.sol            # Fuzz + invariant testing
│   ├── script/
│   │   ├── DeployFactory.s.sol         # Production factory deployment
│   │   ├── DeployVault.s.sol           # Single vault deployment (testing)
│   │   ├── DeployHook.s.sol            # Hook deployment with CREATE2
│   │   └── DeployLocal.s.sol           # Local testnet: factory + mock registries
│   └── foundry.toml
├── sdk/
│   ├── src/
│   │   ├── index.ts
│   │   ├── factory-client.ts           # VaultFactoryClient: create, list, discover
│   │   ├── vault-client.ts             # VaultClient: deposit, withdraw, query
│   │   ├── strategy-engine.ts          # Strategy recommendation + execution
│   │   ├── cca-bidder.ts               # CCA auction evaluation + bid management
│   │   ├── hook-deployer.ts            # HookMiner + CREATE2 deployment
│   │   ├── x402-gateway.ts             # x402-gated strategy endpoints
│   │   ├── reputation-reader.ts        # ERC-8004 reputation queries + tier mapping
│   │   ├── share-pool-client.ts        # Share pool: buy/sell shares via V4 pool
│   │   ├── types.ts
│   │   ├── constants.ts
│   │   └── utils/
│   │       ├── chain-provider.ts
│   │       ├── wallet.ts
│   │       ├── cache.ts
│   │       ├── errors.ts
│   │       └── formatters.ts
│   └── __tests__/
├── memory/                              # DeFi Brain memory system
│   ├── episodic.ts                      # LanceDB episodic memory store
│   ├── semantic.ts                      # SQLite/sqlite-vec semantic memory store
│   ├── consolidation.ts                 # ExpeL distillation loop
│   ├── decay.ts                         # Ebbinghaus curve memory decay
│   └── embedder.ts                      # Transformers.js embedding pipeline
├── src/
│   ├── server.ts                       # Standalone MCP server
│   ├── transport/
│   │   ├── stdio.ts
│   │   ├── http.ts
│   │   └── websocket.ts
│   └── tools/                          # 22 MCP tools
│       ├── factory/
│       │   ├── create-vault.ts
│       │   ├── list-vaults.ts
│       │   └── get-vault-config.ts
│       ├── deposit/
│       │   ├── vault-deposit.ts
│       │   ├── vault-withdraw.ts
│       │   └── vault-simulate-deposit.ts
│       ├── strategy/
│       │   ├── vault-rebalance.ts
│       │   ├── submit-cca-bid.ts
│       │   ├── exit-cca-bid.ts
│       │   ├── claim-cca-tokens.ts
│       │   ├── deploy-liquidity.ts
│       │   └── vault-collect-fees.ts
│       ├── read/
│       │   ├── vault-get-state.ts
│       │   ├── vault-get-strategy.ts
│       │   ├── vault-get-positions.ts
│       │   ├── vault-get-agent-shares.ts
│       │   ├── vault-get-performance.ts
│       │   └── vault-get-risk-metrics.ts
│       ├── identity/
│       │   ├── vault-register-agent.ts
│       │   ├── vault-get-agent-reputation.ts
│       │   └── vault-get-tier-limits.ts
│       └── market/
│           ├── get-cca-auctions.ts
│           └── get-vault-rankings.ts
├── agents/
│   ├── vault-creator.md
│   ├── vault-manager.md
│   ├── vault-strategist.md
│   └── vault-allocator.md
├── skills/
│   ├── create-vault/SKILL.md
│   ├── manage-vault/SKILL.md
│   ├── vault-strategy/SKILL.md
│   ├── cca-participation/SKILL.md
│   └── deposit-vault/SKILL.md
├── ui/                                 # Debug UI (developer-facing)
│   ├── src/
│   │   ├── components/
│   │   │   ├── Dashboard.tsx           # Factory overview: vault count, total TVL
│   │   │   ├── VaultDetail.tsx         # Single vault: positions, performance, agents
│   │   │   ├── Positions.tsx           # LP + CCA position details
│   │   │   ├── Agents.tsx              # Agent registry, tiers, reputation
│   │   │   ├── CCAMonitor.tsx          # Active auction bids and status
│   │   │   └── ToolTester.tsx          # Interactive MCP tool invocation
│   │   └── ...
│   └── ...
├── scripts/
│   ├── testnet.sh                      # One-command: Anvil + factory + seed + server + UI
│   ├── deploy-local.sh
│   ├── seed-testnet.sh                 # Register test agents, deploy sample vaults
│   └── dev.sh
└── prd/                                # This document and supporting specs
```

***

## Unified Server Architecture (Profile-Based)

### Vault Tools in the Core MCP Server

Vault tools are registered as part of the unified Gotts Safe server via the **profile system**. Setting `TOOL_PROFILE=vault` (or including `vault` in a composable profile like `trader,vault`) activates vault-specific tools alongside the core data tools. No separate MCP server process is needed.

```json
{
  "mcpServers": {
    "uniswap": {
      "command": "node",
      "args": ["./packages/safe/dist/index.js"],
      "env": {
        "TOOL_PROFILE": "vault",
        "VAULT_FACTORY_ADDRESS": "0x...",
        "RPC_URL_8453": "..."
      }
    }
  }
}
```

This single server gives agents access to all vault tools (deposit, withdraw, strategy, identity, am-AMM) plus the core data tools (pool info, prices, token search) that vault operations depend on. The profile system is described in [mcp-server/02-architecture.md](/docs/gotts-safe-mcp-server/mcp-server/02-architecture.md).

### How Vault Tools Register

Vault tool modules live in `packages/vault/tools/` and are imported by the core server's tool router when the `vault` profile is active:

```typescript
// packages/safe/src/index.ts
import { registerVaultTools } from "@gotts.ai/vault/register-tools";

if (activeProfiles.includes("vault")) {
  registerVaultTools(server); // Registers all vault MCP tools
}
```

The vault SDK (`packages/vault/sdk/`) provides the implementation layer (VaultClient, StrategyEngine, etc.) and is imported by the vault tool modules. The SDK remains in the vault package and does not move to mcp-server.

### Shared Infrastructure

When vault tools run inside the core server, they share infrastructure rather than reimplementing it:

| Shared Layer       | What Vault Gets                                                             | Replaces                                   |
| ------------------ | --------------------------------------------------------------------------- | ------------------------------------------ |
| Safety Middleware  | Full 15-layer pipeline including simulation, rate limiting, spending limits | Vault's standalone `builtinSafetyPipeline` |
| Chain Providers    | Multi-chain viem `PublicClient` with fallback RPC, connection pooling       | Vault's minimal `ChainProvider`            |
| Wallet Abstraction | All 5 wallet types (local, Privy, Safe, ZeroDev, custom)                    | Vault's 3-provider `WalletInterface`       |
| Cache Layer        | Tiered LRU cache shared across all tool modules                             | Vault's standalone `LRUCache`              |

### Standalone Fallback

For teams requiring complete isolation (e.g., separate security domains, independent scaling), the vault package retains a standalone server entry point (`packages/vault/src/server.ts`). This is not the recommended path but remains available:

```bash
# Not recommended -- use TOOL_PROFILE=vault in the core server instead
cd packages/vault && pnpm start
```

The standalone mode uses the vault's built-in safety checks rather than the full core safety pipeline.

***

## ERC-8004 Metadata Tags for Participant Discovery (D-080, D-086)

Every participant in the AgenticVaults ecosystem registers structured metadata in the ERC-8004 Identity Registry, enabling discovery by any agent with the Agent0 SDK (`@agent0/sdk`). Two metadata layers work together: on-chain metadata (stored in Identity Registry contract storage, readable by smart contracts) and registration file metadata (off-chain JSON at `agentURI`, indexed by the Agent0 subgraph).

### On-Chain Metadata Keys

Stored via `setMetadata(agentId, key, value)` on the Identity Registry:

| Participant    | Key             | Value Example                      |
| -------------- | --------------- | ---------------------------------- |
| Vault Manager  | `role`          | `vault_manager`                    |
| Vault Manager  | `protocol`      | `agenticvaults`                    |
| Vault Manager  | `chain`         | `8453`                             |
| Vault Manager  | `vaultAddress`  | `abi.encode(vaultContractAddress)` |
| Vault Manager  | `asset`         | `USDC`                             |
| Vault Manager  | `strategyType`  | `yield_optimization`               |
| Vault Creator  | `role`          | `vault_creator`                    |
| Vault Creator  | `vaultsCreated` | `abi.encode(uint256(count))`       |
| Investor Agent | `role`          | `investor`                         |
| Investor Agent | `riskProfile`   | `moderate`                         |
| MCP Server     | `role`          | `infrastructure`                   |
| MCP Server     | `serviceType`   | `mcp_server`                       |
| MCP Server     | `version`       | `1.0.0`                            |

### Registration File `services` Array

The `agentURI` resolves to a JSON registration file whose `services` array advertises all communication endpoints. For AgenticVaults participants, this is where MCP, A2A, and OASF data live:

```json
{
  "type": "https://eips.ethereum.org/EIPS/eip-8004#registration-v1",
  "name": "AgenticVaults Yield Optimizer #42",
  "services": [
    {
      "name": "A2A",
      "endpoint": "https://agent42.agenticvaults.xyz/.well-known/agent.json",
      "version": "1.0"
    },
    {
      "name": "MCP",
      "endpoint": "https://mcp.agenticvaults.xyz/",
      "version": "2025-06-18"
    },
    {
      "name": "OASF",
      "endpoint": "ipfs://Qm...",
      "skills": ["advanced_reasoning_planning/strategic_planning"],
      "domains": [
        "finance_and_business/investment_services",
        "technology/blockchain/defi"
      ]
    }
  ],
  "metadata": {
    "vault:address": "0x...",
    "vault:asset": "USDC",
    "vault:strategy": "Uniswap V4 LP + Moonwell lending optimization",
    "vault:fee_performance_bps": "1000",
    "vault:erc4626_compliant": "true",
    "protocol:name": "AgenticVaults",
    "protocol:version": "1.0.0"
  },
  "x402Support": true,
  "active": true,
  "supportedTrust": ["reputation", "crypto-economic"]
}
```

The Agent0 SDK's `searchAgents()` function indexes these `services` entries. An investor agent can query for all active agents with OASF domain `finance_and_business/investment_services` on chain 8453 and immediately get a list of vault managers with their MCP and A2A endpoints.

***

## MCP vs A2A: Complementary Protocol Roles (D-083)

The MCP server exposes both MCP tools and A2A (Agent-to-Agent) skills. These protocols serve complementary roles:

| Concern                     | Protocol | Example                                                                 |
| --------------------------- | -------- | ----------------------------------------------------------------------- |
| Atomic vault operations     | MCP      | `deposit_to_vault`, `withdraw_from_vault`, `get_vault_metrics`          |
| Yield data queries          | MCP      | `search_yield_opportunities`, `get_user_position`, `get_vault_rankings` |
| Reputation actions          | MCP      | `give_feedback`, `vault_enroll_reputation`, `vault_claim_milestone`     |
| Yield strategy negotiation  | A2A      | Multi-turn risk/return analysis with investor agent                     |
| Rebalancing consensus       | A2A      | Vault manager proposes rebalance, guardian agent reviews                |
| Portfolio construction      | A2A      | Iterative refinement between investor and multiple vault managers       |
| Cross-protocol coordination | A2A      | Vault manager negotiates with external protocol agents                  |

MCP tools are stateless, single-call operations. A2A supports multi-turn dialogue with a task lifecycle (`submitted -> working -> input_required -> completed`) that enables the nuanced back-and-forth that complex financial decisions require. Both protocols share the same HTTP server with different route prefixes (`/mcp` and `/a2a`) and can share SSE infrastructure for streaming.

The A2A spec is currently at v0.1.0 (work in progress, governed by the Linux Foundation). The MCP server will expose A2A endpoints alongside MCP tools starting in Phase 4-5.

***

## Yield Service Discovery Architecture (D-082, D-084, D-087)

AgenticVaults functions as **yield service discovery infrastructure** for autonomous agents. Agents query the ERC-8004 ecosystem to find yield opportunities through a four-layer stack:

```
+--------------------------------------------------------------------+
|  Layer 4: Agent Discovery API                                        |
|  Agent0 SDK searchAgents() + searchAgentsByReputation()              |
|  Combines layers 1-3 into queryable interface. Investor agents       |
|  search by asset, chain, Sharpe, reputation tier, TVL range.         |
+--------------------------------------------------------------------+
|  Layer 3: Reputation-Anchored Performance Data                       |
|  ERC-8004 Reputation Registry: tradingYield feedback (per epoch),    |
|  feedbackURI -> risk metrics (Sharpe, drawdown, IL), qualitative     |
|  reviews from investors, yield leaderboard (subgraph-indexed).       |
+--------------------------------------------------------------------+
|  Layer 2: Subgraph Indexing                                          |
|  Indexes vault events (Deposit, Withdraw, SharePrice). Computes      |
|  TVL, APY, volume metrics. Joins with ERC-8004 identity + rep data.  |
+--------------------------------------------------------------------+
|  Layer 1: On-Chain Vault Registration                                |
|  AgentVaultFactory emits VaultCreated events. Each vault's manager   |
|  has ERC-8004 identity. On-chain metadata: vault address, asset,     |
|  strategy type. Registration file: MCP/A2A endpoints, OASF domains.  |
+--------------------------------------------------------------------+
```

### Discovery Flow

1. **Agent0 SDK `searchAgents()`**: Filter by OASF domain (`finance_and_business/investment_services`), chain (8453), active status, protocol metadata (`agenticvaults`).
2. **Filter by Reputation**: `searchAgentsByReputation()` with minimum score (50 for Verified tier), tag filter (`tradingYield`), minimum feedback count (4).
3. **Fetch Rich Yield Data**: For each candidate, read registration file (vault metadata), read `feedbackURI` (risk metrics, Sharpe, drawdown), read on-chain metadata (vault address, asset, TVL).
4. **Connect via MCP or A2A**: MCP for atomic operations (`deposit_to_vault`), A2A for multi-turn strategy negotiation (`yield_strategy_consultation`).

***

## Data Flow: Vault Creation via Factory

```
Agent calls: create_vault(agentId: "42", baseAsset: "USDC", ccaEnabled: true, hookEnabled: true)
         │
         ▼
  ┌─── Vault MCP Server ──────────────────────────────────────────────┐
  │ 1. Verify ERC-8004 identity: agentId 42 is registered            │
  │ 2. Validate config: fee params within allowed range               │
  │ 3. Encode factory.createVault(config) calldata                    │
  └────────┬───────────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Safety Pipeline ────────────────────────────────────────────────┐
  │ Identity verified → Pre-flight simulation → Nonce check            │
  └────────┬───────────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── On-Chain ───────────────────────────────────────────────────────┐
  │ AgentVaultFactory.createVault(config)                              │
  │   → Deploys AgentVaultCore via CREATE2                            │
  │   → If hookEnabled: mines hook address, deploys VaultHook          │
  │   → If ccaEnabled: deploys CCABidAdapter                          │
  │   → If autoPoolEnabled: deploys NAVAwareHook (+ LaunchFeeHook)    │
  │     → Calls PoolManager.initialize() to create share/base pool    │
  │     → Share token is immediately tradeable on Uniswap V4          │
  │   → Registers vault in on-chain registry                          │
  │   → Emits VaultCreated(vault, hook, agentId, baseAsset, sharePool)│
  └────────┬───────────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Response ───────────────────────────────────────────────────────┐
  │ Return: vaultAddress, hookAddress, sharePoolAddress, txHash, url   │
  └────────────────────────────────────────────────────────────────────┘
```

## Data Flow: CCA Collective Bid (Deferred Post-v1)

```
Agent calls: submit_cca_bid(vaultAddress: "0x...", auctionAddress: "0x...", assets: "50000000000", maxPrice: "0.05")
         │
         ▼
  ┌─── CCA Bid Lifecycle ──────────────────────────────────────────────┐
  │                                                                     │
  │  Phase 1: CAPITAL FORMATION                                        │
  │    Agents deposit USDC into vault. Idle capital in vault.          │
  │                                                                     │
  │  Phase 2: BID SUBMISSION                                           │
  │    Manager evaluates auction → calls CCABidAdapter.submitBid()     │
  │    Vault address = bid owner. Capital committed at maxPrice.        │
  │                                                                     │
  │  Phase 3: ACTIVE AUCTION MANAGEMENT                                │
  │    Bids processed block-by-block at uniform clearing prices.       │
  │    If outbid (clearing > maxPrice), call exitBid() to reclaim.    │
  │                                                                     │
  │  Phase 4: POST-GRADUATION SETTLEMENT                               │
  │    Auction graduates → claimTokens() after claim block.            │
  │    LiquidityLauncher migrates to V4 pool.                         │
  │                                                                     │
  │  Phase 5: LP POSITION MANAGEMENT                                   │
  │    Deploy claimed tokens + base currency into V4 pool.             │
  │    Or: hold tokens, sell tokens, compound into new auctions.       │
  │                                                                     │
  │  FAILURE MODE: Auction doesn't graduate → exitBid() reclaims all. │
  └────────────────────────────────────────────────────────────────────┘
```

## Data Flow: Deposit into Vault

```
Agent calls: vault_deposit(agentId: "42", amount: "10000", vaultAddress: "0x...")
         │
         ▼
  ┌─── Vault MCP Tool ──────────────────────────────────────────┐
  │ 1. Verify ERC-8004 identity: agentId 42 → agentWallet      │
  │ 2. Query reputation: getSummary(42) → score, tier           │
  │ 3. Check tier deposit limit: 10000 USDC within tier cap?    │
  │ 4. Encode deposit calldata: vault.deposit(42, 10000e6)      │
  └────────┬────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Safety Pipeline ─────────────────────────────────────────┐
  │ 1. Token allowlist: USDC allowed?                            │
  │ 2. Spending limit: within per-tx and daily limits?          │
  │ 3. Rate limit: not exceeding ops/window?                    │
  │ 4. Balance check: enough USDC + gas?                        │
  │ 5. Pre-flight simulation: eth_call deposit(42, 10000e6)     │
  │ 6. Nonce check: no duplicate pending tx                     │
  │                                                              │
  │ ANY check fails → return structured error, do not sign      │
  └────────┬────────────────────────────────────────────────────┘
           │ All checks pass
           ▼
  ┌─── On-Chain ────────────────────────────────────────────────┐
  │ AgentVaultCore.deposit(42, 10000e6)                         │
  │   → Verifies onlyAgent, hasReputation, withinTierLimit      │
  │   → Mints shares proportional to deposit                    │
  │   → Emits AgentDeposit(42, 10000e6, shares)                │
  └────────┬────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Response ────────────────────────────────────────────────┐
  │ Return: status, txHash, shares, vaultTotalAssets,           │
  │         safetyChecks { tier, reputationScore, ... }         │
  └─────────────────────────────────────────────────────────────┘
```

## Data Flow: TWAMM Rebalance (Large Vault Operations)

When a vault with significant TVL needs to rebalance, TWAMM splits the operation over time to minimize price impact and MEV extraction.

```
Agent calls: vault_rebalance(agentId: "42", vaultAddress: "0x...",
             strategy: {..., useTWAMM: true, twammDuration: 14400})
         │
         ▼
  ┌─── Vault MCP Tool ──────────────────────────────────────────┐
  │ 1. Verify ERC-8004 identity: agentId 42                      │
  │ 2. StrategyEngine.recommendTWAMM() confirms TWAMM advisable  │
  │    (rebalance size > 1% of pool TVL)                         │
  │ 3. Encode TWAMM order submission via Universal Router         │
  └────────┬────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── On-Chain ────────────────────────────────────────────────┐
  │ Universal Router submits TWAMM order:                        │
  │   → Amount split over 14400 seconds (4 hours)               │
  │   → Executes as first pool action in each block              │
  │   → Multiple vaults rebalancing in opposite directions net   │
  │     their flows, minimizing aggregate market impact           │
  │   → Emits TWAMMOrderSubmitted(orderId, amount, duration)     │
  └────────┬────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Response ────────────────────────────────────────────────┐
  │ Return: twammOrderId, estimatedCompletion, txHash,           │
  │         estimatedSlippageBps, monitorUrl                     │
  └─────────────────────────────────────────────────────────────┘
```

## Data Flow: Intent-Based Rebalance Auction (D-064)

For large rebalances where execution quality matters, the vault can use a competitive solver auction instead of (or before falling back to) TWAMM. Permissionless solvers compete to provide the best execution.

```
Manager posts: vault_rebalance(agentId: "42", vaultAddress: "0x...",
               strategy: {..., useAuction: true, maxSlippageBps: 30})
         │
         ▼
  ┌─── Phase 1: INTENT POSTING ────────────────────────────────┐
  │ 1. Verify ERC-8004 identity and Curator/Allocator role      │
  │ 2. StrategyEngine validates: rebalance size > 1% of TVL     │
  │    (smaller rebalances use direct execution, not auction)    │
  │ 3. Post on-chain intent:                                     │
  │    - target position ranges / weights                        │
  │    - maxSlippageBps (default 30)                             │
  │    - allowed routes (optional whitelist)                     │
  │    - deadline (current block + auctionDurationBlocks)        │
  │    - TWAMM fallback instruction (if no valid winner)         │
  │ 4. Emits RebalanceIntentPosted(intentId, vault, params)     │
  └────────┬────────────────────────────────────────────────────┘
           │ Auction window open
           ▼
  ┌─── Phase 2: SOLVER BIDDING (commit-reveal) ─────────────────┐
  │ Permissionless solvers submit sealed bids:                    │
  │   - commit: keccak256(executionCalldata, expectedOutputs,    │
  │             solverFee, salt)                                  │
  │   - bond: anti-grief deposit (covers gas + price impact)     │
  │                                                               │
  │ After auctionDurationBlocks, reveal window opens:             │
  │   - solvers reveal: executionCalldata, expectedOutputs,      │
  │     solverFee, salt                                          │
  │   - invalid reveals → bond slashed                           │
  └────────┬────────────────────────────────────────────────────┘
           │ Reveal complete
           ▼
  ┌─── Phase 3: WINNER SELECTION + EXECUTION ────────────────────┐
  │ Module picks best valid bid:                                  │
  │   - max surplus to vault (min cost subject to constraints)   │
  │   - validates: calldata targets on whitelist, min-out met,   │
  │     no delegatecall, within maxSlippageBps                   │
  │ Winner's calldata executed atomically:                        │
  │   - surplus credited to vault assets                          │
  │   - solver receives fee + bond return                        │
  │   - Emits RebalanceExecuted(intentId, solver, surplus)       │
  │                                                               │
  │ NO VALID WINNER → fallback:                                  │
  │   - If TWAMM instruction set: submit TWAMM order             │
  │   - Else: reschedule intent with extended deadline            │
  └────────┬────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Response ────────────────────────────────────────────────┐
  │ Return: intentId, winnerAddress, surplusBps, txHash,         │
  │         fallbackUsed, executionQualityScore                  │
  └─────────────────────────────────────────────────────────────┘
```

## Data Flow: am-AMM Vault Management Auction

When a vault has `strategyAuctionEnabled=true`, management rights are sold via a continuous Harberger lease auction. Agents bid for the Curator role by offering rent per block to depositors.

```
Agent calls: vault_bid_management(vaultAddress: "0x...", agentId: "42", rentPerBlock: "1000000")
         │
         ▼
  ┌─── Phase 1: BID SUBMISSION ──────────────────────────────────┐
  │ 1. Verify ERC-8004 identity: agentId 42 is registered        │
  │ 2. Check reputation: score >= minManagerReputation (50)       │
  │ 3. Validate bid: rentPerBlock > currentRent * 1.05 (5% min)  │
  │ 4. Calculate required collateral: rentPerBlock * K blocks     │
  │ 5. Transfer collateral from bidder to auction module          │
  │ 6. Schedule manager transition at block + rentLookAheadBlocks │
  └────────┬─────────────────────────────────────────────────────┘
           │ Bid accepted, waiting for transition block
           ▼
  ┌─── Phase 2: TRANSITION ──────────────────────────────────────┐
  │ At transition block:                                          │
  │   → Previous manager's authority revoked                     │
  │   → New manager granted Curator role                          │
  │   → Rent begins accruing per block to depositors             │
  │   → Manager can now: set strategy, adjust fees, appoint       │
  │     Allocator agents, configure adapter parameters            │
  │   → Emits ManagerBid(agentId, manager, rentPerBlock)         │
  └────────┬─────────────────────────────────────────────────────┘
           │ Manager active
           ▼
  ┌─── Phase 3: ACTIVE MANAGEMENT ───────────────────────────────┐
  │ Manager operates within Curator bounds:                       │
  │   → Rebalance LP positions (delegates to vault-manager)       │
  │   → Configure lending venue allocation                        │
  │   → Set dynamic fee parameters                                │
  │   → Rent accrues continuously; depositors call                │
  │     vault_withdraw_rent() to collect                          │
  │   → Must topup collateral before exhaustion                   │
  └────────┬─────────────────────────────────────────────────────┘
           │ If collateral exhausted OR outbid
           ▼
  ┌─── Phase 4: EVICTION or OUTBID ──────────────────────────────┐
  │ Collateral exhausted:                                         │
  │   → Anyone calls vault_evict_manager()                        │
  │   → Manager authority revoked, vault enters "unmanaged" mode  │
  │   → Vault continues operating with last strategy (read-only)  │
  │                                                               │
  │ Outbid:                                                       │
  │   → New bid arrives exceeding current rent by minBidIncrement │
  │   → Transition scheduled at block + K                         │
  │   → Previous manager has K blocks to wind down                │
  │   → Remaining collateral returned to previous manager         │
  └──────────────────────────────────────────────────────────────┘
```

***

## L2-Specific Parameter Context

All vault operations on Base use L2-calibrated parameters. The key differences from Ethereum mainnet (per arXiv:2406.02172, arXiv:2506.14768):

* **LVR is \~5x lower** than naive estimates predict — LP strategies are structurally more viable
* **Dynamic fees use wider thresholds** (σ\_low=20%, σ\_high=80% vs 15%/60% on mainnet)
* **am-AMM lookahead is 36,000 blocks** (equivalent time horizon to 7,200 on mainnet)
* **Gas costs are 50-500x cheaper** — enabling frequent rebalancing and complex multi-step operations

See [06-contracts.md](/docs/gotts-vaults/vault/06-contracts.md) Section 10.18 for the full L2 calibration table with all parameter values.

***

## EulerSwap-Style JIT Borrowing (Advanced Rehypothecation)

The baseline `RehypothecationAdapter` ([06-contracts.md](/docs/gotts-vaults/vault/06-contracts.md) Section 10.9) deploys idle out-of-range liquidity to lending venues via a wrap-and-donate pattern — capital sits idle in the pool until it moves out of range, then routes to lending. EulerSwap introduces a more aggressive architecture: **all vault capital lives in lending vaults at all times**, with JIT (just-in-time) borrowing providing liquidity only when swaps actually need it.

**How it works**: Instead of depositing tokens into a V4 pool and routing idle tokens to lending, the vault deposits 100% of capital into lending protocols (Morpho, Aave, Seamless). When a swap arrives that requires output tokens:

1. The VaultHook's `beforeSwap` callback detects the incoming swap amount and direction
2. The hook flash-borrows the required output tokens from the lending venue (using the vault's deposited collateral)
3. The swap executes against the borrowed liquidity at the hook-determined price
4. The swap input tokens repay the flash borrow; any surplus accrues as vault yield
5. Net effect: the vault earns lending yield on 100% of capital *and* swap fees on every trade

**Effective liquidity depth**: Because the vault can borrow against its full collateral position, the effective liquidity available for any single swap is up to **50x** the vault's own capital (depending on the lending protocol's LTV ratio). A vault with $1M in deposits could provide $50M of effective swap liquidity — matching or exceeding the depth of far larger traditional LP positions.

**Delta-neutral hedging**: The borrowing mechanism enables on-chain delta-neutral strategies. When a vault takes on directional exposure from a swap, it can simultaneously borrow the opposite asset to hedge — maintaining a market-neutral position while still earning swap fees. This connects to the Lipton-Lucic-Sepp unified IL hedging framework (Digital Finance vol. 7, 2025) but implements it natively via lending rather than requiring external options markets.

**Complementarity with existing rehypothecation**: The two patterns serve different vault strategies:

| Pattern                         | Capital in Pool       | Capital in Lending       | Best For                                         |
| ------------------------------- | --------------------- | ------------------------ | ------------------------------------------------ |
| Wrap-and-donate (current)       | Active range: yes     | Out-of-range: yes        | Conservative vaults, simpler implementation      |
| JIT borrowing (EulerSwap-style) | Never                 | 100% always              | Aggressive yield optimization, high-depth vaults |
| Hybrid                          | Active range: partial | Remainder + out-of-range | Balanced risk/yield tradeoff                     |

The vault-strategist agent selects the pattern based on the vault's risk profile, lending market conditions, and target APY. JIT borrowing is gated behind Verified+ tier (reputation 50+) due to the additional smart contract risk from flash borrow interactions.

***

## Policy Cage Architecture for Self-Learning Vaults (D-053)

AI agents managing vault strategies operate within hard on-chain boundaries defined by a `PolicyCage` contract. The cage defines what the agent *can* do; the agent optimizes freely within those constraints.

### Yearn V3 Role Mapping

The policy cage builds on Yearn V3's proven role system, adapted for agent-managed vaults:

| Role                   | Who Holds It                     | On-Chain Constraints                                                   | Maps To                         |
| ---------------------- | -------------------------------- | ---------------------------------------------------------------------- | ------------------------------- |
| `ADD_STRATEGY_MANAGER` | Curator (am-AMM winner, D-012)   | Can add/remove strategy adapters from the approved list                | Yearn V3 `ADD_STRATEGY_MANAGER` |
| `DEBT_MANAGER`         | AI agent (Allocator role, D-020) | `max_debt` cap per adapter, `deposit_limit`, `minimum_total_idle`      | Yearn V3 `DEBT_MANAGER`         |
| `REPORTING_MANAGER`    | AI agent or off-chain bot        | Reports profit/loss per adapter; triggers linear profit unlock (D-018) | Yearn V3 `REPORTING_MANAGER`    |
| `EMERGENCY_MANAGER`    | Multisig (Sentinel role, D-020)  | Can pause all operations; never delegated to an AI agent               | Yearn V3 `EMERGENCY_MANAGER`    |

### Hard Boundary Parameters

```
PolicyCage {
  approvedAssets:     address[]    // Only these tokens can be held
  approvedAdapters:   address[]    // Only these strategy adapters can receive capital
  maxPositionBps:     uint16       // Max % of AUM in any single adapter (default 4000 = 40%)
  maxDrawdownBps:     uint16       // Triggers circuit breaker if exceeded (links to D-026)
  maxRebalanceFreq:   uint32       // Min seconds between rebalances (prevents churn)
  maxDebtPerAdapter:  uint256      // Hard cap per adapter (Yearn `max_debt` pattern)
  minIdleBps:         uint16       // Minimum idle reserve (default 1000 = 10%)
}
```

The agent's `DEBT_MANAGER` role can allocate capital freely across `approvedAdapters` up to `maxDebtPerAdapter`, but cannot add new adapters, change the approved asset list, or exceed the position concentration limit. These boundaries are enforced by the smart contract — no prompt injection or model compromise can bypass them.

### Debt Allocator with APR Oracles

The `DebtAllocator` component (off-chain, part of the vault-strategist agent) reads real-time APR from each adapter via on-chain oracle queries and recommends reallocation. The AI agent executes recommended allocations within policy cage constraints. Strategy rotation is automated when APR differences exceed a configurable threshold.

### Risk-Adjusted Strategy Scoring Framework (D-063)

The Debt Allocator's APR-based rotation is necessary but insufficient — "optimize APY" behavior drifts toward brittle strategies unless systematically penalized for risk. The scoring framework formalizes allocation decisions as a risk-governed optimization.

**Canonical scoring function**:

```
score(adapter) = E[yield] - gamma * RiskPenalty(LVR, drawdown, liquidity, oracle, concentration)
```

Where `gamma` is set per vault template rather than per-user, simplifying UX:

| Template     | gamma | Risk Posture                                                            |
| ------------ | ----- | ----------------------------------------------------------------------- |
| Conservative | 2.0   | Penalizes risk heavily; favors stable, liquid, well-oracular strategies |
| Balanced     | 1.0   | Equal weight to yield and risk                                          |
| Aggressive   | 0.5   | Tolerates higher risk for yield; suitable for Sovereign-tier agents     |

**Risk penalty components** (each normalized to bps):

* **LVR penalty**: Adverse selection cost using the LVR-theta framework (D-029) and fee-implied volatility (D-030) as inputs
* **Drawdown penalty**: Historical max drawdown over trailing window, weighted by frequency
* **Liquidity penalty**: Exit latency class (instant / hours / days) and available depth vs position size
* **Oracle penalty**: Feed freshness, source diversity, and staleness history
* **Concentration penalty**: Correlation with other adapter exposures in the same vault

**Standardized adapter risk reporting**: Each adapter exposes two on-chain view functions consumed by the RiskEngine (D-056):

```
StrategyRiskProfile (static, set at adapter registration):
  exitLatencyClass:    enum { Instant, Hours, Days }
  oracleDependency:    enum { None, Single, Multi }
  maxLeverage:         uint16
  forceExitSupported:  bool
  auditTimestamp:      uint40

StrategyRiskState (dynamic, updated per report cycle):
  currentUtilization:  uint16   // bps of adapter capacity used
  realizedDrawdown:    uint16   // bps, trailing 30d
  oracleFreshFlag:     bool     // true if all required feeds are fresh
  currentLeverage:     uint16   // actual leverage ratio (bps, 10000 = 1x)
```

**Allocation trace artifacts**: Every strategy change must publish an `AllocationTrace`:

* Inputs: current adapter states, scoring function version, risk model hash
* Outputs: recommended allocation weights, score per adapter
* On-chain: `keccak256(trace)` stored in ParameterDecisionTable (D-059)
* Off-chain: full trace blob stored on IPFS, referenced by the on-chain hash

This creates an auditable decision trail. Vault depositors, rating agencies (Credora, Cred Protocol), and composing protocols can independently verify that allocation decisions followed a consistent, risk-aware methodology.

### Competing Strategy Models (Numerai-Inspired, Deferred)

A future extension accepts external strategy model submissions from data scientists. Each model stakes protocol tokens on its performance. Capital is allocated proportionally to stake-weighted performance scores. Models that underperform have their stake slashed; outperformers receive increased allocation. This creates a decentralized, crowd-sourced approach to vault management beyond single-agent decision-making.

***

## ERC-7715: Scoped Wallet Permissions for Agent Operations

ERC-7715 (`wallet_grantPermissions`) standardizes how applications request scoped, time-limited permissions from wallets. For vault operations, this eliminates the pattern of repeated approval prompts that fragments the agent experience.

**How it works**: An agent (or the vault's onboarding flow) calls `wallet_grantPermissions` on the depositor's wallet, requesting a structured permission object:

```json
{
  "permissions": [
    {
      "type": "contract-call",
      "data": {
        "address": "0x...AgentVaultCore",
        "functions": ["deposit(uint256,uint256)", "withdraw(uint256,address)"],
        "constraints": {
          "maxValuePerCall": "1000000000",
          "maxCallsPerDay": 5,
          "validUntil": 1712345678
        }
      }
    }
  ],
  "expiry": 2592000
}
```

The depositor sees a human-readable summary: *"Allow deposits up to 1,000 USDC per call, max 5 calls per day, for 30 days into vault 0x..."* — approves once, and the agent operates autonomously within those bounds for the session lifetime.

**Production readiness**: ERC-7715 is implemented in MetaMask's Delegation Toolkit and supported by the ERC-7710 delegation framework. It integrates with ERC-7579 Smart Sessions — the permission grant creates a session key with the specified constraints, enforced by the wallet's validation module.

**Vault integration patterns**:

| Pattern          | Permission Scope                     | Duration          | Use Case                                             |
| ---------------- | ------------------------------------ | ----------------- | ---------------------------------------------------- |
| DCA deposits     | `deposit()` with daily cap           | 30-90 days        | Automated dollar-cost averaging into vault           |
| Auto-rebalance   | `rebalance()` on specific vault      | 7 days, renewable | Vault manager automated strategy execution           |
| Yield harvesting | `collectFees()` + `deposit()`        | 30 days           | Compound earned fees back into vault                 |
| Emergency exit   | `withdraw()` with trigger conditions | Indefinite        | Guardian agent can withdraw if circuit breaker fires |

**Relationship to existing permission layers**: ERC-7715 operates at the wallet layer (Layer 1 in the safety architecture), complementing rather than replacing the on-chain permission enforcement:

* **ERC-7715** (wallet layer): Controls *which transactions the wallet will sign* — the depositor's approval boundary
* **ERC-7579 Smart Sessions** (account layer): Controls *which transactions the smart account will execute* — the account's policy boundary
* **Vault tier limits** (contract layer): Controls *which operations the vault will accept* — the protocol's trust boundary

All three layers must independently approve a transaction. ERC-7715 is the outermost boundary — it ensures the depositor's wallet never signs a transaction the depositor hasn't pre-approved, even if the agent, account, and vault would all accept it.

***

## Data Flow: Async Redemption (ERC-7540 Vaults)

When a vault has `asyncRequired == true` (CCA Hunter, Full Stack, or any vault with illiquid positions), synchronous `redeem()` reverts. Depositors must use the ERC-7540 request lifecycle.

```
Agent calls: vault_withdraw(agentId: "42", shares: "5000", vaultAddress: "0x...")
         │
         ▼
  ┌─── Vault MCP Tool ──────────────────────────────────────────┐
  │ 1. Verify ERC-8004 identity: agentId 42                      │
  │ 2. Check vault.asyncRequired:                                │
  │    FALSE → standard synchronous withdraw flow                │
  │    TRUE  → route to ERC-7540 requestRedeem() below           │
  │ 3. Encode requestRedeem(shares, controller, owner) calldata  │
  └────────┬────────────────────────────────────────────────────┘
           │ asyncRequired == true
           ▼
  ┌─── Phase 1: REQUEST ──────────────────────────────────────────┐
  │ AgentVaultCore.requestRedeem(5000, agentWallet, agentWallet)  │
  │   → Shares locked in vault (not transferable while pending)   │
  │   → requestId minted as ERC-721 receipt NFT (D-068)           │
  │   → Emits RedeemRequested(requestId, agentId, 5000)          │
  │ Return: requestId, estimatedWaitTime, queuePosition           │
  └────────┬─────────────────────────────────────────────────────┘
           │ Vault settles underlying positions
           ▼
  ┌─── Phase 2: SETTLEMENT (vault-side, async) ───────────────────┐
  │ Vault unwinds illiquid positions to free capital:              │
  │   → CCA positions: wait for auction conclusion or exit bid    │
  │   → Adapter positions: deallocate from lending venues          │
  │   → LP positions: remove liquidity from V4 pools              │
  │ Once sufficient assets are available:                          │
  │   → Mark request as Claimable                                  │
  │   → Emits RedeemClaimable(requestId, assets)                  │
  └────────┬─────────────────────────────────────────────────────┘
           │ Request now Claimable
           ▼
  ┌─── Phase 3: CLAIM ────────────────────────────────────────────┐
  │ Agent calls claimRedeem(requestId, receiver)                   │
  │   → Assets transferred to receiver                             │
  │   → Receipt NFT burned                                         │
  │   → Emits RedeemClaimed(requestId, assets)                    │
  │                                                                │
  │ ALTERNATIVE: Agent can sell the receipt NFT on secondary       │
  │ market for instant (discounted) exit while request is pending  │
  └────────────────────────────────────────────────────────────────┘
```

***

## Data Flow: Share Pool Trading (Alternative Exit via Uniswap)

Depositors can sell vault shares directly on Uniswap instead of calling vault `withdraw()`. The NAVAwareHook ensures fair pricing at net asset value.

```
Agent wants to exit vault position instantly
         │
         ▼
  ┌─── Option A: Traditional Withdrawal ────────────────────────┐
  │ vault_withdraw(agentId, shares) → wait for processing       │
  └─────────────────────────────────────────────────────────────┘
  ┌─── Option B: Sell on Uniswap (instant) ─────────────────────┐
  │ 1. Agent calls get_share_pool(vaultAddress)                  │
  │    → Returns: sharePoolAddress, currentNAV, poolPrice        │
  │ 2. Agent calls execute_swap(tokenIn: shareToken,             │
  │    tokenOut: USDC, amount: shares)                           │
  │    → Routed through NAVAwareHook                             │
  │    → Priced at NAV ± spread (default 50 bps)                 │
  │    → Asymmetric fee: 25-50 bps for selling                   │
  │ 3. Agent receives USDC instantly — no withdrawal queue       │
  └─────────────────────────────────────────────────────────────┘
```

## Data Flow: Time-Delayed Vault Operation (Proxy-Enhanced)

When an agent uses a time-delayed proxy (recommended for vault managers and >$10K AUM), the flow gains two additional phases: announcement and monitoring.

```
Agent calls: vault_rebalance(agentId: "42", vaultAddress: "0x...", strategy: {...})
         │
         ▼
  ┌─── Vault MCP Tool ──────────────────────────────────────────┐
  │ 1. Verify ERC-8004 identity: agentId 42 → agentWallet      │
  │ 2. Encode rebalance calldata for the vault contract         │
  │ 3. Check: is proxy-enhanced mode enabled?                   │
  │    YES → route through proxy.announce()                     │
  │    NO  → route directly to safety pipeline (standard flow)  │
  └────────┬────────────────────────────────────────────────────┘
           │ Proxy-enhanced mode
           ▼
  ┌─── Phase 1: ANNOUNCE ────────────────────────────────────────┐
  │ Agent wallet signs: proxy.announce(vaultAddr, 0, rebalData)  │
  │   → TEE policy: only announce() on proxy address allowed     │
  │   → Proxy stores announcement on-chain                       │
  │   → Emits TransactionAnnounced(txId, agent, target, ...)     │
  │   → Delay timer starts (e.g., 1 hour for "Elevated" tier)   │
  └────────┬─────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Phase 2: MONITOR (during delay window) ──────────────────┐
  │ Monitoring bot detects TransactionAnnounced event:            │
  │   → Primary: viem watchContractEvent (multi-provider)        │
  │   → Secondary: Tenderly Web3 Action (managed backup)         │
  │                                                               │
  │ Evaluates announcement:                                       │
  │   → Target 0xVault on whitelist? YES                         │
  │   → Selector rebalance() on whitelist? YES                   │
  │   → Value within normal range? YES                           │
  │   → Decision: ALLOW                                          │
  │   → Alert: "Approved tx #123: rebalance on vault 0x..."      │
  │                                                               │
  │ If suspicious:                                                │
  │   → Decision: CANCEL                                         │
  │   → Bot calls proxy.cancel(txId)                             │
  │   → Alert: "CANCELLED tx #123: unknown target 0xAttacker"    │
  └────────┬─────────────────────────────────────────────────────┘
           │ Delay elapsed, not cancelled
           ▼
  ┌─── Phase 3: EXECUTE ─────────────────────────────────────────┐
  │ Any executor calls proxy.execute(txId) — permissionless      │
  │ (D-061, see 06-contracts.md Section 10.1b).                  │
  │ vault-executor agent is the canonical role, but any address   │
  │ can execute. Executor receives gas refund + small tip.        │
  │   → Proxy verifies: delay elapsed, not expired, not cancelled│
  │   → Proxy forwards call to vault: vault.rebalance(params)    │
  │   → Vault's on-chain guards verify agent + reputation + tier │
  │   → Rebalance executes                                       │
  │   → Emits TransactionExecuted(txId, success)                 │
  └────────┬─────────────────────────────────────────────────────┘
           │
           ▼
  ┌─── Response ──────────────────────────────────────────────────┐
  │ Return: status, txHash, announcementId, delayUsed,            │
  │         monitoringDecision, executionResult                    │
  └───────────────────────────────────────────────────────────────┘
```

***

## Vault Rebalancing via Uniswap API

When `GOTTS_UNISWAP_API_KEY` is configured, vault rebalancing and LP adjustments use the Uniswap Trading API as the primary execution layer. When not configured, rebalancing uses direct SDK calls (smart-order-router + contract interactions).

```
Rebalance Trigger (price deviation, schedule, or manual)
       │
       ▼
┌─── StrategyEngine ────────────────────────────────────────┐
│ 1. Calculate target allocations from current positions     │
│ 2. Compute delta (which swaps and LP adjustments needed)   │
└────────┬──────────────────────────────────────────────────┘
         │
         ▼
┌─── For Each Required Swap ────────────────────────────────┐
│ POST /check_approval → approval tx if needed               │
│ POST /quote → best route + permitData                      │
│ Safety middleware validation (all 7+1 checks)              │
│ POST /swap (classic) or POST /order (UniswapX gasless)     │
└────────┬──────────────────────────────────────────────────┘
         │
         ▼
┌─── For Each LP Adjustment ────────────────────────────────┐
│ POST /lp/decrease → remove from old range (if rebalancing) │
│ POST /lp/claim → collect accrued fees                      │
│ POST /lp/create or /lp/increase → new/adjusted position    │
└────────┬──────────────────────────────────────────────────┘
         │
         ▼
┌─── Update Vault Accounting ───────────────────────────────┐
│ On-chain: vault.report() updates share price               │
│ Off-chain: emit rebalance event for monitoring             │
└───────────────────────────────────────────────────────────┘
```

The Uniswap Trading API provides:

* **Optimized routing**: Best prices across V2/V3/V4/UniswapX with automatic protocol selection
* **MEV protection**: PRIORITY routing on Base for gasless, MEV-protected execution (min \~1000 USDC)
* **Batch Permit2**: Single signature for multi-token LP operations via `/lp/approve`
* **V3→V4 migration**: Atomic position migration via `/lp/migrate`
* **Reward claiming**: LP incentive rewards via `/lp/claim_rewards`

***

## State Machine Diagrams

### Vault Lifecycle States

```mermaid
stateDiagram-v2
    [*] --> Creating: factory.createVault()
    Creating --> Active: deployment + pool init succeeds
    Creating --> Failed: deployment reverts

    Active --> PausedCreator: creator calls pause()
    Active --> PausedBreaker: circuit breaker triggers (D-026)
    Active --> EmergencyWithdrawal: NAV drawdown > maxDrawdownBps

    PausedCreator --> Active: creator calls unpause()
    PausedBreaker --> Active: conditions normalize + dampening resolves
    PausedBreaker --> EmergencyWithdrawal: conditions worsen

    EmergencyWithdrawal --> Deprecated: all shares redeemed
    EmergencyWithdrawal --> Active: owner + curator restore (longTimelock)

    Failed --> [*]
    Deprecated --> [*]
```

**Key transitions:**

* `Active -> PausedBreaker`: Automatic, triggered by RiskEngine when drawdown or withdrawal velocity exceeds thresholds. Continuous dampening (D-043) means this is gradual, not binary.
* `EmergencyWithdrawal`: All agents can withdraw at NAV; no new deposits accepted; strategy execution halted.
* `Deprecated`: Terminal state after all shares are burned. Vault address remains in factory registry for historical queries.

### Proxy Announcement Lifecycle

```mermaid
stateDiagram-v2
    [*] --> Announced: proxy.announce(target, value, data, riskTier)
    Announced --> Monitoring: MonitorBot detects event
    Monitoring --> Cancelled: CancelAuthority vetoes
    Monitoring --> Executable: delay elapsed + not cancelled
    Executable --> Executed: proxy.execute(announcementId)
    Executable --> Expired: deadline passed without execution

    Cancelled --> [*]
    Executed --> [*]
    Expired --> [*]
```

### Withdrawal Queue States (ERC-7540 Extension)

```mermaid
stateDiagram-v2
    [*] --> Instant: amount <= idle capital
    Instant --> Completed: withdraw() succeeds

    [*] --> Requested: amount > idle capital
    Requested --> Queued: requestRedeem() called
    Queued --> Claimable: sufficient liquidity freed
    Claimable --> Claimed: claimRedeem() called

    Queued --> ForceExited: agent calls forceDeallocate()

    Completed --> [*]
    Claimed --> [*]
    ForceExited --> [*]
```

***

## Sequence Diagrams

### Vault Creation Flow

```mermaid
sequenceDiagram
    participant Agent
    participant Factory as AgentVaultFactory
    participant Identity as IdentityRegistryAdapter
    participant Vault as AgentVaultCore
    participant Hook as VaultHook
    participant PM as V4 PoolManager

    Agent->>Factory: createVault(config)
    Factory->>Identity: isValidAgent(creatorAgentId)
    Identity-->>Factory: true
    Factory->>Factory: validate VaultConfig
    Factory->>Vault: deploy via CREATE2 (EIP-1167 clone)
    Factory->>Hook: deploy VaultHook (if hookEnabled)
    Factory->>PM: initialize(poolKey) share pool
    Factory->>Factory: register in vault registry
    Factory-->>Agent: (vaultAddress, hookAddress, poolId)
```

### Deposit Flow with Identity Gating

```mermaid
sequenceDiagram
    participant Agent
    participant MCP as vault_deposit tool
    participant Identity as IdentityRegistryAdapter
    participant Vault as AgentVaultCore
    participant Token as ERC-20 Base Asset

    Agent->>MCP: vault_deposit(vaultAddress, agentId, assets)
    MCP->>Identity: isValidAgent(agentId)
    Identity-->>MCP: true
    MCP->>Identity: getEffectiveReputation(agentId)
    Identity-->>MCP: reputation score
    MCP->>Vault: tierConfig(tier) - check deposit cap
    MCP->>Token: check allowance, approve via Permit2 if needed
    MCP->>Vault: deposit(assets, agent)
    Vault->>Vault: mint shares, update agentShares
    Vault-->>MCP: shares minted
    MCP-->>Agent: result with shares received
```

### Proxy-Mediated Strategy Execution

```mermaid
sequenceDiagram
    participant Agent
    participant Proxy as AgentProxy
    participant Monitor as MonitorBot
    participant Cancel as CancelAuthority
    participant Vault as AgentVaultCore

    Agent->>Proxy: announce(vault, rebalance, data, riskTier)
    Proxy-->>Agent: announcementId, executionTime
    Proxy->>Monitor: TransactionAnnounced event
    Monitor->>Monitor: evaluate(target, selector, value)
    alt suspicious transaction
        Monitor->>Cancel: alert with analysis
        Cancel->>Proxy: cancel(announcementId)
        Proxy-->>Agent: TransactionCancelled
    else approved transaction
        Monitor-->>Monitor: log approval
        Note over Proxy: delay elapses
        Agent->>Proxy: execute(announcementId)
        Proxy->>Vault: rebalance(params)
        Vault-->>Proxy: result
        Proxy-->>Agent: TransactionExecuted
    end
```
