spl_single_pool/
lib.rs

1#![deny(missing_docs)]
2
3//! A program for liquid staking with a single validator
4
5pub mod error;
6pub mod inline_mpl_token_metadata;
7pub mod instruction;
8pub mod processor;
9pub mod state;
10
11#[cfg(not(feature = "no-entrypoint"))]
12pub mod entrypoint;
13
14use {solana_pubkey::Pubkey, solana_stake_interface as stake};
15
16solana_pubkey::declare_id!("SVSPxpvHdN29nkVg9rPapPNDddN5DipNLRUFhyjFThE");
17
18const POOL_PREFIX: &[u8] = b"pool";
19const POOL_STAKE_PREFIX: &[u8] = b"stake";
20const POOL_ONRAMP_PREFIX: &[u8] = b"onramp";
21const POOL_MINT_PREFIX: &[u8] = b"mint";
22const POOL_MINT_AUTHORITY_PREFIX: &[u8] = b"mint_authority";
23const POOL_STAKE_AUTHORITY_PREFIX: &[u8] = b"stake_authority";
24const POOL_MPL_AUTHORITY_PREFIX: &[u8] = b"mpl_authority";
25
26const MINT_DECIMALS: u8 = 9;
27const PERPETUAL_NEW_WARMUP_COOLDOWN_RATE_EPOCH: Option<u64> = Some(0);
28
29const VOTE_STATE_DISCRIMINATOR_END: usize = 4;
30const VOTE_STATE_AUTHORIZED_WITHDRAWER_START: usize = 36;
31const VOTE_STATE_AUTHORIZED_WITHDRAWER_END: usize = 68;
32
33fn find_pool_address_and_bump(program_id: &Pubkey, vote_account_address: &Pubkey) -> (Pubkey, u8) {
34    Pubkey::find_program_address(&[POOL_PREFIX, vote_account_address.as_ref()], program_id)
35}
36
37fn find_pool_stake_address_and_bump(program_id: &Pubkey, pool_address: &Pubkey) -> (Pubkey, u8) {
38    Pubkey::find_program_address(&[POOL_STAKE_PREFIX, pool_address.as_ref()], program_id)
39}
40
41fn find_pool_onramp_address_and_bump(program_id: &Pubkey, pool_address: &Pubkey) -> (Pubkey, u8) {
42    Pubkey::find_program_address(&[POOL_ONRAMP_PREFIX, pool_address.as_ref()], program_id)
43}
44
45fn find_pool_mint_address_and_bump(program_id: &Pubkey, pool_address: &Pubkey) -> (Pubkey, u8) {
46    Pubkey::find_program_address(&[POOL_MINT_PREFIX, pool_address.as_ref()], program_id)
47}
48
49fn find_pool_stake_authority_address_and_bump(
50    program_id: &Pubkey,
51    pool_address: &Pubkey,
52) -> (Pubkey, u8) {
53    Pubkey::find_program_address(
54        &[POOL_STAKE_AUTHORITY_PREFIX, pool_address.as_ref()],
55        program_id,
56    )
57}
58
59fn find_pool_mint_authority_address_and_bump(
60    program_id: &Pubkey,
61    pool_address: &Pubkey,
62) -> (Pubkey, u8) {
63    Pubkey::find_program_address(
64        &[POOL_MINT_AUTHORITY_PREFIX, pool_address.as_ref()],
65        program_id,
66    )
67}
68
69fn find_pool_mpl_authority_address_and_bump(
70    program_id: &Pubkey,
71    pool_address: &Pubkey,
72) -> (Pubkey, u8) {
73    Pubkey::find_program_address(
74        &[POOL_MPL_AUTHORITY_PREFIX, pool_address.as_ref()],
75        program_id,
76    )
77}
78
79fn find_default_deposit_account_address_and_seed(
80    pool_address: &Pubkey,
81    user_wallet_address: &Pubkey,
82) -> (Pubkey, String) {
83    let pool_address_str = pool_address.to_string();
84    let seed = format!("svsp{}", &pool_address_str[0..28]);
85    let address =
86        Pubkey::create_with_seed(user_wallet_address, &seed, &stake::program::id()).unwrap();
87
88    (address, seed)
89}
90
91/// Find the canonical pool address for a given vote account.
92pub fn find_pool_address(program_id: &Pubkey, vote_account_address: &Pubkey) -> Pubkey {
93    find_pool_address_and_bump(program_id, vote_account_address).0
94}
95
96/// Find the canonical main stake account address for a given pool account.
97pub fn find_pool_stake_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
98    find_pool_stake_address_and_bump(program_id, pool_address).0
99}
100
101/// Find the canonical stake on-ramp account address for a given pool account.
102pub fn find_pool_onramp_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
103    find_pool_onramp_address_and_bump(program_id, pool_address).0
104}
105
106/// Find the canonical token mint address for a given pool account.
107pub fn find_pool_mint_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
108    find_pool_mint_address_and_bump(program_id, pool_address).0
109}
110
111/// Find the canonical stake authority address for a given pool account.
112pub fn find_pool_stake_authority_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
113    find_pool_stake_authority_address_and_bump(program_id, pool_address).0
114}
115
116/// Find the canonical mint authority address for a given pool account.
117pub fn find_pool_mint_authority_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
118    find_pool_mint_authority_address_and_bump(program_id, pool_address).0
119}
120
121/// Find the canonical MPL authority address for a given pool account.
122pub fn find_pool_mpl_authority_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
123    find_pool_mpl_authority_address_and_bump(program_id, pool_address).0
124}
125
126/// Find the address of the default intermediate account that holds activating
127/// user stake before deposit.
128#[deprecated(
129    since = "3.0.0",
130    note = "Default deposit helpers will be removed in a future release; these were \
131    intended to support a wallet flow that never materialized. To set up a new stake \
132    account for deposit, use `instruction::create_account_and_delegate_stake` from \
133    `solana-stake-interface` using any normal keypair."
134)]
135pub fn find_default_deposit_account_address(
136    pool_address: &Pubkey,
137    user_wallet_address: &Pubkey,
138) -> Pubkey {
139    find_default_deposit_account_address_and_seed(pool_address, user_wallet_address).0
140}