← Back to Archive
DeFi / Growth Engineering Case Study

Mento Airdrop

A gamified DeFi loyalty platform tracking cross-chain trading activity and social engagement for community rewards.

NestJS The Graph MongoDB Discord.js Twitter API v2 WebSockets

Architecture Overview

Event-driven monolith. It uses a 'Staggered Cron' architecture to poll multiple Subgraphs without rate-limiting, reconciling 5 different DEX schemas into a single 'Swap Event' model for scoring.

The Challenges

Multi-DEX Data Reconciliation

Problem

We had to track user volume across 5 different protocols (Uniswap, Curve, Mento, etc.), each with different event schemas and Subgraphs. Missing a single trade meant a user might lose their airdrop eligibility.

Solution

Implemented a 'Staggered Ingestion Engine'. Independent cron jobs run at offset intervals (15s, 40s, 55s) to poll specific Subgraphs. We built a normalization layer that maps disparate schemas (e.g., Uniswap `Swap` vs. Curve `TokenExchange`) into a unified `TransactionModel`, deduplicating events by Hash to prevent double-counting.

tasks.service.ts

Polymorphic Task Engine

Problem

Marketing teams wanted complex, changing criteria: 'Hold $50 of cUSD for 7 days' OR 'Trade 5 different assets'. Hardcoding these rules would require a deploy for every new quest.

Solution

Designed a Polymorphic Task Pipeline. We treated Tasks as configurations, not code. The system uses a Strategy Pattern (`TaskProcessor`) where events trigger specific handlers based on the `TaskType` enum. This allowed us to launch 'Volume Challenges' or 'Diversity Quests' dynamically without rewriting the core tracking logic.

taskTracking.service.ts

USD Normalization at Scale

Problem

To calculate 'Volume Leaderboards', we needed the USD value of every trade. However, many exotic pairs (e.g., cEUR/Celo) didn't have a direct USD price feed at the moment of the trade.

Solution

Built a multi-hop pricing resolver in AssemblyScript (Subgraph level). If a direct USD pair didn't exist, the indexer recursively checked for a route through CELO (e.g., cEUR -> CELO -> cUSD). We also verified rates against the on-chain Broker contract's `getAmountOut` to prevent price manipulation exploits.

pricing.ts

Sybil Resistance (Social + Wallet)

Problem

Users try to farm airdrops by linking one Discord account to 50 wallets. We needed strict 1:1 identity mapping.

Solution

Implemented an idempotent Identity Merging system. We use ECDSA signatures to prove wallet ownership and OAuth for Discord/Twitter. The backend enforces a strict unique constraint: If a Discord ID is linked to a new wallet, the previous link is atomically severed (orphaned), ensuring one human cannot farm rewards across multiple addresses.

auth.utils.ts