How GitGrid works.
Connect GitHub, your verified contributions become a sybil-resistant grid score, seasonal leaderboards rank devs, and the top grids split the $GITGRID pool on Base. Here's every moving part.
Overview
The GitHub contribution graph is the most recognizable image in software. GitGrid turns it into a game. You connect GitHub and a Base wallet; your verified contribution activity becomes your grid score (“grid”). Seasonal leaderboards rank devs by grid, and top grids split a $GITGRID reward pool.
Honest framing: the value here is the narrative and the meme, not deep utility — and that's the point. It's a tight first launch and a beachhead for sister concepts. The token stays dumb; all game logic lives off-chain so scoring can iterate without redeploying contracts.
- $GITGRID
- Base L2
- prove your grid
- commit · rank · earn
The game loop
Five steps, one grind:
- 1 · Sync — pull your contribution calendar + repo metadata from GitHub's GraphQL + REST APIs for the active season window.
- 2 · Score — compute a sybil-resistant grid score. Daily activity maintains a streak.
- 3 · Rank — global + seasonal leaderboards, recomputed on a cron (every ~15 min) and cached in Redis.
- 4 · Reward — at season close, top grids claim $GITGRID through a Merkle distributor on Base.
- 5 · Flex — mint your grid as an NFT snapshot, the shareable artifact that pulls the next dev in.
Grid score
Raw commit count is trivially farmable, so the score rewards real work. The MVP formula weights contributions by repo reputation, then caps by account age and multiplies by a streak bonus:
gridScore =
( Σ commit · repoWeight
+ Σ pr · repoWeight · prToOthersBonus
+ reviews · reviewWeight )
× accountAgeFactor
× streakBonusrepoWeight grows with a repo's stars (logarithmically) and craters for the things farmers abuse:
- forks → near-zero weight
- brand-new repos (< 30 days) → heavily penalized
- private repos → discounted (can't be verified publicly)
- your own 0-star repos → clamped to a spam floor, regardless of commit volume
accountAgeFactor ramps from a floor up to full credit at ~90 days, capping week-old accounts. streakBonus rewards consecutive-day activity up to a cap. Every weight lives in a tunable ScoringConfig so the rules tighten season over season without touching the formula.
Anti-sybil — the grid never lies
Treat scoring as adversarial from day one — it's the difference between “fun” and “farmed to zero in 48h.” The quality signals come straight from GitHub:
- Contribution calendar — the green-squares daily counts.
- Repo reputation — stars, forks, and age of the repos commits land in.
- PRs into others' repos — merged PRs to repos you don't own count heavily; they're hard to fake.
- Account age — caps the score of fresh accounts.
The result: a bot with 12,400 raw commits across 50 fresh 0-star repos scores a 41, while a real dev with merged PRs into popular repos scores 1,842. More commits, lower score.
Seasons & rewards
A season is a fixed time window with a $GITGRID pool. Scores accrue during the window; a cron job recomputes ranks continuously. At endsAt the worker finalizes the season:
- 1 — freeze scores and assign final ranks
- 2 — allocate the pool across the top N grids, proportional to grid score, in exact integer wei (no dust lost)
- 3 — open the next season automatically (idempotent)
- 4 — an admin script builds a Merkle tree of
(address, amount)and publishes the root on-chain; users then claim
Claims are trustless: a GridRewardsDistributor contract verifies a Merkle proof and transfers $GITGRID, marking the season claimed per address.
Architecture
Two long-running services (web + worker), Postgres, and Redis — all on Railway. Contracts live on Base, deployed separately with Foundry.
Browser ──OAuth──▶ Next.js (web) ◀── RainbowKit / wagmi
│ Prisma
▼
PostgreSQL ◀──────┐
▲ │ BullMQ
│ ┌───┴────┐
GitHub GraphQL ◀──┼─────────│ worker │ sync + scoring
+ REST │ │ + cron │ + season rollover
▼ └────────┘
Redis (jobs + leaderboard cache)
│ publishes Merkle root each season
▼
Base L2: $GITGRID ERC-20 · GridRewardsDistributor · GridSnapshot (v2)Data model
Prisma + PostgreSQL. The core entities:
User githubId, githubLogin, avatarUrl,
walletAddress?, accountAgeAt
SeasonScore userId, seasonId, gridScore, rawCommits,
streakDays, rank?, rewardWei?, claimed
Season index, startsAt, endsAt, poolWei, merkleRoot?
SyncRun userId, startedAt, status
GridSnapshot userId, year, svg, tokenId? (v2 NFT)rewardWei and poolWei are stringified bigints. A wallet is linked only after the user signs a nonce message proving ownership — the address is never trusted blindly.
Tech stack
Smart contracts
On-chain surface is deliberately tiny — token + claims + (later) NFT. Everything else stays off-chain.
- $GITGRID ERC-20 — standard fixed-supply token (or a fair launch via a Base launcher).
- GridRewardsDistributor — owner sets a Merkle root per season;
claim(seasonIndex, amount, proof)transfers $GITGRID and marks claimed via a per-season bitmap (OpenZeppelin MerkleProof). - GridSnapshot ERC-721 (v2) — mints a rendered grid, tokenURI → IPFS.
The Merkle root is published from a controlled admin script — the distributor owner key is never in the running app.
Deployment
One Railway project, four components: web (public domain), worker (no port), plus Postgres and Redis plugins that inject DATABASE_URL / REDIS_URL. Migrations run via prisma migrate deploy.
GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET # OAuth
AUTH_SECRET # NextAuth
DATABASE_URL / REDIS_URL # Railway plugins
NEXT_PUBLIC_CHAIN_ID=8453 # Base mainnet
NEXT_PUBLIC_BASE_RPC
NEXT_PUBLIC_WALLETCONNECT_ID
GITHUB_SYNC_TOKEN # worker, higher limits
DISTRIBUTOR_OWNER_PK # admin script ONLYRoadmap
MVP: GitHub OAuth + wallet link · contribution sync + grid score · global + season-1 leaderboard · branded grid UI · $GITGRID on Base with a season-1 Merkle claim.
v2+: grid-snapshot NFT mint · $GITGRID staking → score multiplier · cosmetic grid themes (token sink) · tighter anti-sybil (signed-commit requirement, anomaly detection) · team / org grids.
Legal
Not legal or financial advice. An EU token launch sits under MiCA and possibly other rules — especially anything resembling a public sale or an “earn” offering. Get proper counsel before launch. The $GITGRID framing here is narrative-first.