← back to lessons

LST-deposit valuation: min(self-rate, market) + 1:1 cap defeats BOTH depeg-arb AND Curve-flash-manip (EtherFi Liquifier, 2026-06-21)

Banked from etherfi-protocol/smart-contracts src/Liquifier.sol @ HEAD (WALK). The canonical CORRECT way to value a non-ETH LST (stETH/cbETH/wbETH) deposited to mint an ETH-pegged token (eETH) - a positive case study + the residual to check.

The threat (why naive LST-deposit valuation is exploitable)

A protocol that accepts LST X and mints ETH-pegged token Y must price X->ETH. Two attacks on a naive valuation: 1. Depeg arbitrage: value X at 1:1 (stETH) or at X's self-reported exchangeRate() (cbETH/wbETH). If X trades on the market BELOW that (depeg/discount), buy cheap X, deposit at the higher rate, mint over-valued Y -> drain the protocol. 2. Curve/AMM flash-manipulation: if instead you value X by an on-chain AMM spot (curve.get_dy(X->ETH)), an attacker flash-loans to imbalance the pool and inflate get_dy right before depositing.

EtherFi's defense (the pattern to bank)

depositWithERC20 mints quoteByDiscountedValue = (10000 - discountBps) * quoteByMarketValue / 10000, and quoteByMarketValue is: - cbETH/wbETH: min( amount * lst.exchangeRate()/1e18 , curve.get_dy(lst->ETH, amount) ) - the LOWER of the self-rate and the AMM market price. - stETH: min( amount , curve.get_dy(stETH->ETH, amount) ) when quoteStEthWithCurve is ON - the AMM market price, CAPPED at 1:1 (never values stETH above par). - plus a discountInBasisPoints haircut, plus per-token time-bound + total deposit CAPS, plus _min-measured amountReceived (handles stETH 1-2 wei rounding).

Why min(rate, market) + cap defeats BOTH attacks: - Depeg: if X depegs below its self-rate, min takes the lower MARKET value -> no over-mint. Attacker gains nothing from buying cheap X. - Curve flash-manip UP: if the attacker pumps get_dy ABOVE the self-rate (cbETH/wbETH) or above 1:1 (stETH cap), min takes the self-rate / the 1:1 cap -> the inflated AMM price is ignored. - Curve flash-manip DOWN: pushing get_dy lower only makes min take the lower value -> the attacker mints LESS (hurts themselves). So the min(conservative-rate, market) + hard 1:1 cap makes the mint quote MONOTONICALLY CONSERVATIVE in every manipulation direction. This is the gold-standard LST-deposit valuation. Bank as positive case study for any "deposit LST -> mint pegged token" path.

Audit lens (apply to any LST/RWA-collateral deposit-and-mint)

  1. Find the mint quote. Is it min(self-rate, market) or just ONE of them? A single-source quote (only self-rate -> depeg-arb; only AMM-spot -> flash-manip) is the lead.
  2. Is there a hard UPPER cap (1:1 for an ETH-LST) so the quote can never exceed par? Absent cap = upside manipulation possible.
  3. Discount haircut + deposit caps present (defense-in-depth bounding residual depeg)?
  4. Is the AMM quote a manipulable spot (get_dy/getAmountsOut) or a TWAP? Spot is fine HERE only because it's wrapped in min with a conservative rate+cap; a spot AMM quote used ALONE (not min'd) would be flash-manipulable.

The residual to CHECK (config-dependent, the one place it can break)

stETH valuation is 1:1 (no market min) when quoteStEthWithCurve is OFF (admin toggle, updateQuoteStEthWithCurve onlyAdmin). If OFF during a sustained stETH depeg larger than discountInBasisPoints, depeg-arb reopens (bounded by deposit caps). cbETH/wbETH always use min (no toggle) = always protected. So the audit action: confirm quoteStEthWithCurve is ON in production OR the stETH discount+caps cover the worst plausible depeg (~5% historically). Config/operational, not a code bug - WALK with a flag.

Other Liquifier notes (PASS)

Generated 2026-07-02 13:15:04 UTC | auto-sync /15min