Skip to content

Feat/1045 loyalty rewards contract - #1124

Merged
Calebux merged 1 commit into
Calebux:mainfrom
wendypetersondev:feat/1045-loyalty-rewards-contract
Jul 26, 2026
Merged

Feat/1045 loyalty rewards contract#1124
Calebux merged 1 commit into
Calebux:mainfrom
wendypetersondev:feat/1045-loyalty-rewards-contract

Conversation

@wendypetersondev

@wendypetersondev wendypetersondev commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Closes #1045

Briefly describe what this PR does.


Related Issue

Closes #


Test Plan

  • Tested locally
  • Verified expected behavior
  • No regressions introduced

Screenshots (if applicable)


Checklist

  • Code builds successfully
  • Tests pass
  • Follows project conventions
  • No sensitive data exposed

@wendypetersondev
wendypetersondev force-pushed the feat/1045-loyalty-rewards-contract branch from 0ec763e to b9fa7a4 Compare July 25, 2026 09:11
…ewals (Calebux#1045)

Add a new `loyalty_rewards` Soroban contract that accrues loyalty points
for subscribers who renew on time, with streak tracking and a redeem path
against fees.

## Contract mechanics

- **accrue(owner, sub_id, renewal_ledger)** — called by the authorised
  renewal caller after a successful on-time renewal. Awards
  `BASE_POINTS` (100) + `streak × STREAK_BONUS` (50), with the streak
  multiplier capped at `MAX_STREAK_BONUS_LEVEL` (20) to bound the max
  per-renewal award at 1 100 points.

- **miss(owner, sub_id)** — called when a renewal is missed or late.
  Resets the consecutive streak to 0; does not deduct points.

- **redeem(owner, amount)** — burns `amount` points from the owner's
  balance and returns the equivalent fee credit (1 point = 1 credit unit).
  Enforces a minimum redemption of 100 points.

## Storage layout

| Key | Storage tier | Description |
|-----|-------------|-------------|
| `ConfigKey::Admin` | Persistent | Contract administrator |
| `ConfigKey::RenewalCaller` | Persistent | Authorised renewal contract address |
| `ConfigKey::Paused` | Persistent | Global pause flag |
| `UserKey::Account(addr)` | Instance | Per-user `LoyaltyAccount` struct |

## Errors

| Code | Name | Trigger |
|------|------|---------|
| #1 | NotInitialized | Contract not yet initialised |
| #2 | AlreadyInitialized | `init` called twice |
| Calebux#3 | Unauthorized | Auth check failed |
| Calebux#4 | Paused | Contract is paused |
| Calebux#5 | RedeemTooSmall | `amount < MIN_REDEEM` |
| Calebux#6 | InsufficientPoints | Balance < requested amount |
| Calebux#7 | Overflow | Arithmetic overflow guard |

## Test coverage (35 tests)

- init: success + double-init guard
- accrue: base points, streak increment, bonus arithmetic, balance
  accumulation, lifetime points, last-renewal ledger recording
- accrue: streak bonus hard-capped at MAX_STREAK_BONUS_LEVEL
- miss: streak reset, no point deduction, zero-streak noop, restart
  after miss
- redeem: burns points + returns credit, full-balance drain,
  total_redeems counter, lifetime_points invariant
- redeem error paths: below minimum, insufficient balance, empty account
- pause/unpause: accrue / miss / redeem all reject when paused
- set_renewal_caller: admin can rotate the caller address
- multiple independent users: balances and streaks are isolated
- account / streak / balance queries
- uninitialized contract guard

Closes Calebux#1045
@wendypetersondev
wendypetersondev force-pushed the feat/1045-loyalty-rewards-contract branch from b9fa7a4 to efac248 Compare July 25, 2026 09:14
@drips-wave

drips-wave Bot commented Jul 25, 2026

Copy link
Copy Markdown

@wendypetersondev 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

@Calebux
Calebux merged commit 9dc930a into Calebux:main Jul 26, 2026
29 of 34 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.

New contract: staking / loyalty rewards for on-time renewals

2 participants