A modular, multi-blueprint system for non-custodial AI-managed trading on Tangle Network. Users create AI trading bot instances (natural language or code), operators provide compute, an independent AI validator committee approves trade intents, and on-chain vaults execute trades with hard policy guards. No TEE or MPC required — security comes from smart contract custody + multi-operator validation + on-chain policy enforcement.
The system is layered and modular:
- Layer 0:
sandbox-runtime(existing) — container lifecycle - Layer 1:
trading-runtime(new shared lib) — intents, validation, portfolio, protocol adapters - Layer 2: Strategy-specific blueprints — each with different expressivity, protocols, risk profiles
- Validator blueprint — independent committee that validates intents across all strategy blueprints
Each blueprint instance = one AI trading bot. Users create bots, operators run them.
┌─────────────────────────────────────┐
│ USER (or Operator) │
│ │
│ "I want a bot that farms yield on │
│ Aave and Morpho, rebalances when │
│ rate differential > 1%, max 5% │
│ drawdown, USDC only" │
└──────────────────┬──────────────────┘
│ creates instance
▼
┌──────────────────────────────────────┐
│ DeFi Yield Blueprint (Layer 2) │
│ One instance = one trading bot │
│ │
│ ┌────────────────────────────────┐ │
│ │ Sandbox (container) │ │
│ │ - AI agent loaded with user's │ │
│ │ strategy definition │ │
│ │ - Market data feeds │ │
│ │ - Trading runtime (Layer 1) │ │
│ └─────────────┬──────────────────┘ │
└────────────────┼─────────────────────┘
│ generates intents
▼
┌──────────────────────────────────────┐
│ Validator Blueprint │
│ Multi-operator, multi-model │
│ Returns signed approvals │
└────────────────┬─────────────────────┘
│ validated intent + sigs
▼
┌──────────────────────────────────────┐
│ Vault Contract (on-chain) │
│ Policy engine (HARD limits) │
│ Execute trade on DeFi protocols │
└──────────────────────────────────────┘
Who is who:
- User: Creates a bot instance, deposits funds, defines strategy (natural language, config, or code). Could also be an operator.
- Operator: Runs the compute infrastructure — sandboxes, blueprint binaries. Earns fees from bots running on their infra.
- Validator operator: Runs AI validation nodes. Independent from trading operators. Earns validation fees.
The existing shared container runtime crate. No trading logic. Provides:
- Docker container lifecycle (create, stop, resume, delete)
- Reaper / tiered GC (Hot → Warm → Cold → Gone)
- Sidecar HTTP client, auth, metrics
PersistentStore<T>for state
No changes needed. Trading blueprints compose on top.
Shared library for all trading blueprints. Depends on sandbox-runtime for container management. Provides everything a trading bot needs that isn't strategy-specific:
trading-runtime/
├── Cargo.toml
└── src/
├── lib.rs
│
├── intent.rs # TradeIntent type, builder, serialization
├── validator_client.rs # Fan-out to validator committee, collect sigs, aggregate
├── portfolio.rs # Position tracking, P&L, drawdown calculation
├── market_data.rs # Price feeds, pool state, rate fetching
├── vault_client.rs # On-chain vault interaction (deposit, withdraw, execute)
├── strategy.rs # Strategy definition types (NL prompt, config, code ref)
├── fee.rs # Fee calculation and distribution
│
├── adapters/ # Protocol adapters — standardized interface per DeFi protocol
│ ├── mod.rs # ProtocolAdapter trait
│ ├── uniswap.rs # Uniswap V3/V4 swaps
│ ├── aave.rs # Aave V3 supply/borrow
│ ├── morpho.rs # Morpho vaults
│ ├── gmx.rs # GMX V2 perp positions
│ ├── pendle.rs # Pendle yield tokenization
│ ├── polymarket.rs # Polymarket CTF conditional tokens
│ ├── vertex.rs # Vertex perps
│ └── eigenlayer.rs # EigenLayer restaking
│
└── types.rs # Shared types: Action, ValidationResult, PortfolioState
Key trait:
/// Every protocol adapter implements this
#[async_trait]
pub trait ProtocolAdapter: Send + Sync {
/// Human-readable name
fn name(&self) -> &str;
/// On-chain addresses this adapter interacts with (for whitelisting)
fn contract_addresses(&self) -> Vec<Address>;
/// Build calldata for a specific action
async fn build_action(&self, params: ActionParams) -> Result<Action, AdapterError>;
/// Estimate output for a proposed action (for slippage checks)
async fn estimate_output(&self, params: ActionParams) -> Result<U256, AdapterError>;
/// Current state (positions, rates, liquidity)
async fn query_state(&self, vault: Address) -> Result<ProtocolState, AdapterError>;
}Each blueprint defines a category of trading bot with specific:
- Available protocols (which adapters are enabled)
- Risk profile (default policy bounds)
- Validation requirements (which validators, what threshold)
- AI prompting strategy (how the agent reasons about trades)
- Expressivity level (what users can configure)
| Blueprint | Expressivity | Protocols | Risk Level | Target User |
|---|---|---|---|---|
defi-yield-bot |
Low (template + params) | Aave, Morpho, Pendle, EigenLayer | Low | Passive yield seekers |
dex-trading-bot |
Medium (NL strategy) | Uniswap, Curve, 1inch | Medium | Active traders |
prediction-market-bot |
Medium (NL strategy) | Polymarket, Azuro | Medium | Prediction market enthusiasts |
perp-trading-bot |
High (NL + code) | GMX, Vertex | High | Sophisticated traders |
multi-strategy-bot |
Highest (code) | All adapters | Configurable | Developers, quant traders |
Each blueprint is a separate Rust crate with its own binary, contract, and Tangle registration. But they all share trading-runtime and sandbox-runtime.
-
Different risk profiles require different validation thresholds. A yield bot moving funds between Aave and Morpho needs lighter validation than a perp bot taking 5x leverage on GMX.
-
Different policy engines. Yield bots need concentration limits. Perp bots need leverage limits. Prediction market bots need exposure limits.
-
Operator specialization. An operator might run yield bots but not perp bots. Different infrastructure, different risk tolerance, different expertise.
-
Modular upgrades. Can ship a new prediction market blueprint without touching the yield bot. Can add a new protocol adapter to one blueprint without affecting others.
-
Clean Tangle service separation. Each blueprint registers independently, has its own pricing, its own operator set.
This follows the ai-agent-instance-blueprint pattern (1:1 subscription):
User subscribes to "defi-yield-bot" blueprint
│
▼
Tangle creates service instance (instance_id = 42)
│
▼
Blueprint handler: on_instance_created()
1. Deploy vault contract for this instance
2. Set policy engine parameters from user's risk config
3. Provision sandbox container
4. Load user's strategy definition into sandbox
5. Start trading loop
│
▼
Instance is now a running AI trading bot
- Has its own vault (holds user's funds)
- Has its own sandbox (runs AI agent)
- Has its own policy config (user's risk params)
- Generates intents → validators → vault → DeFi
/// Persisted state for each bot instance
struct TradingBotInstance {
instance_id: u64,
vault_address: Address, // on-chain vault for this bot
sandbox_id: String, // sandbox container ID
strategy: StrategyDefinition, // user's strategy
policy: PolicyConfig, // risk parameters
portfolio: PortfolioState, // current positions
status: BotStatus, // Running, Paused, Stopped
created_at: u64,
owner: Address, // user who created the bot
}
enum StrategyDefinition {
/// Natural language description — AI interprets and executes
NaturalLanguage {
prompt: String, // user's strategy in plain English
model: String, // which AI model to use
temperature: f32, // creativity vs. consistency
},
/// Structured config — predefined parameters for a template strategy
Config {
template: String, // e.g., "yield_optimizer", "momentum_trader"
params: serde_json::Value, // template-specific parameters
},
/// Code — user-provided strategy code running in sandbox
Code {
image: String, // custom Docker image with strategy code
entrypoint: String, // or script path within base image
},
}Natural Language (most accessible):
User → "Create a trading bot that..."
│
├── Parsed into: StrategyDefinition::NaturalLanguage { prompt, model }
├── Risk params extracted or defaulted: PolicyConfig { max_drawdown, ... }
│
▼
On-chain: registerStrategy(blueprint_id, strategy_hash, policy_config)
│
▼
Sandbox starts with system prompt:
┌──────────────────────────────────────────────────────┐
│ SYSTEM: You are an AI trading agent running the │
│ following strategy for a DeFi yield optimizer. │
│ │
│ STRATEGY (from user): │
│ "Farm yield on Aave and Morpho, rebalance when rate │
│ differential exceeds 1%, keep max 50% per protocol, │
│ USDC only, target highest safe yield" │
│ │
│ AVAILABLE ACTIONS: │
│ - supply(protocol, token, amount) │
│ - withdraw(protocol, token, amount) │
│ - You CANNOT transfer tokens to arbitrary addresses │
│ - You CANNOT interact with non-whitelisted protocols │
│ │
│ CONSTRAINTS (enforced on-chain, cannot be bypassed): │
│ - Max drawdown: 5% │
│ - Max single trade: 25% of portfolio │
│ - Min time between trades: 1 hour │
│ - Whitelisted protocols: Aave V3, Morpho Blue │
│ │
│ CURRENT STATE: │
│ Portfolio: $50,000 USDC │
│ Aave USDC supply rate: 4.2% │
│ Morpho USDC supply rate: 6.8% │
│ Current allocation: 100% idle in vault │
│ │
│ What trades should be executed? Return as JSON. │
└──────────────────────────────────────────────────────┘
The AI agent processes this, generates intents, and the trading-runtime handles validation + execution. The user's natural language becomes the core of the agent's system prompt.
Config-based (structured, predictable):
{
"template": "yield_optimizer",
"params": {
"tokens": ["USDC", "USDT", "DAI"],
"protocols": ["aave_v3", "morpho_blue"],
"rebalance_threshold_bps": 100,
"max_concentration_bps": 5000,
"check_interval_secs": 3600
}
}This doesn't need AI at all for basic operation — it's a deterministic rebalancing loop. But AI can be layered on top for market condition awareness (e.g., "don't rebalance into a protocol that just had a governance attack").
Code-based (maximum expressivity):
# User provides a Python strategy that runs in the sandbox
# Has access to trading-runtime APIs via HTTP
from trading_sdk import TradingBot, Intent, Action
class MyStrategy(TradingBot):
async def on_tick(self, portfolio, market_data):
# Custom logic — user can do anything here
eth_price = market_data.price("ETH/USDC")
rsi = market_data.indicator("ETH/USDC", "RSI", period=14)
if rsi < 30 and portfolio.cash_pct > 0.2:
return Intent(actions=[
Action.swap("USDC", "ETH", portfolio.cash * 0.1, via="uniswap")
])
elif rsi > 70 and portfolio.position_pct("ETH") > 0.3:
return Intent(actions=[
Action.swap("ETH", "USDC", portfolio.position("ETH") * 0.5, via="uniswap")
])
return None # no trade this tickThe code runs in the sandbox (untrusted), but can only affect the world through intents that go through the validator committee and on-chain policy engine.
Independent, multi-operator validation committee that evaluates trade intents from ALL trading bot blueprints. This is a shared service — one validator set serves every strategy blueprint.
Validators answer: "Is this trade safe and non-manipulative?" — NOT "Is this a good trade idea?"
This distinction is critical:
- Checking alpha is subjective, gameable, and creates Goodhart's law problems
- Checking risk is mechanical: position size vs. limits, slippage, protocol whitelisting, drawdown proximity
- Risk validation is harder to game because the constraints are objective
Each validator operator:
- Registers on-chain with stake (slashable for misbehavior)
- Runs one or more AI models for risk assessment
- Receives trade intents via P2P (HTTP/WS — NOT on-chain job calls, too slow)
- Evaluates and returns a signed score
- Earns validation fees proportional to weight
Trading Bot ──── POST /validate ────► Validator Operator 1 (weight: 30%)
├── POST /validate ────► Validator Operator 2 (weight: 25%)
├── POST /validate ────► Validator Operator 3 (weight: 25%)
└── POST /validate ────► Validator Operator 4 (weight: 20%)
│
Each returns: {score: 0-100, intent_hash, signature}
│
Bot aggregates, checks weighted_avg ≥ threshold
│
Submits intent + signatures[] to vault contract
ValidatorResponse {
intent_hash: bytes32, // keccak256 of the intent
score: uint8, // 0-100 (0 = reject, 100 = fully approve)
timestamp: uint64, // prevents replay
validator: address, // operator address
signature: bytes // ECDSA signature over (intent_hash, score, timestamp)
}
On-chain aggregation:
weighted_score = Σ(weight_i × score_i) / Σ(weight_i)
approved = weighted_score ≥ approval_threshold (e.g., 70)
Weights are determined by:
- Stake amount (base weight)
- Historical accuracy (reputation multiplier)
- Uptime (liveness multiplier)
| Check | Description | Fail Condition |
|---|---|---|
| Protocol whitelist | Target protocol is in approved set | Unknown protocol address |
| Position sizing | Trade size vs. vault AUM ratio | >X% of vault in single trade |
| Concentration | Resulting portfolio concentration | >Y% in single asset |
| Drawdown proximity | Current drawdown vs. circuit breaker | Within Z% of circuit breaker |
| Slippage bounds | Expected slippage reasonable | >N% expected slippage |
| Frequency | Trade frequency vs. rate limits | Excessive trading (churning) |
| Coherence | Trade fits stated strategy type | Yield bot doing leveraged perps |
| Market conditions | Extreme volatility / thin liquidity | Trading into flash crash |
Reputation updates (periodic, on-chain job):
- Track P&L of trades each validator approved
- Validators who approved profitable trades → reputation increase
- Validators who approved trades causing significant losses → reputation decrease
Slashing conditions:
- Validator signs contradictory scores for same intent (equivocation)
- Validator consistently offline (liveness failure)
- Provable front-running (validator-associated address trades before intent execution)
| Job ID | Name | Description |
|---|---|---|
| 0 | register_validator |
Operator registers with stake, model metadata |
| 1 | deregister_validator |
Operator exits, begins unstake cooldown |
| 2 | update_reputation |
Periodic batch reputation update from trade outcomes |
| 3 | slash_validator |
Submit slashing evidence |
| 4 | update_config |
Governance: change threshold, quorum, weights |
| 5 | report_liveness |
Heartbeat / liveness proof |
// Runs alongside the blueprint binary — NOT through Tangle job system
#[post("/validate")]
async fn validate_intent(
intent: Json<TradeIntent>,
ai_client: &State<AiClient>,
operator_key: &State<SigningKey>,
policy_cache: &State<PolicyCache>,
) -> Json<ValidationResponse> {
// 1. Fast policy checks (no AI, sub-millisecond)
let policy_score = check_policies(&intent, &policy_cache).await;
if policy_score == 0 {
return sign_response(0, &intent, operator_key);
}
// 2. AI risk assessment (~1-3s)
let ai_score = ai_client.evaluate_risk(&intent).await;
// 3. Composite score (40% policy, 60% AI)
let final_score = (policy_score * 40 + ai_score * 60) / 100;
// 4. Sign and return
sign_response(final_score, &intent, operator_key)
}┌─────────────────┐ ┌──────────────────┐ ┌────────────────────────────┐
│ VaultFactory │────►│ TradingVault │────►│ PolicyEngine │
│ (deploys per │ │ (holds funds, │ │ - Whitelisted protocols │
│ bot instance) │ │ executes) │ │ - Position limits │
└─────────────────┘ └────────┬─────────┘ │ - Drawdown circuit breaker│
│ │ - Slippage bounds │
┌─────────────────┐ ┌────────┴─────────┐ │ - Per-trade/period caps │
│ StrategyRegistry │ │ FeeDistributor │ └────────────────────────────┘
│ (catalog, │ │ (profit share, │
│ discovery) │ │ management fee) │ ┌────────────────────────────┐
└─────────────────┘ └──────────────────┘ │ TradeValidator │
│ (sig verify, reputation, │
│ weight management) │
└────────────────────────────┘
One vault per bot instance. Holds that bot's user funds and executes validated trades.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.26;
import {ITradeValidator} from "./ITradeValidator.sol";
import {IPolicyEngine} from "./IPolicyEngine.sol";
contract TradingVault {
// ═══════════════════════════════════════════════
// STATE
// ═══════════════════════════════════════════════
address public owner; // user who created the bot
address public operator; // operator running the bot
uint64 public instanceId; // Tangle service instance
ITradeValidator public validator;
IPolicyEngine public policyEngine;
uint256 public totalDeposited;
uint256 public peakAUM; // high water mark
bool public paused;
uint256 public maxDrawdownBps;
mapping(bytes32 => bool) public executedIntents;
// ═══════════════════════════════════════════════
// USER FUNCTIONS
// ═══════════════════════════════════════════════
/// @notice Owner deposits funds
function deposit() external payable onlyOwner {
require(!paused, "Vault paused");
totalDeposited += msg.value;
_updatePeak();
emit Deposited(msg.sender, msg.value);
}
/// @notice Owner withdraws funds
function withdraw(uint256 amount) external onlyOwner {
// Settle any pending fees first
_settleFees();
require(address(this).balance >= amount, "Insufficient balance");
totalDeposited -= amount;
payable(owner).transfer(amount);
emit Withdrawn(owner, amount);
}
// ═══════════════════════════════════════════════
// TRADE EXECUTION
// ═══════════════════════════════════════════════
struct TradeIntent {
bytes32 intentId;
Action[] actions;
uint256 deadline;
uint256 maxSlippageBps;
bytes metadata;
}
struct Action {
address target;
bytes calldata_;
uint256 value;
uint256 minOutput;
}
/// @notice Execute a validated trade intent
function executeValidatedIntent(
TradeIntent calldata intent,
ITradeValidator.ValidationResult[] calldata validations
) external onlyOperator {
require(!paused, "Vault paused");
require(!executedIntents[intent.intentId], "Already executed");
require(block.timestamp <= intent.deadline, "Expired");
// 1. Verify validator committee approved
(bool approved,) = validator.verifyValidation(
keccak256(abi.encode(intent)), validations
);
require(approved, "Validation failed");
// 2. Policy engine check (ALWAYS, even if validators approved)
require(policyEngine.checkIntent(address(this), intent), "Policy violation");
// 3. Execute
executedIntents[intent.intentId] = true;
for (uint256 i = 0; i < intent.actions.length; i++) {
require(policyEngine.isWhitelisted(intent.actions[i].target), "Not whitelisted");
(bool success,) = intent.actions[i].target.call{value: intent.actions[i].value}(
intent.actions[i].calldata_
);
require(success, "Action failed");
}
// 4. Check circuit breaker
_checkCircuitBreaker();
emit IntentExecuted(intent.intentId);
}
// ═══════════════════════════════════════════════
// CIRCUIT BREAKER
// ═══════════════════════════════════════════════
function _checkCircuitBreaker() internal {
uint256 currentAUM = address(this).balance; // simplified — real impl tracks token balances
if (currentAUM < peakAUM) {
uint256 drawdown = ((peakAUM - currentAUM) * 10000) / peakAUM;
if (drawdown >= maxDrawdownBps) {
paused = true;
emit CircuitBreakerTriggered(drawdown);
}
} else {
peakAUM = currentAUM;
}
}
/// @notice Emergency withdrawal — always available
function emergencyWithdraw() external onlyOwner {
paused = true;
uint256 balance = address(this).balance;
totalDeposited = 0;
payable(owner).transfer(balance);
emit EmergencyWithdraw(balance);
}
}Hard policy enforcement on EVERY trade. Cannot be bypassed by validators or operators.
contract PolicyEngine {
struct Policy {
address[] whitelistedProtocols;
address[] whitelistedTokens;
uint256 maxTradeSizeUsd; // max single trade
uint256 maxDailyVolumeUsd; // daily volume cap
uint256 maxPositionConcentrationBps; // max % in single asset
uint256 maxSlippageBps;
uint256 minTimeBetweenTradesSecs; // anti-churning
uint256 maxLeverageBps; // for perp blueprints (10000 = 1x)
}
mapping(address => Policy) public vaultPolicies;
/// @notice Set policy — only vault owner can change
function setPolicy(address vault, Policy calldata policy) external;
/// @notice Check an intent against policy
function checkIntent(address vault, TradeIntent calldata intent)
external view returns (bool);
/// @notice Check if a protocol is whitelisted for a vault
function isWhitelisted(address protocol) external view returns (bool);
}contract FeeDistributor {
struct FeeConfig {
uint256 performanceFeeBps; // e.g., 2000 = 20% of profits
uint256 managementFeeBps; // e.g., 200 = 2% annual on AUM
uint256 validatorFeeBps; // e.g., 500 = 5% of performance fee to validators
}
mapping(address => FeeConfig) public vaultFees;
/// @notice Settle fees between operator and validators
function settleFees(address vault, uint256 profit) external;
}Catalog of available strategies for discovery. Not required for operation — convenience layer.
contract StrategyRegistry {
struct StrategyListing {
uint64 blueprintId; // which Tangle blueprint
address creator; // who created it
string name;
string description;
string strategyHash; // IPFS hash of strategy definition
FeeConfig fees;
uint256 totalAUM; // sum of all vaults using this strategy
uint256 totalReturn; // tracked performance
uint64 instanceCount; // number of active bots
}
/// @notice List a strategy for others to copy
function listStrategy(StrategyListing calldata listing) external;
/// @notice Get top strategies by AUM / return
function getStrategies(SortBy sort, uint256 offset, uint256 limit)
external view returns (StrategyListing[] memory);
}ABSOLUTE (cannot be bypassed by anyone):
├── Protocol whitelist — only approved DeFi contracts callable
├── Position limits — max trade size, concentration, daily volume
├── Circuit breaker — auto-pause on drawdown threshold
├── User withdrawal — always available (emergency mode when paused)
└── No raw transfers — vault can only call whitelisted protocol functions
STRONG (requires multi-party collusion):
├── Validator committee — N-of-M independent operators must approve
├── Reputation system — bad validators lose weight over time
└── Slashing — provable misbehavior loses stake
MODERATE (single operator controls):
├── Strategy execution — which trades to propose (bounded by above)
├── Timing — when to trade (rate-limited by policy)
└── Quality — how good the AI analysis is (market risk, not theft risk)
| Threat | Attack Vector | Mitigation | Residual Risk |
|---|---|---|---|
| Agent steals funds | Generate intent to transfer to attacker | Protocol whitelist — only DeFi calls, no raw transfers | Near zero |
| Operator steals funds | Submit malicious intents | Validator committee + policy engine | Requires majority validator collusion AND policy bypass |
| Validator collusion | Approve malicious trades | Policy engine is hard backstop — even unanimous validators can't bypass | Only exploitable if policy misconfigured |
| Bad trades (not malicious) | Poor AI decisions | Drawdown circuit breaker, position limits | Users accept market risk |
| Front-running by validators | Validators see intents first | Short deadlines, slashing for provable front-running | Partially mitigable |
| Churning | Excessive trading for fees | minTimeBetweenTrades, daily volume caps |
Low with proper policy |
| Malicious strategy code | User's code in sandbox tries to exploit | Sandbox is isolated, can only produce intents, all intents validated | Same security as any other intent |
The sandbox runs untrusted code — and that's fine. Whether the strategy is natural language, config, or user-written code, it all reduces to trade intents. The intent validation pipeline (validators + policy engine) is the security boundary, not the sandbox. The sandbox is a compute environment, not a trust boundary.
Intent
│
┌───────┴───────┐
│ Trade Size? │
└───────┬───────┘
│
┌────────────┼────────────┐
Small (<$1K) Medium Large (>$50K)
│ ($1K-$50K) │
Policy-only Committee Committee +
(instant) (2-5 sec) Time-delay (5min)
│ │ │
└────────────┼──────────────┘
│
On-chain policy
check (ALWAYS)
│
Execute
Small trades (~80% of volume) skip the validator committee entirely. Policy engine is the only check. This is critical for high-frequency strategies and gas efficiency.
| Step | Target | Notes |
|---|---|---|
| Intent generation (AI in sandbox) | 1-3s | Depends on model and strategy complexity |
| Fan-out to validators | 50-100ms | Parallel HTTP POST to all validators |
| Validator evaluation | 1-3s | AI inference + policy check |
| Signature collection | 100ms | Wait for quorum, not all |
| On-chain submission | 2s (L2) / 12s (L1) | Block confirmation |
| Total (standard path) | ~5-10s on L2 | Acceptable for non-HFT strategies |
| Chain | Why | Priority |
|---|---|---|
| Arbitrum | GMX, Vertex, Aave, low gas | P0 |
| Base | Aerodrome, Morpho, high volume | P0 |
| Polygon | Polymarket (CTF), Aave | P1 |
| Tangle | Validator/strategy registry, native | P0 |
ai-trading-blueprints/
├── Cargo.toml # workspace root
│
├── trading-runtime/ # Layer 1: shared trading lib
│ ├── Cargo.toml # depends on sandbox-runtime
│ └── src/
│ ├── lib.rs
│ ├── intent.rs
│ ├── validator_client.rs
│ ├── portfolio.rs
│ ├── market_data.rs
│ ├── vault_client.rs
│ ├── strategy.rs
│ ├── fee.rs
│ ├── types.rs
│ └── adapters/
│ ├── mod.rs
│ ├── uniswap.rs
│ ├── aave.rs
│ ├── morpho.rs
│ ├── gmx.rs
│ ├── pendle.rs
│ ├── polymarket.rs
│ ├── vertex.rs
│ └── eigenlayer.rs
│
├── validator-blueprint/ # Validator committee blueprint
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs # BlueprintRunner
│ ├── lib.rs # Jobs, ABI types
│ ├── jobs.rs # On-chain job handlers
│ ├── validation_server.rs # Off-chain HTTP server
│ ├── ai_evaluator.rs # AI risk assessment
│ └── reputation.rs
│
├── defi-yield-blueprint/ # Layer 2: yield optimizer
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs
│ ├── lib.rs
│ └── jobs.rs
│
├── dex-trading-blueprint/ # Layer 2: DEX trading
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs
│ ├── lib.rs
│ └── jobs.rs
│
├── prediction-market-blueprint/ # Layer 2: prediction markets
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs
│ ├── lib.rs
│ └── jobs.rs
│
├── perp-trading-blueprint/ # Layer 2: perpetuals
│ ├── Cargo.toml
│ └── src/
│ ├── main.rs
│ ├── lib.rs
│ └── jobs.rs
│
├── trading-agent/ # Runs inside sandbox container
│ ├── Cargo.toml # (or Python/JS — TBD)
│ ├── Dockerfile
│ └── src/
│ ├── main.rs
│ ├── strategies/
│ │ ├── mod.rs
│ │ ├── yield_optimizer.rs
│ │ ├── momentum.rs
│ │ ├── prediction.rs
│ │ └── perp.rs
│ ├── market_data.rs
│ ├── ai_client.rs
│ └── execution.rs
│
├── contracts/ # Shared Solidity contracts
│ ├── src/
│ │ ├── TradingVault.sol
│ │ ├── VaultFactory.sol
│ │ ├── PolicyEngine.sol
│ │ ├── StrategyRegistry.sol
│ │ ├── FeeDistributor.sol
│ │ ├── TradeValidator.sol
│ │ └── adapters/
│ │ ├── IProtocolAdapter.sol
│ │ ├── UniswapAdapter.sol
│ │ ├── AaveAdapter.sol
│ │ └── GmxAdapter.sol
│ └── test/
│ ├── TradingVault.t.sol
│ ├── PolicyEngine.t.sol
│ └── Integration.t.sol
│
├── foundry.toml
└── .github/
└── workflows/
├── ci.yml
└── foundry.yml
Solidity (the foundation everything else depends on):
PolicyEngine.sol— whitelist management, limit checks, rate limitingTradingVault.sol— deposit/withdraw, intent execution, circuit breakerVaultFactory.sol— deploy vaults per instanceTradeValidator.sol— signature verification, weight aggregationFeeDistributor.sol— performance + management fee logicStrategyRegistry.sol— strategy catalog- Full Foundry test suite
Rust — trading-runtime crate:
- Core types:
TradeIntent,Action,PortfolioState,StrategyDefinition ValidatorClient— fan-out, collect, aggregate signaturesVaultClient— on-chain vault interaction via alloyPortfolioTracker— position tracking, P&L, drawdownMarketDataClient— price feeds, pool state- Protocol adapter trait + Uniswap adapter (first integration)
- Contract ABI bindings (sol! macro)
- Job handlers: register, deregister, update_reputation, slash
- Off-chain HTTP validation server
- AI risk evaluation client (Claude API)
- Reputation tracking
- Integration tests with mock trading bot
Start with the simplest strategy type to prove the full pipeline end-to-end:
defi-yield-blueprint— instance-per-bot, sandbox provisioning- Job handlers: create instance, deposit, withdraw, pause, resume
- Trading agent container — yield optimizer strategy
- Aave + Morpho protocol adapters
- Full integration test: create bot → deposit → generate intent → validate → execute → withdraw
- DEX trading blueprint + Uniswap/Curve adapters
- Prediction market blueprint + Polymarket adapter
- Perp trading blueprint + GMX adapter
- Multi-strategy blueprint (combines all)
- Natural language strategy creation flow
- Security audit prep (invariant tests, fuzzing, formal verification of vault)
- Testnet deployment (Arbitrum Sepolia / Base Sepolia)
- Monitoring, alerting, dashboards
- Strategy marketplace UI (could be Blueprint Agent integration)
- Documentation + operator onboarding guide
-
Single owner per vault, or allow deposits from multiple users? Single owner is simpler (each bot = one user's funds). Multi-depositor creates a fund-like structure (more capital efficient but needs share accounting, ERC-4626).
-
Where do strategy definitions live? On-chain (expensive, transparent), IPFS (cheap, content-addressed), or in the sandbox state (ephemeral). Recommend: IPFS hash registered on-chain.
-
Trading agent language? Rust (fast, same toolchain), Python (ML ecosystem, most quants use it), or JS (accessible). Could support all via the sandbox — the container image determines the runtime.
-
Multi-chain execution? v1 single chain per blueprint instance. v2 could bridge assets and execute cross-chain, but adds significant complexity.
-
Validator selection per trade? All validators evaluate all trades (simpler), or route to specialized validators based on trade type (more efficient, more complex)?
-
How to handle tokens, not just ETH? Vault needs to track ERC-20 balances, approve protocols for token spending, and account for token value changes. Real implementation needs a token accounting layer.
-
Backtest before deploy? Would be great UX to let users test strategies on historical data before depositing real money. Could be a feature of the sandbox — run strategy against historical market data, report simulated P&L.
-
"Your AI, your rules, your custody." Users create their own bots with their own strategies. Funds stay in smart contracts they control. Emergency withdraw always available.
-
Layers of protection without TEE/MPC complexity. Policy engine (hard limits) + validator committee (soft checks) + circuit breaker (auto-pause). Simple, auditable, no exotic cryptography.
-
Transaction volume flywheel. Every bot trades → every trade = on-chain txs → more bots = more volume → more operators attracted → more bots.
-
Natural marketplace. Strategy creators compete on returns. Operators compete on reliability. Validators compete on accuracy. All tracked on-chain.
-
Modular blueprints. Add new strategy types without touching existing ones. Add new protocols by implementing an adapter. Add new chains by deploying contracts.
-
Composes with existing infra. Builds on
sandbox-runtime(container management) andai-agent-instance-blueprint(1:1 subscription pattern). Doesn't reinvent the wheel.