Skip to content

Commit

Permalink
rebirth
Browse files Browse the repository at this point in the history
  • Loading branch information
xhjkl committed Aug 23, 2023
1 parent 487090a commit 88409e8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 48 deletions.
15 changes: 13 additions & 2 deletions program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,17 @@ pub enum LidoInstruction {
#[allow(dead_code)] // but it's not
max_commission_percentage: u8,
},

MigrateStateToV3 {
#[allow(dead_code)] // but it's not
reward_distribution: RewardDistribution,
#[allow(dead_code)] // but it's not
max_validators: u32,
#[allow(dead_code)] // but it's not
max_maintainers: u32,
#[allow(dead_code)] // but it's not
max_commission_percentage: u8,
},
}

impl LidoInstruction {
Expand Down Expand Up @@ -1162,7 +1173,7 @@ pub fn change_criteria(
}

accounts_struct! {
MigrateStateToV2Meta, MigrateStateToV2Info {
MigrateStateToV3Meta, MigrateStateToV3Info {
pub lido {
is_signer: false,
// Needs to be writable for us to update the metrics.
Expand Down Expand Up @@ -1197,7 +1208,7 @@ pub fn migrate_state_to_v2(
max_validators: u32,
max_maintainers: u32,
max_commission_percentage: u8,
accounts: &MigrateStateToV2Meta,
accounts: &MigrateStateToV3Meta,
) -> Instruction {
let data = LidoInstruction::MigrateStateToV2 {
reward_distribution,
Expand Down
72 changes: 26 additions & 46 deletions program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::ops::{Add, Sub};
use crate::{
error::LidoError,
instruction::{
DepositAccountsInfo, InitializeAccountsInfo, LidoInstruction, MigrateStateToV2Info,
DepositAccountsInfo, InitializeAccountsInfo, LidoInstruction, MigrateStateToV3Info,
StakeDepositAccountsInfoV2, UnstakeAccountsInfoV2, UpdateExchangeRateAccountsInfoV2,
UpdateOffchainValidatorPerfAccountsInfo, UpdateOnchainValidatorPerfAccountsInfo,
UpdateStakeAccountBalanceInfo, WithdrawAccountsInfoV2,
Expand All @@ -28,7 +28,7 @@ use crate::{
},
stake_account::{deserialize_stake_account, StakeAccount},
state::{
AccountType, Criteria, ExchangeRate, FeeRecipients, Lido, LidoV1, ListEntry, Maintainer,
legacy, AccountType, Criteria, ExchangeRate, FeeRecipients, Lido, ListEntry,
MaintainerList, OffchainValidatorPerf, RewardDistribution, StakeDeposit, Validator,
ValidatorList, ValidatorPerf, ValidatorPerfList,
},
Expand Down Expand Up @@ -1174,21 +1174,23 @@ pub fn process_withdraw(
}

/// Migrate Solido state to version 2
pub fn process_migrate_to_v2(
pub fn process_migrate_to_v3(
program_id: &Pubkey,
reward_distribution: RewardDistribution,
max_validators: u32,
max_maintainers: u32,
max_commission_percentage: u8,
accounts_raw: &[AccountInfo],
) -> ProgramResult {
let accounts = MigrateStateToV2Info::try_from_slice(accounts_raw)?;
let lido_v1 = LidoV1::deserialize_lido(program_id, accounts.lido)?;
lido_v1.check_manager(accounts.manager)?;

if !(lido_v1.lido_version == 0 && Lido::VERSION == 1) {
return Err(LidoError::LidoVersionMismatch.into());
let accounts = MigrateStateToV3Info::try_from_slice(accounts_raw)?;
let old = legacy::Lido::deserialize_lido(program_id, accounts.lido)?;
if !(old.lido_version < 3) {
// If the guard does not fire, it means we already have migrated,
// so nothing to do here.
msg!("Data accounts are already at the latest schema.");
return Err(LidoError::AlreadyInUse.into());
}
old.check_manager(accounts.manager)?;

let rent = &Rent::get()?;
check_rent_exempt(rent, accounts.validator_list, "Validator list account")?;
Expand Down Expand Up @@ -1220,31 +1222,6 @@ pub fn process_migrate_to_v2(
return Err(LidoError::AlreadyInUse.into());
}

if lido_v1.maintainers.entries.len() > max_maintainers as usize {
msg!("max_maintainers is too small");
return Err(LidoError::MaximumNumberOfAccountsExceeded.into());
}
let mut maintainers = MaintainerList::new_default(0);
maintainers.header.max_entries = max_maintainers;

for pe in lido_v1.maintainers.entries {
maintainers.entries.push(Maintainer::new(pe.pubkey));
}

if lido_v1.validators.entries.len() > max_validators as usize {
msg!("max_validators is too small");
return Err(LidoError::MaximumNumberOfAccountsExceeded.into());
}
let mut validators = ValidatorList::new_default(0);
validators.header.max_entries = max_validators;

if !lido_v1.validators.entries.is_empty() {
msg!("There should be no validators in Solido state prior to update.");
msg!("You should first deactivate all validators and wait for epoch boundary.");
msg!("Then maintainers will withdraw inactive stake to reserve and remove validators.");
return Err(LidoError::ValidatorListNotEmpty.into());
}

if max_commission_percentage > 100 {
return Err(LidoError::ValidationCommissionOutOfBounds.into());
}
Expand All @@ -1257,25 +1234,27 @@ pub fn process_migrate_to_v2(
validator_perf_list: *accounts.validator_perf_list.key,
maintainer_list: *accounts.maintainer_list.key,
fee_recipients: FeeRecipients {
treasury_account: lido_v1.fee_recipients.treasury_account,
treasury_account: old.fee_recipients.treasury_account,
developer_account: *accounts.developer_account.key,
},
reward_distribution,
manager: lido_v1.manager,
st_sol_mint: lido_v1.st_sol_mint,
exchange_rate: lido_v1.exchange_rate,
sol_reserve_account_bump_seed: lido_v1.sol_reserve_account_bump_seed,
mint_authority_bump_seed: lido_v1.mint_authority_bump_seed,
stake_authority_bump_seed: lido_v1.stake_authority_bump_seed,
metrics: lido_v1.metrics,
manager: old.manager,
st_sol_mint: old.st_sol_mint,
exchange_rate: ExchangeRate {
computed_in_epoch: old.exchange_rate.computed_in_epoch,
st_sol_supply: old.exchange_rate.st_sol_supply,
sol_balance: old.exchange_rate.sol_balance,
},
sol_reserve_account_bump_seed: old.sol_reserve_account_bump_seed,
mint_authority_bump_seed: old.mint_authority_bump_seed,
stake_authority_bump_seed: old.stake_authority_bump_seed,
metrics: old.metrics,
criteria: Criteria::default(),
};

// Confirm that the fee recipients are actually stSOL accounts.
lido.check_is_st_sol_account(accounts.developer_account)?;

validators.save(accounts.validator_list)?;
maintainers.save(accounts.maintainer_list)?;
lido.save(accounts.lido)
}

Expand Down Expand Up @@ -1368,12 +1347,12 @@ pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> P
LidoInstruction::ChangeCriteria { new_criteria } => {
process_change_criteria(program_id, new_criteria, accounts)
}
LidoInstruction::MigrateStateToV2 {
LidoInstruction::MigrateStateToV3 {
reward_distribution,
max_validators,
max_maintainers,
max_commission_percentage,
} => process_migrate_to_v2(
} => process_migrate_to_v3(
program_id,
reward_distribution,
max_validators,
Expand All @@ -1391,6 +1370,7 @@ pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> P
| LidoInstruction::DeactivateValidator
| LidoInstruction::RemoveMaintainer
| LidoInstruction::RemoveValidator
| LidoInstruction::MigrateStateToV2 { .. }
| LidoInstruction::StakeDeposit { .. }
| LidoInstruction::Unstake { .. }
| LidoInstruction::Withdraw { .. } => {
Expand Down
10 changes: 10 additions & 0 deletions program/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub use validator_perf::{Criteria, OffchainValidatorPerf, ValidatorPerf};
mod maintainer;
pub use maintainer::Maintainer;

pub mod legacy;

/// Types of list entries
/// Uninitialized should always be a first enum field as it catches empty list data errors
#[derive(Clone, Debug, PartialEq, Eq, BorshDeserialize, BorshSerialize, Serialize, BorshSchema)]
Expand Down Expand Up @@ -529,6 +531,14 @@ impl Lido {
);
return Err(LidoError::InvalidAccountType.into());
}
if lido.lido_version != Lido::VERSION {
msg!(
"Lido version mismatch, expected {}, got {}",
Lido::VERSION,
lido.lido_version
);
return Err(LidoError::LidoVersionMismatch.into());
}

check_lido_version(lido.lido_version, AccountType::Lido)?;

Expand Down

0 comments on commit 88409e8

Please sign in to comment.