diff --git a/src/consts.rs b/src/consts.rs
index 2f5e013..a60e640 100644
--- a/src/consts.rs
+++ b/src/consts.rs
@@ -1,4 +1,3 @@
-use solana_program::pubkey;
use solana_program::pubkey::Pubkey;
/// The delegation session fees (extracted in percentage from the delegation PDAs rent on closure).
@@ -12,9 +11,3 @@ pub const EXTERNAL_UNDELEGATE_DISCRIMINATOR: [u8; 8] = [196, 28, 41, 206, 48, 37
/// The program ID of the delegation program.
pub const DELEGATION_PROGRAM_ID: Pubkey = crate::id();
-
-/// The admin pubkey of the authority allowed to whitelist validators.
-#[cfg(feature = "unit_test_config")]
-pub const ADMIN_PUBKEY: Pubkey = pubkey!("tEsT3eV6RFCWs1BZ7AXTzasHqTtMnMLCB2tjQ42TDXD");
-#[cfg(not(feature = "unit_test_config"))]
-pub const ADMIN_PUBKEY: Pubkey = pubkey!("3FwNxjbCqdD7G6MkrAdwTd5Zf6R3tHoapam4Pv1X2KBB");
diff --git a/src/instruction_builder/close_validator_fees_vault.rs b/src/instruction_builder/close_validator_fees_vault.rs
index 70b6de9..a6454f5 100644
--- a/src/instruction_builder/close_validator_fees_vault.rs
+++ b/src/instruction_builder/close_validator_fees_vault.rs
@@ -1,5 +1,5 @@
use solana_program::instruction::Instruction;
-use solana_program::{instruction::AccountMeta, pubkey::Pubkey};
+use solana_program::{bpf_loader_upgradeable, instruction::AccountMeta, pubkey::Pubkey};
use crate::discriminator::DlpDiscriminator;
use crate::pda::validator_fees_vault_pda_from_validator;
@@ -12,11 +12,14 @@ pub fn close_validator_fees_vault(
validator_identity: Pubkey,
) -> Instruction {
let validator_fees_vault_pda = validator_fees_vault_pda_from_validator(&validator_identity);
+ let delegation_program_data =
+ Pubkey::find_program_address(&[crate::ID.as_ref()], &bpf_loader_upgradeable::id()).0;
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(payer, true),
AccountMeta::new(admin, true),
+ AccountMeta::new_readonly(delegation_program_data, false),
AccountMeta::new(validator_identity, false),
AccountMeta::new(validator_fees_vault_pda, false),
],
diff --git a/src/instruction_builder/init_validator_fees_vault.rs b/src/instruction_builder/init_validator_fees_vault.rs
index 336ced6..10a5545 100644
--- a/src/instruction_builder/init_validator_fees_vault.rs
+++ b/src/instruction_builder/init_validator_fees_vault.rs
@@ -1,5 +1,5 @@
use solana_program::instruction::Instruction;
-use solana_program::system_program;
+use solana_program::{bpf_loader_upgradeable, system_program};
use solana_program::{instruction::AccountMeta, pubkey::Pubkey};
use crate::discriminator::DlpDiscriminator;
@@ -13,11 +13,14 @@ pub fn init_validator_fees_vault(
validator_identity: Pubkey,
) -> Instruction {
let validator_fees_vault_pda = validator_fees_vault_pda_from_validator(&validator_identity);
+ let delegation_program_data =
+ Pubkey::find_program_address(&[crate::ID.as_ref()], &bpf_loader_upgradeable::id()).0;
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(payer, true),
AccountMeta::new(admin, true),
+ AccountMeta::new_readonly(delegation_program_data, false),
AccountMeta::new(validator_identity, false),
AccountMeta::new(validator_fees_vault_pda, false),
AccountMeta::new_readonly(system_program::id(), false),
diff --git a/src/instruction_builder/protocol_claim_fees.rs b/src/instruction_builder/protocol_claim_fees.rs
index a33f39a..9175399 100644
--- a/src/instruction_builder/protocol_claim_fees.rs
+++ b/src/instruction_builder/protocol_claim_fees.rs
@@ -1,5 +1,5 @@
use solana_program::instruction::Instruction;
-use solana_program::{instruction::AccountMeta, pubkey::Pubkey};
+use solana_program::{bpf_loader_upgradeable, instruction::AccountMeta, pubkey::Pubkey};
use crate::discriminator::DlpDiscriminator;
use crate::pda::fees_vault_pda;
@@ -8,11 +8,14 @@ use crate::pda::fees_vault_pda;
/// See [crate::processor::process_protocol_claim_fees] for docs.
pub fn protocol_claim_fees(admin: Pubkey) -> Instruction {
let fees_vault_pda = fees_vault_pda();
+ let delegation_program_data =
+ Pubkey::find_program_address(&[crate::ID.as_ref()], &bpf_loader_upgradeable::id()).0;
Instruction {
program_id: crate::id(),
accounts: vec![
AccountMeta::new(admin, true),
AccountMeta::new(fees_vault_pda, false),
+ AccountMeta::new_readonly(delegation_program_data, false),
],
data: DlpDiscriminator::ProtocolClaimFees.to_vec(),
}
diff --git a/src/instruction_builder/whitelist_validator_for_program.rs b/src/instruction_builder/whitelist_validator_for_program.rs
index 4c20ead..edbaa0e 100644
--- a/src/instruction_builder/whitelist_validator_for_program.rs
+++ b/src/instruction_builder/whitelist_validator_for_program.rs
@@ -20,6 +20,8 @@ pub fn whitelist_validator_for_program(
let args = WhitelistValidatorForProgramArgs { insert };
let program_data =
Pubkey::find_program_address(&[program.as_ref()], &bpf_loader_upgradeable::id()).0;
+ let delegation_program_data =
+ Pubkey::find_program_address(&[crate::ID.as_ref()], &bpf_loader_upgradeable::id()).0;
let program_config_pda = program_config_from_program_id(&program);
Instruction {
program_id: crate::id(),
@@ -28,6 +30,7 @@ pub fn whitelist_validator_for_program(
AccountMeta::new_readonly(validator_identity, false),
AccountMeta::new_readonly(program, false),
AccountMeta::new_readonly(program_data, false),
+ AccountMeta::new_readonly(delegation_program_data, false),
AccountMeta::new(program_config_pda, false),
AccountMeta::new_readonly(system_program::id(), false),
],
diff --git a/src/processor/close_validator_fees_vault.rs b/src/processor/close_validator_fees_vault.rs
index 39fc6ad..fa838ac 100644
--- a/src/processor/close_validator_fees_vault.rs
+++ b/src/processor/close_validator_fees_vault.rs
@@ -2,9 +2,10 @@ use solana_program::msg;
use solana_program::program_error::ProgramError;
use solana_program::{account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey};
-use crate::consts::ADMIN_PUBKEY;
use crate::error::DlpError::Unauthorized;
-use crate::processor::utils::loaders::{load_initialized_pda, load_signer};
+use crate::processor::utils::loaders::{
+ load_initialized_pda, load_program_upgrade_authority, load_signer,
+};
use crate::processor::utils::pda::close_pda;
use crate::validator_fees_vault_seeds_from_validator;
@@ -30,7 +31,9 @@ pub fn process_close_validator_fees_vault(
_data: &[u8],
) -> ProgramResult {
// Load Accounts
- let [payer, admin, validator_identity, validator_fees_vault] = accounts else {
+ let [payer, admin, delegation_program_data, validator_identity, validator_fees_vault] =
+ accounts
+ else {
return Err(ProgramError::NotEnoughAccountKeys);
};
@@ -39,10 +42,12 @@ pub fn process_close_validator_fees_vault(
load_signer(admin, "admin")?;
// Check if the admin is the correct one
- if !admin.key.eq(&ADMIN_PUBKEY) {
+ let admin_pubkey =
+ load_program_upgrade_authority(&crate::ID, delegation_program_data)?.ok_or(Unauthorized)?;
+ if !admin.key.eq(&admin_pubkey) {
msg!(
"Expected admin pubkey: {} but got {}",
- ADMIN_PUBKEY,
+ admin_pubkey,
admin.key
);
return Err(Unauthorized.into());
diff --git a/src/processor/finalize.rs b/src/processor/finalize.rs
index c000b9a..ccc8827 100644
--- a/src/processor/finalize.rs
+++ b/src/processor/finalize.rs
@@ -5,7 +5,6 @@ use crate::processor::utils::loaders::{
load_initialized_validator_fees_vault, load_owned_pda, load_program, load_signer,
};
use crate::processor::utils::pda::close_pda;
-use crate::processor::utils::verify::verify_state;
use crate::state::{CommitRecord, DelegationMetadata, DelegationRecord};
use solana_program::program_error::ProgramError;
use solana_program::{
@@ -42,7 +41,7 @@ use solana_program::{
///
/// Steps:
///
-/// 1. Validate the new state
+/// 1. Validate the new state (currently state is valid if committed from a whitelisted validator)
/// 2. If the state is valid, copy the committed state to the delegated account
/// 3. Close the state diff account
/// 4. Close the commit state record
@@ -94,13 +93,6 @@ pub fn process_finalize(
let commit_record_data = commit_record_account.try_borrow_data()?;
let commit_record = CommitRecord::try_from_bytes_with_discriminator(&commit_record_data)?;
- verify_state(
- validator,
- delegation_record,
- commit_record,
- commit_state_account,
- )?;
-
// Check that the commit record is the right one
if !commit_record.account.eq(delegated_account.key) {
return Err(DlpError::InvalidDelegatedAccount.into());
diff --git a/src/processor/init_protocol_fees_vault.rs b/src/processor/init_protocol_fees_vault.rs
index 4c7e817..498c2c4 100644
--- a/src/processor/init_protocol_fees_vault.rs
+++ b/src/processor/init_protocol_fees_vault.rs
@@ -18,6 +18,8 @@ use crate::processor::utils::pda::create_pda;
///
/// - fees vault is uninitialized
///
+/// NOTE: this operation is permisionless and can be done by anyone
+///
/// Steps:
///
/// 1. Create the protocol fees vault PDA
diff --git a/src/processor/init_validator_fees_vault.rs b/src/processor/init_validator_fees_vault.rs
index 6a8e54a..4ecd2b9 100644
--- a/src/processor/init_validator_fees_vault.rs
+++ b/src/processor/init_validator_fees_vault.rs
@@ -4,9 +4,10 @@ use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, pubkey::Pubkey, system_program,
};
-use crate::consts::ADMIN_PUBKEY;
use crate::error::DlpError::Unauthorized;
-use crate::processor::utils::loaders::{load_program, load_signer, load_uninitialized_pda};
+use crate::processor::utils::loaders::{
+ load_program, load_program_upgrade_authority, load_signer, load_uninitialized_pda,
+};
use crate::processor::utils::pda::create_pda;
use crate::validator_fees_vault_seeds_from_validator;
@@ -35,7 +36,9 @@ pub fn process_init_validator_fees_vault(
_data: &[u8],
) -> ProgramResult {
// Load Accounts
- let [payer, admin, validator_identity, validator_fees_vault, system_program] = accounts else {
+ let [payer, admin, delegation_program_data, validator_identity, validator_fees_vault, system_program] =
+ accounts
+ else {
return Err(ProgramError::NotEnoughAccountKeys);
};
@@ -45,10 +48,12 @@ pub fn process_init_validator_fees_vault(
load_program(system_program, system_program::id(), "system program")?;
// Check if the admin is the correct one
- if !admin.key.eq(&ADMIN_PUBKEY) {
+ let admin_pubkey =
+ load_program_upgrade_authority(&crate::ID, delegation_program_data)?.ok_or(Unauthorized)?;
+ if !admin.key.eq(&admin_pubkey) {
msg!(
"Expected admin pubkey: {} but got {}",
- ADMIN_PUBKEY,
+ admin_pubkey,
admin.key
);
return Err(Unauthorized.into());
diff --git a/src/processor/protocol_claim_fees.rs b/src/processor/protocol_claim_fees.rs
index b2953b9..d3aa17a 100644
--- a/src/processor/protocol_claim_fees.rs
+++ b/src/processor/protocol_claim_fees.rs
@@ -1,6 +1,7 @@
-use crate::consts::ADMIN_PUBKEY;
use crate::error::DlpError::Unauthorized;
-use crate::processor::utils::loaders::{load_initialized_protocol_fees_vault, load_signer};
+use crate::processor::utils::loaders::{
+ load_initialized_protocol_fees_vault, load_program_upgrade_authority, load_signer,
+};
use solana_program::msg;
use solana_program::program_error::ProgramError;
use solana_program::rent::Rent;
@@ -27,7 +28,7 @@ pub fn process_protocol_claim_fees(
_data: &[u8],
) -> ProgramResult {
// Load Accounts
- let [admin, fees_vault] = accounts else {
+ let [admin, fees_vault, delegation_program_data] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};
@@ -36,10 +37,12 @@ pub fn process_protocol_claim_fees(
load_initialized_protocol_fees_vault(fees_vault, true)?;
// Check if the admin is the correct one
- if !admin.key.eq(&ADMIN_PUBKEY) {
+ let admin_pubkey =
+ load_program_upgrade_authority(&crate::ID, delegation_program_data)?.ok_or(Unauthorized)?;
+ if !admin.key.eq(&admin_pubkey) {
msg!(
"Expected admin pubkey: {} but got {}",
- ADMIN_PUBKEY,
+ admin_pubkey,
admin.key
);
return Err(Unauthorized.into());
diff --git a/src/processor/utils/loaders.rs b/src/processor/utils/loaders.rs
index d210452..980d393 100644
--- a/src/processor/utils/loaders.rs
+++ b/src/processor/utils/loaders.rs
@@ -6,9 +6,10 @@ use crate::{
delegation_record_seeds_from_delegated_account, fees_vault_seeds,
program_config_seeds_from_program_id, validator_fees_vault_seeds_from_validator,
};
+use solana_program::bpf_loader_upgradeable::UpgradeableLoaderState;
use solana_program::{
- account_info::AccountInfo, msg, program_error::ProgramError, pubkey::Pubkey, system_program,
- sysvar,
+ account_info::AccountInfo, bpf_loader_upgradeable, msg, program_error::ProgramError,
+ pubkey::Pubkey, system_program, sysvar,
};
/// Errors if:
@@ -193,6 +194,46 @@ pub fn load_program(info: &AccountInfo, key: Pubkey, label: &str) -> Result<(),
Ok(())
}
+/// Get the program upgrade authority for a given program
+pub fn load_program_upgrade_authority(
+ program: &Pubkey,
+ program_data: &AccountInfo,
+) -> Result