peapod
PEAPOD ENGINEERING

Agentic vault redesign

Design proposal, September 18, 2026. This describes a target architecture for turning Canopy into a strategy-vault product ("Yearn meets trading terminals"). Nothing here is implemented; the current app remains a paper preview with live orders disabled. Contract, fee and reputation details are proposals for review, not commitments.

Engineering workspaceImplementation notes and historical research.

Why redesign

Canopy today is three loosely joined surfaces: a paper Grid Studio whose bots live in browser storage, a discover UI with wallet leaderboards and a copy-trade wizard that posts nowhere, and a deployed but disabled execution backend built on Privy delegated signers and per-swap policies. The roadmap research found that no onchain terminal offers grid or DCA automation, that copy trading is widely resented as exit liquidity, that "points with no token" destroyed trust at BullX, and that tokenized-equity trading on Robinhood Chain has no product built around its after-hours structure.

The redesign centres the product on one object: a vault that runs a user-built strategy under an enforced mandate. A manager runs it privately, may open it to invitees or the public for investment, and proves a track record through attestations without disclosing the strategy or its trades. Everything already built is reused: the execution backend becomes the policy engine and keeper, the lake becomes the statement publisher, Grid Studio becomes the strategy builder, and the discover UI becomes the vault board.

Product model

NounDefinitionWhat it replaces
StrategyA versioned, content-addressed spec: type (grid, escape, bracket, basket, agent), parameters, market scope, session calendar, risk limits, fee terms. Stored encrypted; only its hash is public.Saved Grid Studio bot
VaultAn onchain account holding capital and a mandate (strategy hash plus hard limits). One strategy version at a time. Visibility is private, invite or public.Nothing; bots are paper
ManagerThe wallet that owns a vault's strategy and mandate and may rotate strategy versions within the mandate.Implicit user
InvestorA wallet holding vault shares. The manager is always the first investor; a minimum manager share is enforced onchain.Copy-trade follower
AgentThe offchain process that turns a strategy into proposals: deterministic engines or an LLM agent with tools. Both pass the same policy gate.Browser replay
KeeperExecutes authorized actions against the vault. Canopy-operated first, permissionless later.SQS worker
Track recordA signed, periodic statement of vault NAV, returns, drawdown, share count and age derived from onchain events, plus optional wallet-proof attestations for history that predates the vault.Matched-PnL leaderboard
AttestationA signed claim binding an identity (X handle, other wallet, ENS) or a metric to a manager, verifiable without revealing trades.None

Two ownership models share one mandate and keeper interface:

  • Pooled vault. ERC-4626-style shares over USDG. Holdings are valued through Chainlink feeds, which every Stock Token has. This is what "invest in my strategy" means and it needs new contracts.
  • Mirror vault. An isolated account that executes the same strategy spec in the follower's own capital. No shares, no commingling, no share pricing. This is the current protocol recommendation and ships first on existing Privy rails.

Information architecture

Navigation collapses to five areas. Existing pages map onto them.

/            Landing: what vaults are, public vault board, evidence disclaimers
/explore     Vault board, managers, markets, assets, observed wallets
/build       Strategy builder: type tabs, mandate panel, backtest, policy preview, deploy
/vaults      My vaults (manager) and my investments (investor); /vaults/:id detail
/me          Identity, attestations, reputation, XP and quests, settings, appearance

What each viewer sees on a vault page:

ElementManagerInvestor or inviteePublic
Strategy spec, parameters, live rungs, pending actionsFullHidden; hash, type and market scope onlyHidden
Mandate limits: allowed markets, max position, turnover, drawdown stop, session calendar, feesFullFullFull
NAV, share price, returns, drawdown, share count, TVL, ageFullFullFull, from signed statements
Trade-level historyFullDelayed daily netflows per marketNone
Manager attestations and reputationFullFullFull
Invite link and allowlistFullOwn statusJoin request

The public sees outcomes and bounds, never methods. That is what preserves alpha while letting investors judge risk.

Builder changes keep the range-on-chart editor in web/grid/ and add strategy type tabs, a mandate panel where limits become explicit fields, a policy preview rendered from the backend policy output, and a Deploy flow that replaces Save bot. Saved paper bots become draft strategies. In web/discover/, the copy-trade wizard becomes Invest (pooled) or Mirror (isolated) and targets a vault rather than raw addresses. The wallet leaderboard stays but is relabelled as observed wallets; the vault board ranks verified vaults.

Protocol architecture

Five layers: agents propose, the policy engine authorizes, keepers submit, vault contracts enforce, the lake publishes statements.
Five layers: agents propose, the policy engine authorizes, keepers submit, vault contracts enforce, the lake publishes statements.
L4  Agents (offchain)        grid | escape | bracket | basket | LLM agent
                             emit Proposal {vaultId, strategyHash, actions[], evidence}
L3  Policy engine (offchain) validate against mandate, calendar, risk; simulate;
                             sign EIP-712 Authorization
L2  Keeper (offchain)        submit Authorization + route; reconcile receipts
L1  Vault contracts          VaultFactory, Vault, MandateRegistry, VenueAdapter,
                             FeeSplitter, AttestationRegistry
L0  Lake (offchain)          index vault events; publish signed statements

Vault contracts

Keep the audited surface small.

  • VaultFactory.create(kind, asset, mandateHash, visibility, managerMinShareBps, feeTerms) deploys a minimal-proxy vault and emits VaultCreated.
  • Pooled Vault is ERC-4626 over USDG with holdings valued by a Pricer that reads Chainlink feeds with staleness checks. Deposits and withdrawals are request-then-settle, following the deposits section of automation internals, so a strategy is never forced to liquidate mid-session. Visibility is enforced onchain: private allows only the manager to deposit, invite checks a Merkle allowlist root the manager can update, public allows anyone.
  • Mirror Vault has the same interface with a single depositor and no shares, so both kinds expose the same execute() and events.
  • execute(Authorization auth, bytes route) checks the EIP-712 signature of the policy signer registered for the vault, nonce, deadline, session window and mandate hash, then calls a whitelisted VenueAdapter. Post-call invariants follow the protocol research: outputs go to the vault only, minimum output holds after fees, cumulative inventory stays inside the mandate, keeper reward is bounded and paid only on verified progress. No arbitrary calls or delegatecalls.
  • MandateRegistry.setMandate(vault, mandateHash, limits) applies a timelock when limits loosen and none when they tighten. Limits are numbers the contract can check: allowed market set, max position per market, max daily turnover, session calendar id, expiry. Changing the strategy hash within unchanged limits is free.
  • FeeSplitter accrues a management fee on shares and a performance fee over a per-share high-water mark, crystallised on a fixed cadence, as modelled in LP strategy internals. Canopy takes a fixed cut of manager fees plus the disclosed execution fee per fill.
  • AttestationRegistry.attest(subject, schema, data, signature) stores hashes and issuer only. Use EAS-compatible schemas so third parties can verify.
  • Emergency paths: the manager can pause; investors can always request withdrawal; after expiry or seven days of keeper inactivity anyone can settle and unwind to USDG through the adapter at oracle-bounded prices.

Robinhood Chain's sequencer is centralised and its contracts are instantly upgradable, so a vault cannot claim stronger guarantees than the chain. The vault page states this.

Policy engine

Reuse backend/domain.mjs (plan(), policy()) and the worker's simulation, gas and router-bytecode checks. Add a mandate module that turns a strategy plus limits into the onchain limits struct and an EIP-712 authorization signer bound to one vault. Mirror vaults on the user's embedded wallet keep the existing Privy delegated-signer path and need no new contracts. Pooled vaults use a Canopy-held policy key in KMS that only signs authorizations that pass validation; that key never controls funds.

Agents

Deterministic engines port the browser replay into a server-side engine that emits proposals from live prices (grid), and add escape (breakout with trailing stop, the long-volatility complement to the grid), bracket (session event straddle) and launch basket engines.

LLM agents are a first-class strategy type from the first release. The strategy spec holds the system prompt, allowed skills and tools, model id, cadence and a token budget. Tools are read-only market data, the dislocation radar, vault state and the vault's own statements, plus one write tool, propose(actions[]). The agent never signs and never sees keys; every proposal passes the same policy gate, simulation and mandate limits as a deterministic engine. It runs in the existing Lambda and queue runtime with per-vault concurrency of one and a cost budget in the mandate. Prompt and skills are encrypted with the spec; investors only see the type and the mandate. The builder gets a prompt and skills editor and a dry-run mode that replays the agent against history and shows which proposals the policy gate would have rejected.

Reputation and attestation

Three attestation types, stored as hashes and issuer onchain with full payloads in Canopy's private store.

  1. Identity links. X account through OAuth on Canopy's server; Canopy issues a signed attestation binding the handle to the manager wallet, and the handle is public while the token is not. Other wallets and ENS through an EIP-712 challenge signed by that wallet stating it is operated by the same manager.
  2. Vault track record. The primary, trust-minimised proof. The lake computes daily NAV, return, drawdown, age, TVL and investor count from onchain events; Canopy signs a statement; anyone can recompute from the chain. No trade detail leaves the lake.
  3. Pre-vault wallet track record. The manager signs a challenge from a historical wallet. The lake computes that wallet's observed metrics with the existing wallet accounting, quality flags intact, and publishes only aggregates with confidence bands, never the trade list. The attestation carries the quality flags, because most published wallets have zero accountable trades and the UI must show that class honestly.

Reputation is a published function of verified vault age, drawdown-adjusted return, TVL retained, attestation count and manager skin in the game. There is no points programme; fee revenue share is the incentive.

Strategy privacy: the spec is encrypted at rest under the tenant KMS context already used for signer keys, and the onchain mandate carries only the strategy hash. Investors verify that the running strategy is the committed one by matching the hash in execute() events without reading it.

Backend and data changes

  • DynamoDB. New sort-key types under the tenant partition: STRATEGY#id#vN (encrypted spec, hash, type, status), VAULT#address (kind, visibility, mandate, fee terms, allowlist root), INVITE#code, ATTEST#id. One global index for public vault reads; tenant isolation through the existing leading-key policy for everything else.
  • API. backend/api.mjs gains strategy, vault, visibility, invite, mandate, deposit and withdrawal request, statement and attestation routes. Public reads are served under /api/vaults/* from immutable lake snapshots with a current pointer, the same pattern as /api/discover/*.
  • Lake. A scope indexing vault contract events (a cheap log filter on factory and vault addresses), a daily vault NAV table beside the selected-wallet NAV table, and a signed-statement publisher on the hourly publish job. Chainlink feed reads serve both NAV and the dislocation radar.
  • Frontend. New web/vaults/ and web/me/ apps in the vanilla pattern of web/grid/ and web/discover/. The wallet bundle gains sign-challenge and X-link panels beside the delegation panel.

Phasing

  1. Private mirror vaults on existing rails. Strategy spec and mandate model, server-side grid engine, LLM agent behind the policy gate, Privy delegated signer executing on the user's embedded wallet, the /vaults and /build areas, XP quests retargeted. No new contracts.
  2. Identity and track record. Attestations as offchain signed statements first, then onchain hashes; X link, wallet proof, manager profiles, vault board ranked by verified statements.
  3. Invite-only and public pooled vaults. Factory, ERC-4626 vault, mandate registry, fee splitter, Uniswap v3 and v4 adapter, asynchronous deposits and withdrawals, audit.
  4. More engines. Escape, bracket, launch basket.
  5. Permissionless keepers and EAS-compatible attestations.

Verification plan

Unit tests extend backend/domain.test.mjs for mandate to limits to policy, tests/model.test.mjs for engine parity with the browser replay, and add vault tests; Foundry tests cover vault invariants, allowlists, high-water-mark fee math and the unwind path. Browser tests extend the staging and discover suites for build, deploy and the three visibility views. Live verification runs a testnet mirror vault through the existing worker on staging only, then confirms that statements recompute from chain events.

Open questions

  • Manager minimum share and fee caps: proposed defaults are a 5% minimum manager share, management fee up to 2% per year and performance fee up to 20% over the high-water mark.
  • Whether invite allowlists should live onchain (Merkle root) or only in the API for phase 1 mirror vaults, where there is no shared capital to protect.
  • Which LLM providers and models the agent runtime supports, and how token budgets map to mandate fields.
  • Whether pre-vault wallet attestations should ever be shown without the partial-coverage flag.

Search page titles · Use Tab to choose a result