--- title: Lido protocol with enabled Ethereum withdrawals. Audit scope tags: scope, withdrawals, audits authors: Eugene Mamin, George Avsetsin, Eugene Pshenichnyy --- ## Lido protocol with enabled Ethereum withdrawals. Audit scope * Created: 2022-11-28 * Updated: 2023-03-20 --- ### Simple summary A protocol upgrade for Lido on Ethereum to allow `stETH` token to be redeemed to Ξ natively once Ethereum undergone Shanghai/Capella hardfork implementing withdrawals ([EIP-4895](https://eips.ethereum.org/EIPS/eip-4895)). The major features of the protocol upgrade beyond withdrawals: - A smart contracts architecture which eases diversification of the Lido's validators by facilitating onboarding process of the heterogenous validators subsets (e.g., community-driven validators or committees of [DVT](https://docs.obol.tech/docs/int/key-concepts#distributed-validator)-enabled validators) through a [staking router](https://hackmd.io/XAVMwsAmQz-p_dMpMb5V5g?view) adapter contract. - An updated oracle contract consensus mechanics that allows delivering huge data chunks (virtually unbounded) via two-step procedure: reach a consensus about the data hash, and deliver the data itself in a batched manner. ### Context #### Withdrawals [Lido on Ethereum](https://lido.fi/ethereum) is a liquid staking protocol on Ethereum mainnet. At the moment, Lido staked ether token `stETH` could be redeemed to Ξ only via market exchange mechanics (incentivized [liquidity pools](https://docs.lido.fi/deployed-contracts#liquidity-pools) as the main source) because withdrawals (i.e., Beacon Chain 'unstaking') are not implemented yet on Ethereum natively. The latter is a subject of change when Shanghai/Capella ('Shapella') hardfork got activated. It will enable stand-alone unstaking flow transferring funds from validators to their withdrawal credentials addresses (requires `0x01`-type withdrawals credentials) via new [system-level operation type](https://eips.ethereum.org/EIPS/eip-4895#system-level-operation-withdrawal) when: - a validator has an excessive balance above 32 Ξ - a validator has become inactive (exited either voluntary or ejected by the network consensus if penalized/slashed) Lido validators share the same 0x01-type withdrawal credentials by design which correspond to the [WithdrawalsVault](https://etherscan.io/address/0xb9d7934878b5fb9610b3fe8a5e441e8fad7e293f) contract. The Lido protocol upgrade allows collecting withdrawal requests from `stETH` holders via the `WithdrawalQueue` contract and fulfilling them using an off-chain oracle daemon. The off-chain committee-driven Oracle daemon executes a significant part of withdrawals due to the following major considerations: - Consensus Layer data (validators' states and balances) is unavailable (not exposed) on Execution Layer - There is no way to exit a validator by the command from Execution Layer More details about withdrawals design landscape for Lido on Ethereum are desribed here: https://research.lido.fi/t/withdrawals-for-lido-on-ethereum/3690 #### Staking router Lido-participating Ethereum validators are currently represented by the curated set of node operators. In order to become a node operator in Lido, it is necessary to pass the assessment of the [Lido Node Operator Sub Governance Group](https://lido.fi/governance#lnosg) (LNOSG). This group accepts applications, evaluates and offers a shortlist, which is sent to the DAO for an on-chain approval via voting process. On approval each node operator is added to the [`NodeOperatorRegistry`](https://github.com/lidofinance/lido-dao/blob/master/contracts/0.4.24/nos/NodeOperatorsRegistry.sol) contract, which contains all node operators with their validators keys pre-approved by the Lido DAO. To diversify Lido validators set and make it heterogeneous, there is the intermediate [`StakingRouter`](https://research.lido.fi/t/lip-20-staking-router/3790) contract that incorporates previously known `NodeOperatorRegistry` as a kind of module with ability to add another modules (e.g., community-driven validators or committees of [DVT](https://docs.obol.tech/docs/int/key-concepts#distributed-validator)-enabled validators). #### Two-phase oracle To support withdrawals for Lido, the part of the protocol that currently passes data from consensus layer to execution layer (the Oracle) has to be extended and reworked. More kinds of data are required, not only CL-derived state data, buf also diff data potentially unlimited amount (contains keys to be exited and exited keys since previous report for each protocol-participating node operator). Thus, Oracle has two different reporting intervals: exited keys are reported more frequently (a few hours) than other data (once a day). Off-chain oracle consists of two functional modules. - The accounting module is responsible for protocol accounting and follows the current lifecycle (24h amortized period), though reporting more values than now (withdrawals requests to finalize, withdrawals vault balance corresponding to the report’s epoch, and exited validators for each node operator). This module interacts with the new `AccountingOracle` contract. - The ejection module performs validator exit requests signalling, estimating the needed validator exits amount and interacting with the new `ValidatorExitBusOracle` contract, using more agile report interval. Both modules are running using the same oracle committee, but their lifecycle is uncoupled due to different asynchronous environment and report asumptions. #### Documentation and sources The picture below outlines the smart contracts architecture. ![](https://hackmd.io/_uploads/Sy8MDBO3o.png) The architecture was presented on the [Lido community call #3](https://www.youtube.com/live/-bHBQ9bfSr0?feature=share), see also [Presentation slides](https://pitch.com/public/5d7230ec-a68d-4e81-92b0-67afaf388a9d). ##### General documentation - Protocol documentation: https://docs.lido.fi/ - Protocol sources GitHub repo: - https://github.com/lidofinance/lido-dao/pull/482 (**the [`shapella-upgrade`](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade) branch for audit assessments**) - https://github.com/lidofinance/lido-dao/ (*deployed pre-withdrawals stable version*) - Deployed contracts: https://docs.lido.fi/deployed-contracts/#mainnet The protocol has been running on top of the [Aragon framework](https://mainnet.lido.fi/#/lido-dao.aragonid.eth). ##### Staking router docs - [Architecture decision record: Staking router](https://hackmd.io/f1wvHzpjTIq41-GCrdaMjw) - [Lido improvement proposal #19: Staking router](https://hackmd.io/XAVMwsAmQz-p_dMpMb5V5g?view) ##### Withdrawals docs - [Withdrawals for Lido on Ethereum](https://research.lido.fi/t/withdrawals-for-lido-on-ethereum/3690) - [Withdrawals: Automating validators exit order](https://research.lido.fi/t/withdrawals-automating-lido-validator-exits/3272) - [Withdrawals. On validator exit order](https://research.lido.fi/t/withdrawals-on-validator-exiting-order/3048) - [Lido on Ethereum. Protocol accounting with enabled withdrawals](https://hackmd.io/@lido/HknYRrCws?type=view) ### Usage and purpose #### Withdrawals `stETH` holder interacts with Lido by locking tokens on `WithdrawalQueue` and receiving an enqueued position index in return. The position is monotonically increasing counter representing the place in the internal withdrawal requests queue. Locked `stETH` continues accumulating rewards on behalf of other protocol users, the original holder stops receiving a positive rebase since the block number of the successfully placed withdrawal request. Upon the next oracle report, previously accumulated withdrawal requests are processed and finalized if eligible (timelock passed and enough funds to fulfill). Other requests are carried over to the next oracle report round. `stETH` [shares](https://docs.lido.fi/guides/steth-integration-guide#steth-internals-share-mechanics) are burned on behalf of the Oracle report together with decreasing the total pooled ether amount. The logic of withdrawal requests unwinding and processing is implemented within the off-chain Oracle daemon (accounting module that delivers data to the `AccountingOracle` contract). The Oracle daemon provides the following data during the reports: the index of the last finalized withdrawal request, Lido validators balances, active validators number, exited validators number per each node operator, balance of the [Lido withdrawal credentials address](https://docs.lido.fi/contracts/withdrawals-manager-stub) (all info is valid for the referece slot of the expected report). The oracle must track all of the Lido-participating validators' exits (node operators could also initiate a voluntary exit without request from Lido) that occurred over the previous oracle round and modify their on-chain state stored within Lido protocol to process rewards and balance the newly submitted ether. After the withdrawals requests have been processed and finalized, anyone can claim the ether corresponding to the provided finalized position index on behalf of the original requestor (recipient). Another signaling off-chain process which has its own lifecycle, is needed to report the validator keys needs to be exited to fulfill withdrawal requests (ejection module that delivers data to the `ValidatorExitBusOracle` contract). This process could be executed on behalf of the main Oracle committee to request the exit of specific validators based on the amount of withdrawal requests, slashing conditions, status/performance of validators controlled by Lido, staked ether buffer size, execution layer rewards, and previously requested withdrawals. The order of the proposed exits is deterministic and verifiable externally (i.e., sorted by validator's index resembling validator age counted from its activation). #### Staking router The `StakingRouter` contract is responsible for: - plugging validator subsets modules together - distribute new ether for staking to modules - distribute accrued rewards between modules - push ether together with signed keys to the [`DepositContract`](https://etherscan.io/address/0x00000000219ab540356cbb839cbe05303d7705fa) (Beacon Deposit Contract) `NodeOperatorsRegistry` has the updated interface to be a pluggable module for `StakingRouter`. There is also a separate contract that mitigates [deposit front-running vulnerability](https://github.com/lidofinance/lido-improvement-proposals/blob/develop/LIPS/lip-5.md) [`DepositSecurityModule`](https://github.com/lidofinance/lido-dao/blob/master/contracts/0.8.9/DepositSecurityModule.sol) that involved into the staking flow. ### Permissions and upgradability The permissions model is managed by the [Aragon ACL](https://hack.aragon.org/developers/tools/aragonos/reference-aragonos-3#acl) and [OpenZeppelin](https://docs.openzeppelin.com/contracts/4.x/api/access#AccessControlEnumerable) access control. The protocol contains both upgradable and non-upgradable contracts. ### Scope of the audit The audit scope consists of two parts: on-chain and off-chain code. #### On-chain scope The following [contracts](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts) list is included in the on-chain scope: - ~~[contracts/0.4.24/lib/Math64.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/lib/Math64.sol)~~ (removed) - [contracts/0.4.24/lib/Packed64x4.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/lib/Packed64x4.sol) - [contracts/0.4.24/lib/SigningKeys.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/lib/SigningKeys.sol) - [contracts/0.4.24/lib/StakeLimitUtils.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/lib/StakeLimitUtils.sol) - [contracts/0.4.24/nos/NodeOperatorsRegistry.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/nos/NodeOperatorsRegistry.sol) - [contracts/0.4.24/oracle/LegacyOracle.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/oracle/LegacyOracle.sol) - [contracts/0.4.24/utils/Pausable.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/utils/Pausable.sol) - [contracts/0.4.24/utils/Versioned.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/utils/Versioned.sol) - [contracts/0.4.24/Lido.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/0.4.24/Lido.sol) - [contracts/0.4.24/StETH.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/StETH.sol) - [contracts/0.4.24/StETHPermit.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.4.24/StETHPermit.sol) - [contracts/0.6.11/deposit_contract.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.6.11/deposit_contract.sol) (NB: Ethereum vanilla deposit contract) - [contracts/0.6.12/interfaces/IStETH.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.6.12/interfaces/IStETH.sol) - [contracts/0.6.12/WstETH.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.6.12/WstETH.sol) - [contracts/0.8.9/interfaces/IStakingModule.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/interfaces/IStakingModule.sol) - [contracts/0.8.9/lib/Math.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/lib/Math.sol) - [contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/lib/PositiveTokenRebaseLimiter.sol) - [contracts/0.8.9/lib/UnstructuredStorage.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/lib/UnstructuredStorage.sol) - [contracts/0.8.9/lib/UnstructuredRefStorage.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/lib/UnstructuredRefStorage.sol) - [contracts/0.8.9/oracle/AccountingOracle.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/oracle/AccountingOracle.sol) - [contracts/0.8.9/oracle/BaseOracle.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/oracle/BaseOracle.sol) - [contracts/0.8.9/oracle/HashConsensus.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/oracle/HashConsensus.sol) - [contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/oracle/ValidatorsExitBusOracle.sol) - [contracts/0.8.9/proxy/OssifiableProxy.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/proxy/OssifiableProxy.sol) - [contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/sanity_checks/OracleReportSanityChecker.sol) - [contracts/0.8.9/utils/access/AccessControl.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/utils/access/AccessControl.sol) - [contracts/0.8.9/utils/access/AccessControlEnumerable.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/utils/access/AccessControlEnumerable.sol) - [contracts/0.8.9/utils/PausableUntil.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/utils/PausableUntil.sol) - [contracts/0.8.9/utils/Versioned.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/utils/Versioned.sol) - [contracts/0.8.9/BeaconChainDepositor.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/BeaconChainDepositor.sol) - [contracts/0.8.9/Burner.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/Burner.sol) - [contracts/0.8.9/DepositSecurityModule.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/DepositSecurityModule.sol) - [contracts/0.8.9/EIP712StETH.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/EIP712StETH.sol) - [contracts/0.8.9/LidoExecutionLayerRewardsVault.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/LidoExecutionLayerRewardsVault.sol) - [contracts/0.8.9/LidoLocator.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/LidoLocator.sol) - [contracts/0.8.9/OracleDaemonConfig.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/0.8.9/OracleDaemonConfig.sol) - [contracts/0.8.9/StakingRouter.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/0.8.9/StakingRouter.sol) - [contracts/0.8.9/WithdrawalQueueERC721.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/0.8.9/WithdrawalQueueERC721.sol) (renamed `WithdrawalRequestNFT.sol`) - [contracts/0.8.9/WithdrawalQueue.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/0.8.9/WithdrawalQueue.sol) - [contracts/0.8.9/WithdrawalQueueBase.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/0.8.9/WithdrawalQueueBase.sol) - [contracts/0.8.9/WithdrawalVault.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/0.8.9/WithdrawalVault.sol) - [contracts/common/interfaces/IEIP712StETH.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/interfaces/IEIP712StETH.sol) (renamed `IEIP712.sol`) - [contracts/common/interfaces/ILidoLocator.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/interfaces/ILidoLocator.sol) - [contracts/common/interfaces/IBurner.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/interfaces/IBurner.sol) - [contracts/common/lib/ECDSA.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/lib/ECDSA.sol) - [contracts/common/lib/Math256.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/lib/Math256.sol) - [contracts/common/lib/MemUtils.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/lib/MemUtils.sol) - [contracts/common/lib/MinFirstAllocationStrategy.sol](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade/contracts/common/lib/MinFirstAllocationStrategy.sol) - [contracts/common/SignatureUtils.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/common/lib/SignatureUtils.sol) (new // 2023-03-14) On-chain code size: **~5000** nSLOC (using the [[1]](https://github.com/ConsenSys/solidity-metrics) method) >NOTE: The following contracts were excluded from the scope: >`**/template/**` >`**/mock*` >`**/text*` The contracts are written in Solidity 0.4.24, 0.6.12, and 0.8.9. The project uses the [hardhat](https://hardhat.org/) framework. #### Off-chain scope The following [source files](https://github.com/lidofinance/lido-oracle/tree/feat/oracle-v3/src) are included in the off-chain scope: ``` ./services/withdrawal.py ./services/exit_order.py ./services/validator_state.py ./services/bunker.py ./services/prediction.py ./services/safe_border.py ./variables.py ./providers/consensus/client.py ./providers/consensus/typings.py ./providers/keys/client.py ./providers/keys/typings.py ./providers/http_provider.py ./modules/ejector/ejector.py ./modules/ejector/typings.py ./modules/ejector/data_encode.py ./modules/submodules/oracle_module.py ./modules/submodules/typings.py ./modules/submodules/consensus.py ./modules/submodules/exceptions.py ./modules/accounting/extra_data.py ./modules/accounting/typings.py ./modules/accounting/accounting.py ./metrics/prometheus/basic.py ./metrics/logging.py ./metrics/healthcheck_server.py ./utils/validator_state.py ./utils/events.py ./utils/abi.py ./utils/types.py ./utils/slot.py ./utils/dataclass.py ./utils/blockstamp.py ./typings.py ./web3py/typings.py ./web3py/extensions/keys_api.py ./web3py/extensions/contracts.py ./web3py/extensions/lido_validators.py ./web3py/extensions/consensus.py ./web3py/extensions/tx_utils.py ./web3py/contract_tweak.py ./web3py/middleware.py ./constants.py ./main.py ``` Expected off-chain code size: **~3300** lines of code (using the [loc](https://github.com/cgag/loc)/[cloc](https://github.com/AlDanial/cloc) utils method) The off-chain code is written in Python 3.11. #### [NEW] Links to early research drafts that may be useful - [Accounting oracle](https://hackmd.io/@lido/r1wF0OLhj) - [Associated slashings research](https://hackmd.io/@lido/r1Qkkiv3j) - [Ejector oracle](https://hackmd.io/@lido/BJxY6m52j) ## Final commit to audit The final commits to audit is: - on-chain: - 2023-02-21: [[`e57517730c3e11a41e9cbc32ce018726722335b7`]](https://github.com/lidofinance/lido-dao/tree/e57517730c3e11a41e9cbc32ce018726722335b7/contracts) initial commit ([Lido 2.0 beta2](https://github.com/lidofinance/lido-dao/releases/tag/v2.0.0-beta.2)) - 2023-03-14: [[`2bce10d4f0cb10cde11bead4719a5bcde76b93f9`]](https://github.com/lidofinance/lido-dao/tree/2bce10d4f0cb10cde11bead4719a5bcde76b93f9) updated [Lido 2.0 beta3](https://github.com/lidofinance/lido-dao/releases/tag/v2.0.0-beta.3) - off-chain: - 2023-03-01: [[`20bc575f4fae7b3139b210b92f6d05a28215a9fb`]](https://github.com/lidofinance/lido-oracle/tree/20bc575f4fae7b3139b210b92f6d05a28215a9fb/src) - 2023-03-20: [[`f3b314c31d9823f8c68b8ab3458f4c24a0eef004`]](https://github.com/lidofinance/lido-oracle/tree/f3b314c31d9823f8c68b8ab3458f4c24a0eef004/src) updated [`Oracle 3.0.0-beta.1`](https://github.com/lidofinance/lido-oracle/releases/tag/3.0.0-beta.1) ## Edits log - **2023-01-10**: The audit scope is updated with respect to the [shapella upgrade branch](https://github.com/lidofinance/lido-dao/tree/feature/shapella-upgrade), more up-to-date context regarding Staking Router. - **2023-02-02**: Latest changes described at the moment of writing: two-phase oracle details, new docs, updated contracts list. - **2023-02-06**: Updated contracts list (feature-freeze), [readiness](#On-chain-scope-readiness) tiers, staking router [LIP-20](https://research.lido.fi/t/lip-20-staking-router/3790) - **2023-02-08**: `SelfOwnedStETHBurner` → `Burner` (renamed), [community call #3](https://www.youtube.com/live/-bHBQ9bfSr0?feature=share) and [presentation](https://pitch.com/public/5d7230ec-a68d-4e81-92b0-67afaf388a9d) links added - **2023-02-10**: Tiers updated, scope refinements (`Packed64.sol → Packed64x4.sol`, `LidoOracle` → `LegacyOracle`, `Pausable.sol` moved from libs to utils, `ResizableArray.sol` completely removed) - **2023-02-13**: Tiers removed, soft code freeze is achieved. - **2023-02-21**: New [article](https://research.lido.fi/t/withdrawals-for-lido-on-ethereum-bunker-mode-design-and-implementation/3890) about bunker mode. Code freeze for the off-chain part is on the 1st of March, follow-up [fixes](https://github.com/lidofinance/lido-dao/pull/624) for the on-chain code ("hard freeze", commit id: [`e575177`](https://github.com/lidofinance/lido-dao/tree/e57517730c3e11a41e9cbc32ce018726722335b7/contracts)). - **2023-02-22**: Notes on renamed/removed contracts (-`Math64.sol`, `IEIP712.sol`→`IEIP712StETH.sol`, `WithdrawalRequestNFT.sol`→`WithdrawalQueueERC721.sol`). - **2023-03-01**: Off-chain codefreeze commit, new draft docs about oracle ([Accounting oracle](https://hackmd.io/@lido/r1wF0OLhj), [Associated slashings research](https://hackmd.io/@lido/r1Qkkiv3j), [Ejector oracle](https://hackmd.io/@lido/BJxY6m52j)), new draft about [finalization share rate](https://hackmd.io/-57vYMtvTO6J538yPi427Q). - **2023-03-14**: On-chain code updated to resolve the already reported findings ([2bce10d](https://github.com/lidofinance/lido-dao/tree/2bce10d4f0cb10cde11bead4719a5bcde76b93f9)), new library [contracts/common/SignatureUtils.sol](https://github.com/lidofinance/lido-dao/blob/feature/shapella-upgrade/contracts/common/lib/SignatureUtils.sol) for ERC-1271, see [the release notes](https://github.com/lidofinance/lido-dao/releases/tag/v2.0.0-beta.3). - **2023-03-20**: Off-chain code update to sync up with the on-chain [`beta.3`](https://github.com/lidofinance/lido-dao/releases/tag/v2.0.0-beta.3) version. New commit: [`f3b314c31d9823f8c68b8ab3458f4c24a0eef004`](https://github.com/lidofinance/lido-oracle/tree/f3b314c31d9823f8c68b8ab3458f4c24a0eef004). ## External references - [Withdrawals for Lido on Ethereum: “bunker mode” design and implementation](https://research.lido.fi/t/withdrawals-for-lido-on-ethereum-bunker-mode-design-and-implementation/3890) - [Lido community call #3: Withdrawals techdive](https://www.youtube.com/live/-bHBQ9bfSr0?feature=share) - [Presentation slides for the community call above](https://pitch.com/public/5d7230ec-a68d-4e81-92b0-67afaf388a9d) - [Withdrawals for Lido on Ethereum](https://research.lido.fi/t/withdrawals-for-lido-on-ethereum/3690) - [Pull request for the protocol upgrade](https://github.com/lidofinance/lido-dao/pull/482) - [Draft. Accounting oracle](https://hackmd.io/@lido/r1wF0OLhj) - [Draft. Associated slashings research](https://hackmd.io/@lido/r1Qkkiv3j) - [Draft. Finalization share rate](https://hackmd.io/-57vYMtvTO6J538yPi427Q) - [Draft. Ejector oracle](https://hackmd.io/@lido/BJxY6m52j) - [On withdrawal request finalization rate](https://hackmd.io/-57vYMtvTO6J538yPi427Q) - [EIP-4895: Beacon chain push withdrawals as operations](https://eips.ethereum.org/EIPS/eip-4895) - [Withdrawals: Automating Lido Validator Exits](https://research.lido.fi/t/withdrawals-automating-lido-validator-exits/3272) - [Withdrawals. On validator exiting order](https://research.lido.fi/t/withdrawals-on-validator-exiting-order/3048) - [Consensus Layer. Withdrawals tracking issue](https://github.com/ethereum/consensus-specs/issues/2758) - [Prysm docs. Validator lifecycle](https://docs.prylabs.network/docs/how-prysm-works/validator-lifecycle) - [The next chapter for Lido](https://blog.lido.fi/the-next-chapter-for-lido/) - [Lido on Ethereum: DVT Pilot with SSV Network](https://blog.lido.fi/ssv-network-pilot/) - [Lido on Ethereum: DVT Pilot with Obol Network](https://blog.lido.fi/dvt-pilot-with-obol-network/) - [Architecture decision record: Staking router](https://hackmd.io/f1wvHzpjTIq41-GCrdaMjw) - [Lido improvement proposal #20: Staking router](https://research.lido.fi/t/lip-20-staking-router/3790) - [Lido on Ethereum. Protocol accounting with enabled withdrawals](https://hackmd.io/@lido/HknYRrCws?type=view)