Skip to content
This repository has been archived by the owner on Dec 5, 2024. It is now read-only.

Commit

Permalink
added command for change stake pool structure
Browse files Browse the repository at this point in the history
  • Loading branch information
LetMut1 committed Feb 7, 2022
1 parent e7f9c48 commit d7982a9
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 1 deletion.
55 changes: 54 additions & 1 deletion stake-pool/cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2480,7 +2480,7 @@ fn command_check_existing_validators() -> CommandResult {
}

if !invalid_validators.is_empty() {
let mut message: String = "".to_string();
let mut message: String = "Invalid validators: \n".to_string();

for (vote_account_pubkey, validator_comparable_parameters) in invalid_validators.into_iter() {
message = message + format!("{} : {:?}", vote_account_pubkey.to_string(), validator_comparable_parameters).as_str() + "\n";
Expand All @@ -2492,6 +2492,40 @@ fn command_check_existing_validators() -> CommandResult {
Ok(())
}

fn command_change_structure(
config: &Config,
stake_pool_address: &Pubkey,
) -> CommandResult {
if !config.no_update {
command_update(config, stake_pool_address, false, false)?;
}

let stake_pool = get_stake_pool(&config.rpc_client, stake_pool_address)?;

let mut signers = vec![
config.fee_payer.as_ref(),
config.manager.as_ref()
];

let instructions = vec![
spl_stake_pool::instruction::change_structure(
&spl_stake_pool::id(),
stake_pool_address,
&config.manager.pubkey(),
)
];

let mut transaction =
Transaction::new_with_payer(&instructions, Some(&config.fee_payer.pubkey()));

let (recent_blockhash, fee_calculator) = config.rpc_client.get_recent_blockhash()?;
check_fee_payer_balance(config, fee_calculator.calculate_fee(transaction.message()))?;
unique_signers!(signers);
transaction.sign(&signers, recent_blockhash);
send_transaction(config, transaction)?;
Ok(())
}

fn main() {
solana_logger::setup_with_default("solana=info");

Expand Down Expand Up @@ -3501,6 +3535,18 @@ fn main() {
.subcommand(SubCommand::with_name("check-existing-validators")
.about("Check existing in stake pool validator`s list validators")
)
.subcommand(SubCommand::with_name("change-structure")
.about("Change old StakePool for new")
.arg(
Arg::with_name("pool")
.index(1)
.validator(is_pubkey)
.value_name("POOL_ADDRESS")
.takes_value(true)
.required(true)
.help("Stake pool address."),
)
)
.get_matches();

let mut wallet_manager = None;
Expand Down Expand Up @@ -3962,6 +4008,13 @@ fn main() {
("check-existing-validators", Some(_arg_matches)) => {
command_check_existing_validators()
}
("change-structure", Some(arg_matches)) => {
let stake_pool_address = pubkey_of(arg_matches, "pool").unwrap();
command_change_structure(
&config,
&stake_pool_address
)
}
_ => unreachable!(),
}
.map_err(|err| {
Expand Down
28 changes: 28 additions & 0 deletions stake-pool/program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,15 @@ pub enum StakePoolInstruction {
/// 7. `[]` Stake program account
/// 8. `[s]` (Optional) Stake pool sol withdraw authority
WithdrawLiquiditySol(u64),




/// DELETE AFTER EXECUTION
///
/// 0. `[w]` Stake pool
/// 1. `[s]` Manager
ChangeStructure,
}

/// Creates an 'initialize' instruction.
Expand Down Expand Up @@ -1478,4 +1487,23 @@ pub fn withdraw_liquidity_sol_with_authority(
.try_to_vec()
.unwrap(),
}
}

/// DELETE
pub fn change_structure(
program_id: &Pubkey,
stake_pool: &Pubkey,
manager: &Pubkey,
) -> Instruction {
let accounts = vec![
AccountMeta::new(*stake_pool, false),
AccountMeta::new_readonly(*manager, true),
];
Instruction {
program_id: *program_id,
accounts,
data: StakePoolInstruction::ChangeStructure
.try_to_vec()
.unwrap(),
}
}
77 changes: 77 additions & 0 deletions stake-pool/program/src/processor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Program state processor
use crate::state::StakePoolChanged;

use {
crate::{
error::StakePoolError,
Expand All @@ -18,6 +20,7 @@ use {
account_info::next_account_info,
account_info::AccountInfo,
borsh::try_from_slice_unchecked,
borsh::get_packed_len,
clock::{Clock, Epoch},
decode_error::DecodeError,
entrypoint::ProgramResult,
Expand Down Expand Up @@ -3007,6 +3010,76 @@ impl Processor {
Ok(())
}

/// DELETE
#[inline(never)] // needed to avoid stack size violation
fn process_change_structure(
program_id: &Pubkey,
accounts: &[AccountInfo],
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let stake_pool_info = next_account_info(account_info_iter)?;
let manager_info = next_account_info(account_info_iter)?;

check_account_owner(stake_pool_info, program_id)?;
let stake_pool = try_from_slice_unchecked::<StakePool>(&stake_pool_info.data.borrow())?;
if !stake_pool.is_valid() {
return Err(StakePoolError::InvalidState.into());
}

if stake_pool.last_update_epoch < Clock::get()?.epoch {
return Err(StakePoolError::StakeListAndPoolOutOfDate.into());
}

stake_pool.check_manager(manager_info)?;

if get_packed_len::<StakePool>() < get_packed_len::<StakePoolChanged>() {
msg!("New structure size is bigger");

return Err(StakePoolError::InvalidState.into());
}

let stake_pool_changed = StakePoolChanged {
account_type: stake_pool.account_type,
manager: stake_pool.manager,
staker: stake_pool.staker,
stake_deposit_authority: stake_pool.stake_deposit_authority,
stake_withdraw_bump_seed: stake_pool.stake_withdraw_bump_seed,
validator_list: stake_pool.validator_list,
reserve_stake: stake_pool.reserve_stake,
pool_mint: stake_pool.pool_mint,
manager_fee_account: stake_pool.manager_fee_account,
token_program_id: stake_pool.token_program_id,
total_lamports: stake_pool.total_lamports,
pool_token_supply: stake_pool.pool_token_supply,
last_update_epoch: stake_pool.last_update_epoch,
lockup: stake_pool.lockup,
epoch_fee: stake_pool.epoch_fee,
next_epoch_fee: stake_pool.next_epoch_fee,
preferred_deposit_validator_vote_address: stake_pool.preferred_deposit_validator_vote_address,
preferred_withdraw_validator_vote_address: stake_pool.preferred_withdraw_validator_vote_address,
stake_deposit_fee: stake_pool.stake_deposit_fee,
stake_withdrawal_fee: stake_pool.stake_withdrawal_fee,
next_stake_withdrawal_fee: stake_pool.next_stake_withdrawal_fee,
stake_referral_fee: stake_pool.stake_referral_fee,
sol_deposit_authority: stake_pool.sol_deposit_authority,
sol_deposit_fee: stake_pool.sol_deposit_fee,
sol_referral_fee: stake_pool.sol_referral_fee,
sol_withdraw_authority: stake_pool.sol_withdraw_authority,
sol_withdrawal_fee: stake_pool.sol_withdrawal_fee,
next_sol_withdrawal_fee: stake_pool.next_sol_withdrawal_fee,
last_epoch_pool_token_supply: stake_pool.last_epoch_pool_token_supply,
last_epoch_total_lamports: stake_pool.last_epoch_total_lamports,
rate_of_exchange: stake_pool.rate_of_exchange,
treasury_fee_account: stake_pool.treasury_fee_account,
treasury_fee: stake_pool.treasury_fee,
total_lamports_liquidity: 100121 // TODO TEST !!!!!!!!!!!!!!!!!!! 0
};

stake_pool_changed.serialize(&mut *stake_pool_info.data.borrow_mut())?;

Ok(())
}

/// Processes [Instruction](enum.Instruction.html).
pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> ProgramResult {
let instruction = StakePoolInstruction::try_from_slice(input)?;
Expand Down Expand Up @@ -3144,6 +3217,10 @@ impl Processor {
msg!("Instruction: WithdrawLiquiditySol");
Self::process_withdraw_liquidity_sol(program_id, accounts, lamports)
}
StakePoolInstruction::ChangeStructure => {
msg!("Instruction: ChnageStructure");
Self::process_change_structure(program_id, accounts)
}
}
}
}
Expand Down
127 changes: 127 additions & 0 deletions stake-pool/program/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,133 @@ impl Default for AccountType {
}
}

/// Initialized program details.
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
pub struct StakePoolChanged {
/// Account type, must be StakePool currently
pub account_type: AccountType,

/// Manager authority, allows for updating the staker, manager, and fee account
pub manager: Pubkey,

/// Staker authority, allows for adding and removing validators, and managing stake
/// distribution
pub staker: Pubkey,

/// Stake deposit authority
///
/// If a depositor pubkey is specified on initialization, then deposits must be
/// signed by this authority. If no deposit authority is specified,
/// then the stake pool will default to the result of:
/// `Pubkey::find_program_address(
/// &[&stake_pool_address.to_bytes()[..32], b"deposit"],
/// program_id,
/// )`
pub stake_deposit_authority: Pubkey,

/// Stake withdrawal authority bump seed
/// for `create_program_address(&[state::StakePool account, "withdrawal"])`
pub stake_withdraw_bump_seed: u8,

/// Validator stake list storage account
pub validator_list: Pubkey,

/// Reserve stake account, holds deactivated stake
pub reserve_stake: Pubkey,

/// Pool Mint
pub pool_mint: Pubkey,

/// Manager fee account
pub manager_fee_account: Pubkey,

/// Pool token program id
pub token_program_id: Pubkey,

/// Total stake under management.
/// Note that if `last_update_epoch` does not match the current epoch then
/// this field may not be accurate
pub total_lamports: u64,

/// Total supply of pool tokens (should always match the supply in the Pool Mint)
pub pool_token_supply: u64,

/// Last epoch the `total_lamports` field was updated
pub last_update_epoch: u64,

/// Lockup that all stakes in the pool must have
pub lockup: Lockup,

/// Fee taken as a proportion of rewards each epoch
pub epoch_fee: Fee,

/// Fee for next epoch
pub next_epoch_fee: Option<Fee>,

/// Preferred deposit validator vote account pubkey
pub preferred_deposit_validator_vote_address: Option<Pubkey>,

/// Preferred withdraw validator vote account pubkey
pub preferred_withdraw_validator_vote_address: Option<Pubkey>,

/// Fee assessed on stake deposits
pub stake_deposit_fee: Fee,

/// Fee assessed on withdrawals
pub stake_withdrawal_fee: Fee,

/// Future stake withdrawal fee, to be set for the following epoch
pub next_stake_withdrawal_fee: Option<Fee>,

/// Fees paid out to referrers on referred stake deposits.
/// Expressed as a percentage (0 - 100) of deposit fees.
/// i.e. `stake_deposit_fee`% of stake deposited is collected as deposit fees for every deposit
/// and `stake_referral_fee`% of the collected stake deposit fees is paid out to the referrer
pub stake_referral_fee: u8,

/// Toggles whether the `DepositSol` instruction requires a signature from
/// this `sol_deposit_authority`
pub sol_deposit_authority: Option<Pubkey>,

/// Fee assessed on SOL deposits
pub sol_deposit_fee: Fee,

/// Fees paid out to referrers on referred SOL deposits.
/// Expressed as a percentage (0 - 100) of SOL deposit fees.
/// i.e. `sol_deposit_fee`% of SOL deposited is collected as deposit fees for every deposit
/// and `sol_referral_fee`% of the collected SOL deposit fees is paid out to the referrer
pub sol_referral_fee: u8,

/// Toggles whether the `WithdrawSol` instruction requires a signature from
/// the `deposit_authority`
pub sol_withdraw_authority: Option<Pubkey>,

/// Fee assessed on SOL withdrawals
pub sol_withdrawal_fee: Fee,

/// Future SOL withdrawal fee, to be set for the following epoch
pub next_sol_withdrawal_fee: Option<Fee>,

/// Last epoch's total pool tokens, used only for APR estimation
pub last_epoch_pool_token_supply: u64,

/// Last epoch's total lamports, used only for APR estimation
pub last_epoch_total_lamports: u64,

/// Last epoch's exchange rate for SOL deposit and withdraw
pub rate_of_exchange: Option<RateOfExchange>,

/// Treasury fee account
pub treasury_fee_account: Pubkey,

/// Fee assessed on taking rewards for treasury
pub treasury_fee: Fee,

/// Total liquidity in Sol equivalent under management.
pub total_lamports_liquidity: u64,
}

/// Initialized program details.
#[repr(C)]
#[derive(Clone, Debug, Default, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
Expand Down

0 comments on commit d7982a9

Please sign in to comment.