Laxo is a prediction market platform for forex currencies, built for EthGlobal's 2026 HackMoney hackathon. It lets users bet on currency movements (long/short) with instant, gas-free transactions.
The idea is the following:
Laxo offers a hub with three things for users to do: prediction market on foreign exchange (FOREX) rates, ability to split USDC holdings across foreign stablecoin backed currencies and a view of what their wallet has.
Users take positions on whether a currency pair will be above or below a target price by a resolution time. Winners claim payouts from losers, similar to traditional prediction markets, but optimized for forex.
Laxo leverages the following -
- Smart Contracts (Solidity 0.8.24)
Hardhat for development, testing, and deployment
OpenZeppelin for security patterns (Ownable, ReentrancyGuard, SafeERC20)
Ethers.js v6 for contract interactions
Deployed on Sepolia testnet and Arc Network testnet
Frontend (Next.js 16 + React 18)
App Router with Server Components
Wagmi v3 + Viem v2 for Ethereum interactions
Tailwind CSS for styling
React Query for state management
Partner Technology Integrations
- Yellow Network (ERC-7824 Nitrolite Protocol)
Uses @erc7824/nitrolite for state channel sessions
Custom WebSocket client (yellowClient.js) connecting to wss://clearnet-sandbox.yellow.com/ws
Session-based architecture: each prediction market gets its own Yellow session
Off-chain position tracking: positions stored in YellowSession.positions Map, synchronized via WebSocket messages
On-chain settlement bridge: YellowIntegration.sol records off-chain positions and finalizes settlements on-chain
Test wallet system: localStorage-backed test wallet with deterministic address generation for development (no real funds needed)
- Circle Gateway & Wallets
Circle Gateway API client (gateway.js) for cross-chain USDC transfers
Supports 7 chains: Ethereum, Base, Polygon, Avalanche, Arbitrum, Optimism, Arc
Unified balance queries across chains via Circle's /balances endpoint
Arc Network integration: USDC-native gas (gasPrice: 0 in Hardhat config)
Transfer attestation flow: estimate fees → create attestation → execute cross-chain transfer
- ENS Integration
Viem-based ENS resolver using mainnet public client (ENS doesn't exist on Sepolia)
Deterministic pie wallet generation: hash-based address generation from userAddress + pieId
Local-first ENS tracking: stores ENS names in localStorage, resolves on-chain when available
Format: pie-{shortId}.{userShortAddress}.eth for human-readable portfolio addresses
Notable Implementation Details
- Hybrid Off-Chain/On-Chain Architecture
Positions taken instantly off-chain via Yellow SDK (zero gas)
Settlement recorded on-chain via YellowIntegration.recordOffChainPosition()
Market resolution happens on-chain via PredictionMarket.resolveMarket()
Winners claim payouts on-chain, bridging off-chain positions to on-chain settlements
- Test Wallet System
Generates deterministic test addresses using simple hash function (not cryptographically secure, but sufficient for demos)
Caches wallet state in localStorage (laxo_test_wallet)
Mock signature generation for Yellow Network messages
Balance tracking with BigInt precision for USDC (6 decimals)
- Blockchain Logging System
Custom BlockchainClient wraps Viem's public client
Logs all transactions, events, and connection status
In-memory log buffer (last 100 entries) with event emitter pattern
Graceful degradation: app continues even if blockchain connection fails
- Deployment Automation
Single script (deploy.js) deploys all contracts and creates 10 markets in one transaction
Extracts market addresses from event logs (handles both parsed and raw logs)
Auto-verification on Etherscan with 30-second delay for block confirmations
Saves deployment artifacts to deployments/ directory with timestamps
- State Channel Session Management
Each market gets its own YellowSession instance
Session IDs generated from appDefinition.nonce (timestamp-based)
Position updates sent as custom WebSocket messages (position_update type)
Balance synchronization via payment and sessionMessage event handlers
- Multi-Chain Configuration
Hardhat config supports Sepolia and Arc testnet
Arc uses USDC as native gas (gasPrice: 0)
Environment-based RPC URL selection with fallbacks to public endpoints
PublicNode fallback when Infura/Alchemy keys aren't provided
How Everything Pieces Together
User connects wallet → Wagmi handles MetaMask connection
User initializes Yellow Network → YellowClient creates WebSocket connection to ClearNode
User selects market → YellowSession creates app session with market address as partner
User takes position → Off-chain message sent via Yellow SDK, tracked locally in positions Map
Position recorded → Frontend calls YellowIntegration.recordOffChainPosition() to store on-chain reference
Market resolves → Oracle provides price, PredictionMarket.resolveMarket() calculates winners
Settlement → Winners call finalizeSettlement() to bridge off-chain position to on-chain payout
Cross-chain → Circle Gateway transfers USDC to Arc for USDC-native gas operations