Skip to content

fix(H5): mark wstETH at the Lido exchange rate, not the DEX spot - #16

Merged
jayeshy14 merged 1 commit into
mainfrom
fix/h5-wsteth-exchange-rate
Jul 18, 2026
Merged

jayeshy14 merged 1 commit into
mainfrom
fix/h5-wsteth-exchange-rate

Conversation

@jayeshy14

Copy link
Copy Markdown
Owner

Audit finding H5 (High)

wstethUsdWad() marked wstETH at the lower of the Lido exchange rate and the instantaneous UniV3 slot0 spot. slot0 is flash-loan manipulable within one block, and because it was the lower-of, an attacker could only push the mark down (front-run settleEpoch, depress the pool, mint extra shares cheaply, back-run), skewing share pricing. That mark feeds NAV and settlement directly.

Fix

Mark wstETH purely at stEthPerToken x ETH/USD (the Lido exchange rate). This is the fundamental redemption value (wstETH -> stETH -> ETH), is not flash-manipulable, and is the standard wstETH-collateral marking used by Aave and Morpho. Chosen over an on-chain UniV3 TWAP because it is materially lower-risk (no TickMath vendoring, where a wrong constant would silently mis-price). The pool spot is retained only in wstethBuyAllowed as a depeg gate on buying more wstETH, where a manipulated spot is fail-safe: it can only block a buy, never inflate value.

Trade-off noted: during a real severe wstETH market depeg, NAV marks wstETH at redemption value rather than the discounted market price. The wstETH sleeve is capped at 50% and defaults to 0, and the buy gate still prevents adding wstETH during a depeg.

Tests

  • test_h5_basisBreach_marksAtRate_blocksBuys: a 5% pool depeg keeps the mark at the exchange rate but blocks buys.
  • test_h5_poolPushDownCannotLowerTheMark: an extreme flash-pushed pool spot leaves the value mark unchanged.

Independent of the other PRs; branches off main. Suite 116 -> 117.

Audit H5: wstethUsdWad marked wstETH at the lower of the exchange rate
and the instantaneous UniV3 slot0 spot. slot0 is flash-loan manipulable
within a block, and because it was the lower-of, an attacker could push
the mark DOWN (front-run settleEpoch, depress the pool, mint extra
shares cheaply, back-run) to skew share pricing.

Fix: mark wstETH purely at stEthPerToken x ETH/USD, the fundamental
redemption value and the standard wstETH-collateral marking
(Aave/Morpho). It is not flash-manipulable, so it cannot skew NAV or
settlement pricing. The pool spot is kept ONLY as a depeg gate on
BUYING more wstETH (wstethBuyAllowed), where a manipulated spot is
fail-safe: it can only block a buy, never inflate value. Regression:
a basis breach keeps the mark at the exchange rate while blocking buys;
an extreme flash-pushed pool spot leaves the mark unchanged. 116 -> 117.
@jayeshy14
jayeshy14 merged commit 74a41ef into main Jul 18, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant