Search projects, hackathons, sponsors and tech

    ← All projects

    HashX

    ⏳ HashX: A permissionless Optimistic Oracle on Hedera built using Timelocked puzzles.

    Demo

    About

    HashX is an app for creating and resolving prediction markets with accuracy with the help of privacy-preserving voting on Hedera EVM. Votes are encrypted using BabyJubJub-based ECDH and AES-256-CTR, then revealed via a timelock puzzle or automatically by a server-held key. Rewards are distributed using Merkle proofs. Features - Verifier Secret Key is generated upon Oracle Creation, Public Parameters for solving the SK is published Onchain (RSA modulus $N$, base $a$, iterations $t$) - Encrypted voting with EIP‑712 typed signatures → ephemeral keys → AES-encrypted ballot - Votes are calculated per user basis, Rewards are calculated as per amount staked. - Voters can not prove what they have voted until the vote is resolved. - Hedera EVM integration (Testnet) with RainbowKit. - HBAR staking via `HBARLockingContract` to obtain voting power. This converts HBAR to WHBAR utilizing WHBAR.sol contract. - Solver gets certain percentage (default $5\%$) of the Oracle value. - Oracle rewards among voters are distributed via Merkle proofs. - Postgres DB for fetching markets metadata and serving proofs. ### Contracts (addresses on Hedera Testnet) - HBAR_LOCKING_CONTRACT_ADDRESS: `0xde368C3DCac4E5096f2D2b8AF7Be70277c43b144` - CREATEVOTE_FACTORY_ADDRESS: `0x90Fe5e610A12D2Aa0374e5CEA373bc4CdC103Cbc` - PREDICT_MARKET_FACTORY_ADDRESS: `0x0118250132B55af4Ca1659dA51Bf7430245C1A03` - ABIs: see `ABI/` - Factory contracts are verified on Hashscan. Tech stack - App: Next.js (app router), React 19, Tailwind, Zustand, TanStack Query - Web3: wagmi v2, viem, RainbowKit, SIWE - Crypto: @zk-kit/baby-jubjub, AES-256-CTR, bigint-mod-arith - DB: Postgres (Neon) Using the app 1. Connect wallet. The UI will prompt to add/switch to Hedera Testnet if needed. 2. Stake HBAR (Stake tab) to gain voting power. 3. Create Oracle (Start Creating): - Set rewards, start/end time, and choose resolution mode (auto vs manual puzzle). - The app records `marketId` and oracle `contractAddress`. 4. Create Market: Provide initial liquidity and parameters, then submit. 5. Vote: Pick option, Generate Signature, then Submit Vote. 6. Resolve: After end, click Verify Result (runs decrypt + finalize) and then Claim Rewards.

    How it's made

    - • Tech stack - **App**: Next.js (App Router) 16, React 19 (React Compiler), Tailwind v4, Radix UI, Lucide, Sonner, Next Themes, TanStack Query, Zustand. - **Wallet/Web3**: wagmi v2, viem, RainbowKit (SSR), SIWE. - **Crypto**: `@zk-kit/baby-jubjub` (ECDH), AES‑256‑CTR, `bigint-mod-arith`. - **Contracts**: Solidity (OpenZeppelin), Hedera EVM (Testnet). - **Data/Infra**: Postgres (Neon serverless), Drizzle ORM, Hedera Mirror Node API. - **Build**: Turbopack, TypeScript, ESLint 9. - • High-level architecture - **Smart contracts**: - `HBARLockingContract` stakes HBAR and wraps to WHBAR, tracks deposits, transfers stake to protocol and back for rewards. - `CreateVote` oracle: stores public parameters for the timelock puzzle, accepts encrypted votes (`userPublicKey`, `bytes option`, `amount`), verifies solver secret, finalizes with a Merkle root, and enables `claimRewards`. - `PredictionMarket` + `PredictionMarketToken`: AMM-like market with YES/NO tokens, initial liquidity, probability-based pricing, and settlement driven by the `CreateVote` oracle outcome. Factories deploy both oracle and market. - **Server “actions”** (Next.js server components): - DB via Neon + Drizzle stores oracle public params, optional server-held secret, market metadata, and Merkle proofs. - Finalization flow decrypts votes off-chain (after end), builds Merkle trees, simulates, then sends on-chain `finalizeVote` with a server wallet (env `PRIVATE_KEY`). - **Frontend**: - RainbowKit + wagmi configure Hedera Testnet, SIWE auth; EIP‑712 typed message signing for vote attestations. - Zustand stores reflect balances, transaction hashes; TanStack Query for async data. - • Privacy-preserving vote encryption - Users generate an ephemeral BabyJubJub key by hashing their EIP‑712 vote signature + fresh randomness, mod curve order. - ECDH with the oracle’s BabyJubJub public key derives a shared secret; votes are encrypted with AES‑256‑CTR (constant IV is acceptable here because keys are per‑vote and unique). - On-chain, the vote is stored as `bytes` mapped to the ephemeral public key, keeping the voter’s choice hidden. - • Timelock puzzle (delayed reveal) - On oracle creation, server generates an RSA modulus N (JWK), sets base `a=2` and difficulty `t`. Compute `b = a^(2^t mod φ(N)) mod N`, hash `b` and XOR with the secret key to publish `skLocked`. - Anyone can later recover the secret via repeated squaring (computing `a^(2^t) mod N`), unmask `skLocked`, and submit it on-chain; or in “server mode” the backend reveals SK after end. - Contract double-hashes the expected secret to prevent preimages and rewards the solver (~10%) via the locking contract. - • Finalization and distribution - Backend queries Mirror Node for blocks bracketing start/end timestamps; fetches `VoteCast` logs via viem. - Decrypts each vote with the recovered (or server-held) SK; tallies options; adds losing-side stake to rewards. - Uses `@openzeppelin/merkle-tree` to build Standard Merkle Trees for winners; stores proofs in Postgres. - Simulates `finalizeVote`, then sends it with `winnerMerkleTreeRoot` and added rewards. Users claim on-chain by submitting their Merkle proof. - • Partner tech and how it helped - **Hedera EVM + Mirror Node**: fast finality and easy block range lookup by timestamp for off-chain log collection. - **Neon Postgres + Drizzle**: serverless, simple schema-first DX; storing oracle params and Merkle proofs for the UI. - **RainbowKit + wagmi + viem**: reliable multi-wallet UX, typed EIP‑712 flows, and robust simulation/tx sending. - • Notable hacky bits - Ephemeral JJJ keys derived from typed signatures + randomness for unlinkable, per‑vote encryption. - RSA timelock via repeated squaring implemented in both server action and CLI scripts (`src/scripts/solve_puzzle.ts`), with XOR masking of SK. - Using Mirror Node timestamps → block numbers to bound event fetching precisely. - Hard-coded on-chain operator for oracle admin actions in `CreateVote` to simplify hackathon operations. - AES‑CTR with a fixed IV is safe here due to per‑vote one‑time keys; simpler than managing nonces while preserving privacy.