Somnia AI Yield Scientist is an autonomous on-chain portfolio manager that accepts deposits into ERC-4626 vaults, allocates capital across strategy adapters, and rebalances using an AI-driven policy protected by deterministic guardrails. The monorepo ships smart contracts, an orchestration agent, an event indexer, and a polished Next.js dashboard.
├── contracts/ Solidity sources, Foundry tests, deployment scripts
├── agent/ TypeScript automation agent (planner, simulator, CLI, memos)
├── indexer/ Fastify service ingesting on-chain events and serving REST APIs
├── dapp/ Next.js + Tailwind web application with RainbowKit & charts
├── docs/ Design notes & screenshots (placeholders)
├── memos/ Generated decision memos from the agent
├── scripts/ Repository maintenance scripts (seed data, helpers)
└── Makefile Convenience commands for the entire stack
- Node.js 18+
- pnpm 8+
- Foundry toolchain (
foundryup) - Anvil (or compatible RPC) for local deployments
# Install dependencies
make install
# Seed sample addresses, indexer state, and memos
make seed
# (Optional) deploy contracts against a local Anvil instance
make deploy-test # uses RPC_URL=http://127.0.0.1:8545 by default
# Launch the full stack (indexer + agent runner + dapp)
pnpm -w devIndividual packages can be run with the helper scripts:
pnpm agent plan --vault <vaultAddress>
pnpm agent execute --vault <vaultAddress> --dry-run
pnpm indexer dev
pnpm dapp dev| Contract | Address |
|---|---|
| MockToken (sUSD) | 0x036635f4E2880f1E3889B6753d04F21C6E2ca6FA |
| OracleRouter | 0x2A24B775A9B00FEB3d1035d87c92993491Ed0B9F |
| AutomationRegistry | 0x23A071705b2034Ee7B8a80bE392a0A2D64EbBF8F |
| VaultFactory | 0x15DB14371e5D209a22D448d0Fde1d3eefeEC9D26 |
| Somnia Safe Vault | 0x1468844a022C40ddC57816594B7342846521B8eF |
| PolicyGuard (Safe) | 0xd69B699fcCb0EF8Ea70945D0B077cB7f7894C31F |
| PortfolioNFT (Safe) | 0xb1c4e57fbf9F13D1A2B52fb43fE5de91d4Df30A4 |
Set these values in the relevant .env files before running the agent, indexer, or dapp.
YieldVault– ERC-4626 vault with management/performance fees, guardian-controlled guardrails, and PortfolioNFT minting on first deposit.PolicyGuard– enforces vault caps, adapter caps, cooldowns, daily limits, allowlists, and kill-switch controls.StrategyAdapter+LendingAdapter+LPAdapter– strategy interface and two demo adapters with deterministic APR/slippage modelling.OracleRouter– medianized price router with staleness/deviation checks emittingOracleStaleevents.AutomationRegistry– executor allowlist with cooldown and sim-hash proof registration.PortfolioNFT– soulbound ERC-721 metadata summarising allocations & performance.VaultFactory– guardian-owned factory for deploying risk-profiled vaults.
Unit, fuzz, and invariant tests (NAV monotonicity & cap enforcement) live under contracts/test/. Run them with pnpm --filter @somnia/contracts test.
The agent (TypeScript + viem + React Query) performs:
- Snapshot collection – reads vault state, adapter APR hints, guard caps.
- Planning – momentum + EWMA heuristics produce target weights per risk profile.
- Simulation – dry-run validates guard caps, slippage estimates, and gas envelope.
- Sim proof –
proofOfSimHash = keccak(snapshot||actions||constraints||block)registered with the AutomationRegistry. - Per-run memo – signed JSON written to
memos/(and ready for IPFS pinning) containing plan context. - Execution – CLI submits
rebalancetransactions (or emits calldata for dry runs).
CLI:
pnpm agent plan --vault 0x...
pnpm agent execute --vault 0x... --dry-run
pnpm --filter @somnia/agent dev # interval runnerKey tests in agent/tests/ cover planning invariants, simulator validation, and sim-hash determinism.
The indexer subscribes to vault events, maintains lightweight JSON state via lowdb, and exposes REST endpoints consumed by the dapp:
GET /vaultsGET /vaults/:id/positionsGET /actions/recentGET /oracles/status
It also periodically re-syncs vault data and hydrates the React Query cache used in the UI. Start locally with pnpm indexer dev.
- Next.js 14 (app router), React 18, Tailwind, shadcn-inspired UI primitives.
- Wagmi + RainbowKit + Viem for wallet interactions (deposit/withdraw flows).
- React Query client components (activity feed + live updates).
- Charts via Recharts, motion via Tailwind animations, responsive + accessible design.
- Pages: Home, Vaults, Vault Detail (deposit/withdraw, allocations chart, agent plan panel, safety status), Activity feed, Docs/About.
- Playwright smoke tests live in
dapp/tests/basic.spec.ts.
Place captured screenshots in docs/ (see docs/screenshots.md for expected images).
| Location | File | Notes |
|---|---|---|
| Contracts | contracts/.env.example |
RPC, deployer key, chain id |
| Agent | agent/.env.example |
RPC, executor key, vault/guard addresses, memo dir |
| Indexer | indexer/.env.example |
RPC, chain id, vault list, DB path |
| Dapp | dapp/.env.local.example |
RPC, indexer URL, vault addresses, explorer URL |
pnpm -w lint
pnpm -w test # Foundry, Jest, Vitest
pnpm --filter @somnia/dapp test # Playwright (requires running dev server)GitHub Actions (.github/workflows/ci.yml) run lint, test, build, and Slither.
- Funds isolation: Only the vault holds user assets. Adapters are non-upgradeable and never receive arbitrary delegatecalls.
- PolicyGuard authority: Guardian multisig controls caps, allowlists, rate limits, and can pause or permanently kill vaults.
- Oracle safety: OracleRouter emits
OracleStaleand halts vault operations when feeds deviate or expire. - Automation hygiene: Executions require pre-registered sim-hash proofs and respect global/executor cooldowns.
- Emergency exit: Adapters expose
emergencyExitreturning funds directly to the vault with event tracing. - Testing: Foundry fuzz + invariants ensure caps are never exceeded, and agent simulator rejects plans violating guardrails.
make seed && pnpm -w dev– boot indexer, agent runner, and dapp.- Open
http://localhost:3000➜ connect a wallet via RainbowKit. - Navigate to a vault, approve & deposit test tokens (watch
ToastTx). - Observe allocations chart + agent plan panel (confidence, targets, simHash).
- Trigger
pnpm agent plan --vault <address>➜ checkmemos/for the decision memo and/activityfor new events. - Withdraw partially to verify guardrails and updated KPIs.
scripts/seed.mjs– injects sample vault data, fillsindexer/data/indexer.json, and writes example memos.docs/screenshots.md– guidance on capturing UI snapshots for collateral.
Happy experimenting with Somnia! Contributions and experiments are welcome via issues or pull requests.