|
| 1 | +--- |
| 2 | +title: Operation |
| 3 | +--- |
| 4 | + |
| 5 | +Stake pools are an alternative method of earning staking rewards. This on-chain |
| 6 | +program pools together SOL to be staked by a staker, allowing SOL holders to |
| 7 | +stake and earn rewards without managing stakes. |
| 8 | + |
| 9 | +## Staking |
| 10 | + |
| 11 | +SOL token holders can earn rewards and help secure the network by staking tokens |
| 12 | +to one or more validators. Rewards for staked tokens are based on the current |
| 13 | +inflation rate, total number of SOL staked on the network, and an individual |
| 14 | +validator’s uptime and commission (fee). |
| 15 | + |
| 16 | +Additional information regarding staking and stake programming is available at: |
| 17 | + |
| 18 | +- https://solana.com/staking |
| 19 | +- https://docs.solana.com/staking/stake-programming |
| 20 | + |
| 21 | +## Background |
| 22 | + |
| 23 | +Solana's programming model and the definitions of the Solana terms used in this |
| 24 | +document are available at: |
| 25 | + |
| 26 | +- https://docs.solana.com/apps |
| 27 | +- https://docs.solana.com/terminology |
| 28 | + |
| 29 | +## Motivation |
| 30 | + |
| 31 | +This document is intended for the main actors of the stake pool system: |
| 32 | + |
| 33 | +* manager: creates and manages the stake pool, earns fees, can update the fee, staker, and manager |
| 34 | +* staker: adds and removes validators to the pool, rebalances stake among validators |
| 35 | +* user: provides staked SOL into an existing stake pool |
| 36 | + |
| 37 | +In its current iteration, the stake pool accepts active stakes or SOL, so |
| 38 | +deposits may come from either an active stake or SOL wallet. Withdrawals |
| 39 | +can return a fully active stake account from one of the stake pool's accounts, |
| 40 | +or SOL from the reserve. |
| 41 | + |
| 42 | +This means that stake pool managers and stakers must be comfortable with |
| 43 | +creating and delegating stakes, which are more advanced operations than sending and |
| 44 | +receiving SPL tokens and SOL. Additional information on stake operations are |
| 45 | +available at: |
| 46 | + |
| 47 | +- https://docs.solana.com/cli/delegate-stake |
| 48 | +- https://docs.solana.com/cli/manage-stake-accounts |
| 49 | + |
| 50 | +To reach a wider audience of users, stake pool managers are encouraged |
| 51 | +to provide a market for their pool's tokens, through an AMM |
| 52 | +like [Token Swap](../token-swap.md). |
| 53 | + |
| 54 | +Alternatively, stake pool managers can partner with wallet and stake account |
| 55 | +providers for direct SOL deposits. |
| 56 | + |
| 57 | +## Operation |
| 58 | + |
| 59 | +A stake pool manager creates a stake pool, and the staker includes validators that will |
| 60 | +receive delegations from the pool by adding "validator stake accounts" to the pool |
| 61 | +using the `add-validator` instruction. In this command, the stake pool creates |
| 62 | +a new stake account and delegates it to the desired validator. |
| 63 | + |
| 64 | +At this point, users can participate with deposits. They can directly deposit |
| 65 | +SOL into the stake pool using the `deposit-sol` instruction. Within this instruction, |
| 66 | +the stake pool will move SOL into the pool's reserve account, to be redistributed |
| 67 | +by the staker. |
| 68 | + |
| 69 | +Alternatively, users can deposit a stake account into the pool. To do this, |
| 70 | +they must delegate a stake account to the one of the validators in the stake pool. |
| 71 | +If the stake pool has a preferred deposit validator, the user must delegate their |
| 72 | +stake to that validator's vote account. |
| 73 | + |
| 74 | +Once the stake becomes active, which happens at the following epoch boundary |
| 75 | +(maximum 2 days), the user can deposit their stake into the pool using the |
| 76 | +`deposit-stake` instruction. |
| 77 | + |
| 78 | +In exchange for their deposit (SOL or stake), the user receives SPL tokens |
| 79 | +representing their fractional ownership in pool. A percentage of the rewards |
| 80 | +earned by the pool goes to the pool manager as an epoch fee. |
| 81 | + |
| 82 | +Over time, as the stakes in the pool accrue rewards, the user's fractional |
| 83 | +ownership will be worth more than their initial deposit. |
| 84 | + |
| 85 | +Whenever they wish to exit the pool, the user may use the `withdraw-sol` instruction |
| 86 | +to receive SOL from the stake pool's reserve in exchange for stake pool tokens. |
| 87 | +Note that this operation will fail if there is not enough SOL in the stake pool's |
| 88 | +reserve, which is normal if the stake pool manager stakes all of the SOL in the pool. |
| 89 | + |
| 90 | +Alternatively, they can use the `withdraw-stake` instruction to withdraw an |
| 91 | +activated stake account in exchange for their SPL pool tokens. The user will get |
| 92 | +back a SOL stake account immediately. The ability to withdraw stake is always |
| 93 | +possible, under all circumstances. |
| 94 | + |
| 95 | +Note: when withdrawing stake, if the user wants to withdraw the SOL in the stake |
| 96 | +account, they must first deactivate the stake account and wait until the next |
| 97 | +epoch boundary (maximum 2 days). Once the stake is inactive, they can freely |
| 98 | +withdraw the SOL. |
| 99 | + |
| 100 | +The stake pool staker can add and remove validators, or rebalance the pool by |
| 101 | +decreasing the stake on a validator, waiting an epoch to move it into the stake |
| 102 | +pool's reserve account, then increasing the stake on another validator. |
| 103 | + |
| 104 | +The staker operation to add a new validator requires 0.00328288 SOL to create |
| 105 | +the stake account on a validator, so the stake pool staker will need liquidity |
| 106 | +on hand to fully manage the pool stakes. The SOL used to add a new validator |
| 107 | +is recovered when removing the validator. |
| 108 | + |
| 109 | +### Fees |
| 110 | + |
| 111 | +The stake pool program provides managers many options for making the pool |
| 112 | +financially viable, predominantly through fees. There are five different sources |
| 113 | +of fees: |
| 114 | + |
| 115 | +* Epoch: every epoch (roughly 2 days), the stake accounts in the pool earn |
| 116 | + inflation rewards, so the stake pool mints pool tokens into the manager's fee |
| 117 | + account as a proportion of the earned rewards. For example, if the pool earns |
| 118 | + 10 SOL in rewards, and the fee is set to 2%, the manager will earn pool tokens |
| 119 | + worth 0.2 SOL. |
| 120 | +* SOL withdraw: sends a proportion of the desired withdrawal amount to the manager |
| 121 | + For example, if a user wishes to withdraw 100 pool tokens, and the fee is set |
| 122 | + to 3%, 3 pool tokens go to the manager, and the remaining 97 tokens go to the |
| 123 | + user in the form of a SOL. |
| 124 | +* Stake withdraw: sends a proportion of the desired withdrawal amount to the manager |
| 125 | + before creating a new stake for the user. |
| 126 | +* SOL deposit: converts the entire SOL deposit into pool tokens, then sends a |
| 127 | + proportion of those to the manager, and the rest to the user |
| 128 | +* Stake deposit: converts the stake account's delegation plus rent-exemption |
| 129 | + to pool tokens, sends a proportion of those to the manager, and the rest to |
| 130 | + the user |
| 131 | + |
| 132 | +For partner applications, there's the option of a referral fee on deposits. |
| 133 | +During SOL or stake deposits, the stake pool can redistribute a percentage of |
| 134 | +the fees to another address as a referral fee. |
| 135 | + |
| 136 | +This option is particularly attractive for wallet providers. When a wallet |
| 137 | +integrates a stake pool, the wallet developer will have the option to earn |
| 138 | +additional tokens anytime a user deposits into the stake pool. Stake pool |
| 139 | +managers can use this feature to create strategic partnerships and entice |
| 140 | +greater adoption of stake pools! |
| 141 | + |
| 142 | +### Funding restrictions |
| 143 | + |
| 144 | +To give the manager more control over funds entering the pool, stake pools allow |
| 145 | +deposit and withdrawal restrictions on SOL and stakes through three different |
| 146 | +"funding authorities": |
| 147 | + |
| 148 | +* SOL deposit |
| 149 | +* Stake deposit |
| 150 | +* SOL withdrawal |
| 151 | + |
| 152 | +If the field is set, that authority must sign the associated instruction. |
| 153 | + |
| 154 | +For example, if the manager sets a stake deposit authority, then that address |
| 155 | +must sign every stake deposit instruction. |
| 156 | + |
| 157 | +This can also be useful in a few situations: |
| 158 | + |
| 159 | +* Control who deposits into the stake pool |
| 160 | +* Prohibit a form of deposit. For example, the manager only wishes to have SOL |
| 161 | + deposits, so they set a stake deposit authority, making it only possible to |
| 162 | + deposit a stake account if that authority signs the transaction. |
| 163 | +* Maintenance mode. If the pool needs time to reset fees or otherwise, the |
| 164 | + manager can temporarily restrict new deposits by setting deposit authorities. |
| 165 | + |
| 166 | +Note: in order to keep user funds safe, stake withdrawals are always permitted. |
| 167 | + |
| 168 | +## Security Audits |
| 169 | + |
| 170 | +Multiple security firms have audited the stake pool program to ensure total |
| 171 | +safety of funds. The audit reports are available for reading, presented in descending |
| 172 | +chronological order, and the commit hash that each was reviewed at: |
| 173 | + |
| 174 | +* Quantstamp |
| 175 | + - Initial review commit hash [`99914c9`](https://github.com/solana-labs/solana-program-library/tree/99914c9fc7246b22ef04416586ab1722c89576de) |
| 176 | + - Re-review commit hash [`3b48fa0`](https://github.com/solana-labs/solana-program-library/tree/3b48fa09d38d1b66ffb4fef186b606f1bc4fdb31) |
| 177 | + - Final report https://solana.com/SolanaQuantstampStakePoolAudit.pdf |
| 178 | +* Neodyme |
| 179 | + - Review commit hash [`0a85a9a`](https://github.com/solana-labs/solana-program-library/tree/0a85a9a533795b6338ea144e433893c6c0056210) |
| 180 | + - Report https://solana.com/SolanaNeodymeStakePoolAudit.pdf |
| 181 | +* Kudelski |
| 182 | + - Review commit hash [`3dd6767`](https://github.com/solana-labs/solana-program-library/tree/3dd67672974f92d3b648bb50ee74f4747a5f8973) |
| 183 | + - Report https://solana.com/SolanaKudelskiStakePoolAudit.pdf |
| 184 | + |
| 185 | +## Safety of Funds |
| 186 | + |
| 187 | +One of the primary aims of the stake pool program is to always allow pool token |
| 188 | +holders to withdraw their funds at any time. |
| 189 | + |
| 190 | +To that end, let's look at the three classes of stake accounts in the stake pool system: |
| 191 | + |
| 192 | +* validator stake: active stake accounts, one per validator in the pool |
| 193 | +* transient stake: activating or deactivating stake accounts, merged into the reserve after deactivation, or into the validator stake after activation, one per validator |
| 194 | +* reserve stake: inactive stake, to be used by the staker for rebalancing |
| 195 | + |
| 196 | +Additionally, the staker may set a "preferred withdraw account", which forces users |
| 197 | +to withdraw from a particular stake account. This is to prevent malicious |
| 198 | +depositors from using the stake pool as a free conversion between validators. |
| 199 | + |
| 200 | +When processing withdrawals, the order of priority goes: |
| 201 | + |
| 202 | +* preferred withdraw validator stake account (if set) |
| 203 | +* validator stake accounts |
| 204 | +* transient stake accounts |
| 205 | +* reserve stake account |
| 206 | + |
| 207 | +If there is preferred withdraw validator, and that validator stake account has |
| 208 | +any SOL, a user must withdraw from that account. |
| 209 | + |
| 210 | +If that account is empty, or the preferred withdraw validator stake account is |
| 211 | +not set, then the user must withdraw from any validator stake account. |
| 212 | + |
| 213 | +If all validator stake accounts are empty, which may happen if the stake pool |
| 214 | +staker decreases the stake on all validators at once, then the user must withdraw |
| 215 | +from any transient stake account. |
| 216 | + |
| 217 | +If all transient stake accounts are empty, then the user must withdraw from the |
| 218 | +reserve. |
| 219 | + |
| 220 | +In this way, a user's funds are never at risk, and always redeemable. |
| 221 | + |
| 222 | +## Appendix |
| 223 | + |
| 224 | +### Active stakes |
| 225 | + |
| 226 | +As mentioned earlier, the stake pool works with active stakes to |
| 227 | +maintains fungibility of stake pool tokens. Fully activated stakes |
| 228 | +are not equivalent to inactive, activating, or deactivating stakes due to the |
| 229 | +time cost of staking. |
| 230 | + |
| 231 | +### Transient stake accounts |
| 232 | + |
| 233 | +Each validator gets one transient stake account, so the staker can only |
| 234 | +perform one action at a time on a validator. It's impossible to increase |
| 235 | +and decrease the stake on a validator at the same time. The staker must wait for |
| 236 | +the existing transient stake account to get merged during an `update` instruction |
| 237 | +before performing a new action. |
| 238 | + |
| 239 | +### Reserve stake account |
| 240 | + |
| 241 | +Every stake pool is initialized with an undelegated reserve stake account, used |
| 242 | +to hold undelegated stake in process of rebalancing. After the staker decreases |
| 243 | +the stake on a validator, one epoch later, the update operation will merge the |
| 244 | +decreased stake into the reserve. Conversely, whenever the staker increases the |
| 245 | +stake on a validator, the lamports are drawn from the reserve stake account. |
| 246 | + |
| 247 | +### Validator list account |
| 248 | + |
| 249 | +Every stake pool contains two data accounts: the stake pool and the validator list. |
| 250 | + |
| 251 | +The stake pool contains overall information about the pool, including fees, |
| 252 | +pool token mint, amount under management, etc. |
| 253 | + |
| 254 | +The validator list contains specific information about each of the validator |
| 255 | +stake accounts in the pool. This information includes the amount of SOL staked on |
| 256 | +the validator by the pool, and the amount of SOL being activated / deactivated |
| 257 | +on the validator. |
| 258 | + |
| 259 | +Every stake pool must have its own validator list account, otherwise it will |
| 260 | +fail on initialization. |
| 261 | + |
| 262 | +### Transaction sizes |
| 263 | + |
| 264 | +The Solana transaction processor has two important limitations: |
| 265 | + |
| 266 | +* size of the overall transaction, limited to roughly 1 MTU / packet |
| 267 | +* computation budget per instruction |
| 268 | + |
| 269 | +A stake pool may manage hundreds of staking accounts, so it is impossible to |
| 270 | +update the total value of the stake pool in one instruction. Thankfully, the |
| 271 | +command-line utility breaks up transactions to avoid this issue for large pools. |
0 commit comments