/DEV NOTES
Honest audit of what's real, what's shimmed, and what's missing. Last updated: Feb 2026.
WHAT'S ON-CHAIN (REAL)
The core prediction market loop — connect wallet, create market, submit prediction, resolve with Levenshtein, claim payout — is real blockchain transactions on BASE Sepolia.
| Component | Status | Details |
|---|---|---|
| RPC Endpoint | Real | https://sepolia.base.org — official BASE public RPC, chain ID 84532 |
| PredictionMarketV2 | Real |
0x5174Da96BCA87c78591038DEe9DB1811288c9286Verify on BaseScan |
| GenesisNFT | Real |
0x1A5D4475881B93e876251303757E60E524286A24 — 60/100 minted, finalized, on-chain SVG artVerify on BaseScan |
| ActorRegistry | Real | 0xC71CC19C5573C5E1E144829800cD0005D0eDB723 |
| PayoutManager | Real | 0x88d399C949Ff2f1aaa8eA5a859Ae4d97c74f6871 |
| DecentralizedOracle | Real | 0x7EF22e27D44E3f4Cc2f133BB4ab2065D180be3C1 — deployed but resolution is admin-only |
| Wallet Connection | Real | MetaMask + Coinbase Wallet via EIP-1193. Real personal_sign, real network switching to BASE Sepolia. |
| Market Creation | Real | Real createMarket() transaction, real gas, real testnet ETH |
| Prediction Submissions | Real | Real payable createSubmission() — sends actual testnet ETH to contract |
| Levenshtein Scoring | Real | Computed on-chain as a pure function in PredictionMarketV2 Solidity contract |
| Payout Claims | Real | Real claimPayout() sends ETH back to winner |
| Explorer Data | Real | Reads live contract state. No hardcoded markets, no placeholders. Shows empty state if nothing exists. |
WHAT'S SHIMMED (3 THINGS)
1. Embedded Wallet Key Derivation
services/embedded_wallet.py → _generate_seed()
Uses PBKDF2 with a MASTER_WALLET_SECRET env var instead of the real
Coinbase CDP Server Signer API. The derived wallets do send real transactions
on BASE Sepolia, but the key management is not production-grade.
# For mainnet, replace with Coinbase CDP wallet creation
# via the Server Signer API.
master_secret = os.environ.get('MASTER_WALLET_SECRET', 'default-secret-change-in-production')
combined = f"{master_secret}:{identifier}"
return hashlib.pbkdf2_hmac('sha256', combined.encode(), b'clockchain', 100000)
2. USDC Balance is Hardcoded
services/embedded_wallet.py:389
Returns balance_usdc: 100.0 always. There is no USDC token contract
interaction. ETH balance is real (fetched via eth_getBalance).
3. OTP Verification Accepts Any 6 Digits
services/embedded_wallet.py:366
No real email sending. No real OTP validation. Any 6-digit code passes. This is a testnet convenience — the flow exists but the auth is not enforced.
NOT IMPLEMENTED
Things that would need to exist before anyone should put real money near this.
| Component | Status | Notes |
|---|---|---|
| External Security Audit | Not done | No third-party audit of smart contracts or backend |
| Real Coinbase CDP Integration | Not done | No CDP credentials. Embedded wallet uses PBKDF2 shim (see above) |
| Multisig for Contract Owner | Not done | Single EOA owner: 0x21a85AD98641827BFd89F4d5bC2fEB72F98aaecA |
| Production RPC | Not done | Uses public sepolia.base.org. No Alchemy/QuickNode for reliability or rate limits. |
| Production Monitoring | Not done | No Sentry, no alerting, no uptime monitoring |
| Decentralized Oracle | Not done | Contract deployed but resolution is admin-only. No Chainlink, no UMA, no multi-party oracle. |
KNOWN ISSUES
Public RPC Rate Limits
sepolia.base.org is a free public endpoint. Under load it will throttle
or drop requests. The explorer page makes multiple eth_call reads per
page load (one per market + submissions). Heavy traffic will cause timeouts.
Single-Owner Resolution
Market resolution requires the contract owner's private key. There is no fallback, no timeout-based auto-resolution, and no dispute mechanism. If the owner key is unavailable, markets cannot be resolved.
No Gas Sponsorship
Users need BASE Sepolia testnet ETH to interact. There's no paymaster, no gas relayer, no faucet integration. Users must get testnet ETH from an external faucet before they can create markets or submit predictions.
Embedded Wallet Security
The PBKDF2-derived embedded wallet stores derived keys server-side. The master
secret defaults to 'default-secret-change-in-production' if the env
var isn't set. This is adequate for testnet demos, not for anything with value.
ARCHITECTURE QUICK REF
| Layer | Tech | Key Files |
|---|---|---|
| Smart Contracts | Solidity 0.8.x, Hardhat, BASE Sepolia | contracts/PredictionMarketV2.sol, contracts/GenesisNFT.sol |
| Backend | Flask, Web3.py, Redis, JWT auth | app.py, routes/, services/blockchain_base.py |
| Frontend | Bootstrap 5, vanilla JS, ethers.js/Web3.js | templates/, static/js/wallet.js, static/js/betting-contract.js |
| Contract ABIs | Hardhat artifacts | static/abi/PredictionMarketV2.json |
| Deployment Config | JSON deployment manifest | deployment-base-sepolia.json, config_chain.py |
| Tests | pytest (unit/integration), Hardhat (contract) | tests/unit/, tests/integration/, test/ |