本文档详细介绍了 EigenPodManager,它是 EigenLayer 中管理信标链 ETH 策略的关键组件。
文件 | 备注 |
---|---|
EigenPodManager.sol |
|
EigenPodManagerStorage.sol |
状态变量 |
IEigenPodManager.sol |
接口 |
库和混合合约: | 文件 | 备注 |
---|---|---|
EigenPodPausingConstants.sol |
EigenPod/EigenPodManager 方法的暂停值 |
EigenPodManager
管理着“信标链 ETH 策略”,这是一个虚拟策略,质押者可以持有可委托的份额,类似于 StrategyManager
管理的策略。StrategyManager
的策略份额由存入的 ERC20 代币支持,而信标链 ETH 策略份额由信标链验证器或归属于 EigenPod
的原生 ETH 支持。
EigenPodManager
允许任何质押者部署一个 EigenPod
。EigenPod
包含信标链状态证明逻辑,使质押者能够将其验证器的提款凭证和/或费用接收者地址指向他们的 pod。在向他们的 pod 提交信标链状态证明后,质押者将获得信标链 ETH 策略中的存款份额,然后这些份额将在 DelegationManager
中委托给他们的运营商(如果适用)。有关更多详细信息,请参见 EigenPod.md
。
当 EigenPod
收到余额更新时,这些更新将转发到 EigenPodManager
。由于信标链上的验证器活动或在 EigenPod
中收到的 ETH 余额增加,将导致质押者在信标链 ETH 策略中的存款份额增加。
由于验证器不活动或信标链罚没导致的余额减少不会减少质押者的存款份额。相反,它们会导致质押者的信标链罚没因子**减少**。DelegationManager
在确定以下因素时,会使用信标链罚没因子,以及其它因素:
请注意,可以使用 DelegationManager.getWithdrawableShares(staker, strategies)
查询质押者的存款份额代表的可提取份额数量。
EigenPodManager
的职责可以分解为以下概念:
beaconChainETHStrategy = 0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0
DelegationManager
使用此地址来表示由 EigenPodManager
管理的信标链 ETH 策略。但是,它并不对应于实际的合约!ethPOS = 0x00000000219ab540356cBB839Cbe05303d7705Fa
beaconProxyBytecode
(在 EigenPodManagerStorage.sol
中定义)
EigenPod
使用信标代理进行部署。此字节码是一个常量,包含通过编译 OpenZeppelin 4.7.1 版本的 BeaconProxy
合约 计算出的创建字节码。编译使用 solc 版本 0.8.12
,启用了优化,运行 200 次。经验证的合约示例在此。在质押者开始重新质押信标链 ETH 之前,他们需要部署一个 EigenPod
,质押,并启动一个信标链验证器:
createPod
/**
* @notice 为发送者创建一个 EigenPod。
* @dev 如果 `msg.sender` 已经有一个 EigenPod,该函数将回退。
* @dev 返回 EigenPod 地址
*/
function createPod()
external
onlyWhenNotPaused(PAUSED_NEW_EIGENPODS)
returns (address)
允许质押者部署一个 EigenPod
实例,如果他们尚未这样做。
每个质押者只能部署一个 EigenPod
实例,但一个 EigenPod
可以用作任意数量的信标链验证器的费用接收者/提款凭证。每个 EigenPod
都是使用 Create2 和信标代理模式创建的,使用质押者的地址作为 Create2 盐。
作为 EigenPod
部署过程的一部分,质押者将成为 Pod 所有者,这是 EigenPod
中的一个有权限的角色。
影响:
EigenPodManager.beaconProxyBytecode
,并将 eigenPodBeacon
地址附加为构造函数参数。bytes32(msg.sender)
用作盐。
address eigenPodBeacon
是一个 OpenZeppelin v4.7.1 UpgradableBeacon
,其实施地址指向当前的 EigenPod
实现beaconProxyBytecode
是 OpenZeppelin v4.7.1 BeaconProxy
的构造函数代码EigenPod.initialize(msg.sender)
:初始化 pod,将调用者设置为 Pod 所有者,并激活指向该 pod 的任何验证器的重新质押。EigenPod
)要求:
EigenPod
PAUSED_NEW_EIGENPODS
stake
/**
* @notice 在发送者的 EigenPod 上为新的信标链验证器进行质押。
* 如果发送者还没有 EigenPod,也会为发送者创建一个 EigenPod。
* @param pubkey 信标链验证器的 48 字节公钥。
* @param signature 验证器对存款数据的签名。
* @param depositDataRoot 验证器存款的存款数据的根/哈希。
*/
function stake(
bytes calldata pubkey,
bytes calldata signature,
bytes32 depositDataRoot
)
external
payable
onlyWhenNotPaused(PAUSED_NEW_EIGENPODS)
允许质押者将 32 ETH 存入信标链存款合约,提供质押者的信标链验证器的凭证。调用 EigenPod.stake
方法,该方法自动计算 pod 的正确提款凭证,并将这些凭证与 32 ETH 一起传递给存款合约。
影响:
EigenPod
,如果尚未完成EigenPod.stake
要求:
PAUSED_NEW_EIGENPODS
EigenPod.stake
这些方法只能由 DelegationManager 调用,并在处理取消委托和提款时使用。
概念:
方法:
EigenPodManager
使用以下状态变量跟踪质押者的 存款份额 和 信标链罚没因子:
/**
* @notice 从 pod 所有者到他们在虚拟信标链 ETH 策略中拥有的存款份额的映射
*
* @dev 当 EigenPod 记录余额增加时,存款份额会增加。但是,当记录余额减少时,存款份额不会减少。相反,
* pod 所有者的信标链削减因子会与余额减少成比例地降低。这会影响从质押中提取的份额数量
* 当存款份额在 DelegationManager 中排队等待提取时。
*
* 请注意,在削减发布之前,余额减少时,存款份额会减少。
* 在某些情况下,排队提取加上注册余额减少的组合可能会导致
* 质押者在此映射中具有负存款份额。当
* 质押者完成提取(作为代币或作为份额)时,将更正此负值。
*
* 随着削减发布,不再可能出现负份额。但是,质押者仍然可能有负
* 如果他们在削减发布之前满足了他们的条件,则会共享。如果是这种情况,则质押者
* 应该完成 DelegationManager 中任何未完成的排队提款(“作为份额”)。这将纠正
* 负份额计数,并允许质押者继续像往常一样使用他们的 pod。
*/
mapping(address podOwner => int256 shares) public podOwnerDepositShares;
/**
* @notice pod 所有者经历的信标链削减量,占 WAD 的比例
* @param isSet slashingFactor 是否已更新。用于区分
* "0" 值和未初始化值。
* @param slashingFactor 由于
* 削减或其他信标链余额减少而减少的 pod 所有者余额的比例。
* @dev 注意:如果 !isSet,则 `slashingFactor` 应被视为 WAD。 `slashingFactor` 是单调的
* 减少,如果完全削减,则可以达到 0。
*/
struct BeaconChainSlashingFactor {
bool isSet;
uint64 slashingFactor;
}
/// @notice 返回应用于 `staker` 用于 `beaconChainETHStrategy` 的削减因子
/// 注意:对于所有质押者,此值从 1 WAD (1e18) 开始,并在质押者的 pod 注册时更新
/// 余额减少。
mapping(address staker => BeaconChainSlashingFactor) internal _beaconChainSlashingFactor;
removeDepositShares
/**
* @notice 由 DelegationManager 用于在 pod 所有者进入提款队列时删除他们的存款份额。
* 只需将 `podOwner` 的份额减少 `shares`,最低降至零。
* @dev 如果此函数导致 `podOwnerDepositShares[podOwner]` 小于零,则此函数会回退,即禁止此函数
* 导致 `podOwner` 产生“份额赤字”。此行为可防止 Staker 排队提取,从而不正确地删除过多的
* 来自质押者委托给的运营商的份额。
* @dev 委托管理器会验证 podOwner 不是 address(0)
*/
function removeDepositShares(
address podOwner,
IStrategy strategy,
uint256 depositSharesToRemove
)
external
onlyDelegationManager
当质押者排队提取(或取消委托,也排队提取)时,DelegationManager
会调用此方法。份额在提款队列中时被删除,当队列完成时,份额将被重新授予或作为代币提取(分别为 addShares
和 withdrawSharesAsTokens
)。
质押者的份额余额减少 depositSharesToRemove
。
不允许此方法导致 质押者 的余额变为负数。这可以防止质押者排队提取比他们拥有的份额更多(或者比他们委托给运营商的份额更多)。
请注意,在提款队列中删除的存款份额数量可能不等于完成提款时记入的金额。如果发生削减,质押者可能会收到更少的份额;有关详细信息,请参阅DelegationManager.md
。
影响:
podOwnerDepositShares
中的 podOwner
份额余额中删除 depositSharesToRemove
NewTotalShares
事件要求:
DelegationManager
strategy
必须是 beaconChainETHStrategy
staker
不得为零depositSharesToRemove
必须小于 podOwnerDepositShares
中 staker
的份额余额addShares
/**
* @notice 通过 `shares` 增加 `podOwner` 的份额,如果需要,偿还负份额。
* 由 DelegationManager 用于在退出提款队列时授予 pod 所有者份额
* @return existingDepositShares 在添加之前 pod 所有者的份额。如果为负数,则返回 0
* @return addedShares 添加到质押者余额高于 0 的份额数量。这意味着,如果
* 添加份额后,质押者的余额为非正数,则会返回 0。
*/
function addShares(
address staker,
IStrategy strategy,
uint256 shares
)
external
onlyDelegationManager
returns (uint256, uint256)
当队列中的提款完成并且提款人指定他们希望“作为份额”接收提款(而不是作为基础代币)时,DelegationManager
会调用此方法。质押者可能希望这样做,以便在不需要完全退出其验证器的情况下更改其委托的运营商。
此方法将输入的存款份额记入质押者名下。在大多数情况下,输入的 shares
等于最初在排队提款时删除的相同份额。但是,如果质押者的运营商被削减(或者质押者经历了信标链削减),他们可能会收到更少的份额。有关详细信息,请参阅DelegationManager.md
。
如果质押者有份额赤字(负份额),则从添加的 shares
中偿还赤字。如果 Pod 所有者的正份额计数增加,则此更改将返回给 DelegationManager
以委托给质押者的运营商(如果他们有)。
影响:
podOwnerDepositShares
中 staker
的存款份额余额增加 shares
要求:
DelegationManager
strategy
必须是 beaconChainETHStrategy
staker
不得为 address(0)
int256
时,shares
不得为负数PodSharesUpdated
和 NewTotalShares
事件withdrawSharesAsTokens
/**
* @notice 由 DelegationManager 用于完成提款,将代币发送给 pod 所有者
* @dev 优先减少 podOwner 的份额赤字(如果他们有)
* @dev 此函数假定 `removeShares` 已被 delegationManager 调用,因此
* 如果 `currentpodOwnerDepositShares` 为正数,我们不需要更新 podOwnerDepositShares
*/
function withdrawSharesAsTokens(
address podOwner,
IStrategy strategy,
IERC20,
uint256 shares
)
external
onlyDelegationManager
当队列中的提款完成并且提款人指定他们希望将提款作为份额的基础代币接收时,DelegationManager
会调用此方法。这可用于“完全退出”一些数量的原生 ETH 并将其发送给 pod 所有者(通过 EigenPod.withdrawRestakedBeaconChainETH
)。
请注意,因为此方法需要提取和发送原生 ETH,所以必须满足两个条件才能使此方法成功:(i)提取的 ETH 应该已经在 EigenPod
中,并且(ii)提取的金额应该在 EigenPod.withdrawableExecutionLayerGwei
中核算。后一个条件可以通过在完成队列中的 DelegationManager
提款之前完成 EigenPod
检查点来实现(有关详细信息,请参阅EigenPod:检查点验证器)。
另请注意,与 addShares
一样,如果原始 Pod 所有者有份额赤字(负份额),则在提取任何原生 ETH 之前,将从提取的 shares
中偿还赤字。
影响:
podOwnerDepositShares
中 staker
的份额余额为负数(即,质押者有赤字):
shares
大于当前的赤字:
podOwnerDepositShares
中 staker
的余额设置为 0shares
中减去 |赤字|
并将剩余的份额 1:1 转换为 ETH(请参阅EigenPod.withdrawRestakedBeaconChainETH
)shares
小于或等于当前的赤字:
podOwnerDepositShares
中 staker
的负余额增加 shares
,使其更接近 0PodSharesUpdated
和 NewTotalShares
事件要求:
DelegationManager
strategy
必须是 beaconChainETHStrategy
staker
不得为 address(0)
int256
时,shares
不得为负数EigenPod.withdrawRestakedBeaconChainETH
方法:
recordBeaconChainETHBalanceUpdate
/**
* @notice 将任何正份额增量添加到 pod 所有者的存款份额,并将它们委托给 pod
* 所有者的运营商(如果适用)。负份额增量不会影响 pod 所有者的存款份额,
* 但会降低他们的信标链削减因子并相应地减少委托份额。
* @param podOwner 是要更新其余额的 pod 所有者。
* @param prevRestakedBalanceWei 是通过 pod 重新质押的总金额,包括
* 当前在提款队列中的任何金额。
* @param balanceDeltaWei 是余额变化量
* @dev 只能由 podOwner 的 EigenPod 合约调用。
* @dev 如果 `sharesDelta` 不是一个完整的 Gwei 金额,则会回退
*/
function recordBeaconChainETHBalanceUpdate(
address podOwner,
uint256 prevRestakedBalanceWei,
int256 balanceDeltaWei
)
external
onlyEigenPod(podOwner)
nonReentrant
此方法由 EigenPod
调用,以报告其 pod 所有者的份额变化。它接受正或负的 balanceDeltaWei
。将正增量添加到 pod 所有者的存款份额,并将其委托给他们的运营商(如果适用)。不会从 pod 所有者的存款份额中删除负增量。相反,余额减少的比例用于更新 pod 所有者的信标链削减因子,并减少委托给他们的运营商的份额数量(如果适用)。零增量不会导致任何变化。
请注意,在削减发布之前,负余额增量会从 pod 所有者的份额中减去,并且在某些情况下,可能导致负份额余额。截至削减发布时,负余额增量不再从份额余额中减去,而是更新信标链削减因子。
如果质押者在削减发布时有负份额,则此方法将回退,从而阻止他们的 pod 进行任何进一步的余额更新,同时负份额余额仍然存在。为了解决此问题并恢复其 pod 的使用,质押者应在 DelegationManager
中完成任何未完成的“作为份额”提款,这将纠正份额赤字。
影响:
balanceDeltaWei
为零,则不执行任何操作balanceDeltaWei
为正数:
shares
添加到 podOwner
的 podOwnerDepositShares
PodSharesUpdated
和 NewTotalShares
事件DelegationManager.increaseDelegatedShares
balanceDeltaWei
为负数:
BeaconChainSlashingFactorDecreased
事件DelegationManager.decreaseDelegatedShares
要求:
podOwner
关联的 EigenPod
podOwner
不得为 address(0)
balanceDeltaWei
必须是一个完整的 Gwei 金额currentDepositShares >= 0
)increaseBurnOrRedistributableShares
/**
* @notice 增加给定策略的可燃烧/可重新分配的份额数量。当运营商在 EigenLayer 中被削减时,DelegationManager 会调用此选项。
* @param operatorSet 要燃烧股份的运营商集。
* @param slashId 要燃烧股份的斜线 ID。
* @param strategy 要燃烧股份的策略。
* @param addedSharesToBurn 要燃烧的添加股份金额。
* @dev 只有当运营商被削减时,DelegationManager 才会调用此函数。
*/
function increaseBurnOrRedistributableShares(
OperatorSet calldata operatorSet,
uint256 slashId,
IStrategy strategy,
uint256 addedSharesToBurn
) external onlyDelegationManager;
当运营商被削减时,DelegationManager
会调用此方法,计算可削减的份额数量并在此处标记它们以进行燃烧。
与 StrategyManager
不同,目前没有燃烧这些份额的机制,因为燃烧需要 Pectra 硬分叉才能弹出验证器。这将在未来的更新中添加。
我们也不会像 StrategyManager
那样,基于每个 operatorSet/slashId 区分可燃烧的份额。
影响:
burnableShares
增加 addedSharesToBurn
要求:
DelegationManager
调用
- 原文链接: github.com/Layr-Labs/eig...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!