glitchful-dev / sol-stake-pool-apy

2 stars 7 forks source link

Simplistic method isn't accurate when stake activates #23

Open bji opened 1 month ago

bji commented 1 month ago

Just fetching the number of pool tokens and amount of SOL in the pool is not really accurate.

When SOL is added to the pool, it is not in an activated state. It must be staked to a validator and then it will start to earn returns.

This SOL should not count against APY since no staker could have a reasonable expectation that stake added to a stake pool could earn returns in the epoch in which it is added. The stake came is as unstaked, and doesn't earn returns until starting in the epoch after it is activated.

Imagine a pool with 1 SOL total. Now imagine that 100 SOL is added to the pool. This 100 SOL is immediately stake-activated and will start earning returns next epoch.

The ratio of SOL in the pool (101) to stake pool tokens (101) is 1.0.

In the next epoch, the ratio of SOL in the pool (101+stake_rewards_on_1_SOL) to stake pool tokens (101) will be some tiny fraction higher than 1.0, call it (101.0005031/101), which is 1.000004982.

So the APY for the pool would be calculated as (1.000004982)^159 - 1. This is a 0.0792% APY.

This is not an accurate representation of what the pool might return. The APY number is so low because the 100 SOL added didn't earn anything in the prior epoch - because it can't, because it wasn't activated yet.

The actual APY should have been calculated on just the 1 SOL which was already in the pool: (1.0005031)^159 - 1, which would yield a more accurate value of 8.33% APY.

SOL newly added to a pool needs to not be included in APY calculations to avoid this very large mis-representation of pool APY.

But this is a hard problem, because what constitutes "SOL newly added to the pool"? Hard to distinguish that from SOL un-delegated from the pool during a rebalancing operation.

bji commented 1 month ago

Although on the other hand, the actual returns paid to stake in the pool do get watered down in the epoch in which new stake is added, because all stake in the pool (even newly added stake) shares the returns earned on the stake that was already in the pool. It's a complex topic for sure!

janlegner commented 1 month ago

I think it is similar to the case when some SOL gets de-activated by the pool's operator. That SOL will earn nothing in the next epoch but still, xSOL tokens have been previously minted for these de-activated ones. De-activating that amount also reduces APY effectively.

However, if you have any suggestions in term of how to re-work the calculations in here, I will be glad to discuss further.

Maybe just not counting new SOL for the first epoch? That would probably be quite difficult 🤔

AlexStefan commented 1 month ago

@bji once someone deposits 100 SOL in the pool, new LSTs are minted. When epoch is over, the staking rewards are being distributed in the LST price without taking into account if the LST was just minted or not. This therefore dilutes everyone's APY resulting in the one that is currently being computed. I do agree that the APY of staked SOL is different and should not take into account the inactive SOL (for w/e reason that is), but the APY of the LST is impacted by any inactive SOL