owned this note
owned this note
Published
Linked with GitHub
## _MOOCOW_: Massively Optimized Operations - COnsolidation and Withdrawals
:::success
**UP-TO-DATE LINKS:**
* Core contract PR: [eigenlayer-contracts/1425](https://github.com/Layr-Labs/eigenlayer-contracts/pull/1425)
* CLI PR: [eigenpod-proofs-generation/177](https://github.com/Layr-Labs/eigenpod-proofs-generation/pull/177)
:::

*MOOCOW* is the latest EigenPod upgrade, coming soon to a pod near you! *MOOCOW* turbocharges *PEPE*, taking advantage of new Pectra features to udderly dominate native restakers' gas costs.
For native ETH restakers with multiple validators, this upgrade comes with **up to 64x proof size and cost reduction** through validator consolidation.
### 64x? Holy cow!
You read that right. As an example, take [one of Renzo's EigenPods](https://etherscan.io/address/0xDD0212d0da33a2235d1952dA390a0A18EAcc7af5). This pod has **1775 validators,** representing 56,800 ETH in TVL. When Renzo wants to checkpoint their validators to process validator exits/accrued beacon chain rewards, this requires **24 transactions** and **~99 million total gas spent.**
<!-- According to Renzo, this requires anywhere from 0.05 ETH - 0.5 ETH to run (depending on network congestion). Because regular checkpointing is an important tool LRTs use to manage liquidity constraints, they don't always have the luxury of putting off checkpoints -->
Using *MOOCOW*, Renzo can consolidate all 1775 validators _down to just 28_. Processing a checkpoint for **28 validators** would require only **2 transactions**, and a measley **~1.8 million total gas spent.**
### How does MOOCOW work?
*MOOCOW* adds EigenPod support for two new EIPs included in Pectra:
* [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251#constants) enables *validator consolidation*, allowing multiple 32 ETH validators to be combined into a single validator with up to 2048 ETH
* [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) enables *execution layer triggerable withdrawals*, allowing a pod owner to manage their validator directly from their pod (either by fully exiting their validator, or withdrawing some of their accrued beacon chain balance)
*MOOCOW* is backwards-compatible with the existing EigenPod interface and *PEPE* checkpoint proof system. This upgrade **adds two new state-changing methods** to EigenPods, and **does not alter any existing method ABIs**. Current onchain and offchain integrations with EigenPods can continue to function without alteration, meaning **this upgrade is fully opt-in**.
Additionally, *MOOCOW* is designed to be **fully forwards-compatible** with the eventual implementation of native ETH burning and/or redistribution - just as *PEPE* was designed to be forwards compatible with *MOOCOW.*
Note that while *MOOCOW* is a huge step forward for most restakers, it does not provide substantial benefits for restakers with single-validator pods.
### When MOOCOW?

##### Smart Contracts
*Status:*
* Design: Complete!
* Implementation: Complete!
* Docs and testing: Complete!
* Audits: 6/23 - 6/30
##### CLI
*Status:*
* Implementation: Complete!
##### Frontend
*No changes needed.*
---
### Technical Details
#### How to use these methods
*(Additional details and docs can be found in `IEigenPod.sol`; this section outlines some common points of confusion and an example of a high level flow.)*
**Predeploy fee:**
Both `requestConsolidation` and `requestWithdrawal` are `payable`, accepting a "request fee." This is a new concept introduced in Pectra: both predeploys must be sent a fee along with any requests. This means that when calling `EigenPod.requestConsolidation` and `EigenPod.requestWithdrawal`, you must supply a sufficient fee as `msg.value`.
The new interface exposes getters for this: `IEigenPod.getConsolidationRequestFee()` and `IEigenPod.getWithdrawalRequestFee()` return the fee _for one request, for the current block._ The correct amount to send is `fee * requests.length`, i.e. multiply the return value by the number of requests you intend to send.
Note that depending on how many requests are processed by the network, this fee might increase or decrease at the end of each block. We recommend overestimating the fee sent, as any excess will be sent back to `msg.sender` after all requests have been sent to the predeploy.
**Example maximum consolidation:**
Let's say your EigenPod has 1000 validators and you want to maximally consolidate them using `EigenPod.requestConsolidation`. You haven't done any consolidation before, so all validators have 0x01 withdrawal credentials. Maximally consolidating your validators involves consolidating all of your validators in groups of 64 (since `64 * 32 == 2048`, the new max effective balance for 0x02 validators). This means you will consolidate 1000 validators into 16 (`div_ceil(1000, 64) == 16`).
First, **determine your target validators**.
Consolidation requires a _source_ and a _target_. The target will receive the source's balance after the consolidation is completed. We choose 16 of our validators to be the _target_ for consolidation. Note that each of these target validators MUST have verified withdrawal credentials pointed at our pod.
Second, **initiate *switch requests* for your target validators.**
In order for a validator to be the _target_ of a consolidation, it MUST have 0x02 withdrawal credentials. To achieve this, we call `requestConsolidation` with 16 requests (one for each of our chosen targets), where each `request.srcPubkey == request.targetPubkey`. This will be processed as a "switch request," and will update each of our 16 validators to have 0x02 credentials.
Next, **consolidate the remaining source validators to each target.**
Split each of the remaining 984 validators into groups of 64, assign each group of 64 to one of the selected _target_ validators, and call `requestConsolidation` with `request.srcPubkey` equal to the source validator's pubkey, and `request.targetPubkey` equal to the selected _target_ validator's pubkey.
Finally, **monitor the beacon chain and checkpoint when all consolidations are complete.**
The beacon chain processes 2 consolidation requests per block, for a total of 64 requests per epoch. Given consolidation requests from other pods/validators, it may be several epochs before your requested consolidations are complete.
When they are complete, you can start and complete a checkpoint to update your pod's accounting. Once the checkpoint is complete, you should see your `activeValidatorCount` drop from 1000 to just 16, as the pod views each consolidated _source_ validator as having fully exited from the beacon chain. Your 16 *target* validators should have the combined balance from your _sources._
---
#### Notes on beacon chain behavior
Both consolidation and withdrawal requests are just that - requests. They may not be completed at all, pending beacon chain processing and validation. From the EigenPod's perspective, the status of a request is entirely opaque; EigenPods continue to rely on checkpoints to update the state of the pod.
The lifetime of a request has three stages:
1. Requests are initiated by EigenPod and sent to predeploy. At the end of each block, up to 16 withdrawal requests and up to 2 consolidation requests are dequeued from the predeploy and included as "execution requests" in the [associated beacon block](https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#beaconblockbody).
2. During block processing, the beacon chain performs several validation operations to determine whether each request is valid. If a request is invalid, it is skipped. If it is valid:
* From [process_withdrawal_request](https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-process_withdrawal_request), "full exit" requests immediately initiate a validator exit, similar to how voluntary exits currently work. "Partial exit" requests are appended to `state.pending_partial_withdrawals` (see step 3)
* From [process_consolidation_request](https://github.com/ethereum/consensus-specs/blob/dev/specs/electra/beacon-chain.md#new-process_consolidation_request), "switch requests" are immediately completed, switching the validator's credentials to 0x02. All other requests are added to `state.pending_consolidations` (see step 3)
3. During epoch processing, any pending partial withdrawals/consolidations created during that epoch are completed.
*Note* that the beacon chain is ultimately responsible for validating requests. If requests are deemed invalid and are skipped, the EigenPod does not get a "notification" of this. It is up to offchain systems to see this and determine if a request should be resubmitted through the pod.
---
#### Limitation: cross-pod consolidation
We have some restakers that manage multiple single-validator EigenPods that would like to use EIP-7521 to consolidate their validators into a single EigenPod.
*MOOCOW* will NOT support cross-pod consolidation for these cases. Though this behavior is enabled by EIP-7521, the new `EigenPod.requestConsolidation` method will require that the target validator for a consolidation is active within the same pod.
Though we would like to support cross-pod consolidation, in practice our system would treat this as a "share/asset transfer" between stakers, which is not one of the fundamental staker operations our protocol supports (deposit/withdraw/(un)delegate).
We explored some options for this, but ultimately decided the complexity was just not worth it, especially when the restakers in question are able to replicate the behavior themselves by exiting from EigenLayer and redepositing to 0x02 validators in the target pod.