Skip to content

Commit

Permalink
Setup Admin and Oracle Authority (#15)
Browse files Browse the repository at this point in the history
Reworks the existing authorities to a more generic setup:
*admin*: for config field updates. This can be a multisig.
*oracle_authority*: for updates of history data. This has to be a hot
wallet.

With the previous configuration, the stake_authority had the power to
change itself. Because it had to be a hot wallet, it's much more likely
to get compromised and could then update itself to an attacker's
personal wallet with no recourse from the team. In this configuration,
the admin multisig could set the oracle_authority to a new hot wallet if
the current one has been compromised.
  • Loading branch information
ebatsell authored Jan 10, 2024
1 parent fc34c25 commit 56373f9
Show file tree
Hide file tree
Showing 16 changed files with 100 additions and 101 deletions.
2 changes: 1 addition & 1 deletion keepers/validator-keeper/src/stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ impl UpdateInstruction for StakeHistoryEntry {
validator_history_account: self.address,
vote_account: self.vote_account,
config: self.config_address,
stake_authority: self.signer,
oracle_authority: self.signer,
}
.to_account_metas(None),
data: validator_history::instruction::UpdateStakeHistory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ pub struct InitializeConfig<'info> {
}

pub fn handler(ctx: Context<InitializeConfig>, authority: Pubkey) -> Result<()> {
ctx.accounts.config.stake_authority = authority;
ctx.accounts.config.tip_distribution_authority = authority;
ctx.accounts.config.oracle_authority = authority;
ctx.accounts.config.admin = authority;
ctx.accounts.config.bump = *ctx.bumps.get("config").unwrap();
ctx.accounts.config.counter = 0;
Ok(())
Expand Down
8 changes: 4 additions & 4 deletions programs/validator-history/src/instructions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ pub mod copy_vote_account;
pub mod initialize_config;
pub mod initialize_validator_history_account;
pub mod realloc_validator_history_account;
pub mod set_new_stake_authority;
pub mod set_new_tip_distribution_authority;
pub mod set_new_admin;
pub mod set_new_oracle_authority;
pub mod set_new_tip_distribution_program;
pub mod update_mev_commission;
pub mod update_stake_history;
Expand All @@ -15,8 +15,8 @@ pub use copy_vote_account::*;
pub use initialize_config::*;
pub use initialize_validator_history_account::*;
pub use realloc_validator_history_account::*;
pub use set_new_stake_authority::*;
pub use set_new_tip_distribution_authority::*;
pub use set_new_admin::*;
pub use set_new_oracle_authority::*;
pub use set_new_tip_distribution_program::*;
pub use update_mev_commission::*;
pub use update_stake_history::*;
22 changes: 22 additions & 0 deletions programs/validator-history/src/instructions/set_new_admin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use anchor_lang::prelude::*;

use crate::state::Config;

#[derive(Accounts)]
pub struct SetNewAdmin<'info> {
#[account(
mut,
seeds = [Config::SEED],
bump = config.bump,
has_one = admin,
)]
pub config: Account<'info, Config>,
/// CHECK: fine since we are not deserializing account
pub new_admin: AccountInfo<'info>,
pub admin: Signer<'info>,
}

pub fn handler(ctx: Context<SetNewAdmin>) -> Result<()> {
ctx.accounts.config.admin = ctx.accounts.new_admin.key();
Ok(())
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use anchor_lang::prelude::*;

use crate::state::Config;

#[derive(Accounts)]
pub struct SetNewOracleAuthority<'info> {
#[account(
mut,
seeds = [Config::SEED],
bump = config.bump,
has_one = admin,
)]
pub config: Account<'info, Config>,
/// CHECK: fine since we are not deserializing account
pub new_oracle_authority: AccountInfo<'info>,
pub admin: Signer<'info>,
}

pub fn handler(ctx: Context<SetNewOracleAuthority>) -> Result<()> {
ctx.accounts.config.oracle_authority = ctx.accounts.new_oracle_authority.key();
Ok(())
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ pub struct SetNewTipDistributionProgram<'info> {
mut,
seeds = [Config::SEED],
bump = config.bump,
has_one = tip_distribution_authority,
has_one = admin,
)]
pub config: Account<'info, Config>,
/// CHECK: fine since we are not deserializing account
#[account(executable)]
pub new_tip_distribution_program: AccountInfo<'info>,
pub tip_distribution_authority: Signer<'info>,
pub admin: Signer<'info>,
}

pub fn handler(ctx: Context<SetNewTipDistributionProgram>) -> Result<()> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ pub struct UpdateStakeHistory<'info> {
#[account(
seeds = [Config::SEED],
bump = config.bump,
has_one = stake_authority
has_one = oracle_authority
)]
pub config: Account<'info, Config>,

#[account(mut)]
pub stake_authority: Signer<'info>,
pub oracle_authority: Signer<'info>,
}

pub fn handler(
Expand Down
10 changes: 4 additions & 6 deletions programs/validator-history/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,12 @@ pub mod validator_history {
instructions::set_new_tip_distribution_program::handler(ctx)
}

pub fn set_new_tip_distribution_authority(
ctx: Context<SetNewTipDistributionAuthority>,
) -> Result<()> {
instructions::set_new_tip_distribution_authority::handler(ctx)
pub fn set_new_admin(ctx: Context<SetNewAdmin>) -> Result<()> {
instructions::set_new_admin::handler(ctx)
}

pub fn set_new_stake_authority(ctx: Context<SetNewStakeAuthority>) -> Result<()> {
instructions::set_new_stake_authority::handler(ctx)
pub fn set_new_oracle_authority(ctx: Context<SetNewOracleAuthority>) -> Result<()> {
instructions::set_new_oracle_authority::handler(ctx)
}

pub fn update_stake_history(
Expand Down
4 changes: 2 additions & 2 deletions programs/validator-history/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ pub struct Config {
pub tip_distribution_program: Pubkey,

// Has the ability to upgrade the tip_distribution_program in case of a program upgrade
pub tip_distribution_authority: Pubkey,
pub admin: Pubkey,

// Has the ability to publish stake amounts per validator
pub stake_authority: Pubkey,
pub oracle_authority: Pubkey,

// Tracks number of initialized ValidatorHistory accounts
pub counter: u32,
Expand Down
3 changes: 2 additions & 1 deletion tests/src/fixtures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ impl TestFixture {
new_vote_account(identity_pubkey, vote_account, 1, Some(vec![(0, 0, 0); 10])),
);
program.add_account(keypair.pubkey(), system_account(100_000_000_000));
program.add_account(identity_pubkey, system_account(100_000_000_000));

let ctx = Rc::new(RefCell::new(program.start_with_context().await));

Expand Down Expand Up @@ -127,7 +128,7 @@ impl TestFixture {
accounts: validator_history::accounts::SetNewTipDistributionProgram {
config: self.validator_history_config,
new_tip_distribution_program: jito_tip_distribution::id(),
tip_distribution_authority: self.keypair.pubkey(),
admin: self.keypair.pubkey(),
}
.to_account_metas(None),
data: validator_history::instruction::SetNewTipDistributionProgram {}.data(),
Expand Down
6 changes: 3 additions & 3 deletions tests/tests/test_initialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ async fn test_initialize() {
.await;

assert!(config.counter == 0);
assert!(config.stake_authority == test.keypair.pubkey());
assert!(config.tip_distribution_authority == test.keypair.pubkey());
assert!(config.oracle_authority == test.keypair.pubkey());
assert!(config.admin == test.keypair.pubkey());

// Initialize validator history account

Expand Down Expand Up @@ -170,7 +170,7 @@ async fn test_extra_realloc() {
validator_history_account: fixture.validator_history_account,
vote_account: fixture.vote_account,
config: fixture.validator_history_config,
stake_authority: fixture.keypair.pubkey(),
oracle_authority: fixture.keypair.pubkey(),
}
.to_account_metas(None),
};
Expand Down
18 changes: 9 additions & 9 deletions tests/tests/test_mev_commission.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,13 @@ async fn test_change_tip_distribution_authority() {
// Change tip distribution authority
let instruction = Instruction {
program_id: validator_history::id(),
accounts: validator_history::accounts::SetNewTipDistributionAuthority {
accounts: validator_history::accounts::SetNewAdmin {
config: fixture.validator_history_config,
new_authority,
tip_distribution_authority: fixture.keypair.pubkey(),
new_admin: new_authority,
admin: fixture.keypair.pubkey(),
}
.to_account_metas(None),
data: validator_history::instruction::SetNewTipDistributionAuthority {}.data(),
data: validator_history::instruction::SetNewAdmin {}.data(),
};
let transaction = Transaction::new_signed_with_payer(
&[instruction],
Expand All @@ -224,18 +224,18 @@ async fn test_change_tip_distribution_authority() {
.load_and_deserialize(&fixture.validator_history_config)
.await;

assert!(config.tip_distribution_authority == new_authority);
assert!(config.admin == new_authority);

// Change tip distribution authority
let instruction = Instruction {
program_id: validator_history::id(),
accounts: validator_history::accounts::SetNewTipDistributionAuthority {
accounts: validator_history::accounts::SetNewAdmin {
config: fixture.validator_history_config,
new_authority: fixture.keypair.pubkey(),
tip_distribution_authority: fixture.keypair.pubkey(),
new_admin: fixture.keypair.pubkey(),
admin: fixture.keypair.pubkey(),
}
.to_account_metas(None),
data: validator_history::instruction::SetNewTipDistributionAuthority {}.data(),
data: validator_history::instruction::SetNewAdmin {}.data(),
};

let transaction = Transaction::new_signed_with_payer(
Expand Down
32 changes: 16 additions & 16 deletions tests/tests/test_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async fn test_stake_history_basic_update() {
validator_history_account: fixture.validator_history_account,
vote_account: fixture.vote_account,
config: fixture.validator_history_config,
stake_authority: fixture.keypair.pubkey(),
oracle_authority: fixture.keypair.pubkey(),
}
.to_account_metas(None),
};
Expand Down Expand Up @@ -70,7 +70,7 @@ async fn test_stake_history_basic_update() {
validator_history_account: fixture.validator_history_account,
vote_account: fixture.vote_account,
config: fixture.validator_history_config,
stake_authority: fixture.keypair.pubkey(),
oracle_authority: fixture.keypair.pubkey(),
}
.to_account_metas(None),
};
Expand Down Expand Up @@ -122,7 +122,7 @@ async fn test_stake_history_wrong_authority() {
validator_history_account: fixture.validator_history_account,
vote_account: fixture.vote_account,
config: fixture.validator_history_config,
stake_authority: new_authority.pubkey(),
oracle_authority: new_authority.pubkey(),
}
.to_account_metas(None),
};
Expand Down Expand Up @@ -169,7 +169,7 @@ async fn test_stake_history_future_epoch() {
validator_history_account: fixture.validator_history_account,
vote_account: fixture.vote_account,
config: fixture.validator_history_config,
stake_authority: fixture.keypair.pubkey(),
oracle_authority: fixture.keypair.pubkey(),
}
.to_account_metas(None),
};
Expand All @@ -185,7 +185,7 @@ async fn test_stake_history_future_epoch() {
}

#[tokio::test]
async fn test_change_stake_authority() {
async fn test_change_oracle_authority() {
let test = TestFixture::new().await;
let ctx = &test.ctx;

Expand All @@ -196,13 +196,13 @@ async fn test_change_stake_authority() {
// Change stake authority
let instruction = Instruction {
program_id: validator_history::id(),
accounts: validator_history::accounts::SetNewStakeAuthority {
accounts: validator_history::accounts::SetNewOracleAuthority {
config: test.validator_history_config,
new_authority,
stake_authority: test.keypair.pubkey(),
new_oracle_authority: new_authority,
admin: test.keypair.pubkey(),
}
.to_account_metas(None),
data: validator_history::instruction::SetNewStakeAuthority {}.data(),
data: validator_history::instruction::SetNewOracleAuthority {}.data(),
};
let transaction = Transaction::new_signed_with_payer(
&[instruction],
Expand All @@ -217,23 +217,23 @@ async fn test_change_stake_authority() {
.load_and_deserialize(&test.validator_history_config)
.await;

assert!(config.stake_authority == new_authority);
assert!(config.oracle_authority == new_authority);

// Try to change it back with wrong signer
let instruction = Instruction {
program_id: validator_history::id(),
accounts: validator_history::accounts::SetNewStakeAuthority {
accounts: validator_history::accounts::SetNewOracleAuthority {
config: test.validator_history_config,
new_authority: test.keypair.pubkey(),
stake_authority: test.keypair.pubkey(),
new_oracle_authority: test.keypair.pubkey(),
admin: test.identity_keypair.pubkey(),
}
.to_account_metas(None),
data: validator_history::instruction::SetNewStakeAuthority {}.data(),
data: validator_history::instruction::SetNewOracleAuthority {}.data(),
};
let transaction = Transaction::new_signed_with_payer(
&[instruction],
Some(&test.keypair.pubkey()),
&[&test.keypair],
Some(&test.identity_keypair.pubkey()),
&[&test.identity_keypair],
ctx.borrow().last_blockhash,
);

Expand Down
Loading

0 comments on commit 56373f9

Please sign in to comment.