Live on Polygon PoS

PERMISSIONLESS
ON-CHAIN LOTTERY

The most transparent lottery protocol ever built. Verifiable randomness, permissionless deployment, and provably fair winner selection — all on-chain.

Coming Soon
Total Value Locked
Launch Pending
Active Rounds
drand VRF
Provably Fair

WHITEPAPER

A fully on-chain, permissionless lottery protocol with verifiable randomness, elastic tokenomics, and provably fair outcomes.

Elastic Tokenomics

Target supply is always 1B SORS. When the RewardsPool can't cover cashback, the factory mints the shortfall. Future creation fees burn this surplus first, returning supply to 1B.

  • 200M initial RewardsPool (cashback source)
  • 160M Treasury ops (Gnosis Safe)
  • 250M Reserve (1yr cliff + 2yr linear)
  • 150M Team (PinkSale lock)
  • 80M Marketing/KOL vesting contract
  • 60M Investor presale + 40M Operator presale
  • 60M DEX liquidity provision

Unbiasable Randomness

Two independent entropy sources ensure no single party — not the operator, not the protocol, not any validator — can predict or influence winners.

  • Rolling hash: keccak256(hash, buyer, block.number, prevrandao, ticketId)
  • drand evmnet: Threshold BLS signatures from decentralized nodes
  • Target round set 250 rounds (~750s) ahead — cannot be cherry-picked
  • Final seed: keccak256(rollingHashSnapshot, sha256(drandSignature))

Permissionless Operators

Anyone with 1,000 SORS can stake, register a unique name, and deploy lottery rounds. Operators earn commissions on ticket sales but face slashing if they miss deadlines.

  • MIN_OPERATOR_STAKE: 1,000 SORS
  • Commission: Up to 30% (3000 bps) of prize pot
  • Custom ticket currency (any ERC-20) and duration
  • Up to 20 winner slots with configurable percentages

Slashing & Safety

Economic security through staking. Operators lose 5% of their stake for missing close (24h) or drand submission (48h) deadlines. Unstaking requires a 7-day cooldown.

  • 5% slash for late close or missing beacon
  • 7-day unstake delay; blocked if active rounds exist
  • Emergency refund after 60 days (pull-payment model)
  • Reentrancy guards on all critical functions

Economic Model

Creation Fee Formula

Operators pay a dynamic fee in SORS to create rounds. The fee decreases as the RewardsPool fills up and as the operator's stake increases.

poolFillRatio = min(poolBalance / 200M, 1.0)
baseFee = 10,000 SORS × (1 − poolFillRatio)
stakeRatio = operatorStake / SORS.totalSupply()
finalFee = baseFee × (1 − stakeRatio)
  • • Pool full (200M+): Creation is free
  • • Pool empty: Base fee = 10,000 SORS
  • • High-stake operators pay significantly less
  • • Fees burn mintedSurplus first, then go to RewardsPool

Owner Cut (Protocol Revenue)

The protocol takes a percentage of the operator's commission. This percentage slides based on the operator's share of total staked SORS.

operatorShare = operatorStake / totalStaked
ownerBps = 5000 − 4500 × operatorShare
ownerCut = operatorTake × ownerBps / 10000
operatorNet = operatorTake − ownerCut
0% stake
50% owner cut
25% stake
38.75% owner cut
50% stake
27.5% owner cut
100% stake
5% owner cut

Cashback Mechanics

How Cashback Works

Players earn SORS cashback on every ticket they purchase. The cashback rate depends on how full the RewardsPool is.

cashbackRate = poolFillRatio × 5% (max 5%)
cashbackPool = operatorStakeSnapshot × cashbackRate
cashbackPerTicket = cashbackPool / totalCappedTickets
  • • Each wallet earns cashback on up to 10 tickets per round
  • • Cashback is reserved at settlement to prevent over-commitment
  • • If pool is insufficient, factory mints shortfall into pool
  • • Unclaimed cashback after 180 days returns to pool

RewardsPool Dynamics

The RewardsPool starts with 200M SORS at genesis. It is funded by creation fees and depleted by cashback claims.

  • +Inflows: Initial 200M genesis allocation, creation fees (after surplus burn), slashed operator stakes
  • Outflows: Player cashback claims
  • Self-correcting: When pool can't cover cashback, factory mints shortfall. Next creation fees burn it back to 1B supply.
Pool Fill Ratio
fillRatio = min(balance / 200M, 1.0)
When fillRatio = 1.0 → creation fees are zero

How Winners Are Chosen

1

Ticket Sales Close

Rolling hash snapshot locked. Target drand round calculated as current + 250 (~750s ahead).

2

drand Beacon Submitted

BLS signature verified on-chain via BN254 pairing. Randomness derived as sha256(signature).

3

Fisher-Yates Selection

Final seed = keccak256(rollingHash, drandRandomness). Winners selected via bitmap-deduplicated indexing.

Decentralization Guarantees

  • Permissionless operators: Anyone can stake 1,000 SORS and launch rounds. No whitelist, no approval needed.
  • drand network: Threshold BLS from independent nodes. No single party controls randomness output.
  • EIP-1167 clones: Each round is an independent contract. No central point of failure or fund commingling.
  • Governance timelock: 48h proposal window for template, verifier, and treasury updates. Community can react.
  • Treasury multisig: 2-of-3 Gnosis Safe controls protocol parameters. No single-key admin access.
  • Entropy chain continuity: Previous round's finalSeed seeds the next round. Cross-round entropy linkage.

Safety Mechanisms

  • Operator slashing: 5% penalty for missing close (24h grace) or drand submission (48h deadline). Each fires once per round.
  • Emergency refund: After 60 days stuck, anyone triggers. Ticket holders claim refunds individually via pull-payment.
  • Pull-payment claims: All payouts (prizes, cashback, operator/treasury cuts) are self-serve. No push-based vulnerabilities.
  • Reentrancy guards: All critical functions (buy, claim, settle) protected against reentrant calls.
  • Immutable round params: Once initialize() is called, operators cannot change ticket price, duration, or winner percentages.
  • Under-subscribed protection: If fewer tickets than winner slots, revenue redistributes proportionally among filled slots. No funds locked.
  • Cashback reservation: At settlement, pool balance is locked to prevent over-commitment across concurrent rounds.

TECHNOLOGY

Built with Foundry and Solidity 0.8.24. Deployed on Polygon PoS for low-cost, high-speed transactions. Paris EVM (pre-PUSH0) for compatibility.

EIP-1167 Minimal Proxies

Each round is an independent clone sharing the template's bytecode but with isolated storage. The factory deploys via `clone()` and tracks all instances in a registry array. Clones cannot interfere with each other's state.

Entropy Chain Continuity

Previous round's finalSeed seeds the next round's rolling hash at initialization. This creates cross-round entropy linkage: `rollingHash = keccak256(previousFinalSeed, block.prevrandao, block.number, address(this))`.

Pull-Payment Model

All payouts are self-serve. Prizes, cashback, operator cuts, and treasury cuts sit in the round contract until claimed. This eliminates push-based reentrancy risks and gas griefing attacks.

Timelock Governance

Sensitive updates (template, drand verifier, treasury) use a 48h proposal → apply pattern. Community can monitor proposals and react before they take effect. Ownership transfer is two-step: transferOwnership → acceptOwnership.

Slashing Deadlines

Operators have 24h grace after roundEndTime to close (or anyone slashes them). They have 48h after close to submit drand beacon (or anyone slashes them). Each slash fires at most once per round via boolean guards.

Emergency Refund

If a round is stuck (no drand submission, settlement failure), anyone can trigger emergencyRefund() after 60 days. Ticket holders then claim refunds individually via claimEmergencyRefund(). Round goes DEAD, activeRounds decremented.

Core Contracts

LotteryFactory

Central hub managing operator staking, EIP-1167 clone deployment, fee routing, slashing enforcement, and seed chain continuity.

  • Operator registry with unique names (bytes32)
  • Stake tracking with MIN_OPERATOR_STAKE = 1,000 SORS
  • Unstake queue with 7-day cooldown
  • Creation fee calculation: poolFillRatio × stakeRatio
  • EIP-1167 minimal proxy deployment per round
  • Cross-round entropy: lastSeedByOperator mapping
  • Timelock governance: 48h proposal → apply pattern

PolysorsLottery

Round template deployed as EIP-1167 clones. Full lifecycle: OPEN → CLOSED → SETTLED/DEAD with pull-payment claims.

  • Immutable parameters after initialize() call
  • Rolling hash accumulation per ticket purchase
  • drand beacon verification via BN254 pairing
  • Fisher-Yates winner selection with bitmap deduplication
  • Pull-payment prize/cashback/operator-cut claims
  • Emergency refund after 60 days (two-step process)
  • ReentrancyGuard on all state-changing functions

SORSToken

ERC-20 with elastic supply targeting 1B. Factory-only mint (cashback shortfalls) and burn (fee surplus).

  • Genesis supply: 1,000,000,000 SORS (1B)
  • 200M allocated to RewardsPool at deploy
  • mint(to, amount) — callable only by LotteryFactory
  • burn(amount) — factory burns from its own balance
  • setFactory(addr) — one-time irreversible wiring
  • Supply self-corrects to 1B via mint/burn cycles

RewardsPool

Holds 200M SORS for cashback. Tracks reserved vs available balances. Pool fullness drives creation fees.

  • GENESIS_BALANCE = 200,000,000e18
  • getPoolFillRatio() returns min(balance/200M, 1.0) in 1e18
  • reserveCashback(amount) — locks balance at settlement
  • distributeCashback(to, amount) — releases reservation
  • releaseCashback(amount) — frees unclaimed reservations after 180 days
  • availableForCashback() = balance − reserved

DrandVerifier

BN254 BLS signature verification for drand evmnet beacons. Public key stored as immutables for zero-SLOAD efficiency.

  • evmnet chain: bls-bn254-unchained-on-g1
  • Public key: 4 uint256 constants (X0, X1, Y0, Y1)
  • verifyBeaconSignature(round, signature) — 64-byte BLS G1 sig
  • Message: H2C(DST, keccak256(abi.encodePacked(uint64(round))))
  • Randomness derived on-chain as sha256(signature)
  • Zero storage reads per verification (immutables)

MarketingVesting

KOL/marketing token vesting with custom cliff + linear schedules per recipient. Revocable by owner.

  • 80M SORS allocated for marketing/KOL distribution
  • addRecipient(addr, amount, cliffDays, vestingDays)
  • Per-recipient vesting: cliffEnd = startTime + cliffDuration
  • Linear unlock after cliff: amount × elapsed / vestingDuration
  • revoke(addr) — caps vesting at revocation time
  • withdrawUnallocated() — owner pulls unused tokens

Randomness Deep Dive

Rolling Hash Accumulation

Every ticket purchase contributes entropy to a rolling hash. This hash accumulates throughout the ticket sale window, making it impossible for any party to predict the final outcome.

// Per ticket purchase:
rollingHash = keccak256(
  rollingHash,
  buyer,
  block.number,
  block.prevrandao,
  ticketId
)

// At initialization (seed chain):
rollingHash = keccak256(
  previousFinalSeed,
  block.prevrandao,
  block.number,
  address(this)
)

Snapshot locked at close — no further manipulation possible. Previous round's finalSeed ensures cross-round entropy continuity.

drand Beacon Verification

The drand evmnet network produces threshold BLS signatures every 3 seconds. The contract verifies these on-chain using BN254 pairing checks against an immutable public key.

// Target round calculation:
currentRound = (closeTime - 1727521075) / 3
targetRound = currentRound + 250

// Final seed derivation:
finalSeed = keccak256(
  rollingHashSnapshot,
  sha256(drandSignature)
)

// Winner selection:
ticketIndex = uint256(
  keccak256(finalSeed, i)
) % totalTickets

Public key stored as 4 immutables — zero SLOADs per verification. Signature must match exact targetDrandRound — cherry-picking is impossible.

Access Control Matrix

FunctionWho Can CallConditions
createRound()Registered operatorStake ≥ 1,000 SORS, no pending unstake
buyTicket(buyer)buyer onlymsg.sender == buyer, status OPEN
closeRound()Operator (24h) / Anyone (after)Time expired or tickets full
submitDrandBeacon()Operator (48h) / Anyone (after)Exact targetDrandRound match
claimPrize(idx)Winner at that indexStatus SETTLED
claimCashback()Any ticket holderWithin 180 days of settlement
emergencyRefund()Anyone60 days after close/end
applyTemplate()Owner only48h after proposeTemplate()

ROADMAP

From token launch to multi-chain expansion — our journey to redefine on-chain gaming.

Q2 2026

Token Launch & Presale

  • PinkSale presale listing for early supporters
  • Operator presale allocation (40M SORS)
  • Investor presale allocation (60M SORS)
  • DEX liquidity pool initialization (60M SORS)
  • Initial operator onboarding and staking
  • First lottery rounds go live on mainnet
Q3 2026

Polysors Hub Launch

  • Unified dashboard for all active lottery rounds
  • Operator leaderboard with stake rankings
  • Real-time ticket sales tracking
  • Live drand beacon submission monitoring
  • Winner announcement feed
  • Historical round analytics and statistics
  • Cashback claim notifications
Q4 2026

Protocol Expansion

  • Multi-chain deployment (Arbitrum, BSC)
  • Advanced lottery templates (jackpot rollovers, instant wins)
  • NFT ticket integration for collectible entries
  • Cross-round jackpot pooling
  • Mobile app beta launch
  • Community governance token utilities
  • Partnership integrations with DeFi protocols

The Polysors Hub

The Polysors Hub is your central command center for everything happening in the protocol. Think of it as the mission control for the entire lottery ecosystem — where operators manage their rounds, players discover active games, and everyone can verify outcomes in real-time.

For Players

Browse active rounds, track your tickets, claim prizes and cashback instantly.

For Operators

Monitor your rounds, track commissions, manage stake, and optimize performance.

For Everyone

Full transparency into every round's lifecycle, from creation to settlement.