Skip to content

fix(audit): lock plan v1 layout (MULT-16)#32

Merged
dev-jodee merged 9 commits into
audit/ai-scanner/02-lock-header-v1from
audit/ai-scanner/03-lock-plan-v1
Apr 28, 2026
Merged

fix(audit): lock plan v1 layout (MULT-16)#32
dev-jodee merged 9 commits into
audit/ai-scanner/02-lock-header-v1from
audit/ai-scanner/03-lock-plan-v1

Conversation

@dev-jodee
Copy link
Copy Markdown
Collaborator

Audit finding: MULT-16

Lock the current Plan and PlanData layouts as canonical v1.

Changes

  • pub const PLAN_LEN_V1: usize = 491; + const _: () = assert!(Plan::LEN == PLAN_LEN_V1); in state/plan.rs
  • pub const PLAN_DATA_LEN_V1: usize = 456; + const _: () = assert!(PlanData::LEN == PLAN_DATA_LEN_V1); in instructions/create_plan.rs

No migration code, no CURRENT_VERSION bump. Pre-deployment, no live legacy plans.

Test plan

  • cargo build -p subscriptions
  • cargo test -p subscriptions --lib (210/210 pass)

Stack

Stacked on top of #31 (MULT-4).

- PLAN_LEN_V1 + assert in plan.rs
- PLAN_DATA_LEN_V1 + assert in create_plan.rs
@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 3564 9595 4639 0.000005001 0.000005185 0.000007319
create_plan 84 3525 12538 5081 0.000005001 0.000005203 0.000007540
create_recurring_delegation 25 3587 11092 5394 0.000005001 0.000005215 0.000007697
delete_plan 8 401 401 401 0.000005000 0.000005016 0.000005200
init_subscription_authority 136 6250 19753 8825 0.000005002 0.000005353 0.000009412
revoke_delegation 19 303 570 405 0.000005000 0.000005016 0.000005202
subscribe 21 6639 17163 8006 0.000005002 0.000005320 0.000009003
transfer_fixed 6 8478 8481 8480 0.000005002 0.000005339 0.000009240
transfer_recurring 17 8566 8651 8594 0.000005002 0.000005343 0.000009297
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
Skip rollover when candidate_start >= expiry_ts. Pulls within drift
window remain valid in the final authorized period; no fresh allowance
is granted in terminal periods.

Affects validate_recurring_transfer (used by recurring delegations and
subscription transfers).
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.
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 019a4de into audit/ai-scanner/02-lock-header-v1 Apr 28, 2026
4 checks passed
@dev-jodee dev-jodee deleted the audit/ai-scanner/03-lock-plan-v1 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