This guide provides comprehensive documentation for the on-chain Fogo Stake Pool program, including all instructions, account structures, and program-derived addresses.
Program ID: SP1s4uFeTAX9jsXXmwyDs1gxYYf7cdDZ8qHUHVxE1yr
The Fogo Stake Pool program is a FOGO blockchain program that enables the creation and management of stake pools - collections of delegated stake accounts that are managed collectively and represented by fungible pool tokens.
A stake pool consists of:
- Pool Account: The main account containing pool configuration and state
- Validator List: A list of validators and their associated stake accounts
- Reserve Account: Holds deactivated stake for immediate withdrawals
- Pool Token Mint: Issues tokens representing proportional ownership of the pool
- Manager Fee Account: Receives management fees from the pool
Pool Token Value = Total Pool Lamports / Pool Token Supply
When users deposit stake:
- Their stake is added to the pool's total lamports
- Pool tokens are minted proportionally to their contribution
- Fees are deducted and distributed to managers and referrers
- Authority Separation: Different keys control different operations
- PDA Security: Critical authorities use program-derived addresses
- Fee Protection: Gradual fee changes prevent sudden increases
- Compute Limits: Batch operations respect FOGO's compute budget
The program uses several PDA patterns for secure authority management:
// Deposit authority (for permissionless deposits)
[stake_pool_address, b"deposit"] → deposit_authority
// Withdraw authority (controls all pool stake accounts)
[stake_pool_address, b"withdraw"] → (withdraw_authority, bump_seed)// Transient stake accounts (temporary during rebalancing)
[stake_pool_address, b"transient", validator_vote_account, seed] → transient_stake
// Ephemeral stake accounts (very temporary during complex operations)
[stake_pool_address, b"ephemeral", seed] → ephemeral_stake
// User stake accounts (created during WithdrawStakeWithSession)
[b"user_stake", user_wallet, seed] → user_stake_accountuse solana_program::pubkey::Pubkey;
// Find withdraw authority
let (withdraw_authority, bump) = Pubkey::find_program_address(
&[stake_pool_address.as_ref(), b"withdraw"],
&program_id,
);
// Find deposit authority
let (deposit_authority, _) = Pubkey::find_program_address(
&[stake_pool_address.as_ref(), b"deposit"],
&program_id,
);The program uses several key account structures to manage pool state. For detailed field-level specifications and complete struct definitions, refer to the source code in program/src/state.rs.
- StakePool Account: Main pool account containing authorities, fees, financial state, and configuration
- ValidatorList Account: Stores validator information using BigVec for efficient large-scale management
- ValidatorStakeInfo: Tracks individual validator stake amounts, status, and performance
- Fee Structures: Manages various fee types including epoch fees, deposit fees, withdrawal fees, and referral fees
The program uses efficient data structures optimized for on-chain storage and processing.
The program supports comprehensive stake pool operations through various instructions:
Creates a new stake pool with specified configuration.
Initialize {
fee: Fee, // Management fee on rewards
withdrawal_fee: Fee, // Fee on withdrawals
deposit_fee: Fee, // Fee on deposits
referral_fee: u8, // Percentage of deposit fees for referrers
max_validators: u32, // Expected maximum validators
}Accounts:
[w]New StakePool account[s]Manager[]Staker[]Stake pool withdraw authority (PDA)[w]Validator list storage account[]Reserve stake account[]Pool token mint[]Manager fee account[]Token program[](Optional) Deposit authority
Updates the pool manager (manager only).
SetManagerAccounts:
[w]Stake pool[s]Current manager[s]New manager[]New manager fee account
Updates pool fees (manager only).
SetFee {
fee: FeeType, // Which fee to update and new value
}
pub enum FeeType {
SolReferral(u8),
StakeReferral(u8),
Epoch(Fee),
StakeDeposit(Fee),
SolDeposit(Fee),
StakeWithdrawal(Fee),
SolWithdrawal(Fee),
}Accounts:
[w]Stake pool[s]Manager
Updates the staker authority (manager or current staker only).
SetStakerAccounts:
[w]Stake pool[s]Manager or current staker[]New staker
Updates deposit/withdrawal authorities (manager only).
SetFundingAuthority(FundingType)
pub enum FundingType {
StakeDeposit, // Sets stake deposit authority
SolDeposit, // Sets tokens deposit authority
SolWithdraw, // Sets tokens withdrawal authority
}Accounts:
[w]Stake pool[s]Manager[]New authority (or None)
Adds a validator to the pool (staker only).
AddValidatorToPool(u32) // Optional seed for validator stake accountAccounts:
[w]Stake pool[s]Staker[w]Reserve stake account[]Withdraw authority[w]Validator list[w]Validator stake account[]Validator vote account[]Rent sysvar[]Clock sysvar[]Stake history sysvar[]Stake config sysvar[]System program[]Stake program
Removes a validator from the pool (staker only).
RemoveValidatorFromPoolAccounts:
[w]Stake pool[s]Staker[]Withdraw authority[w]Validator list[w]Validator stake account[w]Transient stake account[]Clock sysvar[]Stake program
Sets preferred validator for deposits/withdrawals (staker only).
SetPreferredValidator {
validator_type: PreferredValidatorType,
validator_vote_address: Option<Pubkey>,
}
pub enum PreferredValidatorType {
Deposit, // For deposits
Withdraw, // For withdrawals
}Accounts:
[w]Stake pool[s]Staker[]Validator list
Increases stake on a validator from the reserve (staker only).
IncreaseValidatorStake {
lamports: u64, // Amount to increase
transient_stake_seed: u64, // Seed for transient account
}Accounts:
[]Stake pool[s]Staker[]Withdraw authority[w]Validator list[w]Reserve stake[w]Transient stake account[]Validator stake account[]Validator vote account[]Clock sysvar[]Rent sysvar[]Stake history sysvar[]Stake config sysvar[]System program[]Stake program
Decreases stake on a validator to the reserve (staker only).
DecreaseValidatorStakeWithReserve {
lamports: u64, // Amount to decrease
transient_stake_seed: u64, // Seed for transient account
}Increases stake on a validator again in the same epoch (staker only).
IncreaseAdditionalValidatorStake {
lamports: u64, // Amount to increase
transient_stake_seed: u64, // Seed for transient account
ephemeral_stake_seed: u64, // Seed for ephemeral account
}Decreases stake on a validator again in the same epoch (staker only).
DecreaseAdditionalValidatorStake {
lamports: u64, // Amount to decrease
transient_stake_seed: u64, // Seed for transient account
ephemeral_stake_seed: u64, // Seed for ephemeral account
}Updates validator balances and processes transient stakes.
UpdateValidatorListBalance {
start_index: u32, // Starting validator index
no_merge: bool, // Skip merging for testing
}Accounts:
[]Stake pool[]Withdraw authority[w]Validator list[w]Reserve stake[]Clock sysvar[]Stake history sysvar[]Stake program..Validator and transient stake account pairs (up to MAX_VALIDATORS_TO_UPDATE * 2)
Updates the stake pool's total balance from validator list.
UpdateStakePoolBalanceAccounts:
[w]Stake pool[]Withdraw authority[w]Validator list[]Reserve stake[w]Manager fee account[w]Pool token mint[]Token program
Removes validators marked as ReadyForRemoval.
CleanupRemovedValidatorEntriesAccounts:
[]Stake pool[w]Validator list
Deposits a stake account into the pool in exchange for pool tokens.
DepositStakeAccounts:
[w]Stake pool[w]Validator list[s]/[]Deposit authority (if required)[]Withdraw authority[w]Stake account to deposit[w]Validator stake account to merge with[w]Reserve stake account[w]User pool token account[w]Manager fee account[w]Referrer pool token account[w]Pool token mint[]Clock sysvar[]Stake history sysvar[]Token program[]Stake program
Withdraws stake from the pool by burning pool tokens.
WithdrawStake(u64) // Amount of pool tokens to burnAccounts:
[w]Stake pool[w]Validator list[]Withdraw authority[w]Validator or reserve stake account to split from[w]New stake account to receive withdrawal[]User account (new withdraw authority)[s]User transfer authority[w]User pool token account[w]Manager fee account[w]Pool token mint[]Clock sysvar[]Token program[]Stake program
Deposits tokens directly into the pool's reserve.
DepositSol(u64) // Amount of tokens to depositAccounts:
[w]Stake pool[]Withdraw authority[w]Reserve stake account[s]Funding account[w]User pool token account[w]Manager fee account[w]Referrer pool token account[w]Pool token mint[]System program[]Token program[s](Optional) tokens deposit authority
Withdraws tokens directly from the pool's reserve.
WithdrawSol(u64) // Amount of tokens to withdrawAccounts:
[w]Stake pool[]Withdraw authority[s]User transfer authority[w]User pool token account[w]Reserve stake account[w]Receiving system account[w]Manager fee account[w]Pool token mint[]Clock sysvar[]Stake history sysvar[]Stake program[]Token program[s](Optional) tokens withdraw authority
Deposits wrapped SOL (WSOL) into the pool using a session token for authentication (FOGO blockchain specific).
DepositWsolWithSession {
amount: u64, // Amount of WSOL to deposit
}Accounts:
[w]Stake pool[]Withdraw authority[w]Reserve stake account[s]Funding account (session authority)[w]User pool token account[w]Manager fee account[w]Referrer pool token account[w]Pool token mint[]System program[]Token program[]Session token account[s]Session authority
Description: This instruction enables gasless transactions on FOGO blockchain by using session tokens. The session authority signs the transaction on behalf of the user, allowing for improved UX without requiring users to sign each transaction individually.
Withdraws wrapped SOL (WSOL) from the pool using a session token for authentication (FOGO blockchain specific).
WithdrawWsolWithSession {
amount: u64, // Amount of pool tokens to burn
}Accounts:
[w]Stake pool[]Withdraw authority[s]Session authority[w]User pool token account[w]Reserve stake account[w]Receiving WSOL account[w]Manager fee account[w]Pool token mint[]Clock sysvar[]Stake history sysvar[]Stake program[]Token program[]Session token account
Description: This instruction enables gasless withdrawals on FOGO blockchain by using session tokens. The session authority validates and processes the withdrawal, providing a seamless user experience for withdrawing stake pool tokens back to WSOL.
Withdraws stake from the pool using a session token, creating a user-owned stake account PDA (FOGO blockchain specific).
WithdrawStakeWithSession {
pool_tokens_in: u64, // Amount of pool tokens to burn
minimum_lamports_out: u64, // Minimum lamports to receive (slippage protection)
user_stake_seed: u64, // Seed for user stake PDA derivation
}Accounts:
[w]Stake pool[w]Validator list[]Withdraw authority[w]Validator/reserve stake account to split from[w]User stake account PDA (destination)[s]Session signer (user_stake_authority)[]User transfer authority (same as session signer in session path)[w]User pool token account[w]Manager fee account[w]Pool token mint[]Clock sysvar[]Token program[]Stake program[]Program signer PDA[]System program[s,w]Payer (for stake account rent)
Description:
This instruction enables gasless stake withdrawals on FOGO blockchain. The user stake account is created as a PDA derived from [b"user_stake", user_wallet, seed], giving the user authority over the stake account. The payer (typically a paymaster) covers the rent for the new stake account.
Withdraws SOL from a deactivated user stake account using a session token (FOGO blockchain specific).
WithdrawFromStakeAccountWithSession {
lamports: u64, // Amount to withdraw (MAX for full withdrawal)
user_stake_seed: u64, // Seed used to derive the user stake PDA
}Accounts:
[w]User stake account PDA[w]User wallet (destination)[]Clock sysvar[]Stake history sysvar[s]Session signer[]Stake program
Description: After a stake account has been deactivated and the deactivation epoch has passed, this instruction allows the user to withdraw the SOL back to their wallet using a session token. The stake account must be fully deactivated (inactive state).
Creates metadata for the pool token.
CreateTokenMetadata {
name: String, // Token name
symbol: String, // Token symbol (e.g., "stktokens")
uri: String, // Metadata URI
}Updates existing token metadata.
UpdateTokenMetadata {
name: String, // Updated token name
symbol: String, // Updated token symbol
uri: String, // Updated metadata URI
}pub const MINIMUM_ACTIVE_STAKE: u64 = 1_000_000; // Minimum stake per validator
pub const MINIMUM_RESERVE_LAMPORTS: u64 = 0; // Minimum reserve balance
pub const MAX_VALIDATORS_TO_UPDATE: usize = 4; // Per instruction limitpub const MAX_WITHDRAWAL_FEE_INCREASE: Fee = Fee {
numerator: 3,
denominator: 2,
}; // Maximum 3/2 ratio increase per epoch
pub const WITHDRAWAL_BASELINE_FEE: Fee = Fee {
numerator: 3,
denominator: 1000,
}; // 0.3% baseline for fee increase calculationspub const AUTHORITY_DEPOSIT: &[u8] = b"deposit";
pub const AUTHORITY_WITHDRAW: &[u8] = b"withdraw";
pub const TRANSIENT_STAKE_SEED_PREFIX: &[u8] = b"transient";
pub const EPHEMERAL_STAKE_SEED_PREFIX: &[u8] = b"ephemeral";The program defines comprehensive error codes for different failure conditions:
pub enum StakePoolError {
// Setup errors
AlreadyInUse,
InvalidProgramAddress,
InvalidState,
IncorrectProgramId,
IncorrectOwner,
// Authority errors
WrongAccountMint,
NonzeroPoolTokenSupply,
StakeListAndPoolLamportsMismatch,
UnknownValidatorStakeAccount,
// Operation errors
StakeListOutOfDate,
StakeNotActive,
ValidatorAlreadyAdded,
ValidatorNotFound,
InvalidValidatorStakeList,
// Fee errors
CalculationFailure,
FeeTooHigh,
WithdrawTooLarge,
WithdrawTooSmall,
InsufficientPoolTokens,
DepositTooSmall,
// And many more...
}- Set Reasonable Fees: Start with low fees and increase gradually if needed
- Choose Reliable Validators: Research validator performance and commission rates
- Regular Updates: Keep the pool updated each epoch for accurate balances
- Monitor Health: Track validator performance and remove underperforming ones
- Check Pool Health: Verify the pool is regularly updated and has reasonable fees
- Handle Errors Gracefully: Account for temporary failures and retry logic
- Respect Compute Limits: Batch operations appropriately
- Validate Inputs: Always validate amounts and accounts before submitting
- Understand Fees: Review all applicable fees before depositing
- Check Pool Performance: Compare APY with direct staking
- Monitor Validator Set: Ensure the pool uses reputable validators
- Consider Liquidity: Pool tokens provide liquidity not available with direct staking
- Pool authorities should use multisig or hardware wallets
- Separate hot/cold wallet strategies for different operations
- Regular authority rotation following security best practices
- Withdrawal fees can only increase by 3/2 ratio per epoch
- Monitor fee changes and validator additions/removals
- Understand referral fee implications
- Pool performance depends on validator selection
- Diversify across multiple high-performing validators
- Monitor validator health and commission rates
This comprehensive guide covers all aspects of the Fogo Stake Pool program. For implementation examples and integration patterns, see the API Reference and API Reference.