Assessment reports>BPF Stake Program>Threat Model>Instruction: Split

Instruction: Split

This instruction splits tokens and stake off a stake account into a new stake account.

Input structure

pub enum StakeInstruction { /// # Account references /// 0. `[WRITE]` Stake account to be split; must be in the Initialized or Stake state /// 1. `[WRITE]` Uninitialized stake account that will take the split-off amount /// 2. `[SIGNER]` Stake authority Split(u64), } fn process_split(accounts: &[AccountInfo], split_lamports: u64) -> ProgramResult {

Parameters

  • split_lamports: The amount of lamports to split off from the source stake account.

Accounts

  • source_stake_account: The initialized or delegated stake account to be split.

    • Signer: No.

    • Init: No.

    • PDA: No.

    • Writable: Yes.

    • Rent checks: The account must be rent-exempt.

    • Ownership checks: The account must be owned by the program.

    • Address checks: None.

  • destination_stake_account: The uninitialized stake account that will take the split-off amount.

    • Signer: No.

    • Init: No.

    • PDA: No.

    • Writable: Yes.

    • Rent checks: None.

    • Ownership checks: The account must be owned by the Solana vote program.

    • Address checks: None.

  • stake_authority: The stake authority account who is authorized to manage the stake account.

    • Signer: Yes.

    • Init: No.

    • PDA: No.

    • Writable: No.

    • Rent checks: None.

    • Ownership checks: None.

    • Address checks: None.

Additional checks and behavior

  • The size of the destination stake account must be equal to the size of StakeStateV2.

  • The destination stake account must be uninitialized.

  • The lamports to be split must be less than or equal to the lamports in the source stake account.

  • The staker of the source stake account must be a signer.

  • The lamports to be split must be greater than zero and less than or equal to the total lamports in the source stake account.

  • The remaining balance of the source stake account after the split must be at least the rent exempt reserve plus the additional required lamports, which can be zero or the minimum delegation amount.

  • If the source stake account is active, which means it has a effective stake, then one of the following criteria must be met: 1) the destination stake account must be prefunded with at least the rent-exempt reserve, or 2) the split must consume 100% of the source stake account.

  • The split amount must be less than the rent reserve plus the additional required lamports minus the current destination balance.

  • If the source stake account is in the Stake state, the following takes place:

    • If the remaining balance of the source stake account is zero, the remaining stake delta and split stake amount must be equal. Otherwise, the stake amount of the source stake account minus the split amount must be greater than or equal to the minimum delegation amount.

    • The split stake amount must be greater than or equal to the minimum delegation amount.

    • The source stake account is split into the destination stake account.

  • If the source stake account is uninitialized, the source stake account must be a signer.

  • Copy the source stake account meta to the destination stake account meta with new rent-exempt reserve.

  • The source stake account is deinitialized if the split amount is equal to the total lamports in the source stake account.

  • The split amount of lamports is moved from the source stake account to the destination stake account.

Zellic © 2025Back to top ↑