Skip to content

feat: Implement Cliff-Based Access for Early Supporters - #160

Merged
elizabetheonoja-art merged 2 commits into
SubStream-Protocol:mainfrom
devJaja:feature/cliff-based-access-early-supporters
Apr 23, 2026
Merged

feat: Implement Cliff-Based Access for Early Supporters#160
elizabetheonoja-art merged 2 commits into
SubStream-Protocol:mainfrom
devJaja:feature/cliff-based-access-early-supporters

Conversation

@devJaja

@devJaja devJaja commented Apr 23, 2026

Copy link
Copy Markdown
Contributor

feat: Implement Cliff-Based Access for Early Supporters

Closes: #52
Labels: backend smart-contract gamification
Branch: feature/cliff-based-access-early-supporters

Summary

Moves the protocol beyond simple per-second access into milestone-based rewards. Creators can now set a lifetime
contribution threshold (cliff) — fans who have streamed or tipped at least that amount receive an "Authorized"
status, unlocking premium content (e.g., a "Behind the Scenes" video after $100 total contributions). Mirrors top-
tier Patreon reward mechanics on-chain.

New Contract Functions

Function Auth Description
set_cliff_threshold(creator, threshold) Creator Sets the token milestone in whole units. Feature is opt-in —
no threshold means no gating.
check_cliff_access(fan, creator) → bool None Returns true when fan's lifetime contributions ≥ threshold.
Returns false if no threshold is set.
get_total_contributed(fan, creator) → i128 None Read-only view of a fan's cumulative lifetime contributions
to a creator.

New Storage Key

  • DataKey::UserContributed(fan, creator) — persistent i128 counter tracking lifetime tokens paid by a fan to a
    creator. (DataKey::CliffThreshold was already reserved in the enum; now fully wired up.)

New Event

  • CliffUnlocked { fan, creator, total_contributed, cliff_threshold } — emitted exactly once when a fan's cumulative
    contributions first meet or exceed the creator's threshold.

Contribution Tracking

Contributions are credited in every path where tokens genuinely flow from a fan to a creator:

  • distribute_and_collect — streaming subscription payouts
  • tip — one-off tips
  • collect_grant — DAO treasury grant payouts (DAO counted as fan)

Early-cancel penalties are intentionally excluded — they are protocol enforcement, not voluntary support.

Tests (14 new — test_cliff_access.rs)

  • test_set_cliff_threshold_stores_value
  • test_set_cliff_threshold_zero_panics
  • test_check_cliff_access_no_threshold_returns_false
  • test_get_total_contributed_zero_initially
  • test_tip_credits_contribution
  • test_cliff_not_unlocked_below_threshold
  • test_cliff_unlocked_at_threshold
  • test_cliff_unlocked_above_threshold
  • test_cliff_unlocked_event_emitted_on_crossing
  • test_cliff_unlocked_event_not_emitted_again_after_crossing
  • test_subscription_stream_credits_contribution
  • test_subscription_stream_unlocks_cliff
  • test_contributions_are_per_creator
  • test_cumulative_tips_accumulate

54/54 tests pass. cargo fmt + cargo clippy -D warnings clean.

Closes #Cliff_Based_Access_Early_Supporters

## What

Adds milestone-based content gating: a creator sets a lifetime
contribution threshold (cliff), and fans who have streamed or tipped
at least that amount receive an 'Authorized' status for premium content.

## New public functions

- set_cliff_threshold(creator, threshold)
  Creator configures the token milestone in whole units. Requires auth.

- check_cliff_access(fan, creator) -> bool
  Returns true when the fan's lifetime contributions >= cliff threshold.
  Returns false if no threshold is set (feature opt-in by creator).

- get_total_contributed(fan, creator) -> i128
  Read-only view of a fan's lifetime token contributions to a creator.

## New storage key

- DataKey::UserContributed(fan, creator) — persistent i128 counter
  (DataKey::CliffThreshold was already reserved; now wired up)

## New event

- CliffUnlocked { fan, creator, total_contributed, cliff_threshold }
  Emitted exactly once when a fan's cumulative contributions first
  meet or exceed the creator's configured threshold.

## Contribution tracking hooks

Contributions are credited in every path where tokens genuinely flow
from a fan to a creator:
  - distribute_and_collect: streaming subscription payouts
  - tip: one-off tips
  - collect_grant: DAO treasury grant payouts (DAO as fan)

Early-cancel penalties are intentionally excluded — they are
enforcement, not voluntary support.

## Tests (14 new — test_cliff_access.rs)

- set_cliff_threshold stores value
- set_cliff_threshold zero panics
- check_cliff_access returns false with no threshold
- get_total_contributed zero initially
- tip credits contribution counter
- cliff not unlocked below threshold
- cliff unlocked at exact threshold
- cliff unlocked above threshold
- CliffUnlocked event emitted on crossing (transfer + TipReceived + CliffUnlocked = 3)
- CliffUnlocked event NOT emitted again after crossing
- subscription stream credits contribution
- subscription stream unlocks cliff
- contributions are per-creator (fan A's total for X ≠ Y)
- cumulative tips accumulate across transactions

All 54 tests pass. cargo fmt + clippy -D warnings clean.
@drips-wave

drips-wave Bot commented Apr 23, 2026

Copy link
Copy Markdown

@devJaja Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@elizabetheonoja-art
elizabetheonoja-art merged commit babcd0b into SubStream-Protocol:main Apr 23, 2026
0 of 3 checks passed
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.

#18 Implement Cliff_Based_Access for Early Supporters

2 participants