Design decisions for LEBs aside from collateral requirements

The community and core team have had many discussions about Low ETH Bonded (LEB) minipools recently. Most of the discussion has been focused on the question of what value of ETH can we safely reduce the collateral requirement to and whether reducing the ETH collateral requires a change to the RPL staking parameters too. There is on-going debate and research about these questions and while they are the most important ones to answer, there are also other design questions and technical implementation implications that need to be considered and have not had much brain power spent on them.

As such, this post will focus on the other design and technical questions and leave the ETH and RPL collateral question to a future more concentrated post.

How to handle rewards up to the point of migrating from 16 ETH to LEB pool?

There is (currently) no mechanism on the Execution Layer (EL) for reading the current balance of a validator. It’s for this reason we use the oDAO to submit balances to the EL periodically. Therefore, when we allow Node Operators (NO) to migrate from their current 16 ETH collateralised minipool to a LEB, we do not have the ability to record what the current balance is on the Consensus Layer (CL) at that time. And so when the validator finally exits, we would have no way of calculating the correct pre-LEB rewards.

For example, a minipool has been operating for 12 months as a regular 16 ETH collateral minipool. It has accrued 1 ETH of beacon rewards up until this point. At 15% node commission the NOs entitlement is 0.575 ETH. If the NO was to migrate the minipool to an LEB, and for the sake of simplicity in this example we chose 4 ETH node collateral requirement and keep the 15% commission, without any process to capture the rewards up until this point, the NO would now only be entitled to 0.25625 ETH if the exited. This means the NO loses 0.31875 ETH by migrating.

It is also likely that node commission will be different between 16 ETH and LEB minipools which further complicates this migration.

Solutions

1. Don’t allow migrations

Only alow new minpools to be LEBs.

Pros:

  • Least amount of complexity added to the protocol. Complexity can make it difficult to make changes later and also increases surface area of exploits.

Cons:

  • Contrary to design goal of expanding our NO supply.
  • NOs would have to wait for withdrawals, exit their minipool, wait in the exit queue, spin up a new LEB minipool. Wasting gas and time.

2. Allow migrations but don’t track rewards

Leave it up to the NO to decide if migrating is best for them based on their time frame. The additional yield achieved via LEB should exceed the rewards foregone after some period of time.

Here are some very rough numbers. Our longest running minipool has, at the time of writing, a 33.17687 ETH balance. This equates to 0.6767 ETH rewards for the node operator. If we dropped to 4 ETH and retained the 15% node commission rate, the NOs entitlement to the rewards would drop to 0.301573 ETH which is a loss of 0.375127 ETH. However, the NOs yield would increase from 4.98% to 8.88% (not counting MEV). This represents an increase of 1.248 ETH a year in rewards and approximately, 3.5 months to break even. The increase in MEV yield would make this even shorter.

If node commission is lowered so that rETH receives a portion of the additional yield, this problem is exacerbated.

Pros:

  • Requires no extra complexity to minipool distribution logic.

Cons:

  • Doesn’t handle slashed minipool balances (if minipool has been slashed significantly, there’s no protection against them migrating to LEB and getting a refund). For this reason, we believe this option is a nonstarter.
  • NOs have to decide to forgo rewards they have already accured in exchange for the increased yield.

3. Line in the sand merkle tree

We pick a CL block number as close as possible to the time LEBs are going to be introduced and do a snapshot of all minipool CL balances on that block. A merkle tree is generated that contains the current balance and commission rate for each minipool. The root is published to the EL. When a NO migrates to an LEB, they submit a proof which is validated against the root. The node’s share of the rewards up until this point is stored in the minipool and it is then migrated to an LEB. On distribution, there is additional logic which takes the stored balance and commission rate at the snapshot block and calculates the appropriate rewards from those inputs.

Pros:

  • NOs who migrate only forgo the delta in rewards between the line-in-the-sand block and when they migrate which will be insignificant for people who migrate sooner rather than later
  • Solves the problem of how to handle slashed minipools (will go into more detail below)

Cons:

  • The longer NOs wait to migrate the more rewards they are forgoing when they do finally migrate.

4. Multi-step migration process

NOs would submit a request to migrate which the oDAO would queue. The oDAO would then periodically snapshot the balance and commission of the queued minipools and submit it to chain (could also be a merkle tree and done in batches). NOs could then perform the second step in the migration process which would be another transaction. This transaction would contain the relevant proof and leaf node data that verifies their balance and stores it on the minipool contract along with the old commission rate. Then much like the line-in-the-sand option, there would be additional logic on distribution to calculate the rewards.

Pros:

  • There is no immediate pressure for NOs to migrate to an LEB as they are not losing any reward opportunity.

Cons:

  • Significantly more complicated then the other two options. More complexity makes it harder to make future changes and creates more surface area of attack.
  • Adds another oDAO responsibility to the protocol.

5. Refund “lost” rewards

Instead of adding additional logic to the distribution process and storing balance and commission at time of migration, we could create a merkle tree that contains the calculated shortfall in ETH by migrating and then increase the capital refund to NOs by this amount. This would be done similarly to the line-in-the-sand merkle tree option.

E.g. In the example given earlier where our longest running minipool forgoes 0.31875 ETH in rewards by migrating, this value would be calculated for every minipool and stored in a merkle tree. When migrating instead of receiving a 12 ETH refund, the NO would receive a 12.31875 ETH refund. Then when the minipool exits and funds are distributed, the user portion is overestimated by 0.31875 so it equals out.

Pros:

  • Same as option 3.
  • There is no difference between new LEB minipools and minipools that have migrated which makes things slightly less complex.
  • NOs get access to capital that would have otherwise been locked until withdrawals to put towards additional minipools.

Cons:

  • Same as option 3.
  • That ETH would have otherwise been locked and could be used as a buffer to protect rETH holders from that minipool being slashed.
  • Creates more demand for liquidity from the rETH deposit pool.

Distribution logic

Some pseudo code for how distribution might work post-migration for option 3 and 4:

// balance_at_migration and commission_at_migration come from merkle tree

if (current_balance < user_capital) {
	node_distribution = 0
	user_distribution = current_balance
} else { 
	if (balance_at_migration > 32) {
		pre_migration_rewards = (balance_at_migration - 32)
		pre_migration_slashing = 0
		pre_migration_rewards_node = (pre_migration_rewards / 2) + (pre_migration_rewards / 2 * commission_at_migration)
		pre_migration_rewards_user = pre_migration_rewards - pre_migration_rewards_node
	} else {
		pre_migration_slashing = 32 - balance_at_migration
		pre_migration_rewards_node = 0
		pre_migration_rewards_user = 0
	}

	if (current_balance > balance_at_migration) {
		post_migration_rewards = (current_balance - balance_at_migration)
		post_migration_slashing = 0
		post_migration_rewards_node = (post_migration_rewards / 2) + (post_migration_rewards / 2 * current_commission)
		post_migration_rewards_user = post_migration_rewards - post_migration_rewards_node	
	} else {
		post_migration_slashing = balance_at_migration - current_balance
		post_migration_rewards_node = 0
		post_migration_rewards_user = 0
	}

	total_slashing = pre_migration_slashing + post_migration_slashing

	node_distribution = node_capital - total_slashing + pre_migration_rewards_node + post_migration_rewards_node
	user_distribution = user_capital + pre_migration_rewards_user + post_migration_rewards_user

}

assert(node_distribution + user_distribution == current_balance)

How to handle penalised and/or slashed minipools who want to migrate?

Migrating to an LEB could be a way to bypass penalties or get around slashing. If a 16 ETH minipool had a 50% penalty (8 ETH), migrating to a 4 ETH pool would refund 12 ETH giving the NO access to funds that would otherwise been withheld from them on distribution. Or if a minipool has a significant slashing event and their balance drops well below 32 ETH, they could migrate to receive more funds than they are entitled to.

Solutions

1. Prevent penalised/slashed minipools from migrating

If a minipool has a penalty, it is prevented from being able to migrate. Unfortunately, CL balance is not available on EL. So in order to prevent a slashed minipool from migrating, we would need to adopt one of the two merkle-tree solutions to the rewards migration problem.

2. Allow slashed minipools to migrate and track their slashing

If we adopt one of the merkle tree solutions to migrating, we will have the balance and commission rate at the time of migration so it is possible to allow slashed minipools to migrate and just keep track of their slashing for distribution. The pseudocode shown above handles this scenario.

We would still need to ensure minipools with penalties greater than the LEB ETH collateral requirement are prevented from migrating.


How to handle the refund from migrating to an LEB?

When migrating to an LEB there is a portion of the NOs collateral which is freed up. The additional collateral is taken from the deposit pool and the freed up capital can then be used to create more minipools. The question is, do we refund the ETH back to the NO so they can do whatever they want with it, or do we restrict them to using the freed up collateral to running more minipools?

Solutions

1. Refund the ETH to the NOs withdrawal address

If LEBs required 8 ETH instead of 16, each migrated minipool would take 8 ETH from the deposit pool and it would be deposited into the NOs withdrawal address. The NO could then choose to spin up another minipool or simply take the ETH and do whatever they want with it.

Pros:

  • NOs with multiple minipools can use the ETH to acquire more RPL which may be required operate more minipools.

Cons:

  • Might result in NOs extracting collateral and then not putting it back into the protocol. This means the protocol has taken on more risk without receiving any benefit which is contrary to the design goal.

2. Apply a “credit” to the NOs account for the balance

When a minipool migrates to an LEB the difference in colleteral is added to a “credit” balance for that NO. When the NO spins up another minipool, their credit balance is deducted and they only need to send enough ETH to top up the difference in their credit and the amount required for a minipool.

e.g. NO has 5 minipools at 16 ETH. LEB collateral requirement is 6 ETH. They migrate all 5 minipools receiving 50 ETH credit balance. The NO can now spin up 8 more minpools without offering any additional ETH as collateral. Their credit balance is now 2 ETH so on their 9th minipool they must supply 4 ETH difference.

Pros:

  • Freed up capital from migrating must be used to create additional minipools.

Cons:

  • The freed up capital can’t be used to acquire additional RPL that might be required to spin up the additional minipools.
  • Adds some UX complexity to the NO experience as NO has to keep track of their credit balance + their ETH balance when creating pools.

Are 16 ETH minipools still supported?

This question has some overlap with the ETH/RPL collateral question and some discussion has been had regarding this. See: Variable minipool size w/RPL stake based on protocol ETH

In the case we don’t proceed with variable minipool collateral sizes, the question remains as to whether 16 ETH minipools are still supported so I will keep this here for completeness.

Although this is another design decision, it is likely that node commission will change for LEBs. This is so rETH users receive a portion of the additional yield generated by the greater capital efficiency of LEBs. This means, in order to continue supporting 16 ETH minipools alongside LEBs, we would need to offer two different node commission rates. This adds some new user complexity to the protocol and requires additional decisions to be made by new NOs.

The consideration for why we would continue to support 16 ETH minipools is one of risk. Due to the way Rocket Pool uses NO collateral first to handle slashing loses, NOs take on additional risk when operating an LEB compared to a 16 ETH minipool. As to why we would not support them any more, LEBs provide greater capital efficiency and provide greater yield to NOs which allows us to share some of that additional yield with rETH holders and overall make Rocket Pool a more attractive product.

So the trade off is NOs assuming greater risk, receiving greater reward and also providing the protocol with increased capital efficiency. And the question is do we want to give NOs the option or force all future minipools to operate at the higher risk/higher capital efficiency model?


How to handle delegate rollbacks?

This section talks about some low level technical implementation details of Rocket Pool minipools and the implications it has on adding support for LEB migrations.

In order to add LEB support to Rocket Pool, we will need to make changes to the minipool delegate contract. This is the contract which minipools delegate all calls made to them to. Rocket Pool was designed to allow NOs to opt in to delegate upgrades. This is an insurance system so that if a malicious oDAO upgrades minipool logic, NOs can always chose to ignore it and they will be able to exit their validator and distribute their capital via the logic they agreed to when creating their minipool. It also acts as an insurance mechanism against bugs/exploits as it allows NOs to roll back to a previous delegate that does not contain the bug/exploit.

To allow minipools to migrate to an LEB they will need to perform a delegate upgrade to get the new functionality. They will then call a migrate function which will refund the difference in collateral between 16 ETH and the LEB ETH collateral requirement. This migrate method will also update the minipool state to record that the NO only has the reduced amount of capital so that when distribute is eventually called, the lesser collateral amount will be returned to them.

The issue is that a NO could upgrade to the LEB delegate, perform the migration, then rollback to the original delegate. The original delegate doesn’t know how to handle the reduced LEB collateral and simply splits rewards in half and calculates commission. So the NO can now get the benefits of posting less collateral but receiving rewards as if they have 16 ETH posted.

The idea I have to prevent this exploit is to essentially corrupt the state of the minipool on migration (and store the correct values in a new storage slot) such that if a rollback is performed after a migration, the previous delegate calculates the node share to be 0. Hence, neutering the attack. Technically, this would be implemented by setting userDepositBalance to some high value during migration and storing the correct userDepositBalance in a new blank storage slot. If a NO upgraded, migrated, rolled back, exited, and then distributed, all the ETH would return to rETH users and the NO would receive nothing.

This prevents the attack but breaks the intention of the rollback which is to allow NOs to rollback to a “safe” delegate. Therefore, there is a security trade off to be made to support LEB migrations. I don’t see this as a major issue as new minipools are created with the latest delegate and have no option to rollback so it’s the same decision an existing NO has to make as a new one.

10 Likes

Thanks Kane! Great writeup and some great ideas in there. Here is some initial thoughts:

How to handle rewards up to the point of migrating from 16 ETH to LEB pool?

Seems like the next question kind of forces a merkle tree solution. I don’t think 4 is necessary. As long as people migrate within a month or two of the line in the sand, losses from waiting should be pretty minimal. There should also be plenty of notice before this goes live, so if someone really wants to min-max this, they should be able to do so. Don’t have an opinion yet on 3 vs 5.

How to handle penalized and/or slashed minipools who want to migrate?

I think slashed minipools definitely shouldn’t be able to migrate. Slashed minipools aren’t earning rewards anymore. So allowing migration means that node operators can turn unproductive locked up ETH into productive ETH, at the cost of rETH holders that now own a bigger share of the ineffective validator.

How to handle the refund from migrating to an LEB?

I like the credit system. Depending on what collateral requirement we land on, I think we may want a way to allow partial refunds of credit eventually.

In this example, the NO may not want to supply the extra 4 ETH. The protocol would still benefit from them creating the 8 extra minipools, so maybe it’s ok to allow a one time refund of “credit dust” (credit less than the LEB collateral requirement). Without, the only way to redeem credit dust would be to create and immediately withdraw a minipool.

1 Like

Re: rewards, wouldn’t it work for Node Operators to just skim and claim existing rewards before migrating?
As far as I know, skimming > 32 ETH balances is planned for the withdrawals HF. This will likely even happen automatically periodically.
I’m not entirely sure if/how the existing minipool contracts can handle this, but they will need to handle that use case regardless.

1 Like

How to handle rewards up to the point of migrating from 16 ETH to LEB pool?

Preference: 3 or 5

From an NO perspective, they trade off a very small amount of rewards for greater future rewards. This scheme encourages NOs to act relatively quickly, which is good overall imo. The idea of “waiting too long” and no longer wanting to migrate always has the fallback of withdrawing and creating new pools.

How to handle penalised and/or slashed minipools who want to migrate?

Preference: 1

For simplicity, I think I agree with @knoshua. There may be a rare case where a minipool was heavily slashed at some point but is still active – that edge case always has the fallback of withdrawing and creating new pools.

How to handle the refund from migrating to an LEB?

Preference: 1 with a twist

I think refunding is simpler. A assumption of LEBs is that they are derisked “enough”, so we shouldn’t continue counting risk vs 16ETH-bond as a criteria (if they’re not derisked “enough”, then we should increase the minimum LEB or similar). If that’s true, then there are no Cons to this idea. I think there’s also a missing Pro: even if an NO migrates from 16ETH-bond to 8ETH-bond, the protocol still gets something – it’s able to match an additional 8ETH of deposits to mint rETH (this Pro is only valid when the deposit pool has ETH in it).

For either method, I think there’s a challenge if the deposit pool is low/empty. For method 1, you wouldn’t be able to get an immediate refund (probably queue up behind new minipools and ahead of rETH burning). For method 2, you wouldn’t be able to effectively use your credit until the pool has enough ETH (queue as a new minipool).

A variant on option 1 would help when the deposit pool is empty: we could refund in rETH instead of ETH. In this case, a migration from 16ETH-bond to 8ETH-bond would mint just under 8rETH that could be provided right away. The NO could determine whether they wish to keep the rETH, wait until there’s enough in the pool to burn the rETH, or sell at market rate to get immediately deployable capital. To be clear: my suggestion is to have the refund denominated in ETH if the pool has enough, and rETH if the pool doesn’t.

A concern if we opt for method 2

If we go with method 2, I feel strongly that we shouldn’t hold funds hostage. In other words, if the credit isn’t enough to create an LEB, we must allow some form of refund. I think we should encourage NOs to stake through rewards, not through force. I’m even a little hesitant to force them to keep something like 6ETH as a credit – what if they’d want to sell part of the ETH for RPL in order to spin up another minipool? The credit system forces users to not just keep the current money, but to invest NEW money.

I think it’s possible to tweak method 2 to allow some refunding that mitigates this concern… but it seems significantly more complicated for a questionable benefit (forcing investors to maintain their level of investment), especially once minipool exits are possible. Once we have exits, then if an NO wants to reduce their investment, they could migrate, get their credits, use them on LEBs, and exit the new LEBs. This is a pain, uses a bunch of gas, and gets us to a similar place as a refund.

How to handle rewards up to the point of migrating from 16 ETH to LEB pool?

It seems to me there might be a way to do a modified version of solution 3 - Update that merkle tree/balance report at regular intervals (monthly?) so that operators that don’t want to jump into LEB’s right away (ie if gas is crazy when it launches) don’t get increasingly left behind.

And I’m wondering if it could be even more frequent - if the odao were to post the beacon root into a contract on the execution layer at a more frequent interval (daily, weekly?), couldn’t the operator themselves build a merkle tree to match that root, and then snapshot their balance on migration that way?

1 Like

This beacon root submission is a good idea worth exploring.

My only hesitation for this is that it adds an oDAO duty for something that is a temporary problem. Once all the minipools that want to migrate have done so there’s no need for the oDAO to continue posting the beacon root. Although, having the beacon root could remove the need for oDAO to submit withdrawable statuses to the EL.

Worth noting is this duty would only be required until EIP-4788 (or similar) is implemented and then we can stop posting it and use the the built-in method.

Thanks for idea!

Agree on all points and I like the idea of allowing refund of credit balance below the value of a single minipool. That sounds like a reasonable compromise.

In regards to the slashed minipools. They way you put it is a great way to look at it and I agree that slashed minipools shouldn’t be able to migrate. There’s also another case I didn’t mention in my post where the validator isn’t slashed but has performed poorly and has a balance below 32 ETH. We could include in the merkle tree whether they are slashed and prevent the slashed ones from migrating while allowing the sub 32 ETH ones to migrate and just carry that information forward into their LEB like is done in the pseudo code I posted.

Great point. If we have skimming before LEBs then that would simplify the migration. Simply have the new delegate distribute the skimmed fees prior to migrating.

1 Like

The refund in rETH is a clever idea. It solves the issue of having to juggle migration refunds from the deposit pool and new assigning ETH to new minipools.

One point to consider is there could be tax implications as the NOs ETH is swapped to rETH which might be considered a taxable event in their country whereas staking/unstaking is not. Therefore, it should be an opt-in thing where if the deposit pool is empty you can choose to take rETH instead. I think that might be what you were suggesting anyway.

I had a conversation in Discord here https://discord.com/channels/405159462932971535/971215160192688138/981669583125610668 Based on the discussion that followed here are my thoughts:

A. How to handle earned rewards. We need to use one of the Merkle tree solutions. Since the refunded NO deposit will come from the deposit pool I believe we will need to use a method that does not require all of the current half-mini pools to transition at the same time.

I would like to see the conversion Merkle tree generated with the 28-day RPLclaim Merkle tree as a multi-leaved Merkle tree. It can use the same IPFS distribution system. RP can commit to generating this conversion pathway for some fixed duration of time (e.g. 18 months or some duration that ends after beacon chain withdrawals are anticipated). RP would include the per minipool data required for migration in the reward Merkle tree for 18 months then after that go back to only include the reward data.

After that 18-month period expires, any v1 minipools wanting to convert to LEBs would then have to beacon-withdrawal (should be allowed by then), exit (closing the old v1 minipool contract) and reenter the queue as a LEB.

B. How to handle penalized minipools. I agree that slashed and minipools with a balance of less than 32 ETH should not be allowed to migrate. Of all the minipools these are the ones that regular stakers (rETHers) will want the NO provided 16 ETH acting as an insurance tranche. Once the underwater minipool balance improves back to 32 ETH or greater it should be allowed to convert.

C. How to handle the refund. Providing cash refunds (in ETH) to the NO does continue to support the LEB prime mission of adding “lift capacity”. For illustration, if at present we have 6000 minipools they currently provide a lift of (5000 x 16) 80,000 rETH. If they all convert to 8 ETH LEBs and the NOs walk away with their refunds to buy NFTs, the RP protocol still has added lift capacity of 5000 x 24 = 120,000 rETH lift. Combine that with the strong financial incentive of LEB’s high APR returns, the majority will be NOs will want to double down and stake again with RP. IMO we should give NOs that choice and keep it simple on the code development by just refunding them in ETH and not credits.

D. Are 16 ETH minipools supported. I do like the idea of variable minipool collateral sizes. However, even if we did not support variable minipools we can still support a few tiers as the contracts do now: half-minipools (16 ETH); quarter-minipools (8 ETH) and eighth-minipools (4 ETH). Doing so does not mean that we need different commissions for each tier. We could for example just assign the same node commission for all tiers of minipool types. For example, setting them at an ideal fixed 10% node commission.

E. Rollbacks. Question. I support this approach. For the example of a series of minipool contract upgrades ( A → B → C ). Where LEBs are enabled in minipool delegate B. The jump from A to B is a one-way door. But from B to C the NO can rollback. This makes sense as the risks are minimal to the NOs that decide to transition. This is the same risk that all NO took from null → A. That was a one-way trip. RP just needs to communicate clearly that upgrading from A → B is also a one-way upgrade.

3 Likes

Yeah - I like it as a way to avoid the queue, so ideally optional or at least warned (“Migration refunds are currently being paid in rETH, please type rETH in the box to proceed”). Hadn’t considered the tax implications, but that does make this even more important.

C. Only issue I see is, where do we get all the ETH from to issue the refunds?

D. Doesn’t keeping the commission at 10% for any sized pools contradict Marceau’s whole argument that as ETH provided by NO goes down, minimum RPL commission should go up?

D. Not sure I follow what “minimum RPL commission” is referring to. Agree that commission should be variable though. Arguably it needs to be in order to make the economics of LEBs work out. Otherwise they would have a higher (as a percentage) gas costs, higher slashing and offline penalties (as a percentage), higher RPL requirements, but no higher commission.

It also makes sense logically since a LEB would be minting more rETH so they’d be entitled to the commission from that.

One thing I love about the LEB design idea is that it now makes the value RPL super clear. RPL unlocks commission. More RPL means you’re allowed to collateralize more ETH from the protocol, meaning you can extract more commission. Simple and clean.

1 Like

Is there a max RPL collateralization for each LEB?

1 Like

Current thinking is 10-150% of the ETH that is pulled from the deposit pool. So 2.8-28 ETH (of RPL) at 4 ETH for example. All this is subject to debate of course and not finalized at all.

But, the topic of this thread is “aside from collateral requirements” so we can probably table that discussion for another thread. :slight_smile:

1 Like