Source: Denglian Community
In this blog post, we will take you to understand the EigenLayer protocol Evolution, describing how the EigenLayer architecture emerged from its initial concept.
This blog is inspired by David Philipson's Account Abstraction series [5] sup> inspire. Special thanks to the community Noam Horowitz[6], Shiva[7], NashQ[8], Mike Neuder[9]< /sup> and Sina[10] for their comments and feedback on this article.
While many people are familiar with the terms restaking and EigenLayer, only a few know that our core contract contains thousands of lines of code< sup>[11] , its structure is as follows.
EigenLayer simplifies architecture
Why does a seemingly simple idea become so complicated?
In this blog post, we’ll take you through the protocol by describing how EigenLayer’s current complex architecture emerged from its initial conceptEvolution.
This article is intended for people who have a basic understanding of smart contracts and have heard of EigenLayer or restaking.
Since the purpose of this blog post is to provide a high-level explanation of the design evolution of EigenLayer, Therefore the interface, variables and logic may be different from the current EigenLayer core contract [12].
Now, let's get started.
Ultimate goal: make building infrastructure easy
First, let’s start with the introduction The problem EigenLayer wants to solve. If you are already familiar with this section, please skip to later chapters.
Developers building decentralized infrastructure on Ethereum face the challenge of establishing their own economic security. While Ethereum provides economic security for smart contract protocols,infrastructure such as bridges or sequencers requires its own economic securityto enable a distributed network of nodes to reach consensus.
Consensus mechanisms are critical to facilitate interaction between these nodes, whether it is L1, oracle network or bridge.
Proof-of-work[13] consumes serious energy, and proof of authority[14] is too centralized. Therefore Proof of Stake[15] (PoS) has become themain consensus mechanism for most infrastructure projects.
However, launching a new PoS network is difficult.
First of all, it is difficult to determine where the staker (the person who provided the pledge) is. There is no good place for developers to find stakers.
Secondly, stakers must invest a large amount of money to obtain collateral for the new network, usually by purchasing the network's native token, which they usually is volatile and difficult to obtain.
Thirdly, stakers must give up other reward opportunities, such as the 5% reward provided by Ethereum.
Finally, the current security model is not ideal because the cost of breaking any dApp is only required to break its most vulnerable infrastructure dependencies the cost of.
Assume for the time being that stakers participating in infrastructure projects are also responsible for operating offline software to ensure their Safety. But we will change this assumption later in the article.
EigenLayer was created to solve these problems:
It serves as a platform to connect stakers and infrastructure developers.
Stakers can use any token to provide financial security.
Pledgers can choose to restake their original pledges and contribute to the security of other infrastructure while receiving Native Ether rewards.
By re-staking, EigenLayer brings security together instead of fragmenting it.
EigenLayer's white paper[16] These issues are discussed in depth.
EigenLayer generalizes the concept of providing economic security.
Goal 1: Create a platform that connects stakers and infrastructure developers
EigenLayer is a platform where pledgers can provide pledges for any infrastructure project, and infrastructure projects can be promoted to potential pledgers on EigenLayer. The backbone of the platform is toenable stakers to make credible commitments to different infrastructures.
These commitments apply to all proof-of-stake systems, not just EigenLayer. L1 stakers typically commit to following the protocol rules and risk losing their stake if a conflicting block is signed at the same block height.
Infrastructure developers build the infrastructure logic and software, while stakers provide pledges to secure the infrastructure. _This pledge is provided as acommitment to the users of the infrastructure. _ Thiscommitment is for the smooth running of the agreement andagainst specific misconduct.
Conceptually when a project has $100 million pledged behind it, it means that if it deviates _part of this $100 million will be cut_ if it violates its promises and exhibits bad faith. Simply put, "cutting" can be understood as destroying this fund.
The higher the number, the more safety and security it provides to its users.
If we allow stakers to assign stakes to various commitments, we can create a user-friendly platform on top of it.
We need a trustless and programmable platform to execute different staker commitments, andEthereum is the best fit. Additionally, Ethereum holds the largest amount of pledges, helping to kickstart the staker market.
The goal here is that stakers should be able to provide security to the bridge protocol on Ethereum via EigenLayer. If a staker maliciously forges a message on Ethereum and transmits it to Gnosis, anyone can submit evidence and slash that staker.
Since the staker's pledge and commitment execution occur on Ethereum, the reduction logic is also implemented in the form of an Ethereum smart contract. If a staker violates their commitment, anyone can provide evidence to the slashing contract and confiscate the malicious staker’s pledge.
This forms the basis of EigenLayer - any staker can make a credible commitment to any infrastructure protocol.
Initial design of EigenLayer
Now, let's try to implement this . We’ll start with the simplest design: stakers stake their tokens into a contract that includes a function that allows the staker’s tokens to be slashed when evidence is submitted and criteria are met. Users can then withdraw their balance.
Other pledgers can also stake tokens into this contract, increasing the security of the infrastructure. We will call this contract TokenPool
.
For greater clarity, here are some definitions of the terms used in this article:
Stakeholder: Anyone who provides tokens to EigenLayer.
Token: any type of token; for now simply think of it as an ERC20 token .
TokenPool: A smart contract that saves staker tokens.
Cut: Removes stakers’ access to their staked tokens.
< span style="text-align: center;">The interface of this TokenPool
can be expressed as follows:
contract TokenPool {
mapping(address => uint256) public balance;
mapping(address => address[]) public slasher;
function stake(uint256 amount) public;
function withdraw() public;
  ;function enroll(address slasher) onlyOwner;
}
except stake
, withdraw
and balance
functions and variables, we also introduced a new function and a new variable. The variable slasher
monitors each staker's currently registered AVS. The function enroll
allows stakers to participate in AVS
Therefore, registering to AVS actually gives the "slasher" the ability to slash your stake .
With this modification, after staking to TokenPool
, stakers can join by calling the enroll
function Specific AVS. This function contains the AVS-specific slasher contract to the slasher
mapping.
The enroll function here is access-controlled because it may allow anyone Able to register to any reducer contract. To ensure that this TokenPool is managed securely, we will assume that it is overseen by a trusted third party.
During the extraction process, the TokenPool
contract can request each slasher
Determine whether the staker is eligible to withdraw. This is verified via the isSlashed
function in the slasher
contract. If isSlashed
is TRUE
for this staker, the staker cannot withdraw their stake because they have been slashed.
contract TokenPool {< br> mapping(address => uint256) public stakerBalance;
mapping(address => uint256) public operatorBalance;
mapping(address => address) public delegation;
mapping(address => address[]) public slasher;
function stake(uint256 amount) public;
function withdraw () public;
function delegateTo(address operator) public;
function enroll(address slasher) operatorOnly;
function exit(address slasher) operatorOnly;< br>}
We have divided the balance variable into two different parts : One for operators and one for pledgers. In addition, we introduce a delegation
mapping to record the delegation relationship between pledgers and operators.
We also made minor changes to the slasher
mapping. It now gives the slasher
contract slashing authority to the operator, rather than the staker.
contract TokenPool {
mapping(address => uint256) public stakerBalance;
function stake(uint256 amount) public;
function withdraw() public;
}
TokenPool
The contract will only track the balance of each staker. Tracking and joining of AVS will be handled by DelegationManager
.
span>contract slasher {
mapping (address => bool) isSlashed;
function slash (address operator, ??? proof);
}
After cleaning up the contract structure and After modularizing each component, the architecture now looks like this:
EigenLayer intermediate design: after separating the operator role and the staker role.
Goal: support more tokens
So far, we The design developed only supports stakingatoken as we only maintainamapping for stakers.
We can solve this problem by adopting a LP share-based model and create a token-specific TokenPool< /code>.
To do this, we will create a new contract called TokenManager
. The TokenManager
will be where stakers go to stake and withdraw their tokens.
Under TokenManager
, each token will have a TokenPool
. TokenManager
will act as the accounting center for all tokens; it will not store any tokens itself. Each TokenPool
will hold its own corresponding token.
A new component designed to now track stakers’ different tokens.
When a user stakes a token, it is handled by TokenManager
. The TokenManager
then calls the stake
function of the corresponding TokenPool
associated with that token. The user's tokens will be transferred to TokenPool
. At the end of the function, totalShares
and stakerPoolShares
will be updated to reflect the new stake. totalShares
tracks the total number of shares issued by a TokenPool
, while stakerPoolShares
records the holdings of each individual staker in each TokenPool
number of shares.
The interface of each contract will look like this:
contract DelegationManager {
// .. .
mapping(address => mapping(address => uint256)) operatorPoolShares;
// ...
}
pre>Now, under the same core architecture, stakers can stake any token to EigenLayer to protect other AVS.
Goal: Extend AVS design
Consider the following situations: A staker withdraws their pledgeimmediatelyafter engaging in slashable behavior, and withdrawbefore anyone else slashes their assets.
_For example_, suppose there is an operator who is both an operator and a staker, acting maliciously in AVS. Before anyone else can stake on-chain, the operator withdraws their stake from the EigenLayer contract. This is possible because at the time of withdrawal, the slasher
has not yet updated to slash their assets. Therefore, AVS is no longer able to slash malicious operators/stakers because there are no more tokens available for slashing.
Potential timeline of events for malicious operators/stakers.
Thus, a "secure" AVS requires one that can freeze malicious content within the same block where the event occurs. Operator's contract reduction. This limitation greatly limits the design of AVS, making most AVS unsafe.
One solution is to introduce an unbundling period. Instead of allowing stakers to immediately withdraw their stake, we are introducing a delay in the withdrawal process called an unstaking period. Afterwards, stakers can withdraw funds as before.
When a staker decides to withdraw from the system, their request is placed into a queue. This queued withdrawal will only be processed after the operator's longest unbinding periodhas expired. This is because one operator may manage multiple AVS, but a staker’s withdrawals can only be aligned with one unbonding period. For security reasons, the system sets the unbinding period to the longest one.
For example, if a staker entrusts their pledge to operators participating in three AVS, the unbonding periods of these three AVS are six and five respectively. and seven days, then after requesting a withdrawal from EigenLayer, they must wait seven days to access their stake. This is because seven days is the longest of the three periods.
At the end of the seven-day period, stakers can withdraw their stake. However, if the operator to which they are entrusted is curtailed during this period, then pending withdrawals will also be stopped.
In order to introduce this change, DelegationManager
needs to track the unbinding period of each operator and update it when the operator joins Update it when new AVScomes available.
contract TokenManager {
mapping(address => address) public tokenPoolRegistry;
mapping(address => mapping(address => uint256)) public stakerPoolShares;
mapping(address => uint256) public withdrawalCompleteTime;
function stakeToPool(address pool, uint256 amount) public;
function queueWithdrawal(address pool) public;
function completeWithdrawal(address pool) public ;
}
When stakers queue up to withdraw, TokenManager
will work with < code>DelegationManager Verifies whether the operator delegated by the pledger has been slashed. If the operator is unslashed, the TokenManager
will update the staker's withdrawalCompleteTime
based on the DelegationManager
's unbondingPeriod
and the current time.
After the unbinding period, stakers can complete their withdrawal through completeWithdrawal
. This function will verify that withdrawalCompleteTime
has elapsed. If it has passed, the staker's tokens will be transferred out according to the previous process.
The design of this process is complex and has gone through several iterations in our process . We could even write a separate article on this topic! Currently, we use a time tracking system to implement this unbundling tracking. This part is still a work in progress!
Modular slashers
Since we are making slashes The mechanism is safer, let's also try to make it more modular and efficient.
Currently, during the extraction process, the TokenManager
needs to check with each individual slasher
to Check whether the operator has been slashed. This adds gas overhead to stakers and may significantly reduce rewards for smaller stakers.
Also, since AVS developers typically design slashers, modularizing this specific component can simplify the development process for individual AVSs.
Similar to TokenManager
, we will adopt a two-part design for the slash mechanism. SlasherManager
maintains the status of each operator. A separate slasher
will handle the slash logic for each AVS.
Further modularize the slash contract to reduce gas costs for stakers.
contract slasher {
function slash(address operator, ??? proof) public;
}
slasher
will be AVS-specific, most likely developed by AVS developers. It will interact with SlasherManager
to update the status of different operators.
EigenLayer has been designed!
To review:EigenLayer’s goal is to simplify infrastructure construction. We started with four main goals:
Build a platform to connect stakers and infrastructure developers.
Allows stakers to use any token to provide economic security.
Enabling stakers to re-stake their stakes and earn native ETH rewards while providing security for other infrastructure .
Pool security through re-staking rather than decentralizing it.
After several iterations, we developed three core components: TokenManager< /code>, DelegationManager
and SlasherManager
. Each component has specific functions:
Simplified architecture of EigenLayer
< code>TokenManager: handles the pledge and withdrawal of pledgers.
DelegationManager
: Allows operator registration and tracking of operator shares.
SlasherManager
: Provides an interface for AVS developers to determine slash logic.
These core components also communicate with each other to ensure the security of the entire system.
In addition to these core contracts, there are many other features and contracts that enhance the entire stack. These additional features support a variety of AVS designs, simplify offline technical complexities, and reduce gas costs for users and operators.
To learn more about these additional features, you can visit our open source code repository: https://github.com/Layr-Labs/eigenlayer -contracts
Additional 1: Who trusts whom?
When the system is modular, it can be challenging to keep track of trust assumptions between participants in the protocol. Therefore, it is crucial to clearly outline the trust assumptions between the participants involved in the agreement.
In EigenLayer, there are three main agents: stakers, operators, and AVS developers.
Operators rely on AVS developers to accurately write client software and on-chain slash conditions. If there is a bug in the AVS software, in the best case, the operator may miss out on potential fee payments. Worst case, the operator may be slashed out of their entire stake.
Given the importance of the values involved, it is important to ensure that the entire system has auxiliary training wheels before being put into use.
Veto committees serve as these training wheels. It has the power to undo slashes caused by non-malicious behavior. The Veto Committee is amutual trust between stakers, operators, and AVS developers.
This way, the assumption of trust in AVS developers can be removed. Even if there is a software bug in AVS, stakers and operators will not be punished.
Stakers trust the operators they entrust. If an operator misbehaves, stakers could miss out on potential fee payments or even lose their entire stake. This trust assumption is the same as existing verification services such as Binance Staking and other staking services.
AVS developers rely on operators operating honestly. If operators are dishonest, AVS service will decline significantly, leading to customer churn and other consequences.
Between participants, through the veto committee, trust is assumed as follows:
-
Pledgers trust operators to act honestly, misbehavior may result in a slash.
AVS developers trust operatorsto operate AVS software honestly.
Stakeholders, operators, and AVS developers trust the veto committee to undo slashes.
Additional 2: Native Restaking
So far , we have discussed using LST for re-staking. However, if you don’t want to stake EigenLayer via the Liquid Staking Protocol, you can start participating in EigenLayer via native re-staking.
Let’s define native re-staking: This is the process of making additional commitments using ETH within a validator. If a validator deviates from the commitment, they will lose the ETH held within their validator.
The challenge here is that the ETH within these validators is not represented in the form of ERC20 tokens. Instead, ETH exists on the Beacon Chain. If you are not familiar with the execution layer or consensus layer (beacon chain), this explanation [17] is a good resource to get you up to speed.
To solve this problem, we can use EigenPod
to track Ethereum validator balances and slash them when necessary.
EigenPod
acts as a virtual accounting system. With EigenPod
we can monitor the ETH balance of each re-staking validator.
At a high level, EigenPods
handles the extraction process of validators. When a validator withdraws its stake from EigenLayer, ETH first passes through EigenPod
to check if the validator has been slashed. If a validator has been slashed, the tokens will be frozen within the EigenPod
contract, effectively slashing them.
Implementing EigenPod
Implementing EigenPod
is tricky because Ethereum validator balances are stored on the beacon chain and wecannot access the beacon chain data on the execution layer.
To solve this problem, we use an oracle to pass the beacon chain state root to the execution layer. By getting the beacon state root, we can access the validator's balance by providing the corresponding Merkle proof.
With the implementation of EIP-4788[18], we can remove this oracle and query the information directly from the execution layer mark root.
In order to encapsulate the accounting system, we will use models similar to the TokenPool
and TokenManager
models to< strong>ModularLocal re-pledge system. Each EigenPod
will handle the withdrawal process for one validator. EigenPodManager
will coordinate with other core contracts to track the amount of ether staked by each operator and staker.
<span ) 10px 10px / 40px no-repeat ;height: 30px;width: 100% ;margin-bottom: -7px;border-radius: 5px;'>contract EigenPodManager{
mapping(address => uint256) public restakerShares;
function createEigenPod(address owner) public;
function stakeToPod(address pod, uint256 amount) public;
  ;function withdrawFromPod(address pod) public;
}
contract EigenPod{
address BEACON_CHAIN_ORACLE;
address podOwner;
uint256 restakedAmount;< br>
function stake(uint256 amount) public;
function verifyRestakedBalance(uint256 amount, MerkleProof proof) public;
function withdraw() public; span>
}
EigenPodManager
Tracks the number of shares each staker owns. It allows stakers to create EigenPod
for which Make a pledge and withdraw from it.
EigenPod
PassedrestakedBalance
Variable tracks the balance of various validators on the beacon chain. Whenever the balance of any restaking validator changes, anyone can verify it by calling verifyRestakedBalance()
Function to update the balance of that specific validator. This function will pass the BEACON_CHAIN_ORACLE that we got from Beacon status root to check if the updated balance is correct.
This is how EigenLayer implements local re-staking.
Reference materials
[1] Link translation plan: https://github.com/lbc-team/Pioneer
[2] Translation team: https://learnblockchain.cn/people/412
< span style="font-size: 14px;">[3]Tiny Bear: https://learnblockchain.cn/people/15
[4]learnblockchain.cn/article…: https://learnblockchain.cn/article/7657
[5] Account abstraction series: https://learnblockchain.cn/article/5426
[6]Noam Horowitz: https://twitter.com/ProbablyNoam
[7]Shiva: https://twitter.com/ShivanshuMadan
[8]NashQ: https://twitter.com/NashQueue
[9]Mike Neuder: https://twitter.com/mikeneuder
[10]Sina: https://twitter.com/sina_eth_
< span style="font-size: 14px;">[11]Code: https://github.com/Layr-Labs/eigenlayer-contracts/tree/master/src/contracts
[12]Contract: https://github.com/Layr-Labs/eigenlayer-contracts/tree/master/src /contracts
[13]Proof of work: https://en.wikipedia .org/wiki/Proof_of_work
[14] Authoritative proof: https:// en.wikipedia.org/wiki/Proof_of_authority
[15]Proof of Stake: https ://en.wikipedia.org/wiki/Proof_of_stake
[16]White paper : https://docs.eigenlayer.xyz/overview/whitepaper
[17 ]This explanation: https://docs.prylabs.network/docs/concepts/nodes-networks
[18]EIP-4788: https://eips.ethereum.org/EIPS/eip-4788
< span style="font-size: 14px;">[19]DeCert.me: https://decert.me/