makemake's blog

How you can completely decentralize Ethereum staking with two (simple) opcodes!

12 min read

There has been quite a lot of discourse around Lido and Ethereum staking. Everyone is split into two camps. Those who praise Lido for enabling easy access to Eth yield, and those who say Lido will send all of our bags straight to zero, as well as send Japanese yakuza to murder you and your family for using it.

People are so polarized regarding Lido because of one key issue: its stake weight. As it stands, Lido has around 33% of all Ethereum stake under its control. And yes, there is nuance to this. This stake is delegated to various third parties who do the staking for them.

stake distribution
lido validator delegations Lido-controlled entities own 32.23% of the stake.

Fearmongering aside, this is a genuine concern. Mainly because it highlights how broken Eth staking and delegation are. If you want staked eth exposure and don’t want to stake yourself, you must trust centralized parties to behave appropriately (Rocket pool does not count, and we’ll get to why it doesn’t). To be clear, I am not arguing for dPoS. It’s unsustainable and insecure, which you can read more about here. Our goal should be to enable individuals who do not meet the minimum staking requirement to run validators for others in a trustless fashion.

Quick rundown on the beacon chain

If you need to familiarize yourself with the beacon chain, I recommend the ethereum.org wiki as a good starting point. I will only cover parts of being a validator that are important to us.

Depositing

To start validating, you must deposit 32 ETH into the deposit contract and a validator signing and withdrawing key.

ETH 2 key diagram

This is awesome, as the validator key can only participate in consensus and initiate a voluntary exit(withdraw). If our validator key gets leaked, the worst thing that can happen is for the attacker to try and slash the validator. Another fantastic property of the validator key is that its BLS, which allows for simple threshold signatures (aka MPC) and aggregation.

Validator status

Once we send a deposit transaction, a validator can be in the following states:

  • Deposited, wait for the network to finalize the deposit transaction.
  • Pending, wait for the validator to become active. It varies based on how many validators there are, as well as the size of the queue.
  • Active, we are participating in Ethereum’s consensus.

If our validator is active, and we are not attesting or producing blocks, we incur penalties. If we want to exit the beacon chain, we get placed in the withdrawal queue, where we are still active but waiting on the network to remove us.

A validator can also be forced to exit if its balance drops below 16 ETH or gets slashed for misbehaving.

Rewards and withdraws

Validators get two types of rewards: Consensus layer and execution layer rewards.

The validator gets consensus layer rewards from participating in consensus. They are withdrawn to the withdrawal key we set up when we deposited our initial 32 ETH. We can initiate a withdrawal (voluntary exit) by broadcasting a message signed with our validator signing key. Execution layer rewards are the gas fees we get from producing a block. This also includes MEV. This address is the fee recipient, set on the CL client.

Where we’re at now and why our current state is problematic

If you want to participate in consensus, you have no alternative but to set up your validator with 32 Eth. This is by design. Ethereum PoS was designed explicitly not to have delegation. As we mentioned before, dPoS is prone to capture and has no culture of individual verification.

The second part is crucial. For a blockchain network to truly be sovereign, you must have users running nodes. Think back to when OFAC-sanctioned tornado cash and public RPCs started getting censored. Or Infura explicitly collects Metamask user data, tying addresses to IPs and real-world identities.

Most importantly, out of all of this, when you have a culture of users running nodes, it becomes impossible to have a malicious hard fork. We have a hard enough time getting people to update before regular hard forks. Now imagine trying to force a coercive one without anyone objecting.

When you delegate Eth to Lido, their node operators start to make these important decisions for you. Thankfully, there have been significant moves to reach a point where you can delegate in a trust-minimized fashion. And the leader here is Rocket Pool.

What we need

So, for us to achieve our goal of decentralized delegation to individuals, we need the following:

  • Communication between the Execution and Consensus layer.
  • A way for delegates to force exit delegators.
  • A way to punish delegators for misbehaving/not participating.
  • Infra to support decentralized, or at least trust-minimized depositing.

The first item on the list is the most complex. Rocket Pool is often mentioned as a decentralized place to which you can delegate your Eth. Unfortunately, it’s far from trustless due to how it handles the problem of EL<>Cl comms. We need to understand why Rocket Pool is like this to talk about how to be fully decentralized.

The EL<>CL problem

As it stands, the EL and CL cannot communicate natively. If we are building a fully automated system, our contracts need to know if a validator behaves as it should. In essence, we need to know the following about a validator:

  • Validator balance and status.
  • If withdraw credentials we’ve used before.
  • Attestations.
  • Fee recipient.

We can already get the fee recipient from the EL directly. Unfortunately, there isn’t a native way to do this.

Rocket Pool handles this with their oracle. The oracle posts data about validators to the EL to ensure everything runs smoothly. Unfortunately, it’s designed so that only whitelisted individuals can participate. There is no way for users to contest these updates so that malicious oracle operators can grieve the system. This is unlikely to happen, as the people running them are vetted and have their reputations on the line, but we should not be relying on people being honest for such an essential part of the protocol.

Getting CL data

In a perfect world, we would get new opcodes to handle this. How exactly these opcodes should look like and function, I’m not sure. A rough draft of what this would look like is below.

VAL_STAT
Stack input: 
- Validator index
Stack output:
- Balance
- Status

VAL_REWARDS
Stack input: 
- Validator index
- Epoch range
Stack output:
- Rewards missed

With the following opcodes, we would get all the information about what a validator is doing. These opcodes are read-only, so they should have little security implications. Because most people set up their clients to communicate via json-rpc, these opcodes should cost a LOT of gas. The epoch range for VAL_REWARDS should also probably have a limit. We need to know how many rewards will be deducted from a delegate’s balance. Where the sweet spot between security and accessibility and CL bloat should be, I’m not so sure.

We could also have opcodes that give us more info about the beacon chain, such as the number of validators, and from that, we can calculate what our rewards should be. From there, we can extrapolate what our balance should be.

This is mostly me thinking out loud and not a serious proposal for new opcodes. Please let me know what you think, especially if I need to correct something about how the CL works concerning this.

Getting CL data, poverty edition

But what if I told you we already have everything we need to delegate trustlessly?

With the power of optimistic oracles, we can shuttle around CL data to the EL in a trust-minimized way. If you’re okay with optimistic oracle security properties and finality, we can build trustless delegation today. For more on optimistic oracles, I’ve written an article about this here.

An oracle like UMA would be perfect for our use case. It’s designed to be highly generic, so as long as you can provably reconstruct data you want on the chain later, you can use it to prove anything.

Tying everything together, how a trust-minimized delegation system looks like in practice

Using what we described, you can build all kinds of trustless delegation systems. In a hypothetical scenario where we are all delegating trustlessly, everything will be peer-to-peer, lido-like, or a combination of the two.

Peer-to-peer

In a peer-to-peer system, delegates and node operators would communicate directly. A node operator and delegator would use MPC to generate the keys, the node operator would post a bond, and the delegator would deposit the Eth.

If a node operator misbehaves, the delegator would be able to initiate an exit and receive the bond as compensation. This approach would work using the optimistic oracle or the new opcode method. The only practical difference is that dispute resolution would take longer. Given the fact that we are dealing with >100k USD amounts, this is okay.

We also have the problem of the delegator needing to run a keeper that checks if the node operator is misbehaving. Although, this can also be delegated to someone else. A peer-to-peer market is also not very scalable or liquid, so lido-like systems would likely appear.

Lido-like

Currently, Lido delegates its Eth via centralized node operators. If they were to decentralize in the way we described, Lido could entrust its Eth to its existing node operators, with an added twist of being able to slash them. Going one step further, they can totally delegate this slashing capability to their DAO and token holders. Essentially turning Eth into a pseudo-dPoS-PoS hybrid.

Conclusion

Is this practical? Maybe? This is me thinking out loud, and I have yet to put too much into consideration how various aspects of the protocol are likely to interact with each other.

Are we going to see any of this hit production? Also maybe. Rocket pool is pretty much how our Optimistic oracle approach would look but with a centralized oracle.

This topic is interesting, and we need more real conversations about embracing decentralizing Eth delegation. The market has clearly spoken about its needs, and the faster we build trustless delegation layers, the more resilient Ethereum becomes.

Addendum: LSD risks

Whenever LSDs get talked about, talks of risk inevitably follow suit. At a very high level, I would classify any risk in DeFi (and crypto in general) as governance and protocol risks. For more on this classification, read this article.

Depending on the protocol, what these risks are and what their implications are vary wildly. When talking about LSD protocols, adding subcategories to these classifications is helpful. For example, we can talk more in-depth about counterparty risk when talking about protocol risk while discussing LSDs. LSDs have an inherent reliance on counterparties as a core part of their protocol, so it makes sense to talk about it more in-depth.

I will try to keep this section brief while conveying all the risks.

Lido risks

Lido on Ethereum works by interacting with a smart contract that accepts ETH and gives you stETH. stETH is a rebasing token that accumulates the rewards and should be backed 1:1 with Ethereum. Users can redeem stETH for Eth whenever they please.

Protocol risks

As mentioned, Lido delegates their ETH to be staked to third parties(node operators). While these third parties control how the Eth is staked, Lido is still the owner of the Eth.

Node operators follow strict guidelines, including setting specific fee recipients and withdrawing credentials. This means that node operators cannot directly rug users. If a withdrawal is initiated, it will go straight to Lido.

Node operators can however soft rug lido holders. They can intentionally misbehave to get slashed, losing Eth in the process. However, there is no reason to do this. The node operator can not extract funds by doing this directly. Lido should be able to initiate withdrawals on a node operator’s behalf if the keys are set up correctly (I have yet to encounter this mentioned anywhere in the Lido docs, though). This means that potential bad actors looking to control a large amount of ETH will be effective in the long term.

The Lido oracle network is similar to the rocket pool network, and both shuttle identical data from the CL to the EL. Individuals chosen by the DAO presumably run the oracle network. I have not found proper docs to what extent users can get impacted by malicious Oracle networks or how exactly they are chosen.

Governance risks

The functions the Lido DAO has that directly impact LSD deposits are:

  • Node operator onboarding.
  • Set various fees and parameters.
  • Act as the treasury for said fees.

Your ETH is safe if the DAO does not approve a malicious node operator or mismanage the fees.

Lido also has a security council to deal with potential node operator misbehavior. A node operator can prefund a deposit with 1 ETH to their withdrawal address. The ETH later deposited to this validator can be withdrawn to the malicious credentials instead of the Lido-approved ones.

Overview

Overall, Lido is very safe. Its few points of centralization are relatively minor and can not cause insolvency to the protocol if other decentralized parts behave as intended.

However, what is to be noted is the large concentration of Eth a quorum of node operators has. This could be better for the overall health of the network. Most of the ETH is staked at cloud providers like AWS and not on infra owned by the Node operators. When us-east-1 had an outage a while back, a large part of the Solana stake went offline, and the network performance degraded by quite a bit. It would be awkward if this happened with Lido. As a solution, I would advise the Lido DAO to force node operators to diversify their infra and release transparency reports to better protect against censorship and other potentially malicious activities.

Rocket pool risks

Rocket pool is a different take on LSDs. Instead of delegating to trusted third parties, anyone can technically become a node operator for rocket pool.

Protocol risks

(todo)

Governance risks

(todo)


Vukašin Gostović

Im makemake and I like it when people put blocks in a chain and turn that into a database. Love building useful programs and anything infra. I like reading about psychology, sociology, and philosophy. I have been making computers do stuff since i was ~11 years old. Rust is pretty cool. I'll mostly be writing about Ethereum and blockchains as that's what my time is mostly preocupied by. Feel free to reach out via my links below if you have any inquiries!