feat(rewards): on-chain referral reward engine with anti-abuse (#656)#662
Merged
joelpeace48-cell merged 1 commit intoJun 19, 2026
Conversation
|
@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
b2c0614 to
90c59a0
Compare
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
7569565
into
FinesseStudioLab:main
11 of 12 checks passed
6 tasks
Contributor
|
Nice Job @Mercy017 , feel free to pick up more issues. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #656
What this delivers
On-chain referral bonuses with abuse protection, plus the attribution/instrumentation hook. Responsibilities are split across the existing contracts:
referrer_of,referral_count,referredevent) — unchanged.Rewards contract (
contracts/rewards/src/lib.rs)set_referral_config(rate_bps, per_referrer_cap)rate_bpsin1..=100_000; cap0= uncappedreferral_config()(rate_bps, cap),(0,0)until setpay_referral_bonus(referrer, referee, qualifying_amount)credit+ref_bonusreferral_bonus_total/referral_reward_count/rewarded_referrer_ofbonus = qualifying_amount * rate_bps / 10_000(checkedu128math).Anti-abuse — enforced on-chain, all-or-nothing
SelfReferral)CircularReferral)ReferralAlreadyRewarded)ReferralCapExceeded)ZeroReferralBonus); respectspaused+ admin authRejected attempts write no state (no balance, counter, or attribution change).
Backend (
backend/src/jobs/eventIndexer.js, migration010)refbonusindexer handler records each attribution edge intoreferral_bonus_eventsfor referral-conversion metrics.creditevent already updates balances, so no double-counting.UNIQUE(referee)mirrors the on-chain invariant and makes re-indexing idempotent.Also
frontend/src/contracts/rewards.ts).docs/REFERRAL_REWARDS.md.Testing (all run locally, green)
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).npm run test:backend(93 pass, incl. 3 new),test:integration(26),typecheck(clean), prettier--checkclean.Follow-ups (rest of #656)