Lido V2 Audit: Critical Flaw Caught Before Launch

Every liquid staking protocol runs on one number: how much ETH a unit of its staked token is worth. In Lido's case, that number is the share rate, and a February 2023 security review of the Lido V2 upgrade found a critical way to manipulate it, a bug that could have let an attacker steal ETH by bypassing the discount factor used in withdrawal accounting. The Lido V2 Upgrade report lays out that finding alongside 24 others.
Key Takeaways
- The review surfaced 25 findings across the Lido V2 upgrade: 1 critical, 3 high, 5 medium, 11 low, and 5 informational.
- The critical finding was a way to steal ETH by bypassing the discount factor in withdrawal accounting; it was fixed and re-validated.
- Scope covered five commits across the
lido-daoandlido-oraclerepositories, including the new off-chain oracle and legacy contract code. - 16 of the 25 findings were fixed; the remaining 9 were acknowledged by the Lido team without a code change.
What is Lido V2, and why did the upgrade need a security review?
Lido lets users deposit ETH, which the protocol stakes across a set of validators, and issues stETH in return: a token representing staked ETH plus the rewards it accrues over time. Before V2, getting original ETH back out of the system was limited. The V2 upgrade added a proper withdrawal path, along with a staking router for managing multiple types of validator operators and a rewritten off-chain oracle that reports validator balances back on-chain.
That's a lot of new surface area touching old code. The scope description for the review calls it "a full review of the Lido V2 protocol, which includes some legacy code, the developed smart contracts and the new off-chain oracle." Five commits were in scope: three across the lido-dao repository and two across lido-oracle, with a final validated commit reviewed after fixes had been applied.
What does the share rate actually control?
In a liquid staking protocol, the share rate determines how much ETH each unit of the staking token is worth at any given moment. Rewards, withdrawals, and the exact amount of ETH a user gets back when they redeem stETH all flow from that single figure being computed correctly.
Lido V2 introduced two mechanisms to protect it: a rebase limiter, which caps how far the share rate can move in a single update, and a withdrawal queue, which finalizes requests using a discount factor tied to that rate. Both are the kind of mechanism where a rounding error or an unhandled edge case turns into a way to extract value that shouldn't exist, and the findings in this review bear that out.
How did the critical finding exploit that mechanism?
The critical issue was a way to steal ETH by bypassing the discount factor used when withdrawal requests are finalized. It was fixed and validated against the final reviewed commit.
Three high-severity findings sat close to the same logic. One showed that withdrawal request finalization could always revert, effectively freezing the queue. Another showed the share rate could be negatively influenced through the shares-burn limit. A medium-severity finding added to the picture: the finalization sanity check didn't account for postponed share burning, meaning the safety check meant to catch bad share-rate movements had a gap of its own. All four were fixed.
What other findings clustered around the withdrawal logic?
Among the remaining medium-severity findings, one showed that accrued rewards weren't being distributed to stakers during withdrawals, and another showed an inactive node operator could permanently block new deposits. A separate medium finding showed Lido wasn't verifying the actual amount received from its execution-layer rewards vault. Four of the five mediums were fixed; one, involving deposit call data not included in guardian signatures, was acknowledged rather than changed.
The 11 low-severity findings were a mix of gas optimizations and smaller correctness issues, including a rebase limiter check that would almost always return false due to rounding, and a quirk allowing anyone to transfer 1 wei of stETH regardless of balance. The five informational findings covered code style, typographical errors, frontrunning risk during contract initialization, and a missing two-step ownership transfer pattern, the kind of control that prevents an admin role from being handed to an unreachable address by mistake.
What changed after the findings were reported?
Of the 25 findings, 16 were fixed and 9 were acknowledged without a code change. The report states that "all our reported issues were fixed or acknowledged by the Lido development team and consequently validated by us," meaning fixes were checked against the final commit rather than taken on faith.
Acknowledged doesn't mean dismissed. Items like the gas optimizations, a redundant storage write, and the frontrunning-on-initialization finding were treated by the Lido team as acceptable tradeoffs rather than defects requiring a patch. That distinction matters when reading any audit summary that just totals "issues resolved" without separating fixes from accepted risk.
Why does a system like this need manual review instead of automated scanning?
Automated tools are reasonably good at flagging reentrancy, missing access checks, or unchecked external calls. They're much weaker at catching a discount factor that can be bypassed under a specific sequence of withdrawal states, or a rebase limiter whose rounding quietly defeats its own purpose. Both require tracing state across multiple contracts and multiple calls rather than pattern-matching a single function.
That's the kind of cross-contract reasoning Hexens applied across the withdrawal queue, staking router, and oracle in this review, since the critical and high-severity findings all trace back to how those three pieces interact rather than to any one function in isolation. A protocol holding billions in staked ETH depends on that interaction holding up under every edge case, not just the common ones.
Frequently Asked Questions
What was the critical finding in the Lido V2 security review? A way to steal ETH by bypassing the discount factor used in withdrawal accounting. It was fixed and validated against the final reviewed commit.
Were all 25 findings in the Lido V2 review fixed? No. 16 were fixed and 9 were acknowledged without a code change, according to the report's status breakdown.
What repositories were in scope for the Lido V2 upgrade review? Five commits across two repositories, lidofinance/lido-dao and lidofinance/lido-oracle, covering the smart contracts, legacy code, and the new off-chain oracle.
Why did the withdrawal queue produce so many of the high and medium findings? Because it shares the same underlying dependency, the share rate, with the rebase limiter and the oracle. A bug in how that rate is calculated or checked tends to surface in more than one place at once.
What does "acknowledged" mean versus "fixed" in this report? Fixed means the code was changed and re-validated against the final commit. Acknowledged means the Lido team reviewed the finding and chose not to change the code, typically judging it an acceptable tradeoff rather than a defect.
The Lido V2 findings are a reminder that in liquid staking, the dangerous bugs rarely look like a missing require statement. They look like a discount factor, a burn limit, or a rounding rule that behaves correctly almost all the time, until a specific sequence of withdrawals proves otherwise. Catching that class of issue is what deep, cross-contract manual review is built for, and the full report, carried out by Hexens and published in February 2023, walks through how each of the 25 findings was identified and resolved.
