Solidity smart contract system for decentralized raffles (lotteries) with NFT tickets and ERC20 prizes.
- RaffleFactory: UUPS-upgradeable proxy contract for deploying and managing individual raffles.
- RaffleNFT: ERC721 contract representing a single raffle. Each NFT is a ticket. The winner receives the ERC20 prize.
- ERC20TestToken: Simple ERC20 token for testing.
- Factory pattern: deploys new raffles as separate contracts.
- Each raffle uses NFT tickets (ERC721).
- Prize is any ERC20 token.
- Upgradeable architecture (UUPS proxy).
- Access control: only managers can create/finish raffles, only admin can withdraw stuck tokens.
- Emergency withdraw for admin.
contracts/
RaffleFactory.sol # Factory contract (UUPS proxy)
RaffleNFT.sol # Raffle contract (ERC721)
test/ERC20.sol # Test ERC20 token
test/
Factory.js # Full test suite (Chai + Hardhat)
deploy/
deploy.js # Deployment script for RaffleFactory (and artifact saving)
deployments/
{network}/
RaffleFactory.json # Full JSON: address, abi, bytecode, txHash, receipt
RaffleNFT.json # ABI and bytecode for frontend and factory
# (you can similarly add ERC20TestToken.json if needed)
-
Install dependencies:
npm install
-
Configure your network and private key in
hardhat.config.jsor via.env:// Example for haqq-testedge2 networks: { 'haqq-testedge2': { url: 'https://rpc.eth.testedge2.haqq.network', accounts: [process.env.PRIVATE_KEY], }, }
-
Deploy RaffleFactory as UUPS proxy using a script:
npx hardhat run deploy/deploy.js --network haqq-testedge2
After deployment, all contract artifacts (address, abi, bytecode, txHash, receipt) for RaffleFactory and RaffleNFT will be saved in
deployments/{network}/.
- Grant MANAGER_ROLE to your address (from admin):
await factory.grantRole(await factory.MANAGER_ROLE(), managerAddress);
- Approve ERC20 tokens to the factory from manager:
await erc20.approve(factory.address, amount);
- Create a new raffle:
await factory.createRaffle( "MyRaffle", "MRFL", "https://example.com/metadata.json", erc20.address, amount, 3600 // 1 hour duration );
To verify on haqq-testedge2:
npx hardhat verify --network haqq-testedge2 0xYOUR_CONTRACT_ADDRTo verify on haqq-mainnet:
npx hardhat verify --network haqq-mainnet 0xYOUR_CONTRACT_ADDRUpgrades RaffleFactory contract via UUPS proxy.
PROXY_ADDRESS=0x1234567890123456789012345678901234567890 npx hardhat run scripts/upgrade.js --network <network_name>Examples:
# Testnet
PROXY_ADDRESS=0x3Bfb78027A66df3180E7174E6f77d37b16DF252b npx hardhat run scripts/upgrade.js --network haqq-testedge2
# Local
PROXY_ADDRESS=0x1234567890123456789012345678901234567890 npx hardhat run scripts/upgrade.js --network localhostRequirements:
- Contract must be deployed as UUPS proxy
- Valid proxy address
- Admin role permissions
Run all tests:
npx hardhat test