Skip to content

Commit

Permalink
stake-pool: Improve error when overdrawing on decrease (solana-labs#2522
Browse files Browse the repository at this point in the history
)
  • Loading branch information
joncinque authored Oct 18, 2021
1 parent 671590d commit 50b5597
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
16 changes: 15 additions & 1 deletion stake-pool/program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,7 @@ impl Processor {
return Err(StakePoolError::InvalidState.into());
}

let (_meta, stake) = get_stake_state(validator_stake_account_info)?;
let (meta, stake) = get_stake_state(validator_stake_account_info)?;
let vote_account_address = stake.delegation.voter_pubkey;
check_validator_stake_address(
program_id,
Expand Down Expand Up @@ -1069,6 +1069,20 @@ impl Processor {
return Err(ProgramError::AccountNotRentExempt);
}

let remaining_lamports = validator_stake_account_info
.lamports()
.checked_sub(lamports)
.ok_or(ProgramError::InsufficientFunds)?;
let required_lamports = minimum_stake_lamports(&meta);
if remaining_lamports < required_lamports {
msg!("Need at least {} lamports in the stake account after decrease, {} requested, {} is the current possible maximum",
required_lamports,
lamports,
validator_stake_account_info.lamports().checked_sub(required_lamports).ok_or(StakePoolError::CalculationFailure)?
);
return Err(ProgramError::InsufficientFunds);
}

create_transient_stake_account(
transient_stake_account_info.clone(),
transient_stake_account_signer_seeds,
Expand Down
45 changes: 40 additions & 5 deletions stake-pool/program/tests/decrease.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ async fn fail_with_small_lamport_amount() {
}

#[tokio::test]
async fn fail_overdraw_validator() {
async fn fail_big_overdraw() {
let (
mut banks_client,
payer,
Expand All @@ -392,8 +392,43 @@ async fn fail_overdraw_validator() {
.unwrap()
.unwrap();

match error {
TransactionError::InstructionError(_, InstructionError::InsufficientFunds) => {}
_ => panic!("Wrong error occurs while overdrawing stake account on decrease"),
}
assert_eq!(
error,
TransactionError::InstructionError(0, InstructionError::InsufficientFunds)
);
}

#[tokio::test]
async fn fail_overdraw() {
let (
mut banks_client,
payer,
recent_blockhash,
stake_pool_accounts,
validator_stake,
deposit_info,
_decrease_lamports,
) = setup().await;

let rent = banks_client.get_rent().await.unwrap();
let stake_rent = rent.minimum_balance(std::mem::size_of::<stake_program::StakeState>());

let error = stake_pool_accounts
.decrease_validator_stake(
&mut banks_client,
&payer,
&recent_blockhash,
&validator_stake.stake_account,
&validator_stake.transient_stake_account,
deposit_info.stake_lamports + stake_rent + 1,
validator_stake.transient_stake_seed,
)
.await
.unwrap()
.unwrap();

assert_eq!(
error,
TransactionError::InstructionError(0, InstructionError::InsufficientFunds)
);
}

0 comments on commit 50b5597

Please sign in to comment.