Decentralized YES/NO prediction market protocol where anyone creates questions, bets native PAS on outcomes, and resolution happens through an optimistic dispute system anchored to Polkadot's on-chain identity layer.
contracts/
├── contracts/
│ ├── PolyDot.sol # Main prediction market contract
│ ├── interfaces/ISystem.sol # System Precompile interface
│ └── mocks/MockSystem.sol # Local test mock
├── test/PolyDot.test.js # 76 tests covering all logic
├── scripts/deploy.js # Deploy + seed 3 demo markets
└── hardhat.config.js
frontend/
├── src/
│ ├── app/ # Next.js App Router pages
│ ├── components/ # UI components
│ ├── hooks/ # wagmi contract hooks
│ └── lib/ # Config, ABI, utils
└── next.config.ts
- Create — Anyone posts a YES/NO question with a deadline (minimum 5 minutes)
- Bet — Users bet PAS on YES or NO during the open period
- Close — After deadline, anyone closes the market
- Propose — Someone proposes the outcome, staking 0.05 PAS bond. Their Polkadot Substrate identity is recorded via the System Precompile
- Challenge — 2-hour window for disputes (also records disputer's Substrate ID)
- Resolve — If undisputed, outcome finalizes. If disputed, market creator breaks the tie
- Claim — Winners claim proportional payouts (1% platform fee)
| Field | Value |
|---|---|
| Network | Polkadot Hub TestNet (Paseo Asset Hub) |
| RPC | https://services.polkadothub-rpc.com/testnet |
| Chain ID | 420420417 |
| Currency | PAS (18 decimals) |
| Explorer | Blockscout |
| Faucet | faucet.polkadot.io |
- Node.js 18+
- MetaMask with PAS from the faucet
cd contracts
npm install
npx hardhat test # Run 76 tests
cp .env.example .env # Add your PRIVATE_KEY
npx hardhat run scripts/deploy.js --network polkadotTestnetcd frontend
npm install
cp .env.example .env.local # Optional: override contract/RPC
npm run dev # http://localhost:3000Update CONTRACT_ADDRESS in frontend/src/lib/contract.ts after deploying.
For hosted environments (including Vercel), you can set NEXT_PUBLIC_CONTRACT_ADDRESS instead of editing source.
This repository is monorepo-style (contracts/ + frontend/). Deploy the Next.js app from the frontend/ directory.
- Import this Git repository into Vercel
- Set Root Directory to
frontend - Set these environment variables in Vercel Project Settings:
NEXT_PUBLIC_CONTRACT_ADDRESS= deployed PolyDot contract addressNEXT_PUBLIC_POLKADOT_RPC_URL=https://services.polkadothub-rpc.com/testnet
- Deploy
Local production check:
cd frontend
npm run build
npm run startCLI deployment:
vercel deploy --cwd frontend --prod --yes- Address:
0x660eE7890D82c6e16bf22c124BF42aD88cFcc6BB - Explorer:
https://blockscout-testnet.polkadot.io/address/0x660eE7890D82c6e16bf22c124BF42aD88cFcc6BB
- No OpenZeppelin — Self-contained contract avoids resolc compatibility issues with OZ v5
- CEI pattern — Checks-Effects-Interactions prevents reentrancy without imported guards
- Low-level calls — All PAS transfers use
addr.call{value: amount}("")(.transfer()fails on PolkaVM due to 2300 gas stipend) - Constructor-injected precompile — Enables MockSystem for tests, real
0x900for testnet - Integer division — Tiny truncation remainders stay in contract (documented, expected)
- Position model — Multiple transactions are supported per user per market on the same side (amounts accumulate). Opposite-side mixing for a single wallet is intentionally blocked in the current version.
76 passing (2s)
13 test groups covering deployment, market creation, betting, closing, proposals, disputes, finalization, dispute resolution, expired disputes, claims, odds calculation, full lifecycle integration, and exit-position flows.