Stake rewards formula

Stake pool rewards are calculated with the following formula found on Pledging and Rewards — Cardano Documentation 1.0.0 documentation :

This formula has the consequence that the rewards are greater with a higher pledge and greater with higher pool saturation. I can understand the reasoning behind this (I think :p), but I’ve got some problems with how the rewards change from min to max reward with increasing pledge and/or pool saturation. Please let me know if there’s something wrong with my reasoning or if I’m missing something…

If a0 is zero, the rewards per staked ADA on the pool (pledged or delegated) per mined block don’t depend on pledge or pool saturation. If a0 is greater than zero, the maximum rewards per ADA per mined block are only reached in a private pool (i.e. total stake equals pledge, no delegators) that is fully saturated. All pools that are not completely saturated or pledged only get a percentage of this maximum. With the current value of a0 (0.3), this minimum percentage equals to 1/1.3, or approx. 76.92%. This will be the rewards for the theoretically empty pool with no pledge and delegated stake (of course such a pool will never mine blocks, hence theoretically).

Note that these percentages are the same for every value of z0 (pool saturation size) and only depend on a0. If I calculate different values for these percentages for different values of pool saturation and pledge, I come to the conclusion that there only really is a meaningful difference in rewards when and the pool saturation is high and the pledge relative to pool size is high.

The following table shows the percentage for different values of pool saturation and pledge size relative to pool size (i.e. percentage of total stake in pool that is pledge). Every row has the percentages for a certain pool saturation, every column has the percentages for a certain pledge relative to pool size.

no pledge 1% 2% 5% 10% 15% 20% 25% 50% 75% 100% (private)
10% 76,92% 76,95% 76,97% 77,03% 77,13% 77,22% 77,30% 77,37% 77,56% 77,49% 77,15%
20% 76,92% 76,97% 77,01% 77,14% 77,35% 77,53% 77,70% 77,85% 78,31% 78,31% 77,85%
30% 76,92% 76,99% 77,06% 77,26% 77,57% 77,85% 78,11% 78,35% 79,17% 79,39% 79,00%
40% 76,92% 77,01% 77,11% 77,37% 77,79% 78,18% 78,55% 78,88% 80,15% 80,73% 80,62%
50% 76,92% 77,04% 77,15% 77,49% 78,02% 78,52% 79,00% 79,45% 81,25% 82,33% 82,69%
60% 76,92% 77,06% 77,20% 77,60% 78,25% 78,88% 79,47% 80,04% 82,46% 84,19% 85,23%
70% 76,92% 77,08% 77,24% 77,72% 78,49% 79,24% 79,96% 80,66% 83,79% 86,31% 88,23%
80% 76,92% 77,11% 77,29% 77,84% 78,73% 79,61% 80,47% 81,31% 85,23% 88,69% 91,69%
90% 76,92% 77,13% 77,34% 77,96% 78,98% 79,99% 80,99% 81,99% 86,79% 91,33% 95,62%
100% 76,92% 77,15% 77,38% 78,08% 79,23% 80,38% 81,54% 82,69% 88,46% 94,23% 100,00%

You can clearly see that if pool saturation is low, more pledge doesn’t really give more rewards (again, I mean relative to the rewards you get when a0 is zero), even for a private pool. Also, when pool saturation is high, the relative rewards only starts making a difference when pledge becomes very high.

Note also that this ‘problem’ cannot be solved by changing the value of a0. The minimum percentage will change, but the percentages will always tend to ‘stay’ with the minimum and only ‘get out’ when both pool saturation and relative pledge size becomes high.

For me, this doesn’t make really sense… If you look at the current stake pools with high saturation, relative pledge rarely is more than 5%, so most of the rewards will roughly have the same percentage, the pools with the higher pledges only get about one percent point more than those with lower (while the pledge of those pools can differ significant relative to each other, e.g. 100k ADA vs 1M ADA, a factor of 10).

It also cannot be the case that the idea is that stake pools should have a really high pledge, e.g. 50% of stake, because that means that all stake pools would have to hold 50% of ADA and that makes no sense at all (because saturation also has to be high), because all that ADA would then be virtually locked up… I know that you can spend pledged ADA, but you can’t get below your pledge at the beginning of an epoch if you want to mine blocks… With this formula, only a few stake pools with a lot of ADA can profit off the higher percentages (because that ‘locked up’ ADA will be small compared to the total amount of ADA).

Am I missing something here? Is it meant to be so that the difference in percentages are not so big and only a few percentage points? Because than the benefits of pledging more isn’t that great and there is still the flip side that a few rich pools can benefit from far greater returns… I get that the greater difference in rewards should lean towards more saturation, but why isn’t it for the pledge size the other way around? So that it does make a significant difference if you change the pledge e.g. from 1% to 2%, but not so much if you go e.g. from 50% to 100%…

Nobody… ?

Hi @brouwerQ

I did my own math come to the conclusion that if you are large pool then pledging close to 100% makes a big difference. If you are small pool then pledging close to 100% does NOT make a big difference to the return

Actually could you also just check if you see that small pools actually generate a higher expected return? This is my conclusion so far

large pool
a - pool with 62mn stake and 0 pledge, reward per epoch is = 61.4k ada (or c. 5.5% annualised)
b - pool with 62mn stake and 62mn pledge, reward per epoch is = 47.2k ada (or c. 7.2% annualised)

small pool
c - pool with 5mn stake and 0 pledge, reward per epoch is = 5.1k ada (or c. 7.4% annualised)
d - pool with 5mn stake and 5mn pledge, reward per epoch is = 5.1k ada (or c. 7.5% annualised)

@dstratio I think you switch the annualised percentages of a and b under large pool.
How did you calculate the rewards per epoch in your example? Because your results doesn’t align with what I got…

Ok, need to think about this a little

@dstratio Already thought? :wink:

Hi Yes, I decided to write a reward calculator / simulator after having worked through the formula and cardano’s monetary policy. I will make it available to for others to test and give feedback. So far I have found all the reward calculators lacking some features.

I found the calculator on cardano’s website does not work well for smaller pools as it works with averages whilst for a small pool arguably there would be much large dispersion around the average return. This can lead to significantly higher and lower return than the predicted average for smaller pools . The best way to demonstrate this (imho) is to run a monte carlo simulation and simulate a large number of epochs and from that work out what the distribution of returns can be expected. I have worked this out in an Excel and am now transposing into an app that other can see.

Also when reviewing the monetary policy I realised that 0.03% (rho parameter) of the current reserve (max ada supply - current ada supply) is being distributed evert epoch between the pools and delegators + the fees from transactions. This today give all the pools a return of c. 5%. As time goes by the reserve will be depleted the the transaction volume will need to pick up to maintain a 5% payout. This is something that i want to be able simulate and to do some sensitivity analysis

I will come back in a couple of days with a prototype and give others a chance to opine and find mistakes. With this I realise that I have highjacked your original question and am trying to work out something more generic, out of which your example will be a special case

Rho is not 0.03% but 0.003 or 0.3%. Not that whole amount is used for rewards though, because 20% of it goes to the treasury (tau parameter = 0.2). So the actual amount available for rewards is 0.24%. Also because most pools only get about 77%-79% of maximum rewards because of a0 (see my analysis), the actual amount is even less (the remaining ADA goes back to the reserve, so the reserve shrinks less than 0.3% per epoch).

Currently, almost all of the rewards come from the reserve, the rewards that come from transaction fees is negligible (at most about 0.1% of total rewards per block currently). So Cardano has to be used a lot more than today for rewards to remain the same, because the rewards from the reserve shrink with each epoch. But that’s the purpose, else there isn’t any point in it :stuck_out_tongue:. I wonder what effect the use of smart contracts will have on the rewards emerged from fees.

All this doesn’t answer my original questions though, why the rewards formula is the way it is, especially that the influence of pledge only counts significantly towards very high pledge…

Yes indeed rho is 0.3%, i must have mistyped, and yes agree with you assessment re the need for revenue from transactions to pick to to maintain the same level of return for pool operators.

As to why the formula is the way it is you might want to check pages 34 onwards in the formal specifications doc link1 and academic paper link2

On the back of this I have created a Calculator to simulate pool Rewards by changing any of the pool and network parameters. Can you take a look here and let me know what to you think?

https://dynamicstrategies.io/crewardcalculator

Your calculator seems far better than the others I’ve seen. Great work! I haven’t got the time for extensive testing, but I do have a few suggestions:

  1. Add a checkmark so you can turn off the simulation under 6. It seems very expensive in terms of calculations and if I change some parameters, it doens’t respond that well. With a checkmark, you can turn it off, change the parameters you want (and still immediately see the changes under 5) and turn it back on again when all parameters are changed.

  2. Under 3, put the total pool stake first because that limits the amount in the field of pool pledge. Because now if I change the fields in order, I can’t enter the intended pledge, because total pool stake is not high enough.

  3. Add a field pool saturation (a percentage, can be more than 100%) so you don’t have to calculate that in your head. If one of the field total pool stake or pool saturation is changed, the other should be updated. Maybe something similar in terms of pool pledge as a percentage of total pool stake.

  4. Maybe under one add an extra parameter for the mean pool performance (percentage), because when this is lower than 100%, less rewards are distributed. I learned this from the paper in your first link and didn’t know this before. E.g. normally an epoch consist of 21,600 blocks. If only 21,000 blocks are mined, only 21,000/21,6000 of the rewards are distributed (mean pool performance equals to 97,22%). It should be capped to 100% (you should allow people to enter a higher value though).

  5. Maybe add some disclaimer next to ‘Pool Reward per Year ADA’ and ‘Annualized Pool Reward’ that these values only hold if the rewards coming from transaction fees compensate for the declining rewards coming from the reserve, i.e. Cardano use should increase over time. If not, these values will be less and shrink over time. This is also stated in the first paper under 5.4.3. Even the rising USD value of ADA is taken into account there! So the percentage in terms of ADA will decline over time…

I’ve come to some other insights/conclusions regarding my original questions/problem:

  • In my previous post I said that remaining rewards, because not everyone get maximum rewards, go back to the reserve, but in the first paper you mentioned under 5.5.2 it says that the remaining rewards go to the treasury and not the reserve. I thought I read somewhere it goes back to the reserve, but maybe that was just some guy on some forum, I can’t find it back…
    I’m not sure if the remaining rewards that result from less than 21,600 blocks mined also go to the treasury or if those will go back to the reserve, I guess the former. Maybe I should just dive in the code to be sure, when I find the time… :stuck_out_tongue: In exaggeration, I’m playing the devil’s advocate here, doesn’t this give some actors (e.g. developers) that seek a bigger treasury an incentive to sabotage stake pools?
    In my opinion, I think these left over rewards should go back to the reserve and not the treasury so that the amount that goes to the treasury only depends on the transaction fees, rho and tau and not on pool saturations, pledge amounts and pool performances. Rho and tau can always be tweaked to control the reserve depletion and treasury growth.
    What do you think about this?

  • I’ve entered some values for pool size and pledge in your calculator and the resulting rewards agree with my conclusions from the table in my initial post. Maximum rewards are only reached with high saturation and high pledge. You can easily see this if you look at the value next to ‘Annualized Pool Reward’ in your calculator. It stays about the same if pool saturation is low (even with high pledge) or pool pledge is low (even with high saturation). Only if both are big, the percentage increases significantly.

  • From 5.6 I can conclude that high saturation is desirable. This makes sense, because else everyone can just run their own pool (if we ignore pool running costs), what wouldn’t be workable. So we can assume that saturation is high. But this means for pledge also to be high enough to make a difference, I lot of ADA will be hold by stake pool owners, what cannot be the goal, because little will be left for actual use… So I stand by my point that there’s a problem with the current formula: it doens’t make much of a difference if you pledge e.g. 5% of total pool stake or 10% of total pool stake and only a few whales with lots of ADA can profit from much higher rewards than the rest if they start a stake pool…

  • From 5.10.2 I understand that a relative high pledge is desirable though because else a Sybil attack would be too easy. But with the current formula, it doesn’t matter a lot; the majority of pools have such a low pledge that it doensn’t have a lot of influence on the rewards relative to each other. Maybe there should be another protocol parameter that caps s not at z0, but at a lower value (e.g. 10% of z0)… So that higher pledge result in higher rewards, up to a certain amount. This diminishes the much bigger advantage of ‘whale pools’.

What are your toughts on all of this? I also would like other people to join this discussion to hear their opinion…

I haven’t find the time yet to read the second paper you’ve linked, maybe that will give me some more insights… :wink:

Thanks for the comprehensive feedback, all good points. I will look to include them with the exception of n4, or maybe replace the perfect 100% of blocks completed with a representative mean. It is indeed a bit perverse that a way to increase a pool’s or treasury’s reward is to compromise the aggregate production of blocks.

On your other thoughts

  • indeed in the spec paper they mention that the left over reward that doesn’t go to the pools goes to treasury… i am not actually sure of what happens to the reward from missed blocks, so it would be great if can find this somewhere, but actually i think that this is quite minor compared to what happen to the reward that for all ada that is not staked. If you work through the formula and ignore the a0 parameter for second (set it to 0) you wil see that the pool’s reward is the aggregate reward * the pool’s sigma. Sigma in turn is pool’s stake divided by the Total Ada in Circulation (not total staked ada) , so the formula works on the basis that all the ada in circulation should be staked, which clearly it is not. Now the probability of a pool of minting blocks is a pool’s stake / by the total ada at stake … Note the diffence in the denominator between the formula and the odds of minting a block. In my heuristics I worked out for myself that the reward for all the ada that is in circulation but that is not staked does not go to the pools, but get sent to treasury. So by this the treasury is getting a windfall of c. 30% of the total reward that was intended for the pools which based on the last epoch should be c. 9mn ada. Which pays for 9 project catalysts funds in 1 epoch !
  • On the size of the pledge, there is some discussion within IOHK on how best to revise the formula. You might want to check the discussion in this post Link1 , and check out the CIP proposal there.

As with my calculator I want to add a comparison across all live pools, so will be working on that over the next few days

Ok, what’s said in that link kinda confirms my conclusions. :slight_smile:

@brouwerQ good to hear !

I also made further changes to the calculator, the link is the same… I’ve added a graph with the distribution of simulated rewards and the ability to query pools Id to get pool parameters and then compare the distribution between pools. I think this is quite critical to get a better understanding for the pool operators and delegators on what type returns can be expected at each pool

I’ll branch it out into a separate topic and ask for feedback from wider community just on the calculator as the original q on pledge vs stake has been answered

@dstratio @brouwerQ Good discussion you had earlier this year. I’m also working on a rewards calculator, but mostly as a personal python exercise. I seem to be ~20 Ada over the rewards amount I’m seeing in adapools.org which I’m using for my validation. I’m wondering if I’m calculating z0 correctly (relative pool saturation) Is z0 simply 1/K value, i.e. .002, or is it a relative value in terms of the pool’s saturation? In other words, should I be using the live saturation value for the pool?

Hi @cardsfan7189 ,

It should be the active stake, the live stake includes any additional delegations during this epoch but that will only start counting towards your pool at the end of next epoch

yes z0 for me is 1/500

Also the pool operator gets paid first the fixed fee and then split the variable fee with the delegators. So if you pool is 340 fixed and 2% variable then from a total reward of 1,000 ada in an epoch the pool would get 340 + (1000 - 340)*2% and the rest will go to other delegators. However because your pledge is counted as a delegate you will also earn a % on that that will count as a pool reward… these small things can be causing a diff?

Can you give for some pools and epochs what your calculator give as reward per block? So I can check something.

@dstratio thanks for clarifying z0. My calculation discrepancy occurs before I divide the rewards. To answer @brouwerQ , I’m getting this total for pool pool1huyzkfxwnttj7r4530hv7gc5v6mzk75vuzysc75aemu85mae9vd (TOSHZ), epoch 305, 1 block: 695.4014381432327. adapools.org shows a total reward of 678.77, so actually a difference of 17 Ada versus 20. The pool also minted 1 block in epoch 306, and my calculator came up with 690.3497210882244. I’ll be curious what your calculations come out to.

I was mainly testing out TOSHZ (my own pool OMAHA hasn’t minted yet). I just now tested another pool, pool1gn5txrx7ay0pxs7cj70ewxpqx64sqnptnkc4u3zghxv8y2y9sxr (MRSP) My calculation for epcoh 302 , 2 blocks, comes to 1380.542928769631. Adapools shows 1370. That’s closer, and I would expect some type of variance because I’m pulling current supply info from the network versus what adapools would’ve used when the 302 rewards were calculated.

Can you give a detailed example of your calculation? Did you adjust for actual minted blocks in the epoch? That roughly gives the difference in your first example but it’s still 2 ADA off so that might by a coincidence and something else may be false. Because it doesn’t hold for your second example.

Or both things might be due to the wrong current supply thing you’re talking about. You can defer current supply from Pots | Cardano Staking (just subtract the reserve column from 45B; be sure to use the right epoch, the values shown are those at the beginning of each epoch, so you should look at 2 epochs before the one you’re calculating the rewards for). You also need the correct total active stake, I don’t immediately find this, but you can look at your historic leaderlogs if you keep them. E.g. for E305, it was 23854747611964256 lovelaces.

On Cardano (ADA) Blockchain Explorer And Pools Statistics you can view the historic total active stake, but it differs from the value from my leaderlogs (3.58M lesser than leaderlog value), so one of them will be incorrect (probably the one on AdaStat), not sure what the difference is exactly; could be wrong handling of retiring pools or so…

Here’s the output from the python script for the epoch 305 rewards for pool1huyzkfxwnttj7r4530hv7gc5v6mzk75vuzysc75aemu85mae9vd

total supply = 33782431258
total active stake = 23854747611.964256
R = 27047176.797511205
sigma = 9.547437215716099e-06
z0 = 0.002
a0 = 0.3
s = 3.6282338484437566e-06
min_sigma = 9.547437215716099e-06
min_s = 3.6282338484437566e-06
beta = 4.756242568370987e-05
sigma_a = 1.3520815507108258e-05
Base reward before block adjustment = 198.70662161211445
Reward adjusted by beta divided by sigma_a: 698.9940006443118

I tried two versions of total supply. I thought you said to get the supply information from two epochs prior, so I used 45B - 11259657628 to calculate the supply based on epoch 303. That yielded a final reward of 702 ada. Above output was generated based on an epoch 305 supply calculation 45B - 11217568742

Let me know if you want to see the python script