Skip to content

feat(recurring): add revokeCycles for admitted bits - #1758

Closed
LeoSlrRf wants to merge 1 commit into
feat/req-429-cancel-schedulefrom
feat/req-429-admit-cycles
Closed

feat(recurring): add revokeCycles for admitted bits#1758
LeoSlrRf wants to merge 1 commit into
feat/req-429-cancel-schedulefrom
feat/req-429-admit-cycles

Conversation

@LeoSlrRf

@LeoSlrRf LeoSlrRf commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Subscriber Self-Trigger via Admitted Cycles

Adds a permissioned self-trigger path to triggerRecurringPaymentBatch, allowing subscribers to initiate their own payment cycles without requiring the relayer to act, provided the relayer has explicitly admitted those cycles.

How it works

  • admitCycles(scheduleKey, mask) — relayer sets bits in a per-schedule bitmap to mark which cycle indices a subscriber is allowed to self-trigger.
  • revokeCycles(scheduleKey, mask) — relayer clears bits to withdraw self-trigger permission for specific cycles without affecting relayer-initiated triggers.
  • _assertRelayerOrAdmitted — internal check that gates triggerRecurringPaymentBatch: callers with RELAYER_ROLE pass unconditionally; any other caller must be the subscriber and must have the target cycle's bit set in admittedCycles.
  • The index == 0 guard is moved before the admission check so it fails fast regardless of caller.
  • The triggerRecurringPayment (single-fee) entry point remains relayer-only and is unaffected by admission.

All existing invariants (NotDueYet, AlreadyPaid, Cancelled, Paused, strict ordering) continue to be enforced on the self-trigger path.

New error

  • ERC20RecurringPaymentProxy__NotAdmitted — reverted when a subscriber attempts to trigger a cycle whose bit has not been set in admittedCycles.

@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds relayer-controlled per-cycle admission and revocation, allowing subscribers to self-trigger admitted recurring batch payments while retaining the existing payment validations.

  • Adds an admission bitmap keyed by recurring batch schedule.
  • Adds relayer-only functions to admit and revoke cycle bits.
  • Extends batch triggering to admitted subscribers while preserving unrestricted relayer triggering.
  • Adds tests for authorization, revocation, due-time, pause, and entry-point behavior.

Confidence Score: 5/5

The PR appears safe to merge with no concrete blocking or independently actionable non-blocking issues identified.

The subscriber self-trigger path requires both subscriber identity and a relayer-admitted cycle bit, while the existing signature, schedule bounds, due-time, cancellation, ordering, and duplicate-payment checks remain in force.

Important Files Changed

Filename Overview
packages/smart-contracts/src/contracts/ERC20RecurringPaymentProxy.sol Adds relayer-managed cycle admission and safely extends recurring batch triggering to admitted subscribers without bypassing existing payment guards.
packages/smart-contracts/test/contracts/ERC20RecurringPaymentProxy.test.ts Adds focused coverage for admission, revocation, caller authorization, pause behavior, due times, and continued relayer access.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Caller[Batch trigger caller] --> Role{Has relayer role?}
  Role -->|Yes| Validate[Validate signature and schedule]
  Role -->|No| Subscriber{Caller is subscriber?}
  Subscriber -->|No| RejectSubscriber[Revert NotSubscriber]
  Subscriber -->|Yes| Admitted{Cycle bit admitted?}
  Admitted -->|No| RejectAdmission[Revert NotAdmitted]
  Admitted -->|Yes| Validate
  Validate --> Guards[Check deadline, bounds, due time, cancellation, order, and unpaid state]
  Guards --> Payment[Mark cycle paid and execute transfers]
Loading

Reviews (1): Last reviewed commit: "feat(recurring): add revokeCycles for ad..." | Re-trigger Greptile

@LeoSlrRf LeoSlrRf closed this Aug 24, 2026
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.

1 participant