What we already have:
- deployed Deposit contract, we cannot rollback this
- contract verifies that
withdrawal_credentialsare of 32 bytes length, so we couldn’t put anything longer in it using current deposit contract
0x00are committed (with hash of BLS withdrawal public key), though contract doesn’t verify it, so we could use other prefixes without changes in contract
What do we want:
Make withdrawals usable both for individual users and different kinds of pools, both custodial and non-custodial. In best case pool assets should be tokenized to fulfill investor’s needs, so it would be easy to invest fractional values less than 32 ETH and exit to money whenever requested by each co-investor. We expect validator stake could be used for issuing derivative assets secured by stake in DeFi or similar, attract more funds in staking and increase development of derivative financial instruments in Ethereum. Pools and tokens should be secured by a well proven mechanism of Ethereum contracts to meet the needs of both investors and pool owners without much trust to each other.
How could we do it:
Push vs Pull
- Limited receive contract capabilities
- only default method could be called
- what gas limit should be set?
- User is limited in handling of withdrawal costs
- Awkward errors handling (if failed, how to pull?)
- Someone should send TX or call System Contract in Eth1 to initiate
- Caller could manage withdrawal result and execute any logic on top
With the target of keeping core Beacon Chain logic as simple as possible, PUSH with the same capabilities will be more complex, therefore PULL proposed for
0x01-prefix should be preferred.
What is important, it also works for trustless pools:
New event is proposed for Eth2,
BLSSetWithdrawalAddress which could change
withdrawal_credentials. Some details about its handling:
- we verify that current validator’s
withdrawal_credentialsis started with
- we verify that new credentials are started from supported prefixes and are not
What this means for usage:
- Validator’s BLS withdrawal key couldn’t be changed
withdrawal_credentialsdoesn’t mean any particular withdrawal target, it means that withdrawal target will be submitted later and should be signed by appropriate key
0x00) could be set only once by submitting
BLSSetWithdrawalAddressat any time even after
withdrawable_epoch. We check whether validator is eligible for withdrawal right now in the end of processing
- Once additional prefixes are confirmed, they could be used in
withdrawal_credentialswhile making deposit by Deposit Contract call
withdrawable_epochis hit by validator, we check whether
withdrawal_credentialsare set to smth starting with a prefix other than
0x00. If it’s, process it, otherwise doing nothing
Some opposes and defends on this decisions:
N: What if BLS withdrawal key is compromised, I should be able to change it
A: You could set an exact withdrawal target in this case, since you are protected from anything signed by a compromised key.
N: What if I set withdrawal to contract address in eth1 and its compromised
A: You could submit a withdrawal contract address change signed by BLS key at any time, so the safest way is to do it, when you are confident in the withdrawal target. If it’s allowed to change withdrawal credentials from one eth1 address to another, the dilemma appears, who should sign such a change. Both pools and their users could could trick each other if it’s allowed.
NN: We could add
is_final flag, so when it’s false, you could submit another change
AA: If it’s not final you could submit a change signed by withdrawal key and change it, so not a final field secures nothing. So it’s the same as having
withdrawal_credentials started with
BLSWithdrawalPrefix but without extra complexity.
There are several concerns about partial withdrawals, let’s dive into it. The main challenge of developing withdrawals is non-symmetry of eth2 with eth1. While it looks like both networks have some kind of accounts and balances associated with it, there are a lot of nuances
BeaconStateand Ethereum 2 don’t have any kind of transaction-like mechanics, so if it’s introduced, we should care both about security and speed. We have about 15 TPS in Ethereum 1, and we target hundreds of thousands validators in Ethereum 2. Partial withdrawals, if available, could increase
BeaconChainload or even delay more important messages.
- Ethereum 2 events are not subject to any fees. It guarantees fastest and equal processing and is part of network safety requirements. Increasing the number of events dramatically could affect other Ethereum 2 events processing and so whole network safety.
BeaconStateis not going to be stateless. It’s the minimal state your client should have to be in Ethereum 2. And we expect that clients could be mobile clients, IoT clients etc in the future. So the target is to keep
BeaconStateas small as possible, with the smallest number of changes on each slot/epoch.
What’s on the other side. Do we really need it?
- Validator could exit and withdraw whenever it wants in less than 24 hours, it’s fairly good liquidity for financial instrument
- Reward payment schedule is similar to some kinds of financial instruments like bonds and bank deposits, though both could provide intermediate payments before the end date.
- If withdrawal is built to make possible construction of pools with tokenization of investment, end user gets a contract which is traded and its price grows since the first date, so rewards could be collected before end date minus some premium
- There is minor interest drop due to the lack of partial withdrawals, but it’s the same for all validators
Interest drop estimations
Let’s estimate interest rate drop by sticking with only full withdrawal:
- Resign rate drop: (55 hours delay is used) If resigns happen less frequently than every 7 months drop is under 1% of advertised rate (for example, 3.96% instead of 4% or 19,80% instead of 20% on start).
- Compound interest rate drop: If we take same 7 months, 0.05% annualized rate miss for 4% annual reward rate (4.05% finally), 1.33% annualized rate miss for 20% of annual reward rate (21.33% finally), so it dramatically increases with speculation reward rates, but in mature network it’s less dominant. At the moment reward is already under 15%.
- Inability to invest funds rate drop: It’s difficult to give a range, as in the worst case, when you have 31.99 ETH and that’s all, you lose all rewards, and with 32 ETH you get all possible rewards. The main rule here is: the less ETH you have the more you lose, but even when you have 351.99 ETH, you have almost a 10% drop rate (3.63% instead of 4%) because 31.99 ETH is not stacked.
So our main target should be making pools and tokenized stacking available as it will abolish the latter case. It will guarantee the decentralization of end users, co-investors of validators, small stake holders. Opportunity of making possible tokenization is more important than partial withdrawal.
Eth1 -> Eth2 gate would be helpful (so, you could send
BLSSetWithdrawalAddress and anything else by call in Eth1) for pools and other contracts, though we are not sure there is a sense of making a system contract for this. Instead, any third party could create one and provide a service for a fee. Being off chain it doesn’t require too much complexity and will offer services that system contracts are unable to provide, for example, callback. In the worst case you will lose a fee, which is small and good service will compensate for the outage by something which couldn’t be written in Solidity.
While such service could improve simplicity of building Eth2 pools and staking tokenization contracts, it’s not a requirement.
Executable beacon chain
One of the latest views on merging Ethereum 1 into Ethereum 2, A rollup-centric ethereum roadmap by @vbuterin assumes one Ethereum 1 execution shard. As Withdrawal touches both Ethereum 2 state and Ethereum 1 shard we expect asynchronous execution of withdrawal (we need to connect eth1 and eth2 events, handle errors, etc) in this case with a lot of extra complexity added due to this. If we are going to couple Ethereum 1 shard with Ethereum 2 state strongly, as currently proposed(see Vitalik’s comment in AMA and Executable beacon chain), so Ethereum1 is wrapped by Ethereum2, it greatly reduces implementation complexity. While it could make eth1-eth2 communication way simpler and increases profitability of validators, it has several nuances:
- Eth1-Eth2 message flow becomes way simpler, so and
0x01withdrawal prefix implementation
- Strong coupling of Beacon Chain and one Ehereum execution shard opens space for almost symmetric deposit-withdrawal designs
- If tight coupling of Ethereum1 shard is chosen for network architecture there is more incentive to build Eth1-Eth2 gate mentioned above as a System Contract, so you could be able to create and push Eth2 message from Ethereum 1 contract code without 3rd party trust
- Eth1 TX processing and fee collection will be a part of validator’s job, so staking pools should aggregate both this fees and Eth2 validator withdrawals, which could be challenging, but total profit increases
As @djrtwo stated, we need to only commit new prefix(es) today, and could start polishing the withdrawal specification. On the other side, this will be enough to start implementation contracts and pools. Though as start is already and withdrawal takes less than a day, we will definitely have a huge backlog of ready for withdrawal validators at launch of withdrawal feature, which should be handled.
BLSSetWithdrawalAddress could be added before everything else, as nothing prevents to submit
withdrawal_credentials to Deposit Contract today with a prefix different to
To prove viability of
0x01 withdrawal prefix we are going to make PoC of staking pool with fractional shares of validator’s stake to clarify challenges in eth1-eth2 deposit-withdrawal flow from staking pool view and start designing of system contract.