尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
A parimutuel stock prediction market built on Robinhood Chain Mainnet, using native Stock Tokens (TSLA, AMZN, PLTR, AMD, NVDA) and live Chainlink Data Feeds as the price oracle.
Live Demo · Network: Robinhood Chain Mainnet (Chain ID 4663)查看完整 README ↗
A parimutuel stock prediction market built on Robinhood Chain Mainnet, using native Stock Tokens (TSLA, AMZN, PLTR, AMD, NVDA) and live Chainlink Data Feeds as the price oracle.
Live Demo · Network: Robinhood Chain Mainnet (Chain ID 4663)
b7b2071, d45fb8e). Real on-chain
history to date: 29 createMarket, 27 lockMarket, 27 settleMarket,
3 placeBet, 2 claimWinnings (independently counted, da13c80; second
claimWinnings on market 14 appeared on-chain 2026-09-08).f40f9a1, 0e2688d,
through subsequent fixes to 17c4ba9).lockMarket/settleMarket operation (664d535,
b4748f6, and other maint: commits).da13c80, added
September 3, 2026 ahead of Continuity Track submission): a Python
reference model derived from the contract's external spec/ABI, cross-checked
against all 27 real settleMarket transactions and both real
claimWinnings transactions pulled directly from chain. 29/29 match; trace
sealed via SHA-256 (verification/settlement/commitments.sha256).
Findings: no decimals-normalization in the price-read path (dormant to
date); README's claimed no-winner refund path has no implementation
(never triggered); all real settlements to date resolved via
tie-defaults-to-BULL rather than genuine price movement. A follow-up check
(1db88b1) found genesis-era rounds on all 5 price feeds report answers
scaled at 18 decimals instead of the 8 decimals() reports — 222
anomalous rounds total, non-uniform cutoffs per feed, confirmed one level
below the proxy via .aggregator(). To our knowledge this is undocumented
elsewhere. No real settlement has touched an anomalous round to date
(~9.9-day buffer). Full detail in
verification/settlement/comparison_report.md.relayer/), gates fund-committing
agent actions on AgentBook human-verification. StockPredictionMarketV2.placeAgentBet()
validates and consumes the attestation on-chain; broadcasting that transaction is still a
manually-triggered step, and the live agent wallet currently reads unbacked on AgentBook.
See Honest Disclosure below.subgraph/, PriceRangeIndex rolling-window stats, verified
against a Python reference model on 89 real on-chain events (verification/graph-computation/).decision-engine/, BULL/BEAR/NO_TRADE over
PriceRangeIndex + relayer attestation status, verified against a Python reference model on
the same 89 real snapshots (verification/decision/). See
Honest Disclosure and docs/spec.md for the momentum
vs. mean-reversion signal-direction choice./agent-activity (AgentDecisionPanel component,
backed by frontend/api/agent-status.js), a read-only visualization of the live agent decision
pipeline. Reuses decision-engine/ and relayer/ modules directly rather than reimplementing
any logic; never calls placeBet() or placeAgentBet(). This is currently the only place a
user can actually observe the pipeline described in
Honest Disclosure below, rather than just read about it.Chain-Native Stock Token Integration
Each market is anchored to a Robinhood Chain native stock token address. createMarket() accepts address stockToken directly, creating an on-chain verifiable link between the prediction market and the actual tokenized equity — something only possible on a chain purpose-built for RWA.
Live Chainlink Data Feeds
The contract reads real-time stock prices via Chainlink AggregatorV3Interface. Each stock has a dedicated ChainlinkPriceFeed wrapper deployed on Robinhood Chain Mainnet, connected to Chainlink's official price feed proxies live from day one of mainnet launch.
Parimutuel Settlement No order book, no counterparty risk. BULL and BEAR pools accumulate independently. At settlement, the winning side splits the total pool proportional to their stake, minus a 2% protocol fee.
Full Market Lifecycle
OPEN → LOCKED → SETTLED. lockMarket() snapshots the opening price from the oracle. settleMarket() reads the closing price and determines the winning direction.
Source: docs/architecture-source.html (rendered via Puppeteer — see the comment at the top of
that file before editing either one).
*Fixed 2026-09-22 per ADR-12 (
prompts/15-refund-tie-openprice-fix.md):openPriceis now snapshotted insidecreateMarket(), at the moment the market is opened, so bettors always have an on-chain reference price to bet against for the entire OPEN window.lockMarket()is now a pure state transition — it no longer reads the price feed at all. If a Chainlink round hasn't updated between open and settle andclosePrice == openPrice,settleMarket()now puts the market into aREFUNDstate instead of defaulting to a BULL win: every bettor on both sides reclaims their exact original stake viaclaimWinnings(), with no fee deducted.settleMarket()also falls back to the sameREFUNDstate if the price-implied winning side's pool is empty (nobody actually bet on the direction the price moved) — this closes a fund-lock gap an independent security review found, where the losing side's entire pool would otherwise become permanently unclaimable. This is tested behavior (test_12_tieSettlement_refundBothSides,test_19_tieDirectionOnly_noBets_matchesTC09,test_22_refundState_bothSidesClaimFullPrincipal_skewedPools,test_23_settleMarket_emptyWinningSideBull_refunds,test_24_settleMarket_emptyWinningSideBear_refundsintest/StockPredictionMarketV2.t.sol). Both price reads (createMarket()'sopenPrice,settleMarket()'sclosePrice) also now validate the oracle response itself — the price must be positive, the round must be complete (answeredInRound >= roundId), and the update must be no older thanSTALENESS_THRESHOLD(4 hours) — before it's trusted for any market logic. The originalStockPredictionMarketV2deployment (0x59DF30E22bdaC70764a5DbF8bBa51BC5a595759C, now deprecated) carried this limitation as documented, intentional-but-unfixed behavior — see ADR-12 for the full before/after context.
| Contract | Address |
|---|---|
| StockPredictionMarketV2 (V3 fix) | 0x06897Ce6A2492BE99B59a7c023A64A6C0Af37849 — deployed 2026-09-22 per ADR-12 (prompts/15-refund-tie-openprice-fix.md), fixing the openPrice-snapshot-timing and default-BULL-tie bugs described below, plus three follow-up fixes from an independent security review (empty-winning-side REFUND, Chainlink oracle staleness/round/timestamp validation) |
| StockPredictionMarketV2 (original) | 0x59DF30E22bdaC70764a5DbF8bBa51BC5a595759C — deprecated 2026-09-22, superseded by the V3 fix above; no longer referenced by frontend, decision-engine, or any new code |
| StockPredictionMarket | 0x72DAb8B1B53b3CF028e9A0d1E21178981f264245 — deprecated, no longer referenced by frontend or any new code |
| AgentStockMarket | 0xE8b3916Ea16AD2F2C0910bB94005e30F5CC341D3 — deployed 2026-09-05, superseded one day later when ADR-10 merged its attestation-verification logic into StockPredictionMarketV2.placeAgentBet(); no longer referenced by any frontend, decision-engine, or relayer code |
| TSLA ChainlinkPriceFeed | 0x072A3A0C04Cf8CDcaf5B4A73a4Ed4fF5A841531f |
| AMZN ChainlinkPriceFeed | 0xcAC5B9d2817325E78090E3Ce4b9C299C819cF953 |
| PLTR ChainlinkPriceFeed | 0xBdC53E50b1167cE1199bFaD54A034f7ab1741051 |
| AMD ChainlinkPriceFeed |
| Ticker | Feed Address |
|---|---|
| TSLA/USD | 0x4A1166a659A55625345e9515b32adECea5547C38 |
| AMZN/USD | 0xD5a1508ceD74c084eBf3cBe853e2C968fB2a651C |
| PLTR/USD | 0x820ABedFF239034956B7A9d2F0a331f9F075eB4c |
| AMD/USD | 0x943A29E7ae51A4798823ca9eEd2ed533B2A22C72 |
| NVDA/USD | 0x379EC4f7C378F34a1B47E4F3cbeBCbAC3E8E9F15 |
| Contract | Address |
|---|---|
| StockPredictionMarket | 0x15636CE4C0EdE55335f84E6386f8F49C897c077d |
# 1. Install dependencies
npm install
# 2. Configure environment
cp .env.example .env
| Variable | Description |
|---|---|
PRIVATE_KEY | Deployer wallet private key (no 0x prefix) |
# 3. Compile
npx hardhat compile
# 4. Deploy to mainnet
npx hardhat run scripts/deploy.js --network robinhoodMainnet
// Create a new prediction round
createMarket(address stockToken, address priceFeed, string symbol, uint256 duration) returns (uint256 marketId)
// Place a bet (send ETH as value)
placeBet(uint256 marketId, Direction direction) // Direction: 0 = BULL, 1 = BEAR
// Lock market and snapshot opening price
lockMarket(uint256 marketId)
// Settle market and determine winner
settleMarket(uint256 marketId)
// Claim winnings after settlement
claimWinnings(uint256 marketId)
Fees
Security
Live Chainlink Integration
Robinhood Chain launched mainnet on July 1, 2026 with Chainlink as the official oracle layer from block zero. This contract integrates Chainlink Data Feeds via a ChainlinkPriceFeed wrapper that implements IPriceFeed (mirrors AggregatorV3Interface). Replacing or upgrading feeds requires only a constructor argument change — zero contract modifications.
Stock Token as Market Identifier On most chains, a prediction market would use an arbitrary string or uint to identify a market. On Robinhood Chain, we use the native stock token contract address directly, creating an on-chain verifiable link between the prediction market and the actual tokenized equity.
The relayer/ service is a trusted-signer relayer bridge, not a trust-minimized one. It
verifies a World AgentKit-signed agent request, checks the agent's wallet against World Chain's
AgentBook for a registered humanId, enforces its own replay-nonce, and signs an attestation
with a relayer-held private key. StockPredictionMarketV2.placeAgentBet()
(contracts/StockPredictionMarketV2.sol) does verify and consume that attestation on-chain: it
ecrecovers the signature against relayerAddress, checks expiresAt and usedAttestations,
and credits the bet into the same bullPool/bearPool a human's placeBet() uses.
decision-engine/src/agent-tx.js builds, simulates, and can broadcast that transaction from the
agent's own wallet — the agent pays its own gas, the relayer never funds or broadcasts anything
— but its own code comment is explicit that the broadcast step is never invoked automatically
and is meant to be wired up only behind an explicit human confirmation. Nothing in this pipeline
runs unattended end-to-end today.
Separately: the agent wallet this project actually uses currently reads unbacked on AgentBook
(57/57 live reads against real, freshly generated addresses returned unbacked — see
prompts/08-world-id-orb-availability-constraint.md), because obtaining a real Orb-verified
World ID is blocked by an external constraint: Taiwan has no stably operating Orb location, and
a possible World ID Sandbox workaround was never confirmed compatible with AgentBook's on-chain
groupId=1 check. Concretely, this means the relayer currently refuses to sign an attestation
for this agent at all (agent_not_human_backed), so placeAgentBet() can never be reached with
a validly-signed attestation through the real pipeline as it stands — the backed branch's
correctness has been verified by code review and unit tests only (relayer/src/agent-book.js,
exercised in relayer/test/replay.test.js and decision-engine/test/), not by a live on-chain
bet.
Separately, and identified after the fact during design: World ID (and therefore AgentBook)
proves an agent maps to one distinct real human — uniqueness — not that the human authorized
this specific spend or amount, and not a post-hoc auditable record of that authorization. The
current design only blocks agent bets with no real human behind them at all; it does not yet
cover spend limits, scoped authorization, or accountability after the fact. See
prompts/03-calibrated-autonomy-boundary.md for the full reasoning.
The lookupHuman three-state read (backed / unbacked / unknown, so an AgentBook RPC
failure is never reported as "not registered") follows the pattern documented in
poh-aggregator's
lookupHumanBacking —
credited here as prior art this implementation deliberately follows, not independently arrived at.
| Layer | Technology |
|---|---|
| Smart contract | Solidity ^0.8.20 |
| Development | Hardhat 3 + ethers.js |
| Oracle | Chainlink Data Feeds (AggregatorV3Interface) |
| Stock tokens | Robinhood Chain native (TSLA, AMZN, PLTR, AMD, NVDA) |
| Frontend | React + wagmi v2 + Vite |
| Deployment | Vercel |
✅ M1 — Contract Deployment
✅ M2 — Frontend
✅ M3 — Mainnet
⬜ W3 — Keeper Automation
⬜ W4 — Architecture Diagram
⬜ W5 — NatSpec Documentation
GitHub: pplmaverick
Wallet: 0xed2B5717c9b936ecC76d75401026A99143e278F5
MIT
| NVDA ChainlinkPriceFeed | 0x914c40a644493b47336de847b0404E729e06C68d |