withdrawStake static method

TransactionInstruction withdrawStake({
  1. required Pubkey stakePoolAddress,
  2. required Pubkey validatorList,
  3. required Pubkey withdrawAuthority,
  4. required Pubkey validatorOrReserveStakeAccount,
  5. required Pubkey unitializedStakeAccount,
  6. required Pubkey userWithdrawAuthority,
  7. required Pubkey userTransferAuthority,
  8. required Pubkey userTokenAccount,
  9. required Pubkey managerFeeAccount,
  10. required Pubkey poolMint,
  11. required bu64 lamports,
})

Withdraw the token from the pool at the current ratio.

Succeeds if the stake account has enough SOL to cover the desired amount of pool tokens, and if the withdrawal keeps the total staked amount above the minimum of rent-exempt amount + max(crate::MINIMUM_ACTIVE_STAKE, solana_program::stake::tools::get_minimum_delegation()).

When allowing withdrawals, the order of priority goes:

  • preferred withdraw validator stake account (if set)
  • validator stake accounts
  • transient stake accounts
  • reserve stake account OR totally remove validator stake accounts

A user can freely withdraw from a validator stake account, and if they are all at the minimum, then they can withdraw from transient stake accounts, and if they are all at minimum, then they can withdraw from the reserve or remove any validator from the pool.

Keys:

  • [w] stakePoolAddress - Stake pool.
  • [w] validatorList - Validator stake list storage account.
  • [] withdrawAuthority - Stake pool withdraw authority.
  • [w] validatorOrReserveStakeAccount - Validator or reserve stake account to split.
  • [w] unitializedStakeAccount - Unitialized stake account to receive withdrawal.
  • [] userWithdrawAuthority - User account to set as a new withdraw authority.
  • [s] userTransferAuthority - User transfer authority, for pool token account.
  • [w] userTokenAccount - User account with pool tokens to burn from.
  • [w] managerFeeAccount - Account to receive pool fee tokens.
  • [w] poolMint - Pool token mint account.

Data:

  • lamports - Amount of pool tokens to withdraw.

Implementation

static TransactionInstruction withdrawStake({
  // Keys
  required final Pubkey stakePoolAddress,
  required final Pubkey validatorList,
  required final Pubkey withdrawAuthority,
  required final Pubkey validatorOrReserveStakeAccount,
  required final Pubkey unitializedStakeAccount,
  required final Pubkey userWithdrawAuthority,
  required final Pubkey userTransferAuthority,
  required final Pubkey userTokenAccount,
  required final Pubkey managerFeeAccount,
  required final Pubkey poolMint,
  // Data
  required final bu64 lamports,
}) {
  //  0. `[w]` Stake pool
  //  1. `[w]` Validator stake list storage account
  //  2. `[]` Stake pool withdraw authority
  //  3. `[w]` Validator or reserve stake account to split
  //  4. `[w]` Unitialized stake account to receive withdrawal
  //  5. `[]` User account to set as a new withdraw authority
  //  6. `[s]` User transfer authority, for pool token account
  //  7. `[w]` User account with pool tokens to burn from
  //  8. `[w]` Account to receive pool fee tokens
  //  9. `[w]` Pool token mint account
  // 10. `[]` Sysvar clock account (required)
  // 11. `[]` Pool token program id
  // 12. `[]` Stake program id
  final List<AccountMeta> keys = [
    AccountMeta.writable(stakePoolAddress),
    AccountMeta.writable(validatorList),
    AccountMeta(withdrawAuthority),
    AccountMeta.writable(validatorOrReserveStakeAccount),
    AccountMeta.writable(unitializedStakeAccount),
    AccountMeta(userWithdrawAuthority),
    AccountMeta.signer(userTransferAuthority),
    AccountMeta.writable(userTokenAccount),
    AccountMeta.writable(managerFeeAccount),
    AccountMeta.writable(poolMint),
    AccountMeta(sysvarClockPubkey),
    AccountMeta(TokenProgram.programId),
    AccountMeta(StakeProgram.programId),
  ];

  final List<Iterable<int>> data = [
    borsh.u64.encode(lamports),
  ];

  return _instance.createTransactionIntruction(
    StakePoolInstruction.withdrawStake,
    keys: keys,
    data: data,
  );
}