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
14// export current sdk types for downstream users building with a different sdk
15// version
16pub use solana_program;
17use solana_program::{pubkey::Pubkey, stake};
18
19solana_program::declare_id!("SVSPxpvHdN29nkVg9rPapPNDddN5DipNLRUFhyjFThE");
20
21const POOL_PREFIX: &[u8] = b"pool";
22const POOL_STAKE_PREFIX: &[u8] = b"stake";
23const POOL_ONRAMP_PREFIX: &[u8] = b"onramp";
24const POOL_MINT_PREFIX: &[u8] = b"mint";
25const POOL_MINT_AUTHORITY_PREFIX: &[u8] = b"mint_authority";
26const POOL_STAKE_AUTHORITY_PREFIX: &[u8] = b"stake_authority";
27const POOL_MPL_AUTHORITY_PREFIX: &[u8] = b"mpl_authority";
28
29const MINT_DECIMALS: u8 = 9;
30const PERPETUAL_NEW_WARMUP_COOLDOWN_RATE_EPOCH: Option<u64> = Some(0);
31
32const VOTE_STATE_DISCRIMINATOR_END: usize = 4;
33const VOTE_STATE_AUTHORIZED_WITHDRAWER_START: usize = 36;
34const VOTE_STATE_AUTHORIZED_WITHDRAWER_END: usize = 68;
35
36fn find_pool_address_and_bump(program_id: &Pubkey, vote_account_address: &Pubkey) -> (Pubkey, u8) {
37    Pubkey::find_program_address(&[POOL_PREFIX, vote_account_address.as_ref()], program_id)
38}
39
40fn find_pool_stake_address_and_bump(program_id: &Pubkey, pool_address: &Pubkey) -> (Pubkey, u8) {
41    Pubkey::find_program_address(&[POOL_STAKE_PREFIX, pool_address.as_ref()], program_id)
42}
43
44fn find_pool_onramp_address_and_bump(program_id: &Pubkey, pool_address: &Pubkey) -> (Pubkey, u8) {
45    Pubkey::find_program_address(&[POOL_ONRAMP_PREFIX, pool_address.as_ref()], program_id)
46}
47
48fn find_pool_mint_address_and_bump(program_id: &Pubkey, pool_address: &Pubkey) -> (Pubkey, u8) {
49    Pubkey::find_program_address(&[POOL_MINT_PREFIX, pool_address.as_ref()], program_id)
50}
51
52fn find_pool_stake_authority_address_and_bump(
53    program_id: &Pubkey,
54    pool_address: &Pubkey,
55) -> (Pubkey, u8) {
56    Pubkey::find_program_address(
57        &[POOL_STAKE_AUTHORITY_PREFIX, pool_address.as_ref()],
58        program_id,
59    )
60}
61
62fn find_pool_mint_authority_address_and_bump(
63    program_id: &Pubkey,
64    pool_address: &Pubkey,
65) -> (Pubkey, u8) {
66    Pubkey::find_program_address(
67        &[POOL_MINT_AUTHORITY_PREFIX, pool_address.as_ref()],
68        program_id,
69    )
70}
71
72fn find_pool_mpl_authority_address_and_bump(
73    program_id: &Pubkey,
74    pool_address: &Pubkey,
75) -> (Pubkey, u8) {
76    Pubkey::find_program_address(
77        &[POOL_MPL_AUTHORITY_PREFIX, pool_address.as_ref()],
78        program_id,
79    )
80}
81
82fn find_default_deposit_account_address_and_seed(
83    pool_address: &Pubkey,
84    user_wallet_address: &Pubkey,
85) -> (Pubkey, String) {
86    let pool_address_str = pool_address.to_string();
87    let seed = format!("svsp{}", &pool_address_str[0..28]);
88    let address =
89        Pubkey::create_with_seed(user_wallet_address, &seed, &stake::program::id()).unwrap();
90
91    (address, seed)
92}
93
94/// Find the canonical pool address for a given vote account.
95pub fn find_pool_address(program_id: &Pubkey, vote_account_address: &Pubkey) -> Pubkey {
96    find_pool_address_and_bump(program_id, vote_account_address).0
97}
98
99/// Find the canonical main stake account address for a given pool account.
100pub fn find_pool_stake_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
101    find_pool_stake_address_and_bump(program_id, pool_address).0
102}
103
104/// Find the canonical stake on-ramp account address for a given pool account.
105pub fn find_pool_onramp_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
106    find_pool_onramp_address_and_bump(program_id, pool_address).0
107}
108
109/// Find the canonical token mint address for a given pool account.
110pub fn find_pool_mint_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
111    find_pool_mint_address_and_bump(program_id, pool_address).0
112}
113
114/// Find the canonical stake authority address for a given pool account.
115pub fn find_pool_stake_authority_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
116    find_pool_stake_authority_address_and_bump(program_id, pool_address).0
117}
118
119/// Find the canonical mint authority address for a given pool account.
120pub fn find_pool_mint_authority_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
121    find_pool_mint_authority_address_and_bump(program_id, pool_address).0
122}
123
124/// Find the canonical MPL authority address for a given pool account.
125pub fn find_pool_mpl_authority_address(program_id: &Pubkey, pool_address: &Pubkey) -> Pubkey {
126    find_pool_mpl_authority_address_and_bump(program_id, pool_address).0
127}
128
129/// Find the address of the default intermediate account that holds activating
130/// user stake before deposit.
131pub fn find_default_deposit_account_address(
132    pool_address: &Pubkey,
133    user_wallet_address: &Pubkey,
134) -> Pubkey {
135    find_default_deposit_account_address_and_seed(pool_address, user_wallet_address).0
136}