
- Fully On-Chain: No centralized backend. All data and logic are managed by the smart contract.
- Create & Join Giveaways: Users can create giveaways by paying a small fee in the native token (e.g., STT). Participants can join by also paying a fee.
- User Profile Page: A dedicated
/profilepage where users can track a history of all giveaways they have created and joined. - Fair Winner Selection: The smart contract uses on-chain data (
block.prevrandao) to ensure a fair and unpredictable random winner selection process after a giveaway's snapshot time. - Owner Fee Withdrawal: The contract owner can withdraw accumulated protocol fees from a special panel on their profile page.
- CSV Winner Export: Giveaway creators can easily download a list of winners in CSV format.
- Fully Responsive UI: A clean, modern user interface built with Tailwind CSS that works seamlessly on desktop and mobile devices.
- Custom Wallet Connection: A beautifully customized and responsive wallet connection flow powered by RainbowKit.
- Framework: Next.js (App Router)
- Language: TypeScript
- Styling: Tailwind CSS
- Web3 Toolkit: wagmi & viem
- Wallet Connection: RainbowKit
- Smart Contracts: Solidity & OpenZeppelin
- Icons: Lucide React
Follow these steps to get the project running locally.
git clone https://github.com/lrmn7/fun-give.git
cd fun-give
pnpm installCopy the example environment file and fill in the required variables.
cp .env.example .envYou will need to edit the .env file:
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID: Get your own ID from WalletConnect Cloud.NEXT_PUBLIC_CONTRACT_ADDRESS: The address of your deployed smart contract (you'll get this in the next step).
The core logic resides in contracts/GiveawayFactory.sol. You can easily deploy it using the Remix IDE.
- Open Remix: Go to remix.ethereum.org.
- Create File: Create a new file named
GiveawayFactory.soland paste the entire content from the project'scontracts/GiveawayFactory.solfile. - Compile:
- Go to the "Solidity Compiler" tab.
- Set the Compiler to
0.8.20or a compatible version (^0.8.20). - Click "Compile GiveawayFactory.sol".
- Deploy:
- Go to the "Deploy & Run Transactions" tab.
- Set the Environment to "Injected Provider" (e.g., MetaMask).
- Ensure your wallet is connected to the correct network (e.g., Somnia Testnet).
- Select the
GiveawayFactorycontract from the dropdown. - Click "Deploy" and confirm the transaction in your wallet.
- Update Address: Once deployed, copy the new contract address and paste it into the
NEXT_PUBLIC_CONTRACT_ADDRESSvariable in your.envfile.
pnpm devOpen http://localhost:3000 in your browser to see the dApp in action.
The winner selection process is designed to be fair and transparent:
- Creator-Only Finalization: After the snapshot time has passed, only the creator of the giveaway can trigger the
finalizefunction. This provides a simple and secure workflow without requiring the creator to manage secret keys. - On-Chain Randomness: The random seed is generated from on-chain, difficult-to-predict variables like
block.prevrandaoand the previousblockhash. - Limitations: While this method is highly secure for most applications, it's important to note that a powerful and motivated validator could theoretically have some influence over these block variables. For high-stakes giveaways, a solution using a Chainlink VRF oracle would be the next step.
- Unbiased Algorithm: The contract uses a Fisher-Yates-like shuffle algorithm to pick winners from the participant list, which avoids modulo bias and ensures every participant has an equal chance.
The contract now contains two mappings, createdGiveaways and joinedGiveaways, which store an array of giveaway IDs for each user. This allows the frontend to efficiently query and display a user's complete history on their profile page.
- Reentrancy Guard: All critical functions involving token transfers (
withdraw) are protected by OpenZeppelin'sReentrancyGuard. - Ownable: Administrative functions like pausing the contract or withdrawing fees are restricted to the contract owner.
- Pausable: The owner can pause key functions (
createGiveaway,joinGiveaway) in case of an emergency.
/
├── app/ # Next.js App Router pages
│ ├── profile/ # The new user profile page
│ └── ...
├── components/ # Reusable React components
│ ├── CustomConnectButton.tsx
│ ├── GiveawayCard.tsx
│ └── ...
├── contracts/ # Solidity smart contracts
│ └── GiveawayFactory.sol
├── lib/ # Shared utilities, hooks, and configs
│ ├── chains.ts # Custom chain definitions
│ ├── contracts.ts # Contract ABI and address
│ └── Web3Provider.tsx # Wagmi & RainbowKit setup
└── public/ # Static assets (images, GIFs)