# Rewards Tree Spec v7

**URL:** <https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097>\
**Category:** Governance\
**Created:** [12 August 2023 13:59 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097 "2023-08-12T13:59:15Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![knoshua](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/knoshua/32/128_2.png) [@knoshua](https://dao.rocketpool.net/u/knoshua)\
**Post date:** [12 August 2023 13:59 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/1 "2023-08-12T13:59:15Z")

</div>

Following some initial [discussion on Discord](https://discord.com/channels/405159462932971535/1139239929948418252/1139240188606943434), I’m proposing two changes to the rewards tree spec following the [process for rewards tree changes](https://dao.rocketpool.net/t/meta-proposal-for-a-watchtower-and-rewards-tree-change-process/1267):

1. Count minipools in the beacon chain queue like active validators for RPL reward calculation.

2. In case there is not a single eligible node at the time of the reward snapshot, RPL inflation meant for node operators goes to the pDAO instead.

### Rationale

#### Beacon Chain Queue Minipools

Not counting these minipools creates a disincentive to bond reduce: For nodes with high RPL collateral and if the queue is long enough, node operators reduce their share of RPL rewards when they convert to a LEB8. But we do want people to bond reduce- we are punishing people for behavior that we want.

#### NO Reward Edge Case

In theory it is possible that no node qualifies for RPL rewards (for example if no node meets the minimum 10% collateral requirement). In this scenario, the spec [calls for raising an error](https://github.com/rocket-pool/rocketpool-research/blob/v6/Merkle%20Rewards%20System/rewards-calculation-spec.md#collateral-rewards) “because the calculation has excessive error”.

### Sentiment Polls

_Poll ([view on site](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/1))_

_Poll ([view on site](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/1))_

---

<div class="post-metadata">

**Author:** ![epineph](https://dao.rocketpool.net/letter_avatar_proxy/v4/letter/e/258eb7/32.png) [@epineph](https://dao.rocketpool.net/u/epineph)\
**Post date:** [12 August 2023 17:22 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/2 "2023-08-12T17:22:51Z")

</div>

Idle ramblings: just wondering if it makes more sense to send to burn address if no eligible NOs? Since we are talking edge cases, diverting 98% of inflation to an address may increase the sweetness of governance attacks/oracle manipulation; and if every NO is below 10%, the pDAO done f’d up bigly somewhere and should we really be giving them (ourselves) more RPL?

---

<div class="post-metadata">

**Author:** ![knoshua](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/knoshua/32/128_2.png) [@knoshua](https://dao.rocketpool.net/u/knoshua)\
**Post date:** [12 August 2023 17:54 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/3 "2023-08-12T17:54:59Z")

</div>

I have no preference here, because I don’t think it will ever happen. For me this is purely about removing undefined behavior from the spec, so that nobody has to worry about the case.

---

<div class="post-metadata">

**Author:** ![jasperthegovghost](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/jasperthegovghost/32/401_2.png) [@jasperthegovghost](https://dao.rocketpool.net/u/jasperthegovghost)\
**Post date:** [13 August 2023 01:13 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/4 "2023-08-13T01:13:00Z")

</div>

Strong support. I think pDAO\>\>\>\>Burn in terms of growth potential at this stage.

---

<div class="post-metadata">

**Author:** ![Valdorff](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/valdorff/32/319_2.png) [@Valdorff](https://dao.rocketpool.net/u/Valdorff)\
**Post date:** [17 August 2023 14:14 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/5 "2023-08-17T14:14:28Z")

</div>

The process says “If contentious, they should be run through our usual Snapshot voting process.”

Given current poll states I feel “Should minipools in beacon chain queue count like active minipools?” is _not_ contentious and could be implemented. The second poll “Should NO inflation go to pDAO if there are no eligible nodes?” is on the edge of my comfort level – there’s a strong bias to yes, but “contentious” shouldn’t be a high bar (as of this writing, 26 yes and 4 no votes).

* * *

I’d like to dig into the problem(s) as seen by the current “No” voters to see if we can address it in situ, or if it would be better to remove that item from v7 and discuss further (would love to hear from @Uisce @ken @underwood @CryptoBarista).

Currently, if there are no eligible nodes, behavior is undefined. I’m guessing that’s not desirable to anyone? If so, is the issue _where_ the funds would go?

Other possible definitions (beyond sending to the pDAO treasury) that make some sense to me:

- Burn (essentially distribute to all RPL holders staked or not)
- Ignore minimum for the period (note that this then has an edge case if no nodes have any stake… but then RP is truly non-existent so probably whatever)
- Send to EF/Gitcoin/similar wallet
- Lido treasury (taking epineph’s “we don’t deserve it” argument to the extreme)

I do want to emphasize that, like knoshua - I don’t think this will ever happen and we’re mostly looking to avoid the “undefined” fork’s existence more than create a policy that is likely to see the light of day.

---

<div class="post-metadata">

**Author:** ![Uisce](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/uisce/32/313_2.png) [@Uisce](https://dao.rocketpool.net/u/Uisce)\
**Post date:** [17 August 2023 16:22 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/6 "2023-08-17T16:22:06Z")

</div>

I do not think it is worth any time defining logic for a scenario that should never occur, no eligible nodes would suggest a critical/malicious oracle error or complete breakdown in incentive structure.

There is no good way to handle such a scenario, sometimes things should just fail ungracefully.

---

<div class="post-metadata">

**Author:** ![underwood](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/underwood/32/563_2.png) [@underwood](https://dao.rocketpool.net/u/underwood)\
**Post date:** [18 August 2023 01:41 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/7 "2023-08-18T01:41:35Z")

</div>

My suggestion: If there are no eligible nodes in this cycle; NODE inflation will be accumulated to the next cycle; I think this will not only comply with the agreement of 70% inflation to NODE, but also solve the problem.

---

<div class="post-metadata">

**Author:** ![Valdorff](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/valdorff/32/319_2.png) [@Valdorff](https://dao.rocketpool.net/u/Valdorff)\
**Post date:** [18 August 2023 02:00 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/8 "2023-08-18T02:00:42Z")

</div>

@underwood  
The proposal requires like a line of code or two. This would be much more complex. And again – this isn’t expected to ever come up.

@Uisce  
Interesting. I’m really just wanting to have an answer so we don’t spin up conversations about it anymore 😛.

---

<div class="post-metadata">

**Author:** ![Hodja](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/hodja/32/477_2.png) [@Hodja](https://dao.rocketpool.net/u/Hodja)\
**Post date:** [18 August 2023 02:48 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/9 "2023-08-18T02:48:27Z")

</div>

#### Beacon Chain Queue Minipools

Yes - because the stupid queue is stopping people from making new minipools. This lessens the blow and may properly incentivise more growth.

#### NO Reward Edge Case

pDAO \> burn, because pDAO can use to improve protocol.

---

<div class="post-metadata">

**Author:** ![Patches](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/patches/32/121_2.png) [@Patches](https://dao.rocketpool.net/u/Patches)\
**Post date:** [18 August 2023 16:33 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/10 "2023-08-18T16:33:23Z")

</div>

> [@Uisce](#):
>
> There is no good way to handle such a scenario, sometimes things should just fail ungracefully.

Generally, I would suggest that instead of saying ‘let the implementor decide’, we should then say that the oDAO should not generate a tree for that interval.

Otherwise we have undefined behavior. As it stands now, I strongly suspect Joe’s implementation of treegen will divide by 0 and die. This is, of course, an implementation detail. If we wind up with multiple treegen implementations, the defacto behavior may be something worse.

**Edit** : Knoshua pointed out to me offline that the spec already has safety rails which would cause it to abort deliberately instead of implicitly.

**Edit 2** : Knoshua pointed out to me offline that the spec actually encodes a divide by 0, which we really should fix if we don’t supercede it with a change to send to the pDAO instead.

---

<div class="post-metadata">

**Author:** ![knoshua](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/knoshua/32/128_2.png) [@knoshua](https://dao.rocketpool.net/u/knoshua)\
**Post date:** [28 September 2023 11:58 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/11 "2023-09-28T11:58:38Z")

</div>

Update and discussion on discord starting [here](https://discord.com/channels/405159462932971535/774497904559783947/1156829002598715422).

---

<div class="post-metadata">

**Author:** ![jcrtp](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/jcrtp/32/95_2.png) [@jcrtp](https://dao.rocketpool.net/u/jcrtp)\
**Post date:** [10 October 2023 05:30 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/12 "2023-10-10T05:30:15Z")

</div>

I have officially compiled these changes (and a few other clarifications / fixes for Holesky) into this draft v7 spec:

> <https://github.com/rocket-pool/rocketpool-research/blob/master/Merkle%20Rewards%20System/rewards-calculation-spec.md>

If we are able to release a new Smartnode this week, I expect this to be the ruleset used for Interval 15 on mainnet. Ramana already has an implementation of it which has parity with mine.

---

<div class="post-metadata">

**Author:** ![jcrtp](https://dao.rocketpool.net/user_avatar/dao.rocketpool.net/jcrtp/32/95_2.png) [@jcrtp](https://dao.rocketpool.net/u/jcrtp)\
**Post date:** [10 October 2023 08:08 UTC](https://dao.rocketpool.net/t/rewards-tree-spec-v7/2097/13 "2023-10-10T08:08:26Z")

</div>

As a note, I’ve added some supplemental clarifications / minor changes that will not affect Mainnet but were necessary for the upcoming Holesky testnet deployment to work, which are covered in the summary of the spec change notes but are repeated here for clarity:

1. In the [Time of Eligibility](https://github.com/rocket-pool/rocketpool-research/blob/master/Merkle%20Rewards%20System/rewards-calculation-spec.md#time-of-eligibility) section, `startTime` is refined: if the value from `RocketRewardsPool.getClaimIntervalTimeStart()` is `0`, use `RocketTokenRPL.getInflationIntervalStartTime()` instead.
  - This is just a safety precaution in case of an anomalous contract state during initial deployment; it was intended as a workaround for a contract bug that occurs when the first rewards interval occurs after Atlas has been deployed (which has been fixed).

2. In the [Collateral Rewards](https://github.com/rocket-pool/rocketpool-research/blob/master/Merkle%20Rewards%20System/rewards-calculation-spec.md#collateral-rewards) and [Oracle DAO Rewards](https://github.com/rocket-pool/rocketpool-research/blob/master/Merkle%20Rewards%20System/rewards-calculation-spec.md#oracle-dao-rewards) sections, the “epsilon” value used as an upper bound for errors during sanity checking has changed. Instead of the total number of minipools, it is now the higher of the total number of nodes and the total number of minipools.
  - This is needed for the sanity check to work properly when there are more Oracle DAO nodes than there are minipools on the network.

3. Clarified in [RPL Amounts per Group](https://github.com/rocket-pool/rocketpool-research/blob/master/Merkle%20Rewards%20System/rewards-calculation-spec.md#rpl-amounts-per-group) that if the amount of pending RPL rewards is `0`, this block cannot be used for rewards submission and the user should just wait until the next interval rolls over.
  - This just ensures that if the interval time is set to a number below 1 day (which is the minimum for when RPL can be minted), the Oracle DAO won’t generate “empty” intervals.

None of these changes affect Mainnet so I don’t anticipate any concerns releasing them together with the rest of v7, but if anyone has any issue with them, let me know.
