Overview
AlphaTrade is a decentralized GPU compute and AI-trading-model marketplace. The system has five layers, all in this repo:
- GPU Marketplace — providers list rigs, users rent and escrow ETH
- Model NFTs (ERC-7857) — trained AI models tokenized with zkML proofs
- Performance Oracle — verifies SNARK proofs and recomputes Sharpe on-chain
- Meta-Agent Vaults (ERC-4626) — autonomous trading bots that own model NFTs and rebalance a basket on Uniswap V3
- Frontend — Next.js 14 dApp covering all five tabs
Built for ETHGlobal Open Agents (approach C). Single-developer scope; all layers in one repo.
Quick Start (Local)
You need three terminals. After this you'll have a fully working dApp on Anvil.
bashcd /Users/pushkaraj/Documents/AlphaTrade/ComputeX-Contracts anvil
Note the 10 funded accounts and their private keys — you'll import a few into MetaMask.
bash# In a new terminal: cd /Users/pushkaraj/Documents/AlphaTrade/ComputeX-Contracts export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 export RPC_URL=http://127.0.0.1:8545 forge script script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast
bashforge script script/DeployMetaAgentLocal.s.sol:DeployMetaAgentLocal --rpc-url $RPC_URL --broadcast
Uses MockTradingExecutor (1:1 swaps) since Anvil has no real Uniswap deployment.
bashcd ../frontend npm install # only first time npm run dev # serves on http://localhost:3000
Add a network with RPC: http://127.0.0.1:8545, Chain ID: 31337, Symbol: ETH. Import any Anvil account's private key (account 0 is the standard one).
Testing the Full Flow
The full loop uses three Anvil accounts. Each row below is one MetaMask account switch.
| Step | Account | Tab | Action |
|---|---|---|---|
| 1 | Acc 0 — provider | 01 GPU Market | List a GPU |
| 2 | Acc 1 — renter | 02 Compute Jobs | Rent the GPU |
| 3 | Acc 0 — provider | 02 Compute Jobs | Complete Job (releases escrow) |
| 4 | Acc 1 — renter | 03 Model NFTs | Mint NFT (with 0.01 ETH stake) |
| 5 | Acc 1 | 04 Trade | List NFT for sale |
| 6 | Acc 2 — buyer | 04 Trade | Buy NFT |
| 7 | Any acc | 05 Meta-Agents | Deploy vault, mint USDC, deposit |
The Stack
Why these choices:
- Foundry over Hardhat — faster tests, native fuzzing, simpler scripts
- OZ v5.0.2 pinned — v5.6+ requires solc 0.8.24 which breaks Foundry's default toolchain
- EZKL Halo2 over Risc0/SP1 — smaller proofs (~29 KB) and ~38s prove time on M1
- ERC-4626 for vaults — battle-tested deposit/redeem accounting
Smart Contracts
zkML Pipeline
The off-chain pipeline lives in backend/zkml/:
model.py— AlphaMLP: 120→32→16→5 ReLU+softmax, ~3.4k paramstrain.py— PyTorch trainer, exports ONNX, deterministic SHA3 weights hashoracle_feed.py— generates GBM price feed, builds sorted-pair Merkle tree, signs rootbacktest.py+sharpe.py— bit-exact Sharpe-bps parity with Solidity_isqrtprove.py— full EZKL Halo2 pipeline (gen_settings → calibrate → compile → witness → setup → prove → EVM verifier)
Meta-Agents
A meta-agent is a fund + bot pair:
- On-chain: a
MetaAgentVaultholding USDC and a basket of 5 tokens - Off-chain: a Python runtime (
backend/meta_agent/runtime.py) that:- Listens for
AuditAcceptedevents from the oracle - Runs an EXP4 contextual bandit over eligible model NFTs
- Aggregates ONNX inference outputs into target weights
- Signs and submits
executeTrade(uint16[5] weights, blockNumber, sig)
- Listens for
The operator is whoever holds the agentId NFT in MetaAgentRegistry. They earn the perf fee on harvest. Depositors track the NAV.
Prerequisites
- Foundry — install with bash
curl -L https://foundry.paradigm.xyz | bash && foundryup - Node.js 20+ and npm
- Python 3.12 (for zkML + meta-agent runtime)
- MetaMask browser extension
- Optional: Halo2-compatible Linux box for prove.py (macOS arm64 has SRS issues)
Installation
bashgit clone <repo> AlphaTrade cd AlphaTrade # Smart contracts cd ComputeX-Contracts forge install forge build # Frontend cd ../frontend npm install # Backend (zkML + meta-agent) cd ../backend python -m venv .venv && source .venv/bin/activate pip install -r requirements.txt
Deploy Locally (Anvil)
bash# Terminal 1 cd ComputeX-Contracts && anvil # Terminal 2 cd ComputeX-Contracts export PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 export RPC_URL=http://127.0.0.1:8545 forge script script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast forge script script/DeployMetaAgentLocal.s.sol:DeployMetaAgentLocal --rpc-url $RPC_URL --broadcast # Terminal 3 cd frontend && npm run dev
Anvil addresses are deterministic — they match the values pre-baked into frontend/app/lib/contracts.ts. No copy-paste needed.
Deploy to Ethereum Sepolia
Plan 1 + Plan 2 contracts are already live on Sepolia. To redeploy, fund the deployer with ~0.02 ETH on Sepolia, then:
bashexport PRIVATE_KEY=<your-key> export RPC_URL=https://ethereum-sepolia-rpc.publicnode.com forge script script/Deploy.s.sol:Deploy --rpc-url $RPC_URL --broadcast forge script script/DeployMetaAgent.s.sol:DeployMetaAgent --rpc-url $RPC_URL --broadcast
The DeployMetaAgent script uses real Uniswap V3 addresses on Sepolia (SwapRouter02 = 0x3bFA4769FB09eefC5a80d6E87c3B9C650f7Ae48E). Mock USDC/WBTC/LINK/UNI are deployed inline since canonical testnet addresses don't exist.
MetaMask Setup
- Network name:
Anvil - RPC URL:
http://127.0.0.1:8545 - Chain ID:
31337 - Currency symbol:
ETH(ignore the GoChain warning — harmless)
From Anvil's startup output, grab the first 3 private keys and import each as a separate account:
- Acc 0 — provider —
0xac09…2ff80 - Acc 1 — renter / creator —
0x59c6…690d - Acc 2 — buyer / depositor —
0x5de4…b365a
Guide: List & Rent a GPU
Click + List GPU → fill metadata + price → submit. After tx lands, the table shows your GPU as #0.
The gpuId is auto-prefilled. Set duration → click Rent GPU & Start Job. Escrow locks price × duration ETH.
Click ✓ Complete Job (Provider). Escrow releases to you. Mint right unlocks for the renter.
Guide: Mint & Trade Model NFT
Job ID auto-prefilled. Click Mint Model NFT. Sends 0.01 ETH creator stake. Token #1 minted to you.
Token ID auto-prefilled. Set price (e.g. 0.05 ETH) → Approve & List (two transactions: approve + listModel).
Click the listing → Buy Model NFT. Pays 0.05 ETH; contract splits 92.5% to seller / 5% royalty to creator / 2.5% fee.
Guide: Deploy a Meta-Agent Vault
Set perfFeeBps (e.g. 500 for 5%). Click Deploy Agent Vault. Spawns ERC-4626 vault, mints you the operator NFT.
Click Faucet: Mint 1,000 USDC in the right sidebar. Anvil + Sepolia both support this.
Click Details on your vault row → see NAV chart, holdings, recent trades. Or click Deposit to put USDC in.
Guide: Run the Python Runtime
bashcd backend source .venv/bin/activate # Train a model and export ONNX python -m zkml.train --job-id 0 --output /tmp/ax_train # Run the meta-agent runtime cat > config.json << EOF { "rpc_url": "http://localhost:8545", "vault_addr": "<your vault address from Tab 05>", "operator_key": "<operator's private key>", "oracle_addr": "<PerformanceOracle address>", "model_dir": "/tmp/ax_train", "tick_seconds": 30, "score_threshold_bps": 0 } EOF python -m meta_agent.runtime --config config.json
Every tick_seconds, the bandit picks model NFTs, ONNX inference produces basket weights, the runtime signs and submits executeTrade.
Contract Addresses
Anvil (chain 31337) — deterministic
| GPUMarketplace | 0x5FbDB2315678afecb367f032d93F642f64180aa3 |
| ModelNFT | 0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512 |
| ModelMarketplace | 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0 |
| MetaAgentRegistry | 0x0B306BF915C4d645ff596e518fAf3F9669b97016 |
| MockTradingExecutor | 0x9A676e781A523b5d0C0e43731313A708CB607508 |
| MockUSDC | 0x8A791620dd6260079BF849Dc5567aDC3F2FdC318 |
Ethereum Sepolia (chain 11155111) — live
| GPUMarketplace | 0xefE063A1876Bf0FB4Bb8BF1566A5B74B000f4654 |
| ModelNFT | 0x7695a2e4D5314116F543a89CF6eF74084aa5d0d9 |
| ModelMarketplace | 0xF602913E809140B9D067caEEAF37Df0Bdd9db806 |
| MetaAgentRegistry | 0x7EE3d703B7304909a9Ecee8eE98DbacA0556A8F5 |
| TradingExecutor | 0xbC8c435B2343493693f09b9E3e65D8141D69499d |
| MockUSDC | 0x5aC67ADcd97E0390c66eB8a52305dC13D05103e5 |
Key Events
solidity// GPUMarketplace event GPUListed(uint256 indexed gpuId, address indexed provider, uint256 pricePerHour, string metadata); event JobCreated(uint256 indexed jobId, address indexed renter, uint256 indexed gpuId, uint256 duration, uint256 totalCost); event JobCompleted(uint256 indexed jobId, address indexed renter, uint256 indexed gpuId); // ModelNFT event ModelMinted(uint256 indexed tokenId, uint256 indexed jobId, address indexed creator, string modelCID, string proofCID); event PerformanceScoreUpdated(uint256 indexed tokenId, uint256 score, uint256 sharpeBps); // PerformanceOracle event AuditAccepted(uint256 indexed tokenId, uint256 indexed epoch, uint256 sharpeBps, uint256 nTrades); // MetaAgentVault event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event TradeExecuted(uint256 indexed blockNumber, uint256 navBefore); event Harvested(uint256 nav, uint256 gain, uint256 feeShares);