Skip to content

Ccheh/plinth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Plinth

Capital layer for AI trading agents on Arc. AI agents create on-chain vaults to raise external USDC; anyone deposits and receives shares; redeem at current NAV at any time; agent deploys vault capital only to a pre-declared, immutable whitelist of venues. Hedge-fund-grade infrastructure for the agentic economy.

License: MIT Tests Solidity Audit Arc Testnet

Aligned with Arc Blueprints

Plinth is infrastructure that hits 5 of Circle's 9 official Arc Blueprints (use-case briefs Arc published May 2026). Each row maps a blueprint to the specific Plinth primitive that addresses it:

Arc Blueprint How Plinth addresses it
Agentic Economy Plinth IS the capital layer for AI agents — vault creation, NAV accounting, capability-not-custody constraints. Five sibling protocols (Cadence/Crucible/Helm/Mandate/Plinth) compose into an agent-economy stack
Treasury Management A Plinth vault IS the AI agent's on-chain treasury: idle USDC sweeps to yield via IYieldVenue adapters (Morpho-ready), trading capital routes via approved-venue whitelist, redemptions open at NAV
Lending and Borrowing MorphoVenueAdapter (ERC-4626 scaffold) plugs Plinth vaults into Morpho on Arc when live. Capability constraints on the borrower side: agent can route to approved lending venues but never withdraw to arbitrary addresses
Capital Markets Settlement Verifiable PnL = settlement primitive: when the trading venue is itself a public chain (Aster L1, Synthra perp on Arc), an independent Underwriter reconciles agent-reported PnL cryptographically. Vault #5: matched to 0.00% delta on chain
Onchain Credit Markets MandatePlinthBridge is the first on-chain sibling-protocol composition: institutional issuers authorize agent-mediated deposits with cryptographic capability constraints across both protocols — capability-bound credit. Live tx

v0.6 on Arc Testnet (recommended — RiskGuard + Cadence composition)

Contract Address Deploy tx
PlinthV06 0x17B7B30d324Add96c5dC5d3259746695e94c92C9 0x183557ce...
CadencePlinthBridge ⭐ (2nd cross-protocol composition) 0x9E3c322c19b13317C662af39994573de6daB5347 0xf5cb23cf...
CruciblePlinthBridge ⭐ (3rd cross-protocol composition) 0xa948e26546c3634da03df8b078b1c8d79ba54a78 0xf8a346dd...
HelmPlinthBridge ⭐ (4th cross-protocol composition) 0xdd612ded1b3972dac53acd7cd0c959a45a82defe 0x4490ffd5...
PlinthSponsorPool ⭐ (Underwriter sustainability layer) 0xf28a58e71b822e76527032973223e422686068e2 0x40a5b5d4...

v0.6 adds on-chain enforcement of 4 risk signals previously off-chain (agent-as-venue flag, 80% venue concentration cap, NAV floor auto-close at 10%, whale deposit flag) plus 4 sibling-protocol compositions live (Mandate × Plinth · Cadence × Plinth · Crucible × Plinth · Helm × Plinth) and the PlinthSponsorPool sustainability layer for the Underwriter network. The 3rd composition — CruciblePlinthBridge — implements quality-proportional management fees: vault investors escrow a fee budget tied to a Crucible quality market; on resolution, the agent receives a fraction proportional to the scoreBps (0–10000). The 4th — HelmPlinthBridge — implements metric-conditional fee release: at the milestone deadline, an oracle reads whether the vault's on-chain metric (e.g. NAV growth ≥ X bps) was met; if yes, the agent receives the full escrow, if no, the sponsor is fully refunded. Together these are the first on-chain quality-conditional + metric-conditional management-fee mechanisms in the Arc ecosystem.

v0.5 on Arc Testnet (security-hardened, still live as historical reference)

Contract Address Deploy tx
PlinthV05 0xba1b087b0ac77b398c250a9fd7e298f3f96addc7 0x55bd1dce...
MockYieldVenue (T-bill cash-sweep) 0xe5cceca53ccb15affc58016e1757e1a138ef3144 0x8714eb2d...
MandatePlinthBridge (1st Plinth × Mandate compose) 0x0b92b6e4fa26e6c2b10a5c668d8313a1bf8c3f50 0x9a7c9f97...

Closes 6 audit findings vs v0 (full report): sandwich-on-reportPnL, returnFromVenue griefing, reportPnL inflation rug, reportPnL on Closed vault, reportPnL magnitude overflow, strategyDescriptor unbounded length. 176/176 unit tests + 3 stateful invariants across 10 test suites (57 v0 + 33 v0.5 + 14 v0.6 RiskGuard + 12 Cadence × Plinth + 13 Crucible × Plinth + 8 Helm × Plinth + 10 SponsorPool + 8 yield-strategy + 10 Morpho adapter + 11 Synthra spot, plus 3 fuzz-verified invariants: solvency, deployedAUM ledger consistency, shares conservation — verified across 60K+ random call sequences over 250s of fuzzing).

v0.6 RiskGuard (just shipped): four risk signals previously enforced only by the off-chain risk-monitor.ts script are now on-chain primitives in PlinthV06.sol — no admin key, no off-chain dependency:

# Signal v0.5 v0.6
1 Agent listed as own venue Risk Monitor flag (off-chain) createVault emits AgentAsVenueFlag
2 Single-venue > 80% concentration Risk Monitor flag deployToVenue REVERTS with VenueConcentrationExceeded
3 NAV < 10% of inception Risk Monitor flag reportPnL auto-Closes the vault, investors retain redemption
4 Whale deposit > 50% of AUM Risk Monitor flag deposit emits WhaleDeposit for Underwriter pipeline

This closes the persona-8 critique of v0.5 ("Risk Monitor is a script the author can turn off") — those four protections are now cryptographically enforced for every vault on v0.6, with no recourse to admin keys.

First v0.5 vault on chain (explorer) with deposit cooldown firing as expected: investor deposit 0x2dc4b91c... → simulated immediate redeem reverts with SharesPendingVesting (0x6ba41e7c).

v0 on Arc Testnet (historical / demo artifact)

Contract Address Deploy tx
Plinth v0 0xc2994ce3df612ebd2f898244a992a0bbfef86627 0xe10e704a...
MockVenue #1 0x50bf887e4957261e7ca0c6b4eeb61ab83ad6ddcd 0x62e48b43...
MockVenue #2 0xc0f8d26cbf7123b0f5148b9feae6c3234cccda35 0x85b612e2...

v0 is preserved on chain as the historical/demo artifact (5 vaults with full lifecycles, 3 Aster L1 round-trips, 6 underwriter reviews including 2 verifiable-PnL reviews and 2 risk alerts). MockVenue contracts are reused by v0.5.

Combined deployed gas (v0 + v0.5): ~4M (~0.16 USDC at 40 gwei).

Live vaults (as of submission)

Vault Strategy descriptor Status NAV
#1 0xc4c82a67... BTC perp momentum, max 3x leverage, daily rebalance full lifecycle ran (deposit, deploy, +PnL, redeem) 1.375 USDC/share
#2 0xd33068c5... ETH/USDC mean reversion, 1x cash, slow weekly rebalance 2 depositors, 0.007 USDC TVL 1.0
#3 0x5c7eebdb... SOL perp grid bot, 2x leverage, ±5% bands deployed 0.002 to venue, +0.001 PnL reported 1.333
#4 0x71002b00... Multi-asset cross-chain arbitrage via CCTP fresh, awaiting depositors 1.0
#5 0xefb495a0... BTC perp via Aster L1 — verifiable PnL demo 3 real Aster round-trips ran, Underwriter posted VERIFIED + CRITICAL (independent reviewers) underwater (correctly flagged)

Plus 6 underwriter reviews on chain — 1 LLM-generated, 1 3rd-party, 2 cryptographically verified against Aster L1 trade history (vault #5, Phase 3 + Phase 5), and 2 risk alerts auto-generated by an off-chain Risk Monitor (vault #5 CRITICAL + vault #1 HIGH).

Security — pre-deployment audit + 6 findings closed in v0.5

docs/security-audit.md is the full in-team audit of Plinth v0 (290 LOC), conducted before any production deployment. 11 findings total: 1 Critical, 2 High, 3 Medium, 2 Low, 3 already-safe-by-design.

Every Critical/High finding has both an exploit POC test in Plinth.t.sol (proving the v0 vulnerability is real) and a defense test in PlinthV05.t.sol (proving v0.5 closes it):

Finding Severity v0 status v0.5 fix
#1 reportPnL sandwich extraction 🔴 Critical exploitable (POC: attacker exits with profit) deposit cooldown — SharesPendingVesting revert
#2 returnFromVenue open access griefing 🟠 High exploitable (POC: 3rd party redirects venue funds) caller must be venue or agent
#3 reportPnL magnitude / rate unbounded 🟠 High exploitable (POC: NAV inflation rug) 10× capital cap + 25%/hr rate limit
#4 reportPnL allowed on Closed vault 🟡 Medium exploitable (POC: exit-NAV manipulation) rejected on Closed
#6 reportPnL near INT256 bounds 🟡 Medium theoretical bounded by #3 fix
#8 strategyDescriptor unbounded length 🟢 Low griefing via gas MAX_STRATEGY_LEN = 1024

Two findings deferred to v0.6 (#5 funds stuck at venue post-close; #7 createVault spam — both have documented mitigations). Three findings are already safe-by-design (reentrancy via OZ ReentrancyGuard + CEI; donation attack neutralized by per-vault accounting; first-depositor inflation prevented by NAV reading storage not balance).

A v0.5 vault is live on chain with deposit cooldown firing correctly: see Plinth.t.sol exploit tests and docs/security-audit.md for the full report.

Yield Strategy — vault cash-sweep into T-bill yield (testnet mock, real USYC in production)

A real AI-trading fund leaves significant capital idle most of the time. Plinth's capability-constraint model makes "cash sweep into a yield venue" a clean, in-architecture pattern: deploy idle USDC to a yield venue exactly the same way capital flows to a trading venue.

Live on Arc Testnet:

  • MockYieldVenue at 0xe5cceca53ccb15affc58016e1757e1a138ef3144 accrues continuous 5% APR on principal, with pre-funded reserve backing payouts.
  • Demo lifecycle (sdk-ts/examples/yield-strategy.ts) ran end-to-end: agent creates vault → investor deposits 0.005 USDC → agent sweeps 0.004 to yield venue → 180s passes → yield accrues exactly 1.218 × 10^-9 USDC (matches 5% × 0.004 × 180/(365×24×3600) to 12 decimals) → agent reports as PnL → NAV moves from 1.0 to 1.000000202943.
  • On-chain evidence: vault page · deploy-to-venue tx · reportPnL tx

The Verifier pattern from Aster L1 applies identically: any third party can read MockYieldVenue.accruedYield() on chain and reconcile it against the agent's reportPnL value. Same architecture, different yield source.

Pluggable yield-venue architecture (v0.6): All yield venues now implement a common IYieldVenue interface, making the production swap drop-in. Shipped adapters:

Adapter Status Underlying
MockYieldVenue ✅ Live on Arc Testnet Fixed 5% APR simple-interest mock
MorphoVenueAdapter 🟡 Scaffold (placeholder mode) — production-ready, awaiting Morpho's Arc deployment Morpho Vault V2 (ERC-4626)
SynthraSpotVenue 🟡 Scaffold (placeholder mode) — production-ready, deploy with Synthra's verified SwapRouter address Synthra v3 spot AMM (Uniswap v3 fork on Arc)

All adapter contracts are fully unit-tested against canonical mock counterparties (21 new tests covering placeholder + production modes, full lifecycle, slippage protection, agent-only access control). When Morpho lands on Arc, MorphoVenueAdapter constructor takes the real vault address and the placeholder gate flips off — zero changes to Plinth. Same pattern for Synthra spot.

Verifier abstraction (v0.6): The Underwriter pipeline now operates against a venue-agnostic IPerpVerifier interface. AsterVerifier (cross-chain via Aster L1) and SynthraPerpVerifier (Arc-native scaffold) both implement it, so a single Underwriter codebase reconciles agent reportPnL against any registered venue.

Production wiring path (documented end-to-end in yield-strategy.ts): the real USYC token on Base (Circle's tokenized US Treasury Bills), bridge Arc USDC↔Base via CCTP using @circle-fin SDKs. The Plinth contract itself is unchanged — USYC just slots in as another approvedVenue under the same IYieldVenue abstraction.

Sibling protocol composition — four on-chain compositions shipped

Five protocols (Cadence, Crucible, Helm, Mandate, Plinth) ship as independent contracts. The README has long described how they compose architecturally; v0.5 + v0.6 ship four actual on-chain compositions — each one a different mechanism for a different kind of fee/credit flow:

# Bridge What it composes Mechanism
1 MandatePlinthBridge Mandate v0 + PlinthV05 Capability-bound capital authorization — institutional issuer authorizes agent-mediated deposits with cryptographic constraints across both protocols
2 CadencePlinthBridge Plinth + Cadence (Arc402) PaymentEscrowV2 Streaming fee deposit — vault depositors route fees to the vault's agent via Cadence's Nanopayments rail. Bridge reads agent from Plinth (no spoofing), forwards funds via depositFor. Agent then has full Nanopayments downstream: signed claims, batched settlement, session keys.
3 CruciblePlinthBridge Plinth + CrucibleMarketV6 Quality-conditional fee (proportional) — investor escrows fee budget tied to a Crucible quality market. When the market resolves with scoreBps, bridge releases a proportional fraction to the agent and refunds the remainder. Below a minimum score: full refund. First on-chain implementation of quality-conditional management fees (to the author's knowledge).
4 HelmPlinthBridge Plinth + Helm futarchy Metric-conditional fee (binary) — investor escrows fee budget tied to a Helm futarchy issue. At resolve time, an oracle attests whether a metric crossed a threshold; if yes, agent collects the full fee; if no, full refund. Useful for "pay agent only if vault reaches $X TVL by date Y" / "pay only if NAV stays above 1.0 by date Y" / etc. First on-chain futarchy-conditioned management fee.

The CadencePlinthBridge is the second-shipped composition. 12 tests cover: end-to-end credit flow, agent-spoofing resistance, per-vault accumulation, multi-vault tracking, sponsorship pattern (funder ≠ agent), zero-value / non-existent-vault / cadence-failure reverts. Deployment: bridge takes (PlinthV05/V06 address, PaymentEscrowV2 address) at construction.

Below: the original Mandate × Plinth composition still ships unchanged.

Mandate × Plinth on chain (first composition)

The original Mandate composition: Mandate authorizes Plinth-vault deposits via a bridge contract.

The story it enables: an institutional issuer (bank, fund, corporate treasury — typically a multi-sig) creates a Mandate authorizing an AI agent to deposit USDC into a specific Plinth Vault, bounded by spend ceiling + counterparty whitelist + purpose whitelist + time window. The agent calls MandatePlinthBridge.depositViaMandate which atomically pulls capital out of the mandate (Mandate.execute) and deposits it into the vault (Plinth.deposit), with shares recorded under the mandate's issuer. Even if the agent's private key is compromised, the agent cannot redeem the shares — capability constraint preserved across both protocols.

Live on Arc Testnet:

  • MandatePlinthBridge at 0x0b92b6e4fa26e6c2b10a5c668d8313a1bf8c3f50 wires Mandate to PlinthV05.
  • Demo lifecycle (sdk-ts/examples/mandate-plinth-composition.ts) ran end-to-end on chain:
    1. Vault created on Plinth v0.5 with bridge as approved-venue (create tx)
    2. Mandate issued — principal = bridge, ceiling = 0.01 USDC, counterparty whitelist = single Merkle leaf for bridge, purpose = keccak256("plinth_invest_v0"), funded with 0.005 USDC (issue tx)
    3. Bridge.depositViaMandate triggered: atomic Mandate.execute → Plinth.deposit (composed tx)
    • Final state on chain: Mandate.spent = 0.005 USDC ✓, Bridge.sharesOfMandate[mandate][vault] = 0.005 ✓, Plinth.inVault on vault += 0.005 ✓

This was the first real architectural compose of sibling protocols, not just README cross-references. The same bridge pattern is now also shipped for the other three: Cadence × Plinth (management fee streaming via Nanopayments), Crucible × Plinth (quality-proportional fee release scored by Schelling market), and Helm × Plinth (metric-conditional fee on on-chain milestone) — all live on Arc Testnet, addresses in the v0.6 table above.

Verifiable PnL — agent's claim matched against Aster L1 trade history

Vault #5 demonstrates the architectural payoff of Plinth's Underwriter Review layer when the off-chain venue is itself a public chain:

Side What happened On-chain evidence
Plinth (Arc Testnet) Agent created vault, investor deposited 0.01 USDC, agent deployed 0.005 to MockVenue vault page
Aster L1 (chainId 1666) Agent opened BUY 0.001 BTC @ 80,500.7, closed SELL @ 80,517.9 after 3 min Aster orders 31402248641 open / 31402286923 close, fills id 134970761 + 134970911
Plinth (Arc Testnet) Agent reported realized −0.047207 USDC PnL reportPnL tx
Underwriter Independently pulled Aster userTrades, summed gross +0.0172 USDT − commissions 0.0644 = −0.0472 USDT, matched agent's claim within 0.00% delta UnderwriterReviewPosted tx — verdict VERIFIED

3 round-trips were executed cumulatively (1 long, 1 long, 1 short). All 3 had positive directional moves; fees ate the gross profit. Net realized: −0.135 USDT across 6 fills, matched to 0.00% delta on chain (second verifier review tx). Total experimental cost: $0.13 USDT.

The same architecture works against any public-chain venue, including future Arc-native perp DEXes. Aster L1 was picked for v0 because it was readily available; the integration code lives in aster/.

Wallet diversity in the demo

Plinth's multi-underwriter + multi-depositor design supports any number of independent identities, each acting from their own key. The demos exercise this with three distinct on-chain wallets:

Wallet Role Funded by Disclosure
0x... (main agent/operator key) Runs Aster Verifier + Risk Monitor + LLM Underwriter Original USDC The project author's primary key
0xA4Fe6D03… ("Bob") Deposited 0.003 USDC into Vault #1 + posted qualitative review of Vault #5 Operator-transferred USDC bob review markdown footer
0xAbc9c5cE… ("Charlie") Deposited 0.0001 USDC into Vault #4 v0.5 via public Circle faucet path Circle's public Arc Testnet faucet docs/charlie-test.md — full disclosure + reproducibility script

All three are operator-orchestrated; Plinth makes no claim of unaffiliated third-party traction. Their value is technical: they prove the cryptographic multi-signer design works end-to-end at the wallet level, not just at the contract level. Charlie additionally proves the fresh-wallet onboarding journey (faucet → deposit) works as documented in docs/quickstart-for-agents.md.

Risk Monitor — second independent Underwriter, complementary to verifiable-PnL

A separate off-chain agent (underwriter/risk-monitor.ts) scans every vault on the deployment and writes structured RiskAlert reviews on chain when any of these signals trigger: underwater NAV, outsized PnL claims vs AUM, agent-as-venue, single-venue concentration, liquidity gap, review staleness.

Two alerts went live during the submission window:

  • Vault #5 (CRITICAL review) — vault is underwater after the Aster round-trips, reportedPnL is 1224% of AUM
  • Vault #1 (HIGH review) — reportedPnL is 50% of AUM and no recent underwriter review

Notably: Vault #5 has TWO reviews from independent underwriters that disagree on what to do. The Aster Verifier says VERIFIED (the agent is honest about PnL). The Risk Monitor says CRITICAL (the position is dangerous). Both are correct and useful — an honest agent reporting a real loss is exactly when investors should be warned about the size of the loss, not when they should be reassured by the verification. This is by design — multiple lenses, each posting independently on chain.

For the gaps the v0 contract intentionally does NOT enforce (per-call size caps, NAV-drop circuit breakers, PnL rate limits, etc.), see docs/risk-controls.md for the v0.5 RiskGuard interface and implementation roadmap.

Read this first. Plinth has shipped through v0.6 on Arc Testnet — 11 contracts live (PlinthV05/V06 + 3 venue adapters + 4 sibling-protocol bridges + SponsorPool + MockVenue), 176/176 forge tests + 3 stateful invariants (60K+ fuzz runs), 11-finding pre-deployment audit with exploit POC + defense test for every Critical/High. One real third-party-venue lifecycle ran end-to-end (Aster L1, 3 BTC perp round-trips, $0.13 experimental cost), matched at 0.00% delta on chain. The pitch: AI agents on Arc need a way to raise and manage external capital with cryptographically verifiable PnL — currently they don't have one. Plinth is that primitive.


What it does

A Plinth Vault is a tokenized USDC pool with:

  • One agent (AI or human) authorized to deploy the pool's capital and report PnL.
  • N shareholders who deposited USDC and received internal shares.
  • An immutable whitelist of approved venues (perp DEXes, prediction markets, AMMs). The agent can ONLY transfer pool funds to addresses on this list.
  • A NAV (net asset value per share) updated continuously from agent PnL reports.
  • An optional Underwriter Review layer: any 3rd party can post a signed risk assessment of the vault on chain.

Core flows

1. Agent creates vault:
     createVault(approvedVenues[], strategyDescriptor)
     - approvedVenues is fixed at creation; agent cannot drain to arbitrary addresses
     - msg.value is agent's "skin in the game" — they get 1 share per USDC at inception

2. Investor deposits:
     deposit(vaultId)
     - msg.value is the USDC amount
     - sharesMinted = msg.value * 1e18 / currentNAV

3. Agent deploys to venue:
     deployToVenue(vaultId, venue, amount)
     - venue must be in approvedVenues
     - inVault decreases, deployedAUM increases
     - USDC flows to venue contract

4. Agent reports PnL:
     reportPnL(vaultId, newPnL)
     - signed int (can be negative)
     - NAV = (inVault + deployedAUM + reportedPnL) / totalShares

5. Investor redeems:
     redeem(vaultId, shareAmount)
     - usdcOut = shareAmount * currentNAV / 1e18
     - reverts if not enough liquid (inVault < usdcOut)

6. Underwriter posts review:
     postUnderwriterReview(vaultId, reviewHash, reviewUri)
     - hash on chain, full review off-chain at reviewUri
     - any address can post; consumers pick which signer to trust

NAV math

totalAUM = inVault + deployedAUM + reportedPnL          (signed int)
NAV      = totalShares == 0 ? 1e18 : (totalAUM * 1e18) / totalShares

Inception NAV is 1 USDC/share (1e18 wei). NAV moves with reportedPnL.

If totalAUM ≤ 0, the vault is "underwater" — deposits and redemptions revert to protect surviving share value. Only the agent unwinding positions and returning funds (or closing the vault) can unlock further action.

Agent safety constraints (Mandate-style)

The agent's authority is hard-capped by the contract:

  • Can only call deployToVenue to addresses in approvedVenues (immutable).
  • Cannot withdraw USDC for personal use — there is no "agent withdraw" function.
  • Cannot mint new shares for themselves outside the deposit flow.
  • Can revoke their own access via closeVault but cannot revoke shareholder claims to their pro-rata of remaining liquidity.

What the agent CAN do badly (documented openly):

  • List themselves (or a sock-puppet venue) as an approvedVenue at creation, then deploy to themselves. This is detectable off-chain by the Underwriter.
  • Report fraudulent PnL. NAV moves on the agent's say-so in v0. v0.2 will add stake/bond economics for honesty enforcement.

Why this fits the agentic economy on Arc

The 5 protocols already shipped form a stack:

Protocol Solves × Plinth
Cadence How agents pay (per-call USDC) ✓ CadencePlinthBridge live
Crucible How agents are scored on output quality ✓ CruciblePlinthBridge live
Helm How agent groups decide (futarchy) ✓ HelmPlinthBridge live
Mandate How institutions authorize agents ✓ MandatePlinthBridge live
Plinth (this) How agents raise capital from external investors — composes with all 4

Plinth is the missing capital layer. Without it, an AI agent can run a great strategy but only on its own funds. With it, the same agent can attract external USDC, scale strategy size, and share returns with its investors.


On Arc specifically

  • USDC as native gas means a deposit/redeem flow is one tx with no separate gas token.
  • Sub-cent settlement makes small-share economics work — you can redeem $0.50 worth of shares without losing the value to gas.
  • L1 finality matters for NAV: a deposit at NAV 1.50 is final, no chain reorg can rewrite the share count.

These properties are what make a "tokenized AI fund" viable here vs on Ethereum mainnet ($5+ gas per deposit kills sub-thousand-dollar vaults).


Reproducing the tests

cd contracts
forge test

Expected: 176 tests passed; 0 failed across 10 suites + 3 stateful invariants. Breakdown:

  • 57 v0 core vault tests (Plinth.t.sol): createVault / deposit / redeem / deployToVenue / returnFromVenue / reportPnL / pause-close / multi-vault isolation / view functions / end-to-end lifecycle + 5 exploit POCs proving every Critical/High audit finding is reproducible on v0
  • 33 v0.5 defense tests (PlinthV05.t.sol): deposit cooldown, PnL magnitude cap, rate limit, returnFromVenue access control, strategyDescriptor length cap
  • 14 v0.6 RiskGuard tests (PlinthV06.t.sol): agent-as-venue flag, venue concentration cap revert, NAV floor auto-close, whale deposit flag
  • 12 Cadence × Plinth bridge tests (CadencePlinthBridge.t.sol)
  • 13 Crucible × Plinth bridge tests (CruciblePlinthBridge.t.sol)
  • 8 Helm × Plinth bridge tests (HelmPlinthBridge.t.sol)
  • 10 SponsorPool tests (PlinthSponsorPool.t.sol): sponsor + claim + dedup + refill-cycle + Sybil drain protection
  • 8 MockYieldVenue tests, 10 MorphoVenueAdapter tests, 11 SynthraSpotVenue tests (yield-strategy + IYieldVenue adapter coverage)
  • 3 stateful invariants (PlinthV06Invariant.t.sol): solvency, deployedAUM ledger consistency, shares conservation — fuzz-verified across 60K+ random call sequences

What's shipped post-v0 (May 2026)

  • TypeScript SDKsdk-ts/ with @circle-fin SDK family integrated
  • LLM Underwriter agent — auto-reviews strategyDescriptor (underwriter/llm-reviewer.ts)
  • Web UIhttps://ccheh.github.io/plinth + verify.html (in-browser PnL reconciliation)
  • Management fee primitives — Cadence × Plinth (streaming), Crucible × Plinth (quality-proportional), Helm × Plinth (metric-conditional)
  • USYC auto-yield pathIYieldVenue interface + MorphoVenueAdapter scaffold; production CCTP integration in Grant M2
  • Underwriter sustainabilityPlinthSponsorPool (per-vault investor → underwriter market)
  • Public-goods extraction@plinth/verifier-core npm-ready package (verifier-sdk/)

What's deferred to v1.0+

  • ERC-20 wrapping of internal shares so they're tradable on AMMs
  • NAV oracle integration — replace agent self-reporting with verifiable feeds (current verifiable-PnL path requires venue to be public-chain)
  • Multi-asset vaults — v0 is USDC-only
  • Insurance / first-loss tranche — investor protection from agent fraud
  • Mainnet deployment — funded by Grant M4

Honest limits

  • Testnet only, no production adopters yet. v0.6 is live on Arc Testnet with 11-finding self-audit (exploit POC + defense test per Critical/High). Grant M1 funds external audit (Trail of Bits / Spearbit); Grant M4 funds mainnet deployment with $5K real TVL + Immunefi bounty.
  • Agent self-reporting of PnL is trust-based — unless the venue is also a public chain. A malicious agent on an opaque (CEX-style) venue can mark a position higher than reality to inflate NAV; we rely on Underwriter Review to catch it. When the venue is itself a public chain — like Aster L1, or future Arc-native perp DEXes — the Underwriter can independently reconcile the agent's claim against the venue's trade history (see Vault #5 above). v1.0 adds bond/stake economics on top.
  • Agent can list themselves as an approved venue at create. Detected and flagged on chain in v0.6 via AgentAsVenueFlag event at createVault, but not blocked — the design choice is to surface for Underwriter pipeline rather than refuse legitimate self-custodial agent vaults. Trade-off: flexibility now, reputation layer later.
  • No on-chain enforcement of disclosed strategy. The strategyDescriptor is free text. Agents may operate differently than they advertise. Investors must trust the Underwriter and the agent's track record.
  • Native USDC only. Plinth assumes 18-decimal native USDC (Arc Testnet semantics). Mainnet adaptation will require IERC-20 + approve/transferFrom semantics.

Repo layout

contracts/src/
├── Plinth.sol                   — v0 core vault + share + NAV contract
├── PlinthV05.sol                — security-hardened v0.5 (closes 6 audit findings)
├── PlinthV06.sol                — v0.6 + on-chain RiskGuard (4 hooks)
├── MockVenue.sol                — placeholder venue for tests and demo
├── MockYieldVenue.sol           — T-bill cash-sweep mock for IYieldVenue
├── MorphoVenueAdapter.sol       — Morpho-on-Arc ERC-4626 scaffold
├── SynthraSpotVenue.sol         — Arc-native DEX adapter scaffold
├── MandatePlinthBridge.sol      — composition #1: capability-bound credit
├── CadencePlinthBridge.sol      — composition #2: management fee streaming
├── CruciblePlinthBridge.sol     — composition #3: quality-proportional fee
├── HelmPlinthBridge.sol         — composition #4: metric-conditional fee
├── PlinthSponsorPool.sol        — Underwriter network sustainability layer
└── interfaces/                  — IPlinth, IYieldVenue, IPerpVerifier, etc.

contracts/test/                  — 10 suites, 176 unit tests + 3 stateful invariants
contracts/script/                — Foundry deploy scripts for every contract above

sdk-ts/                          — TypeScript SDK + @circle-fin/* integration examples
verifier-sdk/                    — @plinth/verifier-core npm-ready public-goods package
underwriter/                     — LLM-reviewer + risk-monitor + aster-verifier off-chain agents
aster/                           — Aster L1 venue adapter + verifiable-PnL Underwriter
docs/                            — security audit, charlie-test, deck, web UI (gh-pages)
video/                           — pitch video + codebase walkthrough build pipeline

Author

Zen Chen — built on Arc Testnet for the Agora Agents Hackathon. Sibling protocols: Cadence · Crucible · Helm · Mandate.

About

Capital layer for AI trading agents on Arc. Hedge-fund infrastructure on-chain — agents create vaults, anyone deposits USDC at NAV, agent deploys to whitelisted venues, investors redeem on demand.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors