How Reffinity turns a referral into a reward
Every rule below runs in the demo.
1. The referral record
Accepting an invitation writes one entry on-chain: who invited whom.
No self-referral
A wallet can't use its own code.
One referrer, forever
A wallet is recorded only once.
No loops
You can't invite back whoever invited you.
2. Milestones and rewards
Each milestone is confirmed by an organizer or another Monark module.
| Milestone | Points to you | Reward to you |
|---|---|---|
| 1Joined | +10 | None |
| 2First workshop | +25 | None |
| 3First bounty | +50 | 10.00 tUSDC |
| 430 days active | +15 | 5.00 tUSDC |
Only the direct inviter is rewarded: no multi-level payouts.
3. The trust score
Starts at 50. Below 50, the referral is recorded but its rewards are held for review.
New wallet, shared funding, sign-up burst: 50 − 12 − 12 − 8 = 18. Held.
| Signal | Effect |
|---|---|
| Wallet active for 6+ months | +20 |
| On-chain history on 2+ networks | +10 |
| Checked in at a workshop by an organizer | +15 |
| Wallet created < 10 minutes ago | −12 |
| Funded by the same address as 3+ other new wallets | −12 |
| 5+ linked wallets joined within 2 minutes | −8 |
4. What's on-chain, and what isn't
On-chain
- Who invited whom
- Confirmed milestones and points
- Rewards unlocked and claimed
- Rejected attempts (reverted)
Off-chain
- Link opens and channel tags
- Trust-score signals (indexer)
- Names and messages
5. For developers: contract events
The dashboard is built from these events alone.
Show the contract events
// Reffinity referral contract (Solidity events, simplified)
event AmbassadorRegistered(address indexed ambassador, bytes8 code, uint256 programId);
event ReferralRecorded(address indexed inviter, address indexed invitee, uint256 programId);
event ReferralRejected(address indexed invitee, bytes32 reason); // SelfReferral | AlreadyReferred | ReferralLoop
event MilestoneReached(address indexed invitee, bytes32 milestone, uint32 points, uint256 reward);
event RewardHeld(address indexed invitee, uint8 trustScore);
event RewardsClaimed(address indexed ambassador, uint256 amount);