Skip to content

fix(audit): align sponsor revoke with transfer drift window (MULT-5)#34

Merged
dev-jodee merged 7 commits into
audit/ai-scanner/04-recurring-rollover-guardfrom
audit/ai-scanner/05-sponsor-revoke-drift
Apr 28, 2026
Merged

fix(audit): align sponsor revoke with transfer drift window (MULT-5)#34
dev-jodee merged 7 commits into
audit/ai-scanner/04-recurring-rollover-guardfrom
audit/ai-scanner/05-sponsor-revoke-drift

Conversation

@dev-jodee
Copy link
Copy Markdown
Collaborator

Audit finding: MULT-5

Sponsor revocation used a strict expiry_ts > current_ts check while transfer paths accepted pulls for TIME_DRIFT_ALLOWED_SECS past expiry_ts. A sponsor could close a delegation account inside the drift window, destroying allowance the delegatee could still legally pull.

Fix

Extract is_effectively_expired(expiry_ts, current_ts) helper. Sponsor revoke and both transfer validators (fixed + recurring) now use it. Sponsor must wait until the drift window closes before reclaiming rent.

Test plan

  • cargo build -p subscriptions
  • cargo test -p subscriptions --lib (212/212 pass; one new regression test)
  • New sponsor_cannot_revoke_within_drift_window asserts sponsor blocked at +110s and allowed at +231s

Stack

Stacked on top of #33 (MULT-7).

Extract is_effectively_expired helper. Sponsor revocation now waits the
same TIME_DRIFT_ALLOWED_SECS past expiry that transfers tolerate, so
sponsor cannot close a delegation while the delegatee can still pull.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 28, 2026

Compute Unit Report

Instruction Samples Min CUs Max CUs Avg CUs Est Cost (Low) [SOL] Est Cost (Med) [SOL] Est Cost (High) [SOL]
cancel_subscription 11 1774 2098 1982 0.000005000 0.000005079 0.000005991
close_subscription_authority 7 1866 1901 1871 0.000005000 0.000005074 0.000005935
create_fixed_delegation 36 3561 9566 5347 0.000005001 0.000005213 0.000007673
create_plan 84 3525 18538 5081 0.000005001 0.000005203 0.000007540
create_recurring_delegation 25 3587 12592 5274 0.000005001 0.000005210 0.000007637
delete_plan 8 401 401 401 0.000005000 0.000005016 0.000005200
init_subscription_authority 136 7305 21253 9597 0.000005002 0.000005383 0.000009798
revoke_delegation 19 303 570 405 0.000005000 0.000005016 0.000005202
subscribe 21 6639 14163 7935 0.000005002 0.000005317 0.000008967
transfer_fixed 6 8478 8481 8480 0.000005002 0.000005339 0.000009240
transfer_recurring 17 8566 8651 8599 0.000005002 0.000005343 0.000009299
transfer_subscription 10 8862 8985 8901 0.000005002 0.000005356 0.000009450
update_plan 21 409 488 461 0.000005000 0.000005018 0.000005230

Generated: 2026-04-28

@dev-jodee dev-jodee marked this pull request as ready for review April 28, 2026 16:24
Extend SubscribeData with expected_mint/amount/period_hours/created_at.
Program rejects with PlanTermsMismatch if the live plan disagrees with
what the subscriber signed. Stale-signed subscribe transactions can no
longer enroll into a recreated plan with different terms.

SDK and webapp callers fetch plan data and pass the snapshot.
Plan::check_destination and Plan::can_pull now filter out zero-padded
slots before membership tests. A plan with fewer than four configured
destinations no longer authorizes a zero-owned receiver, and a plan
with fewer than four pullers no longer authorizes a zero-pubkey caller.
…-10)

Webapp exit flows now pass the on-chain payer as receiver when it
differs from the connected signer, so sponsor-funded delegations and
SubscriptionAuthority accounts can actually be closed.

Also migrates revokeSubscription and cancelAndRevokeSubscription from
buildRevokeDelegation to buildRevokeSubscription with planPda + receiver,
fixing subscription revoke for both sponsor and non-sponsor cases.
…(MULT-9)

Stale-delegation cleanup no longer appends a close on the current
SubscriptionAuthority. Revoking stale delegations is now scoped to the
supplied delegation accounts; the SA stays open and current grants
remain valid.
@dev-jodee dev-jodee merged commit e35e571 into audit/ai-scanner/04-recurring-rollover-guard Apr 28, 2026
6 checks passed
@dev-jodee dev-jodee deleted the audit/ai-scanner/05-sponsor-revoke-drift branch April 28, 2026 19:41
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