From 1ce7d5873150ed7a021291b158a1bd4689dcf7d1 Mon Sep 17 00:00:00 2001 From: Steven Normore Date: Tue, 17 Mar 2026 14:37:11 -0400 Subject: [PATCH 1/2] smartcontract: allow feed authority to operate on non-owned access passes Remove ownership checks that restricted the feed authority to only modify or update access passes it created. The feed authority needs to manage access passes created by other authorities. --- .../src/processors/accesspass/set.rs | 11 +------- .../allowlist/subscriber/add.rs | 7 ----- ...multicastgroup_allowlist_subcriber_test.rs | 26 ++++++------------- 3 files changed, 9 insertions(+), 35 deletions(-) diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs index a9256e8fd4..ec9b4f4b5c 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/accesspass/set.rs @@ -194,16 +194,7 @@ pub fn process_set_access_pass( "Invalid PDA Account Owner" ); - let ap = AccessPass::try_from(accesspass_account)?; - - // Feed authority can only update access passes they own - if globalstate.feed_authority_pk == *payer_account.key && ap.owner != *payer_account.key - { - msg!("Feed authority can only update access passes they own"); - return Err(DoubleZeroError::NotAllowed.into()); - } - - ap + AccessPass::try_from(accesspass_account)? } else { AccessPass { account_type: AccountType::AccessPass, diff --git a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs index a6816d94e6..cbcd98a95a 100644 --- a/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs +++ b/smartcontract/programs/doublezero-serviceability/src/processors/multicastgroup/allowlist/subscriber/add.rs @@ -130,13 +130,6 @@ pub fn process_add_multicastgroup_sub_allowlist( let mut accesspass = AccessPass::try_from(accesspass_account)?; - // Feed authority can only modify access passes they own - if globalstate.feed_authority_pk == *payer_account.key - && accesspass.owner != *payer_account.key - { - return Err(DoubleZeroError::NotAllowed.into()); - } - assert!( accesspass.client_ip == value.client_ip, "AccessPass client_ip does not match" diff --git a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_allowlist_subcriber_test.rs b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_allowlist_subcriber_test.rs index 388d5a1f8f..874df1bc51 100644 --- a/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_allowlist_subcriber_test.rs +++ b/smartcontract/programs/doublezero-serviceability/tests/multicastgroup_allowlist_subcriber_test.rs @@ -510,11 +510,10 @@ async fn test_multicast_subscriber_allowlist_feed_authority() { ) .await; - // 4. Feed authority creates access pass (becomes owner) + // 4. Create access pass (using foundation payer, not feed authority) let (accesspass_pubkey, _) = get_accesspass_pda(&program_id, &client_ip, &user_payer); - let recent_blockhash = banks_client.get_latest_blockhash().await.unwrap(); - let res = try_execute_transaction( + execute_transaction( &mut banks_client, recent_blockhash, program_id, @@ -529,15 +528,11 @@ async fn test_multicast_subscriber_allowlist_feed_authority() { AccountMeta::new(globalstate_pubkey, false), AccountMeta::new(user_payer, false), ], - &feed, + &payer, ) .await; - assert!( - res.is_ok(), - "Feed authority should be able to create access passes" - ); - // 5. Feed authority (owner) adds subscriber allowlist entry — should succeed + // 5. Feed authority (non-owner) adds subscriber allowlist entry — should succeed let recent_blockhash = banks_client.get_latest_blockhash().await.unwrap(); let res = try_execute_transaction( &mut banks_client, @@ -654,11 +649,10 @@ async fn test_multicast_subscriber_allowlist_feed_authority_different_user_payer ) .await; - // 4. Feed authority creates access pass with original_user_payer (becomes owner) + // 4. Create access pass with original_user_payer (using foundation payer, not feed authority) let (accesspass_pubkey, _) = get_accesspass_pda(&program_id, &client_ip, &original_user_payer); - let recent_blockhash = banks_client.get_latest_blockhash().await.unwrap(); - let res = try_execute_transaction( + execute_transaction( &mut banks_client, recent_blockhash, program_id, @@ -673,15 +667,11 @@ async fn test_multicast_subscriber_allowlist_feed_authority_different_user_payer AccountMeta::new(globalstate_pubkey, false), AccountMeta::new(original_user_payer, false), ], - &feed, + &payer, ) .await; - assert!( - res.is_ok(), - "Feed authority should be able to create access passes" - ); - // 5. Feed authority (owner) adds subscriber allowlist with a DIFFERENT user_payer — should succeed + // 5. Feed authority (non-owner) adds subscriber allowlist with a DIFFERENT user_payer — should succeed let different_user_payer = Pubkey::new_unique(); let recent_blockhash = banks_client.get_latest_blockhash().await.unwrap(); let res = try_execute_transaction( From 141fc20519cda9c6614394b4e3da1f3befccaa26 Mon Sep 17 00:00:00 2001 From: Steven Normore Date: Tue, 17 Mar 2026 15:04:39 -0400 Subject: [PATCH 2/2] smartcontract: add changelog entry for feed authority ownership change --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be2fd5d128..ac8cc4fb89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ All notable changes to this project will be documented in this file. ### Breaking ### Changes +- Onchain Programs + - Serviceability: remove ownership restriction on feed authority access pass operations, allowing it to update access passes and modify multicast subscriber allowlists for passes created by other authorities ## [v0.12.0](https://github.com/malbeclabs/doublezero/compare/client/v0.11.0...client/v0.12.0) - 2026-03-16