Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7,439 changes: 3,567 additions & 3,872 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
RUST_TOOLCHAIN_NIGHTLY = nightly-2025-02-16
SOLANA_CLI_VERSION = 2.3.4
RUST_TOOLCHAIN_NIGHTLY = nightly-2025-05-09
SOLANA_CLI_VERSION = 3.0.6

nightly = +${RUST_TOOLCHAIN_NIGHTLY}

Expand Down
72 changes: 36 additions & 36 deletions clients/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,55 +8,55 @@ license = "Apache-2.0"
edition = "2021"

[dependencies]
agave-feature-set = "2.2"
bincode = "1.3.1"
borsh = "1.5.7"
clap = { version = "3.2.23", features = ["derive"] }
agave-feature-set = "3.1"
bincode = "1.3.3"
borsh = "1.6.0"
clap = { version = "3.2.25", features = ["derive"] }
console = "0.16.1"
serde = "1.0.219"
serde_derive = "1.0.103"
serde = "1.0.228"
serde_derive = "1.0.228"
serde_json = "1.0.145"
serde_with = "3.16.0"
solana-account = "2.2"
solana-account-decoder = "2.3.4"
serde_with = "3.16.1"
solana-account = "3.2"
solana-account-decoder = "3.1.3"
solana-borsh = "3.0"
solana-clap-v3-utils = "2.3.4"
solana-cli-config = "2.3.4"
solana-cli-output = "2.3.4"
solana-client = "2.3.4"
solana-clock = "2.2"
solana-commitment-config = "2.2"
solana-epoch-schedule = "2.2"
solana-instruction = "2.2"
solana-keypair = "2.2"
solana-clap-v3-utils = { version = "3.1.3", features = ["agave-unstable-api"] }
solana-cli-config = "3.1.3"
solana-cli-output = { version = "3.1.3", features = ["agave-unstable-api"] }
solana-client = "3.1.3"
solana-clock = "3.0"
solana-commitment-config = "3.1"
solana-epoch-schedule = "3.0"
solana-instruction = "3.0"
solana-keypair = "3.0"
solana-logger = "3.0"
solana-native-token = "3.0"
solana-pubkey = "2.2"
solana-remote-wallet = "2.3.4"
solana-rent = "2.2"
solana-sdk-ids = "2.2"
solana-signature = "2.3"
solana-signer = "2.2"
solana-system-interface = "1.0"
solana-sysvar = "2.2"
solana-stake-interface = "1.2.0"
solana-stake-program = "3.0"
solana-transaction = "2.2"
solana-transaction-status = "2.3.4"
solana-vote-program = "2.2"
spl-associated-token-account-interface = "1.0.0"
spl-token = { version = "8.0", features = ["no-entrypoint"] }
spl-token-client = { version = "0.16.1" }
solana-pubkey = "4.0"
solana-remote-wallet = "3.1.3"
solana-rent = "3.0"
solana-sdk-ids = "3.1"
solana-signature = "3.1"
solana-signer = "3.0"
solana-system-interface = "3.0"
solana-sysvar = "3.1"
solana-stake-interface = "2.0.1"
solana-stake-program = "3.1"
solana-transaction = "3.0"
solana-transaction-status = "3.1.3"
solana-vote-program = "3.1"
spl-associated-token-account-interface = "2.0.0"
spl-token = { version = "9.0", features = ["no-entrypoint"] }
spl-token-client = { version = "0.18.0" }
spl-single-pool = { version = "3.0.0", path = "../../program", features = [
"no-entrypoint",
] }
tokio = "1.48"

[dev-dependencies]
solana-test-validator = "2.3.4"
solana-test-validator = "3.1.3"
serial_test = "3.2.0"
test-case = "3.3"
tempfile = "3.20.0"
tempfile = "3.23.0"

[[bin]]
name = "spl-single-pool"
Expand Down
9 changes: 6 additions & 3 deletions clients/cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(clippy::arithmetic_side_effects)]
#![allow(clippy::uninlined_format_args)]

use {
clap::{ArgMatches, CommandFactory, Parser},
Expand All @@ -16,7 +17,7 @@ use {
solana_signer::Signer,
solana_stake_interface as stake,
solana_transaction::Transaction,
solana_vote_program::{self as vote_program, vote_state::VoteState},
solana_vote_program::{self as vote_program, vote_state::VoteStateV4},
spl_associated_token_account_interface::instruction::create_associated_token_account,
spl_single_pool::{
self, find_pool_address, find_pool_mint_address, find_pool_onramp_address,
Expand Down Expand Up @@ -117,7 +118,7 @@ async fn command_initialize(config: &Config, command_config: InitializeCli) -> C
match get_initialized_account(config, vote_account_address).await? {
Some(vote_account)
if vote_account.owner == vote_program::id()
&& VoteState::deserialize(&vote_account.data).is_ok() => {}
&& VoteStateV4::deserialize(&vote_account.data, &vote_account_address).is_ok() => {}
_ => return Err(format!("{} is not a valid vote account", vote_account_address).into()),
}

Expand Down Expand Up @@ -645,7 +646,8 @@ async fn command_update_metadata(
.get_account(vote_account_address)
.await?
{
let vote_account = VoteState::deserialize(&vote_account_data.data)?;
let vote_account =
VoteStateV4::deserialize(&vote_account_data.data, &vote_account_address)?;

if authorized_withdrawer.pubkey() != vote_account.authorized_withdrawer {
return Err(format!(
Expand Down Expand Up @@ -777,6 +779,7 @@ async fn command_display(config: &Config, command_config: DisplayCli) -> Command
let minimum_pool_balance = quarantine::get_minimum_pool_balance(config).await?;
let pool_and_vote_addresses = if command_config.all {
// the filter isn't necessary now but makes the cli forward-compatible
#[allow(deprecated)]
let pools = config
.rpc_client
.get_program_accounts_with_config(
Expand Down
8 changes: 4 additions & 4 deletions clients/cli/tests/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use {
solana_transaction::Transaction,
solana_vote_program::{
vote_instruction::{self, CreateVoteAccountConfig},
vote_state::{VoteInit, VoteState},
vote_state::{VoteInit, VoteStateV4},
},
spl_single_pool::{
id,
Expand Down Expand Up @@ -126,7 +126,7 @@ async fn start_validator(raise_minimum_delegation: bool) -> (TestValidator, Keyp

async fn wait_for_next_epoch(rpc_client: &RpcClient) -> Epoch {
let current_epoch = rpc_client.get_epoch_info().await.unwrap().epoch;
println!("current epoch {}, advancing to next...", current_epoch);
println!("current epoch {current_epoch}, advancing to next...");
loop {
let epoch_info = rpc_client.get_epoch_info().await.unwrap();
if epoch_info.epoch > current_epoch && epoch_info.slot_index > 0 {
Expand All @@ -152,7 +152,7 @@ async fn create_vote_account(
.unwrap();

let vote_rent = rpc_client
.get_minimum_balance_for_rent_exemption(VoteState::size_of() * 2)
.get_minimum_balance_for_rent_exemption(VoteStateV4::size_of() * 2)
.await
.unwrap();

Expand All @@ -176,7 +176,7 @@ async fn create_vote_account(
},
vote_rent,
CreateVoteAccountConfig {
space: VoteState::size_of() as u64,
space: VoteStateV4::size_of() as u64,
..Default::default()
},
));
Expand Down
45 changes: 23 additions & 22 deletions program/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,42 @@ edition = "2021"

[features]
no-entrypoint = []
custom-heap = []
custom-panic = []
Comment on lines 10 to +13
Copy link
Member Author

@2501babe 2501babe Nov 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

someone on stack exchange claims you dont need this to silence warnings on the latest solana-program-entrypoint but we are on latest so i dont think thats true


[dependencies]
arrayref = "0.3.9"
borsh = "1.5.7"
borsh = "1.6.0"
num-derive = "0.4"
num-traits = "0.2"
num_enum = "0.7.4"
solana-account-info = "2.3"
num_enum = "0.7.5"
solana-account-info = "3.1"
solana-borsh = "3.0"
solana-clock = "2.2"
solana-cpi = "2.2"
solana-instruction = "2.2"
solana-clock = "3.0"
solana-cpi = "3.1"
solana-instruction = "3.0"
solana-msg = "3.0"
solana-native-token = "3.0"
solana-program-entrypoint = "2.3"
solana-program-error = "2.2"
solana-program-pack = "2.2"
solana-pubkey = { version = "2.2", features = ["borsh", "curve25519"] }
solana-rent = "2.2"
solana-stake-interface = { version = "1.2.1", features = ["borsh"] }
solana-system-interface = "1.0.0"
solana-sysvar = "2.2"
solana-vote-interface = "2.2.6"
solana-program-entrypoint = "3.1"
solana-program-error = "3.0"
solana-program-pack = "3.0"
solana-pubkey = { version = "4.0", features = ["borsh", "curve25519"] }
solana-rent = "3.0"
solana-stake-interface = { version = "2.0.1", features = ["bincode", "borsh", "sysvar"] }
solana-system-interface = { version = "3.0.0", features = ["bincode"] }
solana-sysvar = "3.1"
solana-vote-interface = { version = "4.0.4", features = ["bincode"] }
solana-security-txt = "1.1.2"
spl-token = { version = "8.0", features = ["no-entrypoint"] }
spl-token-interface = "2.0.0"
thiserror = "2.0"

[dev-dependencies]
agave-feature-set = "2.2"
solana-program-test = "2.3.4"
solana-sdk = "2.2"
spl-associated-token-account = { version = "7.0.0", features = ["no-entrypoint"] }
spl-associated-token-account-client = { version = "2.0.0" }
agave-feature-set = "3.1"
solana-program-test = { version = "3.1.3", features = ["agave-unstable-api"] }
solana-sdk = "3.0"
spl-associated-token-account-interface = "2.0.0"
test-case = "3.3"
bincode = "1.3.1"
bincode = "1.3.3"
rand = "0.9.2"
approx = "0.5.1"

Expand Down
1 change: 0 additions & 1 deletion program/src/entrypoint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use {
solana_account_info::AccountInfo,
solana_msg::msg,
solana_program_entrypoint::{entrypoint, ProgramResult},
solana_program_error::ToStr,
solana_pubkey::Pubkey,
solana_security_txt::security_txt,
};
Expand Down
2 changes: 1 addition & 1 deletion program/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ impl From<SinglePoolError> for ProgramError {
}
}
impl ToStr for SinglePoolError {
fn to_str<E>(&self) -> &'static str {
fn to_str(&self) -> &'static str {
match self {
SinglePoolError::InvalidPoolAccount =>
"Error: Provided pool account has the wrong address for its vote account, is uninitialized, \
Expand Down
10 changes: 5 additions & 5 deletions program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ use {
solana_program_pack::Pack,
solana_pubkey::Pubkey,
solana_rent::Rent,
solana_stake_interface as stake,
solana_stake_interface::{self as stake, sysvar::stake_history},
solana_system_interface::{instruction as system_instruction, program as system_program},
solana_sysvar as sysvar,
solana_sysvar as sysvar, spl_token_interface as spl_token,
};

/// Instructions supported by the `SinglePool` program.
Expand Down Expand Up @@ -223,7 +223,7 @@ pub fn initialize_pool(program_id: &Pubkey, vote_account_address: &Pubkey) -> In
),
AccountMeta::new_readonly(sysvar::rent::id(), false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(stake_history::id(), false),
#[allow(deprecated)]
AccountMeta::new_readonly(stake::config::id(), false),
AccountMeta::new_readonly(system_program::id(), false),
Expand Down Expand Up @@ -253,7 +253,7 @@ pub fn replenish_pool(program_id: &Pubkey, vote_account_address: &Pubkey) -> Ins
false,
),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(stake_history::id(), false),
#[allow(deprecated)]
AccountMeta::new_readonly(stake::config::id(), false),
AccountMeta::new_readonly(stake::program::id(), false),
Expand Down Expand Up @@ -329,7 +329,7 @@ pub fn deposit_stake(
AccountMeta::new(*user_token_account, false),
AccountMeta::new(*user_lamport_account, false),
AccountMeta::new_readonly(sysvar::clock::id(), false),
AccountMeta::new_readonly(sysvar::stake_history::id(), false),
AccountMeta::new_readonly(stake_history::id(), false),
AccountMeta::new_readonly(spl_token::id(), false),
AccountMeta::new_readonly(stake::program::id(), false),
];
Expand Down
13 changes: 7 additions & 6 deletions program/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use {
borsh::BorshDeserialize,
solana_account_info::{next_account_info, AccountInfo},
solana_borsh::v1::{get_packed_len, try_from_slice_unchecked},
solana_clock::Epoch,
solana_clock::{Clock, Epoch},
solana_cpi::invoke_signed,
solana_msg::msg,
solana_native_token::LAMPORTS_PER_SOL,
Expand All @@ -31,11 +31,12 @@ use {
solana_stake_interface::{
self as stake,
state::{Meta, Stake, StakeActivationStatus, StakeStateV2},
sysvar::stake_history::StakeHistorySysvar,
},
solana_system_interface::{instruction as system_instruction, program as system_program},
solana_sysvar::{clock::Clock, stake_history::StakeHistorySysvar, Sysvar},
solana_sysvar::SysvarSerialize,
solana_vote_interface::program as vote_program,
spl_token::state::Mint,
spl_token_interface::{self as spl_token, state::Mint},
};

/// Calculate pool tokens to mint, given outstanding token supply, pool active
Expand Down Expand Up @@ -248,8 +249,9 @@ fn check_vote_account(vote_account_info: &AccountInfo) -> Result<(), ProgramErro
.and_then(|s| s.try_into().ok())
.ok_or(SinglePoolError::UnparseableVoteAccount)?;

#[allow(clippy::manual_range_patterns)]
match u32::from_le_bytes(state_variant) {
1 | 2 => Ok(()),
1 | 2 | 3 => Ok(()),
0 => Err(SinglePoolError::LegacyVoteAccount.into()),
_ => Err(SinglePoolError::UnparseableVoteAccount.into()),
}
Comment on lines 253 to 257
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this gives us VoteStateV4 support, it was necessary to do in this pr to get tests to pass. in the future it would be cleaner to switch to the VoteState parser though, which did not exist when this program was originally written. i didnt want to make any nontrivial functional changes in this one

Expand Down Expand Up @@ -1635,8 +1637,7 @@ mod tests {
#[test_case(rand::random(), true, true; "no_minimum")]
fn random_deposit_withdraw(seed: u64, with_rewards: bool, no_minimum: bool) {
println!(
"TEST SEED: {}. edit the test case to pass this value if needed to debug failures",
seed
"TEST SEED: {seed}. edit the test case to pass this value if needed to debug failures",
);
let mut prng = rand::rngs::StdRng::seed_from_u64(seed);

Expand Down
1 change: 1 addition & 0 deletions program/tests/accounts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use {
find_pool_onramp_address, id,
instruction::{self, SinglePoolInstruction},
},
spl_token_interface as spl_token,
test_case::test_case,
};

Expand Down
4 changes: 2 additions & 2 deletions program/tests/create_pool_token_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ use {
helpers::*,
solana_program_test::*,
solana_sdk::{
instruction::InstructionError, pubkey::Pubkey, signature::Signer,
system_instruction::SystemError, transaction::Transaction,
instruction::InstructionError, pubkey::Pubkey, signature::Signer, transaction::Transaction,
},
solana_system_interface::error::SystemError,
spl_single_pool::{id, instruction},
};

Expand Down
5 changes: 2 additions & 3 deletions program/tests/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use {
solana_sdk::{signature::Signer, signer::keypair::Keypair, transaction::Transaction},
solana_stake_interface::state::{Authorized, Lockup},
solana_system_interface::instruction as system_instruction,
spl_associated_token_account_client::address as atoken,
spl_associated_token_account_interface::address::get_associated_token_address,
spl_single_pool::{error::SinglePoolError, id, instruction},
test_case::test_case,
};
Expand Down Expand Up @@ -320,8 +320,7 @@ async fn fail_uninitialized(activate: bool) {
)
.await;

let token_account =
atoken::get_associated_token_address(&context.payer.pubkey(), &accounts.mint);
let token_account = get_associated_token_address(&context.payer.pubkey(), &accounts.mint);

create_independent_stake_account(
&mut context.banks_client,
Expand Down
Loading