Skip to content

feat: merkle root, reentrancy lock, group refund, subscription billing#300

Merged
Kingsman-99 merged 1 commit into
Stellar-split:mainfrom
Emmy6654:feat/all-four-tasks
Jun 27, 2026
Merged

feat: merkle root, reentrancy lock, group refund, subscription billing#300
Kingsman-99 merged 1 commit into
Stellar-split:mainfrom
Emmy6654:feat/all-four-tasks

Conversation

@Emmy6654

@Emmy6654 Emmy6654 commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Closes #259
Closes #260
Closes #261
Closes #262

Summary

This PR implements four independent features for the StellarSplit contract:

Task 1 — Merkle Root for Caller Allowlist

Replaces the expensive on-chain Vec<Address> allowed_callers with a Merkle root (BytesN<32>). The creator stores only the root on-chain; each payer submits a Merkle proof when paying.

Changes:

  • Added allowed_callers_root: Option<BytesN<32>> to InvoiceExt, Invoice, InvoiceOptions, and InvoiceTemplate
  • Added verify_merkle_proof() helper using SHA-256 with lexicographic ordering
  • Added set_allowed_callers_root() public function for creators
  • Updated _pay() to verify Merkle proof when the root is set
  • All existing allowed_callers: None references updated to allowed_callers_root: None

Task 2 — Reentrancy Protection

Added require_non_reentrant() / clear_reentrant() guards to all state-mutating public functions (~55 functions). Fixed broken set_self_limit() and resolve_dispute() implementations uncovered during the audit.

Task 3 — Group All-or-Nothing Refund

Modified refund() to detect invoice group membership. When any group member is underfunded past the deadline, all group invoices are refunded together. Extracted _refund_single() as a helper for the per-invoice refund logic.

Task 4 — Subscription Billing

Overhauled the subscription system:

  • SubscriptionParams now includes interval_secs, next_invoice_at, active, and last_invoice_id
  • create_subscription() accepts a configurable billing interval (min 1 day)
  • Added opt_into_subscription() for payers to opt in
  • Added cancel_subscription() and cancel_subscription_creator() for opt-out
  • Added process_subscription() — creates the next invoice per cycle, charges all opted-in payers, and auto-releases if fully funded

Files Changed

  • contracts/split/src/lib.rs — All four tasks
  • contracts/split/src/types.rs — Merkle root fields, subscription params

…ion billing

Task 1 — Merkle root for caller allowlist:
Replace the stored Vec<Address> allowed_callers with a merkle root
(BytesN<32>). The creator stores only the root on-chain; each payer
submits a merkle proof when paying via pay_with_proof(). Added
verify_merkle_proof(), set_allowed_callers_root(), and wired the
proof parameter through _pay().

Task 2 — Reentrancy protection:
Added require_non_reentrant() / clear_reentrant() to all state-mutating
public functions that were missing them (~55 functions). Fixed broken
set_self_limit() and resolve_dispute() implementations in the process.

Task 3 — Group all-or-nothing refund:
Modified refund() to detect group membership. When any member of a
group is underfunded past the deadline, all group invoices are refunded
together. Extracted _refund_single() as an internal helper.

Task 4 — Subscription billing:
Extended SubscriptionParams with interval_secs, next_invoice_at, active
flag, and last_invoice_id. Updated create_subscription() to accept a
billing interval. Added opt_into_subscription(), cancel_subscription(),
cancel_subscription_creator(), and process_subscription() which creates
the next invoice and charges all opted-in payers each cycle.
@drips-wave

drips-wave Bot commented Jun 27, 2026

Copy link
Copy Markdown

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

@Kingsman-99 Kingsman-99 merged commit 6c7dd03 into Stellar-split:main Jun 27, 2026
1 of 2 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

2 participants