From 8cd5abfd8e82bc42160da41f1dcc3e571bee072b Mon Sep 17 00:00:00 2001 From: Evan Batsell Date: Wed, 31 Jul 2024 19:12:02 -0400 Subject: [PATCH 1/3] Read active stake rather than validator list balance --- programs/steward/src/instructions/rebalance.rs | 12 ++++++++++-- programs/steward/src/state/steward_state.rs | 6 ++++-- tests/tests/steward/test_state_methods.rs | 7 +++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/programs/steward/src/instructions/rebalance.rs b/programs/steward/src/instructions/rebalance.rs index 76d14ca1..87ff0629 100644 --- a/programs/steward/src/instructions/rebalance.rs +++ b/programs/steward/src/instructions/rebalance.rs @@ -1,4 +1,4 @@ -use std::num::NonZeroU32; +use std::{borrow::BorrowMut, num::NonZeroU32}; use anchor_lang::{ idl::*, @@ -10,7 +10,7 @@ use anchor_lang::{ }, }; use borsh::BorshDeserialize; -use spl_pod::solana_program::stake::state::StakeStateV2; +use spl_pod::solana_program::{borsh1::try_from_slice_unchecked, stake::state::StakeStateV2}; use spl_stake_pool::{ find_stake_program_address, find_transient_stake_program_address, minimum_delegation, state::ValidatorListHeader, @@ -179,6 +179,13 @@ pub fn handler(ctx: Context, validator_list_index: usize) -> Result<( transient_seed = u64::from(validator_stake_info.transient_seed_suffix); + let stake_account_data = &mut ctx.accounts.stake_account.data.borrow(); + let stake_state = try_from_slice_unchecked::(&stake_account_data)?; + let stake_account_active_lamports = match stake_state { + StakeStateV2::Stake(_meta, stake, _stake_flags) => stake.delegation.stake, + _ => return Err(StewardError::StakeStateIsNotStake.into()), + }; + let minimum_delegation = minimum_delegation(get_minimum_delegation()?); let stake_rent = Rent::get()?.minimum_balance(StakeStateV2::size_of()); @@ -196,6 +203,7 @@ pub fn handler(ctx: Context, validator_list_index: usize) -> Result<( &validator_list, stake_pool_lamports_with_fixed_cost, reserve_lamports_with_rent, + stake_account_active_lamports, minimum_delegation, stake_rent, &config.parameters, diff --git a/programs/steward/src/state/steward_state.rs b/programs/steward/src/state/steward_state.rs index 9ab234ac..268c348e 100644 --- a/programs/steward/src/state/steward_state.rs +++ b/programs/steward/src/state/steward_state.rs @@ -825,6 +825,7 @@ impl StewardState { validator_list: &BigVec<'_>, stake_pool_lamports: u64, reserve_lamports: u64, + stake_account_current_lamports: u64, minimum_delegation: u64, stake_rent: u64, parameters: &Parameters, @@ -885,10 +886,11 @@ impl StewardState { let target_lamports = get_target_lamports(&self.delegations[index], stake_pool_lamports)?; - let (mut current_lamports, some_transient_lamports) = + let (_, some_transient_lamports) = stake_lamports_at_validator_list_index(validator_list, index)?; - current_lamports = current_lamports.saturating_sub(base_lamport_balance); + let current_lamports = + stake_account_current_lamports.saturating_sub(minimum_delegation); if !some_transient_lamports { /* This field is used to determine the amount of stake deposits this validator has gotten which push it over the target. diff --git a/tests/tests/steward/test_state_methods.rs b/tests/tests/steward/test_state_methods.rs index 7bab19ff..7b049001 100644 --- a/tests/tests/steward/test_state_methods.rs +++ b/tests/tests/steward/test_state_methods.rs @@ -522,6 +522,7 @@ fn test_rebalance() { &validator_list_bigvec, 4000 * LAMPORTS_PER_SOL, 1000 * LAMPORTS_PER_SOL, + u64::from(fixtures.validator_list[0].active_stake_lamports), 0, 0, &fixtures.config.parameters, @@ -557,6 +558,7 @@ fn test_rebalance() { &validator_list_bigvec, 4000 * LAMPORTS_PER_SOL, 1000 * LAMPORTS_PER_SOL, + u64::from(fixtures.validator_list[1].active_stake_lamports), 0, 0, &fixtures.config.parameters, @@ -595,6 +597,7 @@ fn test_rebalance() { &validator_list_bigvec, 4000 * LAMPORTS_PER_SOL, 1000 * LAMPORTS_PER_SOL, + u64::from(fixtures.validator_list[1].active_stake_lamports), 0, 0, &fixtures.config.parameters, @@ -631,6 +634,7 @@ fn test_rebalance() { &validator_list_bigvec, 4000 * LAMPORTS_PER_SOL, 1000 * LAMPORTS_PER_SOL, + u64::from(fixtures.validator_list[1].active_stake_lamports), 0, 0, &fixtures.config.parameters, @@ -683,6 +687,7 @@ fn test_rebalance() { &validator_list_bigvec, 4000 * LAMPORTS_PER_SOL, 1000 * LAMPORTS_PER_SOL, + u64::from(fixtures.validator_list[0].active_stake_lamports), 0, 0, &fixtures.config.parameters, @@ -715,6 +720,7 @@ fn test_rebalance() { &validator_list_bigvec, 3000 * LAMPORTS_PER_SOL, 0, + u64::from(fixtures.validator_list[0].active_stake_lamports), 0, 0, &fixtures.config.parameters, @@ -733,6 +739,7 @@ fn test_rebalance() { &validator_list_bigvec, 3000 * LAMPORTS_PER_SOL, 0, + u64::from(fixtures.validator_list[0].active_stake_lamports), 0, 0, &fixtures.config.parameters, From 76dc81f6053f94359c8e5535b771d808815004e2 Mon Sep 17 00:00:00 2001 From: Evan Batsell Date: Wed, 31 Jul 2024 19:15:18 -0400 Subject: [PATCH 2/3] unused import --- programs/steward/src/instructions/rebalance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/steward/src/instructions/rebalance.rs b/programs/steward/src/instructions/rebalance.rs index 87ff0629..6116b10e 100644 --- a/programs/steward/src/instructions/rebalance.rs +++ b/programs/steward/src/instructions/rebalance.rs @@ -1,4 +1,4 @@ -use std::{borrow::BorrowMut, num::NonZeroU32}; +use std::num::NonZeroU32; use anchor_lang::{ idl::*, From bc018cefebaf3f2115e8251cb7c2541b0243e2bb Mon Sep 17 00:00:00 2001 From: Evan Batsell Date: Wed, 31 Jul 2024 19:24:06 -0400 Subject: [PATCH 3/3] clippies --- programs/steward/src/instructions/rebalance.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/programs/steward/src/instructions/rebalance.rs b/programs/steward/src/instructions/rebalance.rs index 6116b10e..e706ffd4 100644 --- a/programs/steward/src/instructions/rebalance.rs +++ b/programs/steward/src/instructions/rebalance.rs @@ -180,7 +180,7 @@ pub fn handler(ctx: Context, validator_list_index: usize) -> Result<( transient_seed = u64::from(validator_stake_info.transient_seed_suffix); let stake_account_data = &mut ctx.accounts.stake_account.data.borrow(); - let stake_state = try_from_slice_unchecked::(&stake_account_data)?; + let stake_state = try_from_slice_unchecked::(stake_account_data)?; let stake_account_active_lamports = match stake_state { StakeStateV2::Stake(_meta, stake, _stake_flags) => stake.delegation.stake, _ => return Err(StewardError::StakeStateIsNotStake.into()),