Rewards Tree Spec v10

Hey everyone!

It’s been a while since we’ve had some rewards tree changes but new network upgrades tend to bring them, and this time we have two: v9 from Patches and v10 from me (proposed here). Luckily they aren’t mutually exclusive; they can come in either order and one (or both) can be ratified without issue. I’m calling this v10 out of respect because his came first and I’m assuming it’s going to go through.

Anyway, unlike past updates where I dump all of the proposal contents into one of these, I wrote a proper RPIP this time. For your consideration:

The full details are covered in there but to summarize, in Houston we added a special setting called an “RPL withdrawal address” in accordance with RPIP-31. It’s distinct from the primary withdrawal address (the one you have today). If you have the RPL withdrawal address set, then all RPL rewards you claim will go to that address and all Smoothing Pool ETH you claim will go to your primary withdrawal address.

The problem, though, is that if you have an RPL withdrawal address set, you can’t claim rewards anymore as the node operator. Only the RPL withdrawal address is allowed to claim rewards. This is fine for RPL rewards but since the Smoothing Pool ETH is tied to the claiming system, it means only the RPL withdrawal address can claim Smoothing Pool ETH on your behalf. Bummer.

v10 proposes a fix to that via a small tweak to the rewards tree spec, which (thanks to a quirk in the contracts), doesn’t require any contract changes and doesn’t affect nodes that don’t have an RPL withdrawal address set. Here’s the TLDR:

  • No contract changes
  • Nodes without an RPL withdrawal address are unchanged
  • Nodes with an RPL withdrawal address will be removed from the tree, and in their place will be 2 entries:
    • 1 for the primary withdrawal address, with the ETH
    • 1 for the RPL withdrawal address, for the RPL
  • Yes, having tree entries that aren’t node operators actually works and yes, you can only claim for those entries from the entry address itself. Like I said, weird quirk.

This has an interesting side effect too: if the RPL withdrawal address is set, nodes with the same one will have their RPL aggregated into a single entry within the rewards tree so claiming it will only take a single transaction instead of n transactions (n being the number of nodes with that particular address set). Same story for ETH rewards. It reduces O(n) operations down to O(1) which is compelling for entities that plan to use this setup but are being blocked by linearly scaling gas costs.

That being said, this also has some important ramifications. For example, it means nodes with the RPL withdrawal address set can no longer claimAndStake, and they can’t claim from the node address anymore - claims have to be done from both the primary withdrawal address and the RPL withdrawal address.

Instead of rehashing the entire proposal here I think that’s probably a fair summary. Please go take a look at the RPIP and let’s talk!

Updated with formal spec definitions. Same idea, way more verbose rules.

After some discussion with Patches, we decided to make v9 required as part of this - it will now build off v9 and deprecate the old JSON rewards file format. We’ll have the JSON use the old field names for the sake of making it easier to move existing tooling from JSON to SSZ, but v10 will be the last format that officially supports JSON rewards files.

Just a small note that per RPIP-52 (v9):

The Oracle DAO SHOULD upload all four files to a publicly accessible webserver, where individual Node Operators can retrieve them.

The Oracle DAO MAY discontinue publishing the JSON Rewards File after a transitionary period to allow tooling to adopt the new format.

Taken together with joe’s changes, this means the oDAO will continue to provide json rewards format files in the existing format through v9 and into v10, and during v10 the old field names will still be present, but at some point in the future, once tooling such as sprocketpool and rocketsweep have a chance to switch to the ssz format, the json files may change formats at the discretion of the oDAO seat that releases them.

Keep in mind that the ssz captures all of the information present in the json, so even after the oDAO stops providing json files, any enterprising individual can simply convert ssz files to json as-needed, using whatever field names and schema they prefer.

As a quick update, this can be done before Houston if desired; in that case the “is the RPL withdrawal address set” flag will just be false (since the function doesn’t exist yet) and the behavior will be identical to v8 / v9. That may make it more convenient to enact at the same time as v9 if desired.

I am confused. It says

If a node operator has a “regular” withdrawal address set, they will not be affected by this change.


If the node does not have an RPL withdrawal address set, there will be a single claimer with the following details:

  • The address will be the address of the node.
  • The network will be the rewards network selected by the node.
  • The RPL rewards will be the amount of RPL earned by the node for this rewards period.
  • The ETH rewards will be the amount of ETH earned by the node for this rewards period.

So, are the nodes not specifying an RPL withdrawal address profiting from the “only one transaction per node” or not?

To be unambiguous, the top line you quoted should say

If a node operator has a “regular” withdrawal address set, but does not have an RPL withdrawal address set, they will not be affected by this change.

So to answer your question when you refer to “only one transaction per node” - let’s set up this scenario to make it clear:

  • Node A has primary withdrawal address X and no RPL withdrawal address.
  • Node B has primary withdrawal address X and no RPL withdrawal address.

Here’s what can happen:

  • Node A will be able to claim and stake its own rewards (the ones listed under Node A in the tree) in one TX, like it can do today.
  • Node B will be able to claim and stake its own rewards (the ones listed under Node B in the tree) in one TX, like it can do today.
  • Node A cannot claim Node B’s rewards.
  • Node B cannot claim Node A’s rewards.
  • Address X can claim Node A’s rewards and stake them for Node A, and it can claim Node B’s rewards and stake them for Node B, but this will take two separate transactions (one per node). It cannot claim / claim and stake both rewards in a single TX.

This isn’t specific to v10; this particular scenario plays out the same way with or without v10. v10 only impacts nodes that have an RPL withdrawal address set.

Ah, I have intertwined claim with distribute and thought those two could be done in one transaction with this change.

I’ve updated the RPIP to address your confusion; give that a look and let me know if it makes things more clear for you.

In the process I’ve also updated the rules based on feedback from Patches and Knoshua. Here’s a brief description of what’s changed (stuff in emphasis):

  • If a node does not have an RPL withdrawal address set, or if it has one but its primary withdrawal address is the same as the node address, their node address is the claimer address (same as today).
  • If a node has an RPL withdrawal address set and its primary withdrawal address is different from the node address, the node’s rewards will be split in two (…)

Reason being, without that, the split mode thing will end up producing 2 entries - one for ETH, one for RPL, both only claimable via RPL address; this consolidates it to 1 and ensures the RPL withdrawal address has an incentive to claim.

Yes, it’s clear now, thank you! Seems to be good.

The RPIP has been merged, so let’s do a quick feeler to see what people think:

  • I support v10
  • I support v10 but only if the pDAO agrees to fix the issue in Saturn
  • I do not support v10
0 voters

what’s “the issue” and how does fixing it in Saturn look like?


I want to state my understanding of the situation, and my opinion on this RPIP in relation to Houston to give some clarity, and explain why I voted the way I did above in the poll.

The situation is that the Houston contracts are broken regarding the treatment of the RPL withdrawal address. I believe this was discovered late enough in the development process that the option of fixing the contracts was taken off the table. So instead, we have to do a workaround via part of this RPIP. There is the possibility of fixing the contracts in Saturn, but so far no firm commitments either around a timeline for Saturn nor that the issue will even be fixed in Saturn.

To ratify this RPIP would therefore to me also mean signalling that “the pDAO is fine with contracts being broken in this way”. This is not something I can endorse, and would therefore vote against it. I am sympathetic to the view that we don’t want to delay the Houston release. To reconcile these views, I am open to going forward as-is without fixing the contracts if I can get a firmer commitment to fixing them in Saturn and some sense of timeline for when that will be (i.e. how long we will be in a broken state).

I have heard arguments saying that the issue is not worth worrying about because it is probably rare and only affects “weird” node operators. However, the full extent of the effect has not been fully documented, and it is not out of the question yet that the funds of weird node operators could get locked up because of this problem. I don’t think this is a defensible position for Rocket Pool as a protocol. Especially since anyone could accidentally become a “weird” node operator if they aren’t paying close attention to what the bug is and how to avoid it, i.e. reading all the text in an RPIP like this in detail, and/or paying close attention to all the messages in the governance channel on the Discord.

What’s the bug in the contracts? Essentially the issue as I understand it is that the contracts only allow claims of tree-based rewards by the RPL withdrawal address if an RPL withdrawal address is set. This is buggy because the RPL withdrawal address should not have dominion over Smoothing Pool rewards, but Smoothing Pool (ETH) rewards are included in tree-based rewards. RPIP 53 works around this issue for many cases but not for the case where the RPL withdrawal address is also a registered node operator. In that case it simply gives up and says “Don’t do that. You could lose your funds. We don’t make any promises about what could happen.”

1 Like

My preferred outcomes given this situation would be one of the following:

  • Fix the contracts before deploying Houston to precisely allow rewards claims from the correct addresses.
  • Commit to fixing this problem in Saturn, with a clear timeline, and ratify RPIP 53 in the meantime, and make a clear declaration of the risky-scenario-to-avoid for all node operators in the meantime.

I voted for “I support v10”. Time to market is important and this should not delay the release.

Apparently my original post is not so helpful, so here’s another attempt at some info that might be more helpful:

I’ve added an appendix that replaces the “here be dragons” note with examples of how various scenarios would play out: Update RPIP-53 with Appendix by jclapis · Pull Request #182 · rocket-pool/RPIPs · GitHub

This should help when deciding whether or not to support the proposal.

1 Like

The issue is well highlighted by Ramana above; essentially it’s that RPIP-31 has a section called Claiming RPL Rewards with this line:

  • If a node’s RPL withdrawal address is set, the call MUST come from one of: the node’s primary withdrawal address, the current RPL withdrawal address, or the node’s address

That’s technically true in Houston (if it’s set, it only works it it comes from the current RPL withdrawal address, which does follow the language) but the intent seems to be that any of those addresses should be allowed to trigger a claim. I think cleaning up that line to whatever the formal-spec-friendly-verbiage of that is will do; something like

  • If a node’s RPL withdrawal address is set, the call MUST come from ANY of: the node’s primary withdrawal address, the current RPL withdrawal address, or the node’s address

Then changing the contracts to respect that line would probably do it. That being said, this proposal has opened the door to some other uncertainties and/or opportunities that should be addressed, so we can probably do better than that fix alone.

1 Like

is my vote, but by ‘the issue’ I would like to specify that I see this as a first step towards making all rewards claimable by both the node address and withdrawal address to which the rewards will be sent in a future change. This means that this change will one day be generalized to use a withdrawal address as claimer_address in all cases, and the smart contracts will be updated to support that.


With the addition of the Appendix, and some of the other changes the RPIP author has implemented following discussion here and in Discord, I would like to explicitly state now that I am happy with the RPIP and no longer concerned about potential loss of funds or unfair or unspecified behaviour.

However, I still believe we can and should not allow the issue – the discrepancy between the intent of RPIP-31, and what is actually implemented and achievable in Houston + RPIP-53 – to stand indefinitely, or even for a long time. Hence I am not changing my vote on the poll. I still hope to see a commitment to resolve this issue in the next contract upgrade (or deployment, in case Houston needs to be changed anyway for some other reason). I would like this stance to be reflected for capture in the snapshot vote (if we haven’t secured a commitment by the time the vote is created).

1 Like