Skip to content

feat(rewards): on-chain referral reward engine with anti-abuse (#656)#662

Merged
joelpeace48-cell merged 1 commit into
FinesseStudioLab:mainfrom
Mercy017:feat/onchain-referral-rewards-656
Jun 19, 2026
Merged

feat(rewards): on-chain referral reward engine with anti-abuse (#656)#662
joelpeace48-cell merged 1 commit into
FinesseStudioLab:mainfrom
Mercy017:feat/onchain-referral-rewards-656

Conversation

@Mercy017

Copy link
Copy Markdown
Contributor

Closes #656

Scope note for reviewers: #656 is a large "epic" (difficulty: hard, effort: L) that consolidates four features. This PR lands the on-chain referral-reward slice (the #603 referral-economy portion) end-to-end — self-contained, fully tested, and CI-green — so it can be reviewed and merged independently. The remaining features (quests/streaks, recurring scheduler, seasonal leaderboards) are scoped as follow-ups below. Happy to relabel ClosesPart of if you'd prefer to keep the epic open.

What this delivers

On-chain referral bonuses with abuse protection, plus the attribution/instrumentation hook. Responsibilities are split across the existing contracts:

  • Campaign contract already owns attribution (referrer_of, referral_count, referred event) — unchanged.
  • Rewards contract gains the payout and its anti-abuse invariants (new).

Rewards contract (contracts/rewards/src/lib.rs)

Function Auth Notes
set_referral_config(rate_bps, per_referrer_cap) admin rate_bps in 1..=100_000; cap 0 = uncapped
referral_config() view (rate_bps, cap), (0,0) until set
pay_referral_bonus(referrer, referee, qualifying_amount) admin credits referrer, returns bonus, emits credit + ref_bonus
referral_bonus_total / referral_reward_count / rewarded_referrer_of view metrics + attribution lookups

bonus = qualifying_amount * rate_bps / 10_000 (checked u128 math).

Anti-abuse — enforced on-chain, all-or-nothing

  • Self-referral blocked (SelfReferral)
  • Circular A→B then B→A blocked (CircularReferral)
  • Sybil/replay: one bonus per referee, ever (ReferralAlreadyRewarded)
  • Per-referrer cap (ReferralCapExceeded)
  • Zero/dust bonus rejected (ZeroReferralBonus); respects paused + admin auth

Rejected attempts write no state (no balance, counter, or attribution change).

Backend (backend/src/jobs/eventIndexer.js, migration 010)

  • New refbonus indexer handler records each attribution edge into referral_bonus_events for referral-conversion metrics.
  • Instrumentation only — the paired credit event already updates balances, so no double-counting. UNIQUE(referee) mirrors the on-chain invariant and makes re-indexing idempotent.

Also

Testing (all run locally, green)

  • Contracts: cargo fmt --check, cargo clippy --workspace --all-targets -- -D warnings -A deprecated, cargo test --workspace (55 rewards incl. 13 new, + campaign + integration), doc-completeness check, WASM build, bindings regen (campaign bindings unchanged → no version drift).
  • Backend: npm run test:backend (93 pass, incl. 3 new), test:integration (26), typecheck (clean), prettier --check clean.

Follow-ups (rest of #656)

  1. Quest/streak engine → reputation/badges
  2. Recurring/seasonal scheduler (locked, idempotent config cloning)
  3. Seasonal leaderboards (reset + immutable archive over indexed rollups)
  4. Quest-completion & season-retention growth metrics

@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

@Mercy017 is attempting to deploy a commit to the joelpeace48-cell's projects Team on Vercel.

A member of the Team first needs to authorize it.

…seStudioLab#656)

Lands the on-chain referral-reward slice of the viral growth engine epic
(the FinesseStudioLab#603 referral-economy portion). Attribution stays in the campaign
contract; the rewards contract gains the payout plus its abuse invariants.

Rewards contract:
- set_referral_config(rate_bps, per_referrer_cap) + referral_config view
- pay_referral_bonus(referrer, referee, qualifying_amount): admin-gated,
  credits the referrer and emits credit + ref_bonus events
- Anti-abuse, all enforced on-chain and all-or-nothing:
  - self-referral blocked
  - circular referral (A->B, B->A) blocked
  - one-bonus-per-referee uniqueness (sybil/replay gate)
  - configurable per-referrer cumulative cap
  - zero/dust bonus rejected; respects paused + admin auth
- Views: referral_bonus_total, referral_reward_count, rewarded_referrer_of
- 13 new contract tests covering happy path, events, and every invariant

Backend:
- eventIndexer gains a refbonus handler recording referral-conversion
  metrics into the new referral_bonus_events table (migration 010);
  instrumentation only (the paired credit event owns balances) and
  idempotent via UNIQUE(referee)
- 3 new indexer tests

Also regenerates the rewards TypeScript bindings and adds a walkthrough
(docs/REFERRAL_REWARDS.md) scoping which epic tasks land here vs. follow-up.

Closes FinesseStudioLab#656
@Mercy017 Mercy017 force-pushed the feat/onchain-referral-rewards-656 branch from b2c0614 to 90c59a0 Compare June 19, 2026 14:04
@vercel

vercel Bot commented Jun 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
trivela-frontend Ready Ready Preview, Comment Jun 19, 2026 2:20pm

@joelpeace48-cell joelpeace48-cell merged commit 7569565 into FinesseStudioLab:main Jun 19, 2026
11 of 12 checks passed
@joelpeace48-cell

Copy link
Copy Markdown
Contributor

Nice Job @Mercy017 , feel free to pick up more issues.
Nice working with you!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GROWTH] Viral growth engine: referrals + quests + seasons + recurring campaigns

2 participants