Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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(
Expand Down
Loading