A decentralized, provably fair lottery system built with Solidity and Foundry, leveraging Chainlink VRF for verifiable randomness and Chainlink Automation for automated winner selection.
- Provably Fair Raffle Smart Contract
This project implements a transparent and trustless raffle/lottery system on the blockchain where:
- Users can enter by paying an entrance fee
- Winners are selected randomly using Chainlink VRF (Verifiable Random Function)
- Winner selection is automated using Chainlink Automation (formerly Keepers)
- The entire prize pool is automatically transferred to the winner
- Provably Fair Randomness: Utilizes Chainlink VRF V2 to generate verifiable random numbers for winner selection
- Automated Execution: Chainlink Automation triggers winner selection at predetermined intervals
- Transparent & Trustless: All logic is on-chain and verifiable
- Gas Optimized: Built with best practices for gas efficiency
- Comprehensive Testing: Includes unit tests, integration tests, and fork tests
- Solidity - Smart contract programming language
- Foundry - Development framework and testing suite
- Chainlink VRF V2 - Verifiable random number generation
- Chainlink Automation - Decentralized automation network
- Clone the repository
git clone https://github.com/BuildsWithKing/raffle-contract
cd raffle-contract- Install dependencies
make install- Build the project
make buildDeploy to Sepolia testnet:
make deploy-sepoliaRun all tests:
make testRun tests with verbosity:
make test -vvvRun specific test:
forge test --match-test testFunctionNameTest coverage:
make coverageEnter the raffle:
cast send <RAFFLE_ADDRESS> "enterRaffle()" --value 0.01ether --rpc-url $SEPOLIA_RPC_URL --account myaccountCheck raffle state:
cast call <RAFFLE_ADDRESS> "getRaffleState()" --rpc-url $SEPOLIA_RPC_URL-
Entry Phase: Users call
enterRaffle()and pay the entrance fee. Their addresses are stored in an array. -
Upkeep Check: Chainlink Automation nodes continuously call
checkUpkeep()to determine if it's time to pick a winner based on:- Time interval has passed
- Raffle is in OPEN state
- Contract has ETH balance (at least two player)
- Subscription is funded with LINK
-
Winner Selection: When conditions are met,
performUpkeep()is called:- Raffle state changes to CALCULATING
- Request is sent to Chainlink VRF for random number
-
Fulfillment: Chainlink VRF calls
fulfillRandomWords():- Random winner is selected using modulo operation
- Prize pool is transferred to winner
- Raffle resets for next round
enterRaffle()- Enter the lottery by paying entrance feecheckUpkeep()- Check if conditions are met for winner selectionperformUpkeep()- Trigger the winner selection processfulfillRandomWords()- Callback function for Chainlink VRF
getEntranceFee()- Get the entrance fee amountgetRaffleState()- Get current raffle state (OPEN/CALCULATING)getPlayer(uint256)- Get player address at indexgetRecentWinner()- Get the most recent winner
Create a .env file with the following variables:
SEPOLIA_RPC_URL=your_sepolia_rpc_url
ETHERSCAN_API_KEY=your_etherscan_api_key
├── script
│ ├── DeployRaffle.s.sol
│ ├── HelperConfig.s.sol
│ └── Interaction.s.sol
├── src
│ └── Raffle.sol
└── test
├── integration
│ └── IntegrationTest.t.sol
├── mocks
│ └── LinkToken.sol
└── unit
└── RaffleTest.t.sol
├── foundry.toml
└── README.md
- Uses Chainlink VRF for cryptographically secure randomness
- Implements checks-effects-interactions pattern
- State changes before external calls to prevent reentrancy
- Comprehensive test coverage
- Audited Chainlink contracts
- Uses custom errors instead of require strings
- Efficient storage patterns
- Optimized loops and array operations
Michealking
- GitHub: @BuildsWithKing
- Twitter: @BuildsWithKing
- Discord: @BuildsWithKing
- Cyfrin Updraft - Foundry Solidity Course
- Patrick Collins - Course instructor
- Chainlink - VRF and Automation services
This project is licensed under the MIT License.
Contributions, issues, and feature requests are welcome! Feel free to check the issues page.