[ODAO] Rewards Tree Specs v3, v4, and Beyond

Hi all,

Today I want to talk about some updates to the rewards tree specs. This is an evolution of the excellent discussion in the previous v3 proposal thread with some extra spice thrown in for flavor. As a TLDR, the upcoming changes and future proposals are listed here; the details are below for those interested.



This is a minor bugfix / correction to v2.


This changes RPL reward calculation to incorporate each minipool’s activation / exit dates into the calculation so nodes are not awarded RPL for minipools before those minipools are activated or after they’ve exited. Nodes with minipools that were active 100% of the time during an interval will not have their RPL changed (aside from a very small increase caused by this rebalancing). This is particularly important to introduce before Capella, when withdrawals are enabled. This does NOT prorate RPL based on minipool performance on the Beacon Chain.

  • Formal spec and implementation are still pending due to the holidays.
  • Target is Interval 6 on February 16th.


No spec changes are targeted beyond these two; the discussion around pro-rating RPL based on minipool performance is ongoing and will go through the formal RPIP / snapshot voting process. It is expected to be months before this comes to fruition if it does at all.

@Knoshua made a good point that such a change should be done well after withdrawals are enabled since it’s changing the terms around RPL rewards that were present when a node operator originally signed up. Since they may not agree with such changes, they would be free to exit accordingly.

Because of these, I want the community to continue the conversation around pro-rating RPL based on attestation performance. We can keep using the old v3 thread, or make a new one with a more appropriate name since that thread no longer represents what the canonical v3 will be.



As we’ve mentioned before, @Peteris and I have separate implementations of the rewards tree spec that we use to check each other and ensure both the spec and our implementations match up properly. We compare our trees every day for consistency. His implementation of ruleset v2 matched mine for the first half of December. On December 13th, his results deviated from mine.

After a day or so of exploration, we found an omission in the rewards tree spec for ruleset v2. At a high level, it doesn’t explicitly state that a minipool which was activated after its parent node left the Smoothing Pool should be disqualified from Smoothing Pool rewards. The way it was written makes the calculation for minipool eligibility ambiguous; his implementation excluded those minipools, and mine did not.

Several prominent community members, including @Peteris, @Knoshua, @Valdorff, and @Patches, were directly involved with identifying the problem and discussing a solution. After running the numbers, we found 9 minipools that this bug applied to during Interval 4. These minipools were erroneously awarded a combined 0.157 ETH from the Smoothing Pool, out of a total balance of 156.756 ETH.

The team and the aforementioned community members felt that given the timing (about 1 week before Interval 4 hit), the rather small impact of the bug, and the proximity to the holidays meaning some Oracle DAO members were unavailable, we decided to leave it in-place and fix it for Interval 5 unless it became clear that someone was actively exploiting it (which thankfully didn’t end up being the case). That being said, we decided not to acknowledge it until after Interval 4 to prevent any opportunistic abuse.

This was a very simple issue to fix both in the spec and in my implementation so I amended a fork of the Smartnode with these updated rules on December 15th. You can see the actual commit here if you’re curious. Peteris and I have continued our daily cross-checks, and his has matched mine every time. We believe the issue has been resolved, so I amended the rewards tree spec with this clarification:

If a minipool’s minipoolStartSlot occurs after its parent node’s nodeEndSlot (i.e., the minipool was activated after the node left the Smoothing Pool), it is ineligible for Smoothing Pool rewards during that period and can be removed from consideration as though it weren’t active.

This will become ruleset v3. It has already been included in v1.7.2, and will apply to Interval 5 on January 19th.


v4 was, ironically, proposed before the real v3 discussed above even existed; it stems from the original v3 proposal thread back when it was being considered “v3”. It is the first the time RPL rewards will have changed since the protocol’s inception, though the change is relatively small and provisionally more fair for everyone than what we have today.

In a nutshell, this update will make the following high-level change to the spec:

RPL rewards will now take each minipool’s activation epoch and exit epoch into account to prevent RPL rewards being earned by dormant / exited minipools.

Essentially this means that a node’s RPL is unchanged from today for nodes that already have all of their minipools active and staking. It only brings two notable changes:

  1. Currently, a node’s RPL rewards are pro-rated by the registration date of the node itself. After the change, it would be pro-rated by the activation date of the node’s minipools instead (where each minipool impacts the node’s total effective stake). This decreases rewards for nodes that have minipools sitting in the Beacon activation queue waiting for their turn.
  2. Slashed or exited minipools won’t be eligible for RPL rewards anymore (starting from their time of exit), so nodes with one or more of these may have their effective stake reduced and thus their RPL rewards lowered.

This is important to incorporate prior to Capella (withdrawals) because the Rewards Tree is responsible for distributing RPL now; it needs to ensure that node operators don’t exit their minipools but leave their RPL staked, thus still earning RPL rewards without providing any contribution to the network.

As @Knoshua pointed out during our discussions, there are a few ways to actually implement this:

  1. Recalculate the effective stake of a node each time one of these events occurs, and aggregate them together to produce a weighted average of the node’s “true” effective stake across the entire interval
  2. Do a two-step process where the node’s effective stake is calculated as it is done today, then that is scaled by number of blocks each minipool was “active” (analogous to how the Smoothing Pool’s eligibility window is calculated)

Ideally both approaches produce the same results and it comes down to implementation particulars, but this is TBD. There’s still time to have an open dialog around v4 to solidify these details.

I am currently planning to apply v4 to Interval 6 on February 16th predicated on how development and testing goes.


One of the things made abundantly clear in the original v3 proposal thread is that attaching any kind of incentives or scaling to RPL rewards based on minipool performance is inherently controversial and brings up a lot of supplemental questions. Aside from bug fixes, I think v4 will be a good ruleset to carry us into Capella and beyond for the time being so I’m less focused on what comes afterwards. I know that whatever it is, it won’t go live before Capella anyway.

I highly encourage the community to continue the dialog around this and any other points that may arise around rewards modification. I’m happy to make a new thread dedicated to that topic (though there have been several already) if it makes sense to do so; otherwise, keep on keeping on in that current thread.