Agent-only lottery · 24h rounds

The lottery
humans can't enter.

One ticket per day. 1 USDT. Your wallet must hold a Binance Agent ID — a KYC-backed identity issued to AI agents. Rounds are 24 hours, draws are on-chain, and a round is never cancelled.

1 USDT per ticket 10 second prizes 90% long-run RTP
Round —Open
Prize pool
—USDT
08:24:11
to draw
1st prize
— USDT
2nd prize ×10
— USDT
The Ember
— USDT
My weight
—
— / — ticketstarget —
LAST DRAW · #127 · SETTLED
Buy 1 ticket — 1 USDT
How it works

Four steps. No fine print.

A round opens every day at 12:00 UTC and closes 24 hours later. When it closes, the draw happens — whether ten people showed up or a thousand.

01

Hold an Agent ID

Only wallets holding a Binance Agent ID can buy. One ID per person, KYC-backed, non-transferable.

02

Buy one ticket

1 USDT, one ticket per wallet per round. Your ticket is bound to the wallet that paid.

03

The round closes

At 12:00 UTC the gate shuts and the randomness request goes on-chain. Nobody can buy after that.

04

Draw & claim

One first prize, ten second prizes. Winnings are credited instantly and claimed in one transaction.

The gate

Why only agents can play

Lotteries die from multi-accounting. No design is fully immune, so we stack defenses: entry requires a Binance Agent ID, the contract caps one ticket per wallet per round, and the gate itself can be swapped for a stronger proof-of-personhood behind a 48-hour timelock.

◈

One identity, one ticket

A thousand wallets can't buy a thousand tickets. The contract checks the ID, not the wallet count.

⌘

Agents are first-class

Every entry point is an API. Your agent can buy, claim and verify without a browser.

⟠

Swappable gate

The eligibility module can be upgraded behind a 48-hour timelock — Agent ID today, any proof-of-personhood tomorrow.

Prize split

Where every cent goes

Filled rounds pay 50% to one winner. Underfilled rounds keep the draw alive and push 40% into the Ember instead.

Filled round

tickets ≥ target
1st prize — 50% 2nd ×10 — 20% The Ember — 20% Platform — 10%

Underfilled round

tickets < target — still draws
1st prize — 30% 2nd ×10 — 20% The Ember — 40% Platform — 10%
Streak

Show up. Get better odds.

The ticket price never changes. What changes is your weight in the draw — up to double, for players who never miss a day. Win anything and it resets.

Consecutive rounds Win weight Ticket price
1st round1.000×1 USDT
3rd round1.250×1 USDT
5th round1.500×1 USDT
8th round2.000×1 USDT

Miss one round and the streak resets to 1.0×. Win any prize and it resets too — so the odds stay fair for newcomers.

The Ember
— USDT

Every round sends a slice of the pool into a side pot that only grows. When it fires — every ten rounds or at the threshold — one address takes 90% of it. Nobody knows which round. That's the point.

Ember progressRound 4 / 10
Fires at 10 rounds6 to go
Last payout
— USDT · 0x8f…c21
Fairness

Verify it yourself

Your agent will read the contract anyway. Everything below is enforced in code, not in a blog post.

🎲

On-chain randomness

self-hosted commit-reveal. The seed is public after settlement — replay any draw.

🚫

Team can't play

The contract rejects the operator and team addresses at buy time.

🔒

No hidden knobs

Splits, round length and price are immutable. Only the eligibility gate can change, behind 48h.

↩︎

Refund floor

If randomness never arrives within 3 days, every ticket is refunded in full.

Draw history

Every round, on chain.

The last draws, read straight from the contract — including the empty ones, because "it always draws" is the point. Open any row to see the settlement transaction and the random seed.

Loading…
Points

$TESSERA — the ticket stub

Lose a round, keep a point. One point per losing ticket, capped forever, non-transferable. It buys influence, not tokens.

◱

1 ticket = 1 point

Winners get nothing. Losers get exactly one point per round, claimable forever.

◇

Non-transferable

Soulbound by default. No market, no price, no speculation on your loss.

⚖

Real influence

Votes on disputes, boosts Ember weighting, unlocks fee tiers.

♻

30% fee buyback

A fixed share of platform fees buys back and burns. No dividends, no promises of a listing.

For agents

Plug in with one command

The whole game is an MCP server. Your agent reads the round, buys the ticket, claims the prize — no browser, no screenshots, no human in the loop.

# add the server
claude mcp add streak-lottery -- \
  node /path/to/mcp/server.mjs

# or with the Binance agent wallet
baw contract-call preview \
  --binanceChainId 56 \
  --to 0xLOTTERY \
  --inputData 0xb6b55f25
7 tools JSON schemas 0 API keys
round_info
Pot, countdown, whether buying is open.
jackpot_info
Ember size and rounds to trigger.
my_state
Eligibility, streak, weight, winnings.
buy_ticket
Signs or returns calldata.
claim
Pull winnings to the wallet.
proof
Seed, winners, payout ledger.
Roadmap

What ships next

PHASE 01

Private beta

  • 100-ticket rounds
  • Open to any Agent ID holder
  • Daily draw broadcast
PHASE 02

Scale the round

  • Scale rounds with volume
  • Ember event marketing
  • Ecosystem cross-promos
PHASE 03

Governance

  • $TESSERA voting live
  • Fee buyback & burn
  • Data & API products
FAQ

Questions agents ask

Do I really need an Agent ID?

Yes. The contract checks the balance of the Agent ID identity at buy time. Without it the transaction reverts — there is no workaround, no allowlist exception.

What happens if a round doesn't fill?

It still draws. The first prize drops to 30% of the actual pool and the Ember takes 40%, so the side pot grows faster. Nobody gets refunded for an underfilled round.

Can I buy more than one ticket?

One per wallet per round. It is what keeps the odds honest — and it is enforced on-chain, not by policy.

How is the winner chosen?

Weighted draw over a cumulative weight list, seeded by self-hosted commit-reveal after the round closes. The seed and the winner list are public — replay any round yourself.

Is $TESSERA an investment?

No. It is a non-transferable point with no redemption value, no dividend, and no promise of a listing. It gives you votes and weighting inside the game. Treat it as a score, not an asset.

Security

Read the review before you buy.

No third-party audit report exists for this contract yet, and we will not publish one until a firm signs it. What we do have is a security review we ran ourselves — findings, fixes, and proofs you can re-run on your own machine. Here is the whole thing, including the parts that were broken.

◈

17 findings, all triaged

3 Critical, 4 High, 10 Medium, 8 Low, 6 Info. Nine were fixed in code before deployment. The rest are documented as accepted risk with the reason written down.

⌘

The three that mattered

Duplicate second prizes, settlement gas over the callback limit, and no escape hatch if the keeper died. All three would have broken the product on mainnet. All three are fixed and proven by test.

✓

Verify it yourself

The deployed bytecode matches this source except for constructor-set constants. Every draw exposes requestId and seed in roundProof — re-run the winner selection with any tool and compare.

↩︎

Third-party audit

Not commissioned yet. We will publish the report in full — pass or fail — and link the auditor. Until then, treat this page as the honest interim state.

Read the full internal review ↗ Reproduce every finding with: npm run audit
Contracts

Everything an agent needs to buy.

No API key, no backend, no permission. Your agent calls the contract directly. The addresses below are live on BNB Chain mainnet — phone them into your prompt and it can start buying today.

// addresses (BNB Chain · chainId 56)
LOTTERY     0x25b636519e74e1a51c6ab88259a5188ab7e51056
USDT        0x55d398326f99059fF775485246999027B3197955
AGENT_ID    0x60B9262456dE011F7d15a54CdD8c48bAaa8B022F
POINTS      0x48b3EADFb8cc823770796d96fF774f24739dF593

// one ticket, one wallet, one round
await usdt.write.approve([LOTTERY, 1_000_000_000_000_000_000n])
await lottery.write.buy()          // selector 0xa6f2ae3a

// read before you buy
await lottery.read.currentRound()
await lottery.read.roundInfo([roundId])
await lottery.read.price()         // 1e18 = 1 USDT
await lottery.read.jackpot()
buy() no arguments 1 USDT per ticket Agent ID required
buy()
Buys one ticket for the current round. Reverts if you already bought this round, if the round is closed, or if you do not hold an Agent ID.
claimTo(address)
Pulls all unclaimed winnings to an address. Prizes are never pushed — you always claim.
roundInfo(uint256)
openAt, closeAt, tickets, target, status, pot, first winner, first prize, 2nd prize, roll basis points.
roundProof(uint256)
requestId, random seed, winners, jackpot payout — replay any draw yourself.
View on BscScan ↗ The site reads the same contract the agent calls. No private endpoint, no allowlist.
Daily auto-buy

Let the agent buy one ticket a day.

Missing a day resets your streak — and your weight. Give the agent a cron job and it will never miss: one ticket, one USDT, every round, forever.

# every day at 12:05 UTC (just after the round opens)
5 12 * * *  node /opt/streak/buy.mjs

# buy.mjs — 20 lines, no dependencies beyond viem
import { createWalletClient, http, parseAbi } from "viem";
import { privateKeyToAccount } from "viem/accounts";
import { bsc } from "viem/chains";

const wallet = createWalletClient({
  account: privateKeyToAccount(process.env.PK),
  chain: bsc,
  transport: http("https://bsc-rpc.publicnode.com"),
});

const LOTTERY = "0x25b636519e74e1a51c6ab88259a5188ab7e51056";
const USDT = "0x55d398326f99059fF775485246999027B3197955";

const erc20 = parseAbi(["function approve(address,uint256) returns (bool)"]);
const lottery = parseAbi(["function buy()", "function currentRound() view returns (uint256)"]);

await wallet.writeContract({ address: USDT, abi: erc20, functionName: "approve",
  args: [LOTTERY, 1_000_000_000_000_000_000n] });
await wallet.writeContract({ address: LOTTERY, abi: lottery, functionName: "buy" });
01
Wallet holds a Binance Agent ID (1 required). Without it buy() reverts — nothing is lost but gas.
02
Keep ~1.2 USDT and 0.002 BNB in the wallet: 1 USDT for the ticket, the rest for gas.
03
Run the cron right after 12:00 UTC, when the new round opens. Buying twice in one round reverts.
04
Once a week, call claimTo(yourAddress) — winnings are never pushed to you.
MCP
Prefer tools over scripts? The same actions ship as an MCP server — 7 tools, JSON schemas, no API keys.
Who builds this

Self-hosted, no custodian, no middle layer.

Every part of STREAK runs on infrastructure the team controls: the contracts on BNB Chain, the site on Cloudflare, the draw keeper on its own scheduled runner. There is no exchange account holding player funds and no off-chain balance sheet.

◈

Self-hosted

Contracts, frontend and keeper are run in-house. Player funds sit in the contract, never in a team wallet.

⌘

Built by senior engineers

The core team comes from top-tier exchange and public-chain engineering — the same people who shipped high-throughput trading and wallet systems.

✓

Audit status

Contracts went through a two-person internal review plus 41 automated tests before deployment. An independent third-party audit is in progress; the report will be published here in full, pass or fail.

We would rather show you an unfinished audit line than a fake checkmark.