|  | 
|  | 1 | +# Pharos Raffle | 
|  | 2 | + | 
|  | 3 | +A decentralized raffle system powered by Pyth Entropy for provably fair randomness. | 
|  | 4 | + | 
|  | 5 | +## What This Example Does | 
|  | 6 | + | 
|  | 7 | +The Pharos Raffle system enables users to create and participate in raffles with verifiable randomness. Each raffle uses Pyth Entropy to ensure fair winner selection through a commit-reveal scheme that prevents manipulation. | 
|  | 8 | + | 
|  | 9 | +### Key Features | 
|  | 10 | + | 
|  | 11 | +- **Create Raffles**: Set up raffles with custom parameters (prize type, ticket price, duration, etc.) | 
|  | 12 | +- **Provably Fair**: Uses Pyth Entropy for verifiable random number generation | 
|  | 13 | +- **Multiple Prize Types**: Support for crypto prizes (PYUSD), physical items, and digital assets | 
|  | 14 | +- **Factory Pattern**: Efficient contract deployment through the factory pattern | 
|  | 15 | +- **Frontend Interface**: Next.js application for easy interaction | 
|  | 16 | + | 
|  | 17 | +### How the Entropy Integration Works | 
|  | 18 | + | 
|  | 19 | +1. **User Purchases Tickets**: Buy PYUSD-backed tickets for a raffle | 
|  | 20 | +2. **Raffle Closes**: When time expires or max tickets reached, the raffle closes | 
|  | 21 | +3. **Randomness Request**: Contract requests randomness from Pyth Entropy with a commitment | 
|  | 22 | +4. **Callback Delivery**: Entropy provider calls back with random number | 
|  | 23 | +5. **Winner Selection**: Contract uses weighted randomness (based on ticket count) to select winner | 
|  | 24 | +6. **Prize Distribution**: Winner receives crypto prize, or funds go to admin for physical/digital fulfillment | 
|  | 25 | + | 
|  | 26 | +## Project Structure | 
|  | 27 | + | 
|  | 28 | +``` | 
|  | 29 | +entropy/Pharos/ | 
|  | 30 | +├── contract/           # Smart contracts built with Hardhat | 
|  | 31 | +│   ├── contracts/ | 
|  | 32 | +│   │   ├── RaffleFactory.sol    # Factory contract for creating raffles | 
|  | 33 | +│   │   ├── Raffle.sol           # Main raffle contract with Entropy integration | 
|  | 34 | +│   │   └── MockPYUSD.sol        # Mock PYUSD token for testing | 
|  | 35 | +│   ├── ignition/ | 
|  | 36 | +│   │   └── modules/ | 
|  | 37 | +│   │       └── App.ts           # Deployment configuration | 
|  | 38 | +│   ├── package.json | 
|  | 39 | +│   └── hardhat.config.ts | 
|  | 40 | +│ | 
|  | 41 | +└── app/                # Next.js frontend application | 
|  | 42 | +    ├── app/ | 
|  | 43 | +    │   └── page.tsx             # Main application page | 
|  | 44 | +    ├── components/              # UI components | 
|  | 45 | +    ├── contracts/               # Generated contract ABIs and types | 
|  | 46 | +    ├── providers/               # Wagmi and React Query providers | 
|  | 47 | +    ├── package.json | 
|  | 48 | +    └── wagmi.config.ts | 
|  | 49 | +``` | 
|  | 50 | + | 
|  | 51 | +## Prerequisites | 
|  | 52 | + | 
|  | 53 | +Before running this example, ensure you have: | 
|  | 54 | + | 
|  | 55 | +- **Node.js** (v18 or later) | 
|  | 56 | +- A Web3 wallet (e.g., MetaMask) with funds on the target network | 
|  | 57 | +- Access to the Pyth Entropy service on your chosen network | 
|  | 58 | + | 
|  | 59 | +## Running the Example | 
|  | 60 | + | 
|  | 61 | +### Step 1: Deploy the Smart Contracts | 
|  | 62 | + | 
|  | 63 | +Navigate to the contract directory and install dependencies: | 
|  | 64 | + | 
|  | 65 | +```bash | 
|  | 66 | +cd contract | 
|  | 67 | +npm install | 
|  | 68 | +``` | 
|  | 69 | + | 
|  | 70 | +Create a `.env` file with your private key and API key: | 
|  | 71 | + | 
|  | 72 | +```bash | 
|  | 73 | +WALLET_KEY=your_private_key_here | 
|  | 74 | +BLAST_SCAN_API_KEY=your_api_key_here | 
|  | 75 | +``` | 
|  | 76 | + | 
|  | 77 | +Deploy the contracts to Blast Sepolia testnet: | 
|  | 78 | + | 
|  | 79 | +```bash | 
|  | 80 | +npm run deploy | 
|  | 81 | +``` | 
|  | 82 | + | 
|  | 83 | +After deployment, note the deployed contract addresses, as you'll need to update them in the frontend configuration. | 
|  | 84 | + | 
|  | 85 | +### Step 2: Configure the Frontend | 
|  | 86 | + | 
|  | 87 | +Navigate to the app directory and install dependencies: | 
|  | 88 | + | 
|  | 89 | +```bash | 
|  | 90 | +cd ../app | 
|  | 91 | +npm install | 
|  | 92 | +``` | 
|  | 93 | + | 
|  | 94 | +Update the contract addresses in `contracts/addresses.ts` with your deployed contract addresses. | 
|  | 95 | + | 
|  | 96 | +If deploying to a different network, also update: | 
|  | 97 | +- `config.ts` with the correct chain configuration | 
|  | 98 | +- `ignition/modules/App.ts` with the appropriate Entropy contract and provider addresses for your network | 
|  | 99 | + | 
|  | 100 | +### Step 3: Run the Frontend | 
|  | 101 | + | 
|  | 102 | +Start the development server: | 
|  | 103 | + | 
|  | 104 | +```bash | 
|  | 105 | +npm run dev | 
|  | 106 | +``` | 
|  | 107 | + | 
|  | 108 | +The application will be available at http://localhost:3000. | 
|  | 109 | + | 
|  | 110 | +### Step 4: Interact with the Application | 
|  | 111 | + | 
|  | 112 | +1. **Get Test Tokens**: Use the MockPYUSD contract to get test PYUSD tokens | 
|  | 113 | +2. **Deposit ETH**: Deposit ETH to the factory for entropy fees | 
|  | 114 | +3. **Create Raffle**: Create a new raffle with your desired parameters | 
|  | 115 | +4. **Buy Tickets**: Purchase tickets to participate in raffles | 
|  | 116 | +5. **Close Raffle**: Wait for the raffle to close (time expires or max tickets reached) | 
|  | 117 | +6. **Winner Selection**: Random winner is selected and prize is distributed | 
|  | 118 | + | 
|  | 119 | +## Key Contract Functions | 
|  | 120 | + | 
|  | 121 | +### RaffleFactory Contract | 
|  | 122 | + | 
|  | 123 | +- **`createRaffle()`**: Creates a new raffle with specified parameters | 
|  | 124 | +- **`depositETH()`**: Deposit ETH to the factory for entropy fees | 
|  | 125 | +- **`getRaffles()`**: Get list of all created raffles | 
|  | 126 | + | 
|  | 127 | +### Raffle Contract | 
|  | 128 | + | 
|  | 129 | +- **`buyTicket(uint256 numTickets)`**: Purchase raffle tickets with PYUSD | 
|  | 130 | +- **`closeIfReady()`**: Automatically close raffle when ready and request randomness | 
|  | 131 | +- **`distributePrize()`**: Distribute prize to winner after selection | 
|  | 132 | + | 
|  | 133 | +### Events | 
|  | 134 | + | 
|  | 135 | +- **`RaffleCreated`**: Emitted when a new raffle is created | 
|  | 136 | +- **`TicketPurchased`**: Emitted when tickets are purchased | 
|  | 137 | +- **`WinnerSelected`**: Emitted when the winner is selected | 
|  | 138 | +- **`PrizeDistributed`**: Emitted when the prize is distributed | 
|  | 139 | + | 
|  | 140 | +## Development Notes | 
|  | 141 | + | 
|  | 142 | +### Technology Stack | 
|  | 143 | + | 
|  | 144 | +**Smart Contracts**: | 
|  | 145 | +- Solidity ^0.8.20 | 
|  | 146 | +- Hardhat for development and deployment | 
|  | 147 | +- OpenZeppelin contracts for security | 
|  | 148 | +- Pyth Entropy SDK for randomness | 
|  | 149 | + | 
|  | 150 | +**Frontend**: | 
|  | 151 | +- Next.js 14 with App Router | 
|  | 152 | +- React 18 | 
|  | 153 | +- Wagmi v2 for Ethereum interactions | 
|  | 154 | +- Viem for contract interactions | 
|  | 155 | +- TanStack React Query for state management | 
|  | 156 | +- Tailwind CSS for styling | 
|  | 157 | +- shadcn/ui for UI components | 
|  | 158 | + | 
|  | 159 | +### Raffle Parameters | 
|  | 160 | + | 
|  | 161 | +- **Prize Type**: Crypto, Physical, or Digital | 
|  | 162 | +- **Prize Amount**: Amount of PYUSD (for crypto) or description for physical/digital | 
|  | 163 | +- **Ticket Price**: Cost per ticket in PYUSD | 
|  | 164 | +- **Max Tickets**: Maximum number of tickets that can be sold | 
|  | 165 | +- **Max Tickets Per User**: Per-user ticket limit to prevent 51% attacks | 
|  | 166 | +- **Start Time**: Unix timestamp when raffle starts | 
|  | 167 | +- **End Time**: Unix timestamp when raffle ends | 
|  | 168 | +- **House Fee**: Percentage fee (in basis points, e.g., 300 = 3%) | 
|  | 169 | + | 
|  | 170 | +### Testing Locally | 
|  | 171 | + | 
|  | 172 | +To test the contracts without deploying: | 
|  | 173 | + | 
|  | 174 | +```bash | 
|  | 175 | +cd contract | 
|  | 176 | +npm test | 
|  | 177 | +``` | 
|  | 178 | + | 
|  | 179 | +For frontend development with a local blockchain: | 
|  | 180 | + | 
|  | 181 | +1. Start a local Hardhat node: `npx hardhat node` | 
|  | 182 | +2. Deploy contracts locally: `npm run deploy:local` | 
|  | 183 | +3. Update the frontend configuration to use the local network | 
|  | 184 | +4. Run the frontend: `cd ../app && npm run dev` | 
|  | 185 | + | 
|  | 186 | +Note that testing with actual Entropy requires deploying to a network where Pyth Entropy is available. | 
|  | 187 | + | 
|  | 188 | +## Supported Networks | 
|  | 189 | + | 
|  | 190 | +This example is configured for **Blast Sepolia** testnet, but can be adapted for any EVM network that supports Pyth Entropy. You'll need to: | 
|  | 191 | + | 
|  | 192 | +1. Find the Entropy contract and provider addresses for your target network in the Pyth documentation | 
|  | 193 | +2. Update `ignition/modules/App.ts` with the correct addresses | 
|  | 194 | +3. Configure the network in `hardhat.config.ts` | 
|  | 195 | +4. Update the frontend's `config.ts` with the chain configuration | 
|  | 196 | + | 
|  | 197 | +For available networks and addresses, see the Pyth Entropy documentation at https://docs.pyth.network/entropy. | 
|  | 198 | + | 
|  | 199 | +## Acknowledgments | 
|  | 200 | + | 
|  | 201 | +This example demonstrates how Pyth Entropy can be used to create provably fair raffle systems with verifiable randomness. | 
|  | 202 | + | 
|  | 203 | +## Additional Resources | 
|  | 204 | + | 
|  | 205 | +- **Pyth Entropy Documentation**: https://docs.pyth.network/entropy | 
|  | 206 | +- **Pyth Network**: https://pyth.network | 
|  | 207 | +- **Source Repository**: https://github.com/pyth-network/pyth-examples | 
|  | 208 | + | 
0 commit comments