forked from solana-labs/solana-program-library
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
stake-pool-docs: Rearrange docs, add quickstart guide (solana-labs#2561)
* stake-pool-docs: Rearrange docs, add quickstart guide * Rearrange doc sidebar
- Loading branch information
Showing
14 changed files
with
1,588 additions
and
1,352 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,24 @@ | ||
module.exports = { | ||
docs: { | ||
"Other Thing": [], | ||
"Solana Program Library (SPL)": [ | ||
"introduction", | ||
"token", | ||
"token-swap", | ||
"token-lending", | ||
"associated-token-account", | ||
"memo", | ||
"name-service", | ||
"shared-memory", | ||
"stake-pool", | ||
"feature-proposal", | ||
], | ||
}, | ||
docs: [ | ||
"introduction", | ||
"token", | ||
"token-swap", | ||
"token-lending", | ||
"associated-token-account", | ||
"memo", | ||
"name-service", | ||
"shared-memory", | ||
{ | ||
type: 'category', | ||
label: 'Stake Pool', | ||
collapsed: true, | ||
items: [ | ||
"stake-pool", | ||
"stake-pool/quickstart", | ||
"stake-pool/overview", | ||
"stake-pool/cli", | ||
], | ||
}, | ||
"feature-proposal", | ||
], | ||
}; |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,271 @@ | ||
--- | ||
title: Operation | ||
--- | ||
|
||
Stake pools are an alternative method of earning staking rewards. This on-chain | ||
program pools together SOL to be staked by a staker, allowing SOL holders to | ||
stake and earn rewards without managing stakes. | ||
|
||
## Staking | ||
|
||
SOL token holders can earn rewards and help secure the network by staking tokens | ||
to one or more validators. Rewards for staked tokens are based on the current | ||
inflation rate, total number of SOL staked on the network, and an individual | ||
validator’s uptime and commission (fee). | ||
|
||
Additional information regarding staking and stake programming is available at: | ||
|
||
- https://solana.com/staking | ||
- https://docs.solana.com/staking/stake-programming | ||
|
||
## Background | ||
|
||
Solana's programming model and the definitions of the Solana terms used in this | ||
document are available at: | ||
|
||
- https://docs.solana.com/apps | ||
- https://docs.solana.com/terminology | ||
|
||
## Motivation | ||
|
||
This document is intended for the main actors of the stake pool system: | ||
|
||
* manager: creates and manages the stake pool, earns fees, can update the fee, staker, and manager | ||
* staker: adds and removes validators to the pool, rebalances stake among validators | ||
* user: provides staked SOL into an existing stake pool | ||
|
||
In its current iteration, the stake pool accepts active stakes or SOL, so | ||
deposits may come from either an active stake or SOL wallet. Withdrawals | ||
can return a fully active stake account from one of the stake pool's accounts, | ||
or SOL from the reserve. | ||
|
||
This means that stake pool managers and stakers must be comfortable with | ||
creating and delegating stakes, which are more advanced operations than sending and | ||
receiving SPL tokens and SOL. Additional information on stake operations are | ||
available at: | ||
|
||
- https://docs.solana.com/cli/delegate-stake | ||
- https://docs.solana.com/cli/manage-stake-accounts | ||
|
||
To reach a wider audience of users, stake pool managers are encouraged | ||
to provide a market for their pool's tokens, through an AMM | ||
like [Token Swap](../token-swap.md). | ||
|
||
Alternatively, stake pool managers can partner with wallet and stake account | ||
providers for direct SOL deposits. | ||
|
||
## Operation | ||
|
||
A stake pool manager creates a stake pool, and the staker includes validators that will | ||
receive delegations from the pool by adding "validator stake accounts" to the pool | ||
using the `add-validator` instruction. In this command, the stake pool creates | ||
a new stake account and delegates it to the desired validator. | ||
|
||
At this point, users can participate with deposits. They can directly deposit | ||
SOL into the stake pool using the `deposit-sol` instruction. Within this instruction, | ||
the stake pool will move SOL into the pool's reserve account, to be redistributed | ||
by the staker. | ||
|
||
Alternatively, users can deposit a stake account into the pool. To do this, | ||
they must delegate a stake account to the one of the validators in the stake pool. | ||
If the stake pool has a preferred deposit validator, the user must delegate their | ||
stake to that validator's vote account. | ||
|
||
Once the stake becomes active, which happens at the following epoch boundary | ||
(maximum 2 days), the user can deposit their stake into the pool using the | ||
`deposit-stake` instruction. | ||
|
||
In exchange for their deposit (SOL or stake), the user receives SPL tokens | ||
representing their fractional ownership in pool. A percentage of the rewards | ||
earned by the pool goes to the pool manager as an epoch fee. | ||
|
||
Over time, as the stakes in the pool accrue rewards, the user's fractional | ||
ownership will be worth more than their initial deposit. | ||
|
||
Whenever they wish to exit the pool, the user may use the `withdraw-sol` instruction | ||
to receive SOL from the stake pool's reserve in exchange for stake pool tokens. | ||
Note that this operation will fail if there is not enough SOL in the stake pool's | ||
reserve, which is normal if the stake pool manager stakes all of the SOL in the pool. | ||
|
||
Alternatively, they can use the `withdraw-stake` instruction to withdraw an | ||
activated stake account in exchange for their SPL pool tokens. The user will get | ||
back a SOL stake account immediately. The ability to withdraw stake is always | ||
possible, under all circumstances. | ||
|
||
Note: when withdrawing stake, if the user wants to withdraw the SOL in the stake | ||
account, they must first deactivate the stake account and wait until the next | ||
epoch boundary (maximum 2 days). Once the stake is inactive, they can freely | ||
withdraw the SOL. | ||
|
||
The stake pool staker can add and remove validators, or rebalance the pool by | ||
decreasing the stake on a validator, waiting an epoch to move it into the stake | ||
pool's reserve account, then increasing the stake on another validator. | ||
|
||
The staker operation to add a new validator requires 0.00328288 SOL to create | ||
the stake account on a validator, so the stake pool staker will need liquidity | ||
on hand to fully manage the pool stakes. The SOL used to add a new validator | ||
is recovered when removing the validator. | ||
|
||
### Fees | ||
|
||
The stake pool program provides managers many options for making the pool | ||
financially viable, predominantly through fees. There are five different sources | ||
of fees: | ||
|
||
* Epoch: every epoch (roughly 2 days), the stake accounts in the pool earn | ||
inflation rewards, so the stake pool mints pool tokens into the manager's fee | ||
account as a proportion of the earned rewards. For example, if the pool earns | ||
10 SOL in rewards, and the fee is set to 2%, the manager will earn pool tokens | ||
worth 0.2 SOL. | ||
* SOL withdraw: sends a proportion of the desired withdrawal amount to the manager | ||
For example, if a user wishes to withdraw 100 pool tokens, and the fee is set | ||
to 3%, 3 pool tokens go to the manager, and the remaining 97 tokens go to the | ||
user in the form of a SOL. | ||
* Stake withdraw: sends a proportion of the desired withdrawal amount to the manager | ||
before creating a new stake for the user. | ||
* SOL deposit: converts the entire SOL deposit into pool tokens, then sends a | ||
proportion of those to the manager, and the rest to the user | ||
* Stake deposit: converts the stake account's delegation plus rent-exemption | ||
to pool tokens, sends a proportion of those to the manager, and the rest to | ||
the user | ||
|
||
For partner applications, there's the option of a referral fee on deposits. | ||
During SOL or stake deposits, the stake pool can redistribute a percentage of | ||
the fees to another address as a referral fee. | ||
|
||
This option is particularly attractive for wallet providers. When a wallet | ||
integrates a stake pool, the wallet developer will have the option to earn | ||
additional tokens anytime a user deposits into the stake pool. Stake pool | ||
managers can use this feature to create strategic partnerships and entice | ||
greater adoption of stake pools! | ||
|
||
### Funding restrictions | ||
|
||
To give the manager more control over funds entering the pool, stake pools allow | ||
deposit and withdrawal restrictions on SOL and stakes through three different | ||
"funding authorities": | ||
|
||
* SOL deposit | ||
* Stake deposit | ||
* SOL withdrawal | ||
|
||
If the field is set, that authority must sign the associated instruction. | ||
|
||
For example, if the manager sets a stake deposit authority, then that address | ||
must sign every stake deposit instruction. | ||
|
||
This can also be useful in a few situations: | ||
|
||
* Control who deposits into the stake pool | ||
* Prohibit a form of deposit. For example, the manager only wishes to have SOL | ||
deposits, so they set a stake deposit authority, making it only possible to | ||
deposit a stake account if that authority signs the transaction. | ||
* Maintenance mode. If the pool needs time to reset fees or otherwise, the | ||
manager can temporarily restrict new deposits by setting deposit authorities. | ||
|
||
Note: in order to keep user funds safe, stake withdrawals are always permitted. | ||
|
||
## Security Audits | ||
|
||
Multiple security firms have audited the stake pool program to ensure total | ||
safety of funds. The audit reports are available for reading, presented in descending | ||
chronological order, and the commit hash that each was reviewed at: | ||
|
||
* Quantstamp | ||
- Initial review commit hash [`99914c9`](https://github.com/solana-labs/solana-program-library/tree/99914c9fc7246b22ef04416586ab1722c89576de) | ||
- Re-review commit hash [`3b48fa0`](https://github.com/solana-labs/solana-program-library/tree/3b48fa09d38d1b66ffb4fef186b606f1bc4fdb31) | ||
- Final report https://solana.com/SolanaQuantstampStakePoolAudit.pdf | ||
* Neodyme | ||
- Review commit hash [`0a85a9a`](https://github.com/solana-labs/solana-program-library/tree/0a85a9a533795b6338ea144e433893c6c0056210) | ||
- Report https://solana.com/SolanaNeodymeStakePoolAudit.pdf | ||
* Kudelski | ||
- Review commit hash [`3dd6767`](https://github.com/solana-labs/solana-program-library/tree/3dd67672974f92d3b648bb50ee74f4747a5f8973) | ||
- Report https://solana.com/SolanaKudelskiStakePoolAudit.pdf | ||
|
||
## Safety of Funds | ||
|
||
One of the primary aims of the stake pool program is to always allow pool token | ||
holders to withdraw their funds at any time. | ||
|
||
To that end, let's look at the three classes of stake accounts in the stake pool system: | ||
|
||
* validator stake: active stake accounts, one per validator in the pool | ||
* transient stake: activating or deactivating stake accounts, merged into the reserve after deactivation, or into the validator stake after activation, one per validator | ||
* reserve stake: inactive stake, to be used by the staker for rebalancing | ||
|
||
Additionally, the staker may set a "preferred withdraw account", which forces users | ||
to withdraw from a particular stake account. This is to prevent malicious | ||
depositors from using the stake pool as a free conversion between validators. | ||
|
||
When processing withdrawals, the order of priority goes: | ||
|
||
* preferred withdraw validator stake account (if set) | ||
* validator stake accounts | ||
* transient stake accounts | ||
* reserve stake account | ||
|
||
If there is preferred withdraw validator, and that validator stake account has | ||
any SOL, a user must withdraw from that account. | ||
|
||
If that account is empty, or the preferred withdraw validator stake account is | ||
not set, then the user must withdraw from any validator stake account. | ||
|
||
If all validator stake accounts are empty, which may happen if the stake pool | ||
staker decreases the stake on all validators at once, then the user must withdraw | ||
from any transient stake account. | ||
|
||
If all transient stake accounts are empty, then the user must withdraw from the | ||
reserve. | ||
|
||
In this way, a user's funds are never at risk, and always redeemable. | ||
|
||
## Appendix | ||
|
||
### Active stakes | ||
|
||
As mentioned earlier, the stake pool works with active stakes to | ||
maintains fungibility of stake pool tokens. Fully activated stakes | ||
are not equivalent to inactive, activating, or deactivating stakes due to the | ||
time cost of staking. | ||
|
||
### Transient stake accounts | ||
|
||
Each validator gets one transient stake account, so the staker can only | ||
perform one action at a time on a validator. It's impossible to increase | ||
and decrease the stake on a validator at the same time. The staker must wait for | ||
the existing transient stake account to get merged during an `update` instruction | ||
before performing a new action. | ||
|
||
### Reserve stake account | ||
|
||
Every stake pool is initialized with an undelegated reserve stake account, used | ||
to hold undelegated stake in process of rebalancing. After the staker decreases | ||
the stake on a validator, one epoch later, the update operation will merge the | ||
decreased stake into the reserve. Conversely, whenever the staker increases the | ||
stake on a validator, the lamports are drawn from the reserve stake account. | ||
|
||
### Validator list account | ||
|
||
Every stake pool contains two data accounts: the stake pool and the validator list. | ||
|
||
The stake pool contains overall information about the pool, including fees, | ||
pool token mint, amount under management, etc. | ||
|
||
The validator list contains specific information about each of the validator | ||
stake accounts in the pool. This information includes the amount of SOL staked on | ||
the validator by the pool, and the amount of SOL being activated / deactivated | ||
on the validator. | ||
|
||
Every stake pool must have its own validator list account, otherwise it will | ||
fail on initialization. | ||
|
||
### Transaction sizes | ||
|
||
The Solana transaction processor has two important limitations: | ||
|
||
* size of the overall transaction, limited to roughly 1 MTU / packet | ||
* computation budget per instruction | ||
|
||
A stake pool may manage hundreds of staking accounts, so it is impossible to | ||
update the total value of the stake pool in one instruction. Thankfully, the | ||
command-line utility breaks up transactions to avoid this issue for large pools. |
Oops, something went wrong.