
Like2Win
Follow + Like = Win $DEGEN
About
The problem it solves Like2Win - Supporting the DEGEN Ecosystem 🎯 Our Mission Recognize and reward users who support the DEGEN ecosystem through the tipping system - the engine of Farcaster's economy. 💜 Why DEGEN Deserves Recognition DEGEN has transformed Farcaster by creating: - Real economy - Tips that give monetary value to social interaction - Authentic incentives - Rewards for quality content - Community building - Tips create genuine connections - Mass adoption - Thousands of daily active users Like2Win exists to reward those who make this possible: DEGEN tippers. 🎮 Fair Recognition System DEGEN Tippers 🪙 - Follow @Like2Win + LIKE = 1 ticket - Why: You already contribute to the ecosystem with tips Regular Users 👥 - Follow @Like2Win + LIKE + RECAST + COMMENT = 1 ticket - Why: Free participation requires maximum engagement = Same ticket, effort proportional to your DEGEN ecosystem contribution 🚀 Impact - For DEGEN ecosystem: Recognition for its most valuable supporters - For tippers: Rewards for keeping the economy running - For Farcaster: More engagement and viral growth - For everyone: Fair system where contribution = benefits 🎯 Simple Proposition "We reward those who make the DEGEN economy work with simplified raffle participation, while maintaining democratic access for everyone." Bi-weekly raffles | DEGEN prizes | Automatic system | Fair for all --- Like2Win: Where your support for the DEGEN ecosystem becomes real winning opportunities. Smart Contract Address(es) 0x6dd600a1afac3d0921ea588adf58d96c39c052e4 Other Onchain Proof Project: Like2Win - Daily DEGEN Raffles on FarcasterSmart Contract: 0x6dd600a1afac3d0921ea588adf58d96c39c052e4 (Base)Token Integration: DEGEN (0x4ed4E862860beD51a9570b96d89aF5E1B0Efefed)Funding Amount: 3,500 DEGEN tokensTraction: Automated daily rewards system with real token distribution
How it's made
Challenges we ran into 🐛 Critical Smart Contract Compilation Issues OpenZeppelin v5 Breaking Changes Problem: The smart contract wouldn't compile in Remix due to deprecated OpenZeppelin patterns: // This failed ❌ constructor(address _degenToken) { degenToken = IERC20(_degenToken); } // Missing required parameter for Ownable Solution: Updated to OpenZeppelin v5 syntax: // This worked ✅ constructor(address _degenToken) Ownable(msg.sender) { require(_degenToken != address(0), "Invalid token address"); degenToken = IERC20(_degenToken); } Also had to replace deprecated toEthSignedMessageHash(): // Old way ❌ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; messageHash.toEthSignedMessageHash() // New way ✅ import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol"; using MessageHashUtils for bytes32; messageHash.toEthSignedMessageHash() 🔧 TypeScript Compilation Nightmares Implicit 'any' Parameter Errors Problem: API routes failing with cryptic TypeScript errors: // This crashed ❌ const totalTickets = userTickets.reduce((sum, ut) => sum + ut.tickets, 0); // Error: Parameter 'ut' implicitly has an 'any' type Solution: Added explicit typing: // This worked ✅ const totalTickets = userTickets.reduce((sum: number, ut: any) => sum + ut.tickets, 0); NextResponse vs Plain Object Returns Problem: Mixing NextResponse with plain objects in internal functions caused runtime crashes: // This was broken ❌ function executeDailyRaffleInternal() { return NextResponse.json({ success: true }); // Wrong context! } Solution: Separated concerns properly: // This worked ✅ async function executeDailyRaffleInternal() { // Internal logic returning plain objects return { success: true, winner: selectedWinner }; } export async function POST() { const result = await executeDailyRaffleInternal(); return NextResponse.json(result); // Wrap at API boundary } 📦 Mysterious Missing Dependencies The tslib.es6.mjs Mystery Problem: Server crashing on startup with: Error: ENOENT: no such file or directory, open 'node_modules/tslib/tslib.es6.mjs' Solution: Found the file was nested in a subdirectory and manually copied it: cp node_modules/@metamask/sdk/node_modules/tslib/tslib.es6.mjs node_modules/tslib/ This was a dependency resolution issue where the main tslib installation was incomplete. 🗄️ Prisma Integration Failures Client Initialization Issues Problem: Prisma client randomly failing to initialize in development: Error: @prisma/client did not initialize yet. Please run "prisma generate" Solution: Created fallback API without Prisma dependencies: // Created /api/automation/daily-raffle-simple/route.ts // Simulates all functionality without database calls export async function POST(request: NextRequest) { // Pure simulation logic that always works return NextResponse.json({ success: true, message: 'Full daily cycle completed (simulated)', simulation: { /* mock data */ } }); } 🤖 GitHub Actions YAML Syntax Hell Escape Character Nightmares Problem: Workflow file with malformed YAML: # This was broken ❌ run: | curl -X POST ${{ secrets.VERCEL_URL }} \ -d "{\"action\": \"${{ github.event_name }}\", \"authorization\": \"${{ secrets.AUTOMATION_SECRET }}\"}" Solution: Simplified and properly escaped: # This worked ✅ run: | curl -X POST ${{ secrets.VERCEL_URL }} \ -H "Content-Type: application/json" \ -d '{"action": "full_daily_cycle", "authorization": "${{ secrets.AUTOMATION_SECRET }}"}' 🔐 Smart Contract Security Vulnerabilities Signature Replay Attacks Problem: Original contract was vulnerable to replay attacks: // Vulnerable ❌ bytes32 messageHash = keccak256(abi.encodePacked(raffleId, _participant, _ticketCount, block.timestamp)); // Attacker could replay old signatures Solution: Added nonce system: // Secure ✅ mapping(address => uint256) public userNonces; bytes32 messageHash = keccak256(abi.encode(raffleId, _participant, _ticketCount, _nonce)); require(_nonce == userNonces[_participant], "Invalid nonce"); userNonces[_participant]++; // Increment after use 🚀 Key Learnings 1. Always check OpenZeppelin version compatibility before deployment 2. Type everything explicitly in TypeScript, even if it seems obvious 3. Keep fallback systems for critical dependencies like databases 4. Test YAML syntax thoroughly before pushing to production 5. Security audit early - vulnerabilities are easier to fix during development The most valuable lesson: Build redundant systems. The fallback API saved the entire project when Prisma failed, allowing continuous development and testing while debugging the main system in parallel.