Rewards economy
points, caps, levels.
Every number that decides how many points an action gives, and how often. All of it is set in the console (Rewards economy and Features) and written to config/public. Defaults below come from docs/CONTRACT.md and admin/src/manifest.ts.
01Ground rules
- The server decides. Every credit goes through one server transaction (
credit()infirebase/functions/src/credit.ts) that writes a ledger row with the balance after it. Wheel and scratch results are drawn on the server; the scratch animation is cosmetic. - Whole points only. No decimals in the ledger. The VIP or booster multiplier is rounded down. VIP and booster never stack: the larger one applies.
- The day is UTC. Daily caps, streaks and the daily leaderboard reset at 00:00 UTC; the weekly leaderboard uses the ISO week in UTC.
- Points have no cash value. The console's Legal → Points notice is shown in onboarding, in the settings and on the rules screen of the app. Keep its meaning. The 4.0 cash wallet is a separate balance that points can never reach (the hard rule).

02Rewards economy settings
| Setting | Field in config/public | Default | Allowed |
|---|---|---|---|
| Points per rewarded video | economy.pointsPerAd | 10 | 1 to 10000 |
| Rewarded videos per day (per user) | economy.adDailyCap | 20 | 1 to 500 |
| Seconds between rewarded videos | economy.adCooldownSeconds | 30 | 0 to 3600 |
| Daily streak rewards | economy.streakRewards | 5, 10, 15, 20, 25, 30, 50 | One number per line, day 1, day 2… After the last day the last value repeats; a missed day restarts at day 1. |
| Free wheel spins per day | economy.spinDailyFree | 1 | 0 to 20 |
| Extra spins per day for watching an ad | economy.spinExtraViaAdDaily | 2 | 0 to 20 |
| Wheel segments | economy.wheel | 5|5|30, 10|10|25, 20|20|18, 50|50|8, 2|2|30, 100|100|2, 15|15|20, 0|0|10 | One per line as label|points|weight. 4 to 12 segments, weight above 0 (higher = more likely). |
| Free scratch cards per day | economy.scratchDailyFree | 2 | 0 to 20 |
| Extra scratch cards per day for watching an ad | economy.scratchExtraViaAdDaily | 3 | 0 to 20 |
| Scratch card prizes | economy.scratchPrizes | 0|20, 5|35, 10|25, 25|12, 50|6, 200|2 | One per line as points|weight. 1 to 12 prizes. |
| Points per correct quiz answer | economy.quizPointsPerCorrect | 5 | 0 to 1000. A quiz can override it with its own points value. |
| Quizzes per day (per user) | economy.quizDailyCap | 5 | 0 to 100 |
| Inviter bonus (points) | economy.referralInviterPoints | 100 | Paid once the invited user has earned the unlock amount. |
| Welcome bonus for the invited user | economy.referralInviteePoints | 50 | 0 to 100000 |
| Points the invited user must earn first | economy.referralUnlockPoints | 100 | 0 to 1000000 |
| Days after sign-up to enter an invite code | economy.referralWindowDays | 7 | 0 to 365 |
| Level thresholds | economy.levels | 0, 100, 300, 700, 1500, 3000, 6000, 10000, 16000, 25000 | Lifetime points for level 1, 2, 3… Starting at 0, strictly ascending. |
| VIP multiplier | economy.vipMultiplier | 1.5 | 1 to 5. Applied while VIP is active (rounded down) to rewarded-ad, rewarded-interstitial, spin, scratch, quiz, task, check-in and mini-game credits (docs/CONTRACT-3.1.md §10.3). With an active booster the higher of the two multipliers applies, never both. |
| Offer completions credited per day (per user) | economy.offerDailyCap | 10 | 0 to 100 |
| Second-level invite bonus (points) | economy.referralTier2Points | 0 (off) | 0 to 100000. Paid to the inviter's inviter. Never more than two levels (details). |
| Check-in calendar rewards | economy.checkinRewards | 31 values from 10 to 150, bigger every 7th | Line n = reward for the n-th check-in of the month (details). |
| Points per 1 USD of provider payout | economy.offerwallPointsPerUsd | 1000 | 0 to 100000. Set in the Offerwalls and surveys section (details). |
| Most points one conversion can credit | economy.offerwallMaxPointsPerConversion | 50000 | 0 to 1000000. Same section. |
Rewarded-interstitial points, mini-game points, the mystery box, the season pass and achievements have their own sections: see Placements and Engagement features. Several of these numbers can be A/B-tested (A/B experiments).
A wheel segment without a weight, for example, is left out. The console's Status page lists every skipped line.
03Features on and off
Console → Features. A switched-off feature disappears from the app and the Functions refuse its calls. All are on by default. Features that need content (season, events, store and so on) show nothing until you add it.
| Switch | Field |
|---|---|
| Lucky wheel | features.spin |
| Scratch cards | features.scratch |
| Quizzes | features.quiz |
| Daily tasks | features.tasks |
| Offers | features.offers |
| Leaderboard | features.leaderboard |
| Invite friends | features.referral |
| Daily streak | features.streak |
| Offerwalls and surveys tab | features.offerwalls |
| Sponsored content | features.sponsors |
| Check-in calendar | features.checkin |
| Achievements | features.achievements |
| Season pass | features.season |
| Events and tournaments | features.events |
| Teams | features.teams |
| Friends | features.friends |
| Mini-games | features.games |
| Rewards store | features.store |
| Notifications inbox | features.inbox |
| Promo codes | features.promo |
The mystery box has its own on/off setting, off by default (Mystery box).
04Levels, badges and leaderboards
The level follows lifetime points, which never go down. Badges are awarded by the server: first_ad, ads_50, ads_250, streak_7, streak_30, quiz_10, quiz_master (100% on a quiz with 5 or more questions), spinner_25, inviter_1, inviter_10, level_5, level_10 and vip. Their names are in app/lib/l10n/app_en.arb.
Leaderboards exist for today, this week and all time. Points you add by hand in the console do not change leaderboards.
05Built-in protection
- Caps and cooldown per user and day, as above.
- Rate limits on every callable function, per user, over a one-minute window (
firebase/functions/src/guard.ts). - One-time ad sessions: each verified callback credits once; mismatches open a fraud flag.
- App Check on every callable in production.
- Banned users are refused by every function except account deletion.
- Anti-fraud: device reports, an accounts-per-device limit, a velocity rule and a review queue (Anti-fraud).