Overview
Clef is Cloudflare's family of decision models: you send a state and typed questions, and the model returns probabilities over a bounded schema instead of text. Clef is trained to be calibrated, with a Brier loss and with partial credit for adjacent ordinal choices.
Clef on chain turns that idea into a market. Every hour the chain publishes a decision request in the exact Clef shape, about tokenized stocks and ETH. Anyone answers with probabilities and a stake: a person in the app, or an agent running Clef or any other model. When the hour closes the chain reads what happened, scores every entry with the same proper scoring rules, and redistributes the stakes so that well calibrated entries earn from poorly calibrated ones. There is no oracle operator and no house edge on losses.
- Round
- one hour, every hour
- Entries close
- 5 minutes before the hour
- Questions
- 3 on weekdays, 2 on weekends
- Answered by
- soft outcomes from TWAPs
- Scored by
- Brier and ranked probability
- Paid by
- weighted-score wagering
- Fee
- 5% of profit, none on a loss
- Stake
- 0.0005 to 0.1 ETH, 1 ETH a round
This is an independent builders camp project. It borrows Clef's request shape and the scoring Clef is trained on. It does not run Cloudflare's model for you: the baseline shown in the app is our own Clef reference.
How a round works
Round n is the hour that starts n × 3600 seconds after the Unix epoch. Its timing is fixed by two immutable numbers: the period P = 3600 s and the TWAP window W = 300 s. Nothing needs a keeper to open or close a round; the contract reads the clock.
- Open. Entries for round n open at
start − P − Wand stay open for one full period. At any moment exactly one round is open: . - Lock. Entries close at
start − W, five minutes before the hour, which is exactly when the start TWAP window begins. Nobody who enters knows any part of the reference price. - Start price. The time-weighted average price over
[start − W, start]. - End price. The time-weighted average price over
[end − W, end]. The move that decides every question is the change between the two. - Settle. Anyone may call
settle(n)onceblock.timestamp ≥ end. The contract reads every pool once, turns each move into the chain's answer and freezes it. A keeper settles ended rounds within minutes of the hour; if it has not, the first claim settles the round. - Claim.
claim(rounds)pays every listed round in one ETH transfer. Once a round is settled there is no deadline: the answer is stored, so a claim works days later.
The questions
The weekday card mirrors the blog's urgent, team and severity example: one yes or no question, one categorical choice and one ordinal score. Each question resolves from the start to end TWAP move D of an asset, in tick-seconds (1 tick = 1.0001×, about one basis point; D / W is the move in ticks). M is the soft margin of the next section.
Weekday card · stock session
| Key | Type | Asks | Resolves on |
|---|---|---|---|
up | noul | Yes above 0, soft margin 12 ticks | |
lead | choice | The largest move, soft margin 20 ticks | |
severity | score | No impact under 0.10%, Minor to 0.25%, Major to 0.50%, Critical beyond; soft margin 2 ticks |
Weekend card · ETH only
| Key | Type | Asks | Resolves on |
|---|---|---|---|
up | noul | Yes above 0, soft margin 3 ticks | |
severity | score | Same buckets as the weekday card; soft margin 2 ticks |
Which card a round gets depends on when its hour starts. Tokenized stocks trade around the clock, but outside Robinhood's 24/5 stock session their pools go quiet and become cheap to push, so stock questions are only asked while the session is open. The contract keeps a 168 bit hour-of-week schedule, with hour 0 at Monday 00:00 UTC (1 January 1970 was a Thursday, 72 hours after a Monday):
- Monfrom 02:00
- Tueall day
- Wedall day
- Thuall day
- Friall day
- SatETH only
- SunETH only
Daylight saving. The stock session runs Sunday 20:00 to Friday 20:00 New York time: Monday 00:00 to Saturday 00:00 UTC in summer time, and one hour later in winter time (1 November 2026 to 14 March 2027). The schedule is kept in UTC and does not move with the clocks, so it starts at hour 2: in winter time the session opens at 01:00 UTC, and the first weekday round still takes its start price from 01:55 to 02:00, inside the session. Hours 2 to 119 keep both price windows of every weekday round inside the session in summer and in winter. US market holidays are not modelled: on a holiday the weekday card runs on quiet stock pools, unless the owner switches the schedule for that day.
The owner can change the schedule for rounds that have not started. A round keeps the card it was born with: the card is fixed at its first entry, enter takes the card number and reverts if it is not the one due, and the app always asks the contract, schemaFor(n), which card a round gets.
How the chain answers
A hard line such as "Yes when D > 0" is cheap to game in a quiet hour: hold a pool one tick off for a second and a close call flips. So the chain answers the way a decision model does, with probabilities. Each question has a soft margin M in ticks, and the answer is an outcome vector o in basis points that slides smoothly from one option to the next as the move crosses a line. A push of d tick-seconds moves a yes or no answer or a bucket by at most about 5,000 d / (M W) basis points, and a choice among K by at most about (K − 1) × 10,000 d / (M W); turning a clear answer around takes M ticks held for the whole 5 minute window, against every arbitrageur. Every division rounds toward minus infinity and every value is clamped to 0 to 10,000.
noul · above or below a line
The line is b ticks (0 for up or down), and ono = 10,000 − oyes. A move of half the margin above the line reads 75% Yes; a full margin or more reads 100%.
choice · the leader
Every asset within M ticks of the leader shares the answer, closer ones more. The rounding remainder goes to the first leader in the list.
score · ordered buckets
The bucket lines are b0 < b1 < b2. O is the answer's cumulative distribution, with OK−1 = 10,000 and x = |D| for a question about the size of a move.
With a large move every vector is one-hot and the answer is exactly the hard rule. Near a line it is a split: NVIDIA up 6 ticks with M = 12 gives x = 1,800 and oyes = 5,000 + ⌊5,000 × 1,800 / 3,600⌋ = 7,500, so the chain answers Yes 75%, No 25%. Proper scoring still holds: your expected score is highest when you report the answer you expect.
Scoring
Every question is scored by a strictly proper scoring rule: your expected score is highest when you report exactly what you believe. The contract works in integer losses: your probabilities p and the chain's answer o are both in basis points, so every loss is an exact integer and lib/score.js reproduces the contract bit for bit.
Brier · noul and choice
The squared distance between your forecast and the chain's answer. The score is s = 1 − L / N: 1 for certainty on a clear answer, 0 for certainty on a wrong one, 0.75 for a coin flip on a yes or no.
Ranked probability score · score
The same idea on cumulative probabilities, so saying Major when the answer is Minor costs less than saying Critical: adjacent ordinal choices get partial credit, which is the idea behind Clef's RLCD training. Again s = 1 − L / N.
Card score
Entry i's mean score over the Q questions of its card: 1 is a perfect card. The scores are for reading; the money math below uses the exact losses.
Payout
Stakes are redistributed by the weighted-score wagering mechanism (Lambert, Langford, Wortman, Chen, Reeves, Shoham and Pennock, 2008). With stakes wi, the pot W = ∑ wj, the card scores Si defined above, and the room's stake-weighted mean S̄ = ∑ wj Sj / W:
Weighted-score wagering
Here Si is the card score, the mean of your question scores between 0 and 1. Score above the room and you gain in proportion to your stake; score below it and you lose in proportion.
The exact integer math
The contract never stores a score. At entry it adds each forecast into three running sums per question: W += w, Q2[q] += w ∑ u2 and Q1[q][j] += w uj, where u is p for a Brier question and the cumulative c for a ranked one. After settlement the room's total loss on question q follows exactly from the answer v (o, or the cumulative O):
With Λ the least common multiple of the questions' normalisers Nq (6 × 108 for both cards), each payout is one division, rounded toward minus infinity and clamped at zero:
Since (Tq − W Liq) / (W Nq) = siq − s̄q, the fraction is wi (Si − S̄): the line above, computed without a single rounded intermediate.
Why it adds up
Before rounding the gains and losses cancel exactly, question by question:
So the payouts sum to the pot. Solidity's / truncates toward zero, which would round a loser's negative correction up and could pay out a wei more than the pot; with a floor the payouts can only fall short of it, by at most one wei per entry. That dust stays in the contract.
Why honesty pays
Pull your own score out of the mean and the payout reads
The other entries' scores do not depend on your forecast, and your own score enters with a positive weight whenever anyone else has entered. Your payout is a positive affine transform of a strictly proper score, so it is maximized in expectation by reporting your true beliefs. The mechanism also has these properties:
- Budget balanced. It pays out what came in, minus the fee on profits and at most a wei of rounding per entry.
- Sybil-proof. Splitting one stake across many wallets with the same forecast pays the same, up to a wei of rounding per wallet.
- Individually rational. By its own beliefs, an honest forecaster expects at least its stake back before the fee, because no other report scores better in its eyes.
- Neutral when everyone agrees. If every entry reports the same probabilities, everyone gets the stake back.
- A lone entry is refunded exactly. With one entry, Si = S̄.
- The fee bends it a little. Because the fee is taken from profit only, a forecaster gains slightly by shading toward the room. At a 5% fee the best report moves by less than 2 percentage points from your true belief.
Worked example
Three wallets enter one weekday round. The forecasts and the price moves are illustrative; every number after them is what the contract computes, to the wei.
Computed with the contract's exact integer rules.
1 · What happened
At settle the contract reads each pool's tickCumulatives and gets these moves, in tick-seconds (divide by W = 300 for ticks):
NVDA+1,800+6 ticks
GOOGL+3,600+12 ticks
ETH−4,800−16 ticks
So the chain answers:
up: x = 1,800 and M W = 12 × 300 = 3,600, so oyes = 5,000 + ⌊5,000 × 1,800 / 3,600⌋ = 7,500: Yes 75%, No 25%.lead: GOOGL leads with 3,600 and M W = 20 × 300 = 6,000, so g = 4,200 for NVDA (1,800 behind), 6,000 for GOOGL and 0 for ETH (8,400 behind). ⌊10,000 × 4,200 / 10,200⌋ = 4,117 and ⌊10,000 × 6,000 / 10,200⌋ = 5,882, plus the remainder of 1 for the leader: NVDA 41.17%, GOOGL 58.83%, ETH 0%.severity: |D| = 4,800 sits between the 0.10% line (3,000) and the 0.25% line (7,500), far beyond the 2 tick margin of either: Minor 100%.
2 · The entries and the chain's answer
| Option | A · calibrated | B · bold | C · flat | Chain's answer |
|---|---|---|---|---|
| Stake | 0.01 ETH | 0.02 ETH | 0.005 ETH | |
up Will NVIDIA close higher? | ||||
| Yes | 60.00% | 95.00% | 50.00% | 75.00% |
| No | 40.00% | 5.00% | 50.00% | 25.00% |
lead Which gains the most? | ||||
| 35.00% | 70.00% | 33.34% | 41.17% | |
| 40.00% | 15.00% | 33.33% | 58.83% | |
| 25.00% | 15.00% | 33.33% | 0.00% | |
severity How far will ETH move? | ||||
| No impact | 20.00% | 5.00% | 25.00% | 0.00% |
| Minor | 45.00% | 5.00% | 25.00% | 100.00% |
| Major | 25.00% | 10.00% | 25.00% | 0.00% |
| Critical | 10.00% | 80.00% | 25.00% | 0.00% |
3 · Losses and scores
| Score s and loss L | A | B | C |
|---|---|---|---|
up Brier | 0.977500L 4,500,000 | 0.960000L 8,000,000 | 0.937500L 12,500,000 |
lead Brier | 0.949118L 10,176,378 | 0.851138L 29,772,378 | 0.908878L 18,224,478 |
severity RPS | 0.942500L 17,250,000 | 0.515833L 145,250,000 | 0.875000L 37,500,000 |
| Card score S, the mean | 0.956373 | 0.775657 | 0.907126 |
Check one by hand. A's up loss is (6,000 − 7,500)² + (4,000 − 2,500)² = 4,500,000, so its score is 1 − 4,500,000 / 200,000,000 = 0.9775. A's severity loss uses the cumulative forecast 2,000, 6,500 and 9,000 against the answer's 0, 10,000 and 10,000: 2,000² + 3,500² + 1,000² = 17,250,000. B was confident on the wrong leader and on a big ETH move, and its card shows it: confidence is not calibration.
4 · Payouts
The pot is W = 35,000,000,000,000,000 wei. The room's total losses are T = 267,500,000,000,000,000,000,000, 788,333,730,000,000,000,000,000 and 3,265,000,000,000,000,000,000,000 for the three questions, Λ = 6 × 108, and the room's mean card score S̄ is 0.846071. With Q = 3 and the 5% fee on profit:
| In wei | A | B | C |
|---|---|---|---|
| Si − S̄ | +0.110301 | −0.070414 | +0.061054 |
| Stake | 10,000,000,000,000,000 | 20,000,000,000,000,000 | 5,000,000,000,000,000 |
| Payout | 11,103,012,936,507,936 | 18,591,714,761,904,761 | 5,305,272,301,587,301 |
| Profit | 1,103,012,936,507,936 | −1,408,285,238,095,239 | 305,272,301,587,301 |
| Fee, 5% of profit | 55,150,646,825,396 | 0 | 15,263,615,079,365 |
| Received | 11,047,862,289,682,540 | 18,591,714,761,904,761 | 5,290,008,686,507,936 |
| Received, ETH | 0.01104786228968254 | 0.018591714761904761 | 0.005290008686507936 |
The payouts sum to 34,999,999,999,999,998 wei, the pot minus 2 wei: every payout rounds toward minus infinity, and B's exact correction, −1,408,285,238,095,238.09, floors to −1,408,285,238,095,239. The fees, 70,414,261,904,761 wei, accrue to the treasury. B paid for being sure of the wrong things; C, who said nothing, still beat the room's mean and made a little; A made the most per ETH staked.
Fees, limits, void rounds
Fee
Only when the payout is above the stake w: the fee is taken from profit only, and a losing or break-even entry pays nothing.
- Rate. 500 basis points (5%) by default, with a hard maximum of 1,000 written into the contract. A new rate takes effect 24 hours after the owner sets it, and each round keeps the rate in force at its first entry, so a change never touches a round already in play.
- Where it goes. Fees accrue in the contract and
withdrawFees()sends them to the treasury. Nothing else can leave the contract except payouts to the wallets that staked. - Limits. 0.0005 to 0.1 ETH per entry, up to 1 ETH per round, one entry per wallet per round. The caps are deliberately small at launch while the pools prove deep (see accepted risks).
- Void rounds. If any pool's
observecall reverts at settle (for exampleOLD, when its observation buffer no longer reaches back to the round), the round is void and every entry gets its full stake back with no fee. - Pause. The owner can pause new entries. A pause never blocks
settleorclaim, and the owner can never move a player's stake.
Prices and TWAPs
Every price comes from a Uniswap V3 pool on Robinhood Chain quoted in USDG. A pool keeps a running sum of its tick over time, the tickCumulative. For round n the contract makes one observe call per pool with four look-backs and gets c0 to c3, the cumulatives at start − W, start, end − W and end:
D is W times the change of the 5 minute mean tick, with no rounding at all. Where the asset is the pool's second token the sign flips. One tick is a factor of 1.0001, so D / W is the move in roughly basis points.
Why not the Chainlink feeds
The Robinhood stock feeds on this chain update in 0.5% steps with a 24 hour heartbeat, on the 24/5 market calendar. An hourly question would almost always resolve to "no change". The deep USDG pools trade around the clock and keep between 15 and 180 hours of observations, so observe at settle time still reaches the round long after it ends. A 5 minute TWAP also costs real money to push: moving it means holding the price away from every arbitrageur for the whole window.
Deep enough to settle
A pool writes at most one observation per second, so someone could roll a short buffer over by trading in enough distinct seconds, and an observe that no longer reaches the round would void it. The contract refuses a card unless every pool it reads keeps at least P + W + 600 = 4,500 observations, and it only registers pools that the Uniswap V3 factory itself vouches for. ETH keeps about 10,800 observations and NVDA and GOOGL keep 7,200 each, far more than a round needs when it is settled within minutes of the hour.
Three assets wait. lead races NVIDIA and Alphabet against ETH because all three pools are deep and their prices are pulled back by arbitrage when someone pushes them: the stocks against their listed shares while the market is open, ETH against every other exchange around the clock. SpaceX (SPCX) is a private company, so its token has no outside price that anyone could arbitrage a push against. Tesla's pool charges a 0.3% fee, which lets its price sit up to about 30 ticks off without arbitrage, too loose for an hourly race. Cloudflare (NET) keeps 1,400 observations today and joins a card once its pool grows.
Registered assets. The cards read ETH, NVDA and GOOGL; the others are ready for later cards.
For agents
The round is a Clef call. An agent fetches the request, asks a decision model, turns the answer into basis points and sends one transaction.
1 · Fetch the round
GET /api/round (or /api/round?n= for a given round) returns { round, schemaId, timing, request, reference, encoding, ... }. The request field is exactly the body Clef expects, and it already carries the right card for the hour:
{
"model": "clef",
"state": "Clef decision round 497,479 on Robinhood Chain. The hour runs 2026-10-02 07:00 to 08:00 UTC and entries close at 06:55 UTC.\nEach move is measured between 5 minute TWAPs of Uniswap V3 pools quoted in USDG, at the start and at the end of the hour.\nSnapshot at 2026-10-02 05:57 UTC:\nNVIDIA (NVDA): $232.02, last hour +0.10%, 24 h range $229.50 to $232.38.\nAlphabet (GOOGL): $339.81, last hour +0.04%, 24 h range $336.67 to $354.58.\nEther (ETH): $2,717.27, last hour +0.82%, 24 h range $2,677.80 to $2,740.86.",
"questions": {
"up": {
"type": "noul",
"instructions": "Will NVIDIA close the hour higher than it opened?"
},
"lead": {
"type": "choice",
"instructions": "Which will gain the most this hour?",
"criteria": {
"NVDA": "NVIDIA, Robinhood Token",
"GOOGL": "Alphabet, Robinhood Token",
"ETH": "Ether"
}
},
"severity": {
"type": "score",
"instructions": "How far will ETH move this hour, either way?",
"criteria": [
"No impact (under 0.10%)",
"Minor (0.10% to 0.25%)",
"Major (0.25% to 0.50%)",
"Critical (0.50% or more)"
]
}
}
}
2 · Ask Clef on Workers AI
Pipe the request straight into @cf/cloudflare/clef, the same call as the blog's example. The smaller Clef-flash model takes the same body when latency matters more.
curl -s https://clef.finance/api/round | jq '.request' > request.json
curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/run/@cf/cloudflare/clef \
-X POST \
-H "Authorization: Bearer $CLOUDFLARE_AUTH_TOKEN" \
-d @request.json
Any model that returns a probability per option works. The site's own parser, fromClefResponse in /lib/schema.js, accepts the common answer shapes and rounds each question to whole basis points.
3 · Convert and pack
Each question's probabilities become integers in basis points that sum to exactly 10,000 (round with the largest remainder). Then they go into one uint256: option i, counting through the questions in card order, occupies bits 16i to 16i + 15. The weekday card has 9 options, the weekend card 6.
| i | Option | Bits | Basis points | 16-bit word |
|---|---|---|---|---|
| 0 | up Yes | 0 to 15 | 6,000 | 1770 |
| 1 | up No | 16 to 31 | 4,000 | 0fa0 |
| 2 | lead NVDA | 32 to 47 | 3,500 | 0dac |
| 3 | lead GOOGL | 48 to 63 | 4,000 | 0fa0 |
| 4 | lead ETH | 64 to 79 | 2,500 | 09c4 |
| 5 | severity No impact | 80 to 95 | 2,000 | 07d0 |
| 6 | severity Minor | 96 to 111 | 4,500 | 1194 |
| 7 | severity Major | 112 to 127 | 2,500 | 09c4 |
| 8 | severity Critical | 128 to 143 | 1,000 | 03e8 |
That is wallet A from the worked example. Its packed value, in decimal, is 340,295,348,019,613,949,744,392,668,201,101,819,910,000.
// Whole basis points summing to exactly 10000 (largest remainder, ties to the lower index).
function toBasisPoints(probs) {
const total = probs.reduce((a, b) => a + b, 0);
const exact = probs.map((p) => (p / total) * 10000);
const out = exact.map(Math.floor);
let left = 10000 - out.reduce((a, b) => a + b, 0);
const order = exact.map((x, i) => [x - Math.floor(x), i])
.sort((a, b) => b[0] - a[0] || a[1] - b[1]);
for (let i = 0; left > 0; i++, left--) out[order[i % order.length][1]] += 1;
return out;
}
// Questions in card order, options in order. Weekday card: up, lead, severity.
const answer = {
up: [0.6, 0.4],
lead: [0.35, 0.4, 0.25],
severity: [0.2, 0.45, 0.25, 0.1],
};
const bp = [answer.up, answer.lead, answer.severity].flatMap(toBasisPoints);
const packedProbs = bp.reduce((acc, p, i) => acc | (BigInt(p) << BigInt(16 * i)), 0n);
4 · Enter
One call, enter(round, schemaId, packedProbs), with the stake as the value. Use the round and schemaId from /api/round; the contract rejects a round that is not open and a card that is not the one due. Your agent reads the ClefRounds address from the same answer, encoding.to (it is also DEPLOY.rounds in /js/config.js).
import { ethers } from 'ethers';
const provider = new ethers.JsonRpcProvider(ROBINHOOD_RPC_URL);
const signer = new ethers.Wallet(AGENT_PRIVATE_KEY, provider);
const info = await fetch('https://clef.finance/api/round').then((r) => r.json());
const rounds = new ethers.Contract(info.encoding.to, [
'function enter(uint256 round, uint256 schemaId, uint256 probs) payable',
'function claim(uint256[] rounds) returns (uint256)',
], signer);
const tx = await rounds.enter(info.round, info.schemaId, packedProbs, { value: ethers.parseEther('0.01') });
await tx.wait();
# enter the open round
cast send $CLEF_ROUNDS_ADDRESS "enter(uint256,uint256,uint256)" $ROUND $SCHEMA_ID $PACKED_PROBS \
--value 0.01ether --rpc-url $ROBINHOOD_RPC_URL --account $YOUR_KEYSTORE
# after the hour: settle if needed and collect, several rounds in one transfer
cast send $CLEF_ROUNDS_ADDRESS "claim(uint256[])" "[$ROUND]" \
--rpc-url $ROBINHOOD_RPC_URL --account $YOUR_KEYSTORE
Every variable above is yours to fill in. Robinhood Chain is chain id 4663. A claim settles the round first when nobody has: let the wallet or cast estimate gas, or set at least 2,500,000 by hand, because settle checks it has gas left before each pool read and refuses to run short rather than void the round. Read-only helpers on the contract include openRound(), schemaFor(n), timing(n), roundInfo(n), entryOf(n, wallet) and previewPayout(n, wallet).
Clef reference
The app shows a baseline forecast called Clef reference. To be plain about it: it is not Cloudflare's Clef model. It is a transparent statistical baseline, a realized-volatility model built from the same on-chain TWAPs, so every round has a number to beat and anyone can reproduce it. It runs in your browser, in /api/round and in the keeper, and it is deterministic for a given round and data.
- Data. For each asset, the 5 minute TWAP tick at every hour boundary over the last 24 to 48 hours, read with one
observecall per pool. That gives hourly moves D in ticks. - Volatility. σ = √EWMA(D²) with λ = 0.94 and a floor of 2 ticks. A stale share π0 counts recent hours that barely moved (|D| < 0.5 tick), which happens when the stock market is closed.
- The forecast. Each move is modelled as a normal with that volatility, plus a point mass π0 at zero. Because the chain answers softly, the honest report is the answer you expect on average, so the model averages the soft rule over that distribution: in closed form for
upandseverity, and draw by draw forlead. - choice. A Gaussian copula Monte Carlo: correlations from paired hourly moves, shrunk halfway to zero, 20,000 draws from a generator seeded by the round id, each draw scored with the chain's soft rule.
- Output. Rounded to basis points per question with the largest remainder, so each question sums to 10,000.
When the house entry is switched on, the keeper enters every round with the reference forecast and a small stake. The Decision Index then reports each wallet's skill against it.
Embed the live round
Show this hour's decision on your own site. /embed is a small page made for an iframe: the round number, the countdown to the lock, the questions with the Clef reference bars, and a Play on clef.finance button that opens a new tab. It needs no wallet, shows no addresses and stores nothing. It is the only page on clef.finance that other sites may frame.
<iframe src="https://clef.finance/embed?theme=light"
title="Clef: this hour's decision round"
width="100%" height="740" loading="lazy"
style="border:0;max-width:460px"></iframe>
theme=lightortheme=darkpicks the colours;theme=autofollows the viewer's system setting.compact=1keeps one short row per question with the reference's top answer, for sidebars. Give it a height of about 270.- Height. The full card needs about 740 on a phone-width frame, about 600 at its full 460 pixels, and less on the ETH-only card. The page also posts its height to the parent as
{ type: 'clef:embed', height }if you prefer to size the frame yourself. - Freshness. The countdown runs on the viewer's clock, and the card follows
/api/round, refreshed every minute and right after each lock.
Risks and defences
Prices on a decentralized exchange can be moved by anyone who trades, and a contract that pays on them has to assume someone will try. This is how Clef defends itself, what it accepts, and what you take on when you stake.
How the design defends itself
- Pushing the price at the close. With a hard line such as "up if the move is above zero", a trader could flip a close call in a quiet hour by holding a pool one tick off for a second, for a few dollars of swap fees. Three defences work together. Soft answers: near a line the chain answers with a split, so turning a clear answer around takes the whole soft margin, held for the full 5 minute window against every arbitrageur. The schedule: stock questions are only asked while the stock session keeps their pools busy, and the weekend card asks only about ETH, the deepest pool. Small caps: 0.1 ETH per entry and 1 ETH per round keep the prize of any push small.
- Voiding a round by flooding the oracle. A pool remembers a fixed number of price observations and writes at most one per second. Someone losing a round could trade in thousands of separate seconds until the round's prices fall out of memory; the round would turn void and refund their stake. The contract refuses any card that reads a pool remembering fewer than P + W + 600 = 4,500 observations, more than a round needs from its start window until 10 minutes after its end, and the keeper settles within minutes of the hour.
- Running settle out of gas. Settle checks it has enough gas before each pool read and refuses to run short, so a low gas limit cannot turn a failed read into a void round.
- A fake price feed. Only pools that the Uniswap V3 factory itself vouches for, quoted in USDG, can be registered.
- A surprise fee. A new fee takes effect 24 hours after it is set, and a round keeps the fee in force at its first entry.
Accepted risks, stated plainly
- A round can be filled for the price of gas. A handful of wallets that all send the same card can fill the round cap, and everyone else is turned away for that hour. Identical entries are refunded exactly, so it costs the filler only gas. Accepted for launch: the owner can pause new entries or raise the cap.
- The fee bends honesty a little. The payout before the fee rewards your true belief exactly. Because the fee is taken from profit only, shading toward the room pays slightly: at 5%, someone who believes 70% does best reporting about 68.9%. The bend stays under 2 percentage points.
- A determined push can still pay a little on a full round. Holding a pool a whole soft margin away for the entire closing window costs real money, more when arbitrageurs push back. Our review measured it on a fork of the live pools at the launch margins, in a full 1 ETH round with 0.5 ETH pushing against 0.5 ETH of honest stake and nobody pushing back: holding NVIDIA 13 ticks up cost about 78 USDG and lost 0.009 ETH, so that push no longer pays; holding Alphabet 21 ticks up to lead cost about 18 USDG and netted about 0.02 ETH; pushing ETH netted under 0.004 ETH, and only if no exchange arbitrages ETH for five minutes. On smaller rounds the prize shrinks and a push does not pay. Accepted for launch: the owner can widen margins, lower the round cap or drop Alphabet from lead with a new card.
- Settle on time, or everyone is refunded. The oracle defence above keeps a weekday round safe for about 55 minutes after its end, a weekend round for about two hours. Later than that, someone willing to pay for two hours of tiny trades could void an unsettled round, which refunds every entry. The keeper settles within minutes, anyone can settle from the moment the hour ends, and a claim settles first if needed.
- Rounding dust. Payouts round down, so up to one wei per entry stays in the contract.
What you take on
- You can lose stake. A payout depends on everyone's forecasts. A confident miss in a room of calibrated entries can lose most of a stake.
- Experimental, unaudited code. ClefRounds is tested (unit, fuzz, fork tests, an internal adversarial review and JS parity) but has not had an external audit. Stake only what you can afford to lose.
- Answers come from prices traders can move. The defences above make that costly, not impossible.
- Public entries. Entries are on chain, so later entrants can see earlier forecasts. That is information, not an exploit: the scoring still rewards each entrant's honest best belief.
- Chain and wallet risk. Robinhood Chain, its RPC endpoints, your wallet and your keys are outside this project's control.
- Not advice. Nothing here is financial advice. Check whether taking part is allowed where you live.
FAQ
Is this Cloudflare's Clef running on chain?
No. Clef is Cloudflare's model on Workers AI. This project mirrors its request shape and the scoring it is trained on, so an agent can point Clef (or any model) at a round. The baseline in the app is our own statistical Clef reference.
Why is the chain's answer sometimes a split?
Because the hour was close. Near a line the chain answers with probabilities, the same way you do, so a tiny trade cannot flip a close call. A clear move gives a clear 100% answer.
Why are weekend rounds only about ETH?
Stock pools go quiet when the stock session closes, and a quiet pool is cheap to push. ETH trades deeply around the clock, so weekend rounds ask two ETH questions instead of three stock and ETH questions.
Do I need $CLF to play?
No. Rounds are staked and paid in ETH on Robinhood Chain. $CLF is the project's token; Buy $CLF and Copy CA sit in the header of every page.
What if I am the only entry?
You get your stake back exactly. With one entry the pot equals your stake and your score equals the mean, so the correction is zero.
Can I change or cancel an entry?
No. One entry per wallet per round, final once mined. The next round opens five minutes before this one starts.
Why probabilities instead of a yes or no?
Because a probability carries confidence, and confidence is what a decision model is for. A proper scoring rule pays for the whole distribution: over many rounds, someone who says 95% and is right 60% of the time scores below someone who says 60%.
Who settles the round?
Anyone. A keeper settles ended rounds within minutes of the hour so the app updates quickly, but correctness never depends on it: the first claim settles a round if nobody has.
How long can I wait to claim?
As long as you like once the round is settled: the answer is stored at settlement, so a claim is a plain payout from then on. The part that should not wait is the settle itself, which the keeper does within minutes of the hour. A round still unsettled about an hour later can be voided by a griefer, which refunds everyone.
What does skill on the Decision Index mean?
How much better a wallet's forecasts scored than the Clef reference on the same rounds: 0 means no better, positive is better, negative is worse. It appears when the house entry is running.
Be right with the right confidence.
Launch app