Stake pools are essentially good for Solana. They help decentralize the blockchain by distributing stake across its validators, instead of consolidating most of the funds in the most profitable ones (or, as it often happens, the best-marketed ones).
They also make staking a lot easier for the delegators: all the hassle of checking, comparing and monitoring the validators’ APY, performance and downtime are taken care of by the pool. The stake pool automates the process, and redistributes your funds using its smart strategy as soon as one of the validators becomes suboptimal in terms of your yield.
So yeah, as a community, we should hope that stake pools stay around and prosper. However, there is a couple of issues out there that are preventing stake pools from gaining a bigger share of the blockchain’s delegated funds: about a year since the first pools were launched, their aggregated share of the total staked SOL is only at 4%.
Only 4% of total staked SOL is delegated through stake pools.
Running a Solana stake pool ourselves, we had the opportunity to take a good look at the relevant problems and limitations from the inside.
This article is dedicated to these problems and the potential ways of mitigating them in the short and medium term.
Problem #1: APR loss caused by stake redistribution
If you unstake from one validator, then delegate to another, you lose an epoch’s worth of profits. Same happens when a stake pool moves stake between validators.
There are various reasons to redistribute the users’ SOL between validators within the pool:
* APY drop
* increased fee, etc.
Redistribution of stake should improve the pool’s overall APY. However, in order to move the SOL to another validator, you first need to deactivate the stake from the low-performing validator, and this stake won’t generate any rewards for the current epoch. With ~140 epochs per year, an epoch’s worth of rewards is approximately 0.05% of the SOL amount being moved. Might not seem like much, but if you need to redistribute often, it does add up to some significant loss of profits.
To put it into context, JPool’s total fee is around 0.12% of staked SOL p.a.
As we see it, there are three potential solutions to this problem:
1) Change the Solana staking code, adding the functionality of moving a stake account between validators without deactivation.
Pro: Solves the problem seamlessly and completely; easy, loss-free, and unlimited stake reshuffling enables the smart strategy to achieve highest possible APY for the pool users.
Contra: Requires changes in the very core of Solana’s staking code, which is complicated and involves a risk of side-effects affecting staking mechanics as a whole.
We know that the Solana Foundation is considering possible solutions for the issue involving changes in code, but as of now, no decision has been made.
2) Create a “staked SOL marketplace”: a kind of exchange where SOL staked to validators is traded in form of activated staked accounts. A stake pool would be able to sell the SOL staked to one validator and purchase SOL staked to another, thus effectively redistributing stake as needed.
Pro: Sometimes enables redistribution with minimal or zero losses.
Contra: Optimal trades won’t always be available, so the problem is only solved partially, on an ad hoc basis.
3) Cover the shortfall out of the pool’s fees: effectively return to the delegators a part of the fees the stake pool earned by providing its services. The loss is still there, but it affects the pool’s bottom line and not the users.
Pro: Delegators are happy as they don’t lose any rewards.
Contra: Only limited stake redistribution is possible since pool fees are very low (at least at JPool) and will only cover moving pool’s total stake approximately twice per year. Also, the pool’s own profitability suffers.
Problem #2: Staking to a pool generates a tax event
When you delegate your SOL to a stake pool, you receive its liquidity token, e.g., at JPool you would receive $JSOL which can be used in various DeFi instruments to earn additional yield. This is the core of the liquid staking concept; if you are interested in more details, please refer to our Medium articlе.
However, this means that when you delegate to a stake pool, you technically purchase stake pool tokens, such as JSOL or scnSOL, for your SOL. In the eyes of a fiscal authority, you’ve just sold your SOL, which generates a so-called tax event: the difference between purchase and sale price is recorded, and taxes are calculated based on your profit.
This does not happen when you delegate directly to a validator, since you’re not trading your tokens but keeping them, even though they are locked. That’s why if someone has a lot of $SOL to stake, “traditional” direct staking has a serious advantage over liquid staking to a pool.
There is currently only one solution that I am aware of: a pool manager manages the whale’s stake without issuing liquidity tokens. This has the obvious downside of being unable to participate in any DeFi, however all other advantages of staking through a pool are there, both for the delegator and for the blockchain. The SOL are distributed between validators to maximize decentralization and strengthen the blockchain while ensuring high, stable APY for the client.
Problem #3: Delayed unstake “reward stealing” attack
Whenever you stake your SOL directly to a validator, the old-fashioned way, it only activates at the end of the current epoch, causing you to lose this epoch’s rewards. Does not matter if you staked 5 minutes after epoch #100 began or 5 minutes before it ended, your rewards will only be accrued for epoch #101.
It turns out, there is a workaround — or rather an exploit — that can be used to receive full rewards for the current epoch.
Stake pools offer the delayed unstake option which returns the users’ SOL in exchange for their liquid tokens, in the form of a staking account, activated and producing rewards. As it is a “slower” option (compared to instant unstake where you immediately receive non-staked SOL), pools normally don’t charge any fees for using delayed unstake.
A user can do this 30 seconds before the epoch ends and receive full rewards for that epoch, while their unstaked SOL are now in the pool, staked and in the process of being activated, i.e. not generating rewards.
Effectively, the user steals an epoch’s worth of rewards from the pool’s delegators.
The solution we came up with is pretty straightforward:
Step 1. The stake pool needs to introduce a fee for delayed unstake, equal to the rewards for one epoch. By doing so, they will make this attack economically unjustified: you lose as much as you earn.
Step 2. The pool must also burn these fees by destroying the pool tokens produced by the operation. This way, the additional SOL are effectively split between all pool token holders and they are reimbursed for the exact amount of epoch rewards lost.
At JPool, we will introduce the delayed unstake fee in the next epoch, and mark all fees collected this way for subsequent burning; the actual burn functionality will take some more time to develop, but as soon as it goes live, all delayed unstake fees will be burned retroactively to benefit JSOL holders.
Stake pools are obviously not perfect, there is still a lot of work to do, both on the blockchain side and in the individual pools. However, it has by now become obvious that the stake pools are here to stay. They are essential not only for Solana, but for pretty much any Proof-of-Stake project, fostering decentralization and strengthening the blockchains.
And so far, there has not been a single pool-related issue that Solana would not be able to overcome.