This system enables sellers to create and manage an NFT-based ticketing system in a decentralized and transparent manner using Solidity smart contracts.
Participants can deposit funds (USDC or other ERC20) to qualify for a lottery, where winners are randomly selected via Gelato's VRF service. Second option to get your seats is participation in live auctions.
We had a limitation by loom therefore we had to split to multiple videos:
Part I
https://www.loom.com/share/1bbe0842fdd44baeba9c8354d2d5e2b2
Part 2
https://www.loom.com/share/a0f5f33b34b04d639a921ad31aa01d1a
Part 3
https://www.loom.com/share/2a15180337ea4aad91f7693936ed173c
NFTLotteryTicket.sol
: Represents tickets as NFTs. Some tickets (depending on auction or lottery type) might be non-transferable (soulbound). Winning the lottery or an auction grants the ability to mint such token.LotteryV1Base.sol
: Enables to participate in initial sale of small portion of tickets. Eligible buyers are selected randomly via VRF.LotteryV2Base.sol
: Allows potential buyers and sellers to roll a dice and generate a random number. Numbers close to the seller's position become eligible for minting.AuctionV1Base.sol
: Customers bid the same price and if there's a higher demand for tickets, lucky bidders are selected via VRF.AuctionV2Base.sol
: Firstn
highest bids are eligible to mint tickets (n = number of available tickets)
-
Deploy the NFTLotteryTicket Contract:
- Compile
NFTLotteryTicket.sol
similarly. - Deploy the contract, providing the URI for the NFT metadata as a constructor parameter.
- Compile
-
Deploy the Lottery, LotteryV1 and Auction contracts:
- Compile
LotteryV1Base.sol
,LotteryV2Base.sol
,AuctionV1Base.sol
andAuctionV2Base.sol
using Forge, Remix, or Hardhat. - Deploy the contract to your chosen EVM compatible network. During deployment, specify the seller's address as a constructor parameter.
- Compile
-
Use those Contracts to create BlessedFactory (setBaseContracts function)
- To see the whole process of configuring Sale, check the endpoint in Blessed app: https://github.com/BlessedOrg/swifty-app/blob/main/src/app/api/events/%5Bid%5D/deployContracts/route.ts
-
Start the Lottery:
- Call
startLottery
to change the state to ACTIVE and automatically check for eligible participants.
- Call
-
Selecting Winners:
- Manually initiate the winner selection process by calling
selectWinners
. - The contract will request randomness from Gelato's VRF, and winners will be selected one by one.
- Monitor the
WinnerSelected
andLotteryEnded
events.
- Manually initiate the winner selection process by calling
-
End the Lottery:
- Once all winners are selected, or when you decide to end the lottery, call
endLottery
.
- Once all winners are selected, or when you decide to end the lottery, call
-
Withdraw Funds:
- After the lottery ends, call
sellerWithdraw
to collect the funds from losing participants.
- After the lottery ends, call
-
Deposit Funds:
- Send funds to the contract while the lottery is NOT_STARTED using
deposit
function. Beforehand adding allowance approval for our contracts would be required. The amount must meet or exceed the minimum deposit amount.
- Send funds to the contract while the lottery is NOT_STARTED using
-
Check Eligibility:
- You can check if you're marked eligible after the lottery starts.
-
After Lottery Ends:
- If you're a winner, mint your NFT ticket using
mintMyNFT
. - If not a winner, withdraw your deposited funds using
buyerWithdraw
.
- If you're a winner, mint your NFT ticket using
NFTLotteryTicket.sol
: https://opcelestia-raspberry.gelatoscout.com/address/0xA69bA2a280287405907f70c637D8e6f1B278E613LotteryV1Base.sol
: https://opcelestia-raspberry.gelatoscout.com/address/0xC883d0b60EaF2646483cEafC0c50Ea755C7f794CLotteryV2Base.sol
: https://opcelestia-raspberry.gelatoscout.com/address/0xAF3c36Cb30b88899873E76bFd5E906E0d69d1F53AuctionV1Base.sol
: https://opcelestia-raspberry.gelatoscout.com/address/0xbb5EFc7c05867A010bF6Fa3Ed34230D40CF85941AuctionV2Base.sol
: https://opcelestia-raspberry.gelatoscout.com/address/0xc0C18852552DF4A66FcE60bC444b23Eb5B4FCF59
Connection details: https://raas.gelato.network/rollups/details/public/opcelestia-raspberry
Bridge: https://bridge.gelato.network/bridge/opcelestia-raspberry
forge create --rpc-url https://rpc.opcelestia-raspberry.gelato.digital \
--private-key "{YOUR_PRIVATE_KEY}" \
src/NFTLotteryTicket.sol:NFTLotteryTicket
forge create --rpc-url https://rpc.opcelestia-raspberry.gelato.digital \
--private-key "{YOUR_PRIVATE_KEY}" \
src/LotteryV1Base.sol:LotteryV1Base
forge create --rpc-url https://rpc.opcelestia-raspberry.gelato.digital \
--private-key "{YOUR_PRIVATE_KEY}" \
src/LotteryV2Base.sol:LotteryV2Base
forge create --rpc-url https://rpc.opcelestia-raspberry.gelato.digital \
--private-key "{YOUR_PRIVATE_KEY}" \
src/AuctionV1Base.sol:AuctionV1Base
forge create --rpc-url https://rpc.opcelestia-raspberry.gelato.digital \
--private-key "{YOUR_PRIVATE_KEY}" \
src/AuctionV2Base.sol:AuctionV2Base
forge verify-contract {CONTRACT_ADDR} NFTLotteryTicket --verifier blockscout --verifier-url https://opcelestia-raspberry.gelatoscout.com/api --chain 123420111 --constructor-args $(cast abi-encode "constructor(string,bool)" "https://example.com/" true)
When script is not working for some reason, the best option is to try use flattened code technique.
All you need to do is:
- flatten contract code using
forge flatten --output ./src/{ContractName}.flattened.sol ./src/{ContractName}.sol
- go to the explorer, type address, click Contract => Verify
- select single file code mode
- paste flattened contract code
- specify compiler version to 0.8.25
- specify evm version to
paris
- if you fail to verify, go to
out
folder, find your{ContractName}.json
file, and under therawMetada
object look for the keyscompiler
andevmVersion
cargo install --git https://github.com/foundry-rs/foundry --profile local --locked forge cast chisel anvil
forge test -vv
- Thoroughly test all functionalities, especially around deposits, winner selection, and NFT minting.
- Consider security best practices and potentially get a smart contract audit.
This NFT Lottery Ticket System offers a transparent and fair way to distribute unique NFTs to participants. The integration with Gelato VRF ensures trusted randomness.
Here we list all relevant other repos.
We create a dedicated repo for the APP to you understand the database structure and how to set it up. https://github.com/BlessedOrg/swifty-app
We create a dedicated UX repo as we also partipated in the UX challenge and we explained there in detail with screenshoots what challenges we had and what how we solved that UX wise.
https://github.com/BlessedOrg/UX--UI
For the Gelato Bounty we create also our own repo where we share our findings.
We needed to link it at the UX Challenge too, please consider that this was a constraint of handing in a submission to pick one and to be complete we listed it here as well as in the other signed in built where we soley focused on UX challenges.
https://github.com/BlessedOrg/Gelato