Part 3 β Module 1: Liquid Staking & Restaking
Difficulty: Intermediate
Estimated reading time: ~40 minutes | Exercises: ~2-3 hours
π Table of Contents
Liquid Staking Fundamentals
- Why Liquid Staking Exists
- Two Models: Rebasing vs Non-Rebasing
- Deep Dive: The Exchange Rate
- Withdrawal Queue (Post-Shapella)
- Build Exercise: LST Oracle Consumer
Protocol Architecture
- Lido Architecture
- Deep Dive: Shares-Based Accounting in Lido
- wstETH: The Non-Rebasing Wrapper
- Oracle Reporting & the Rebase Mechanism
- Rocket Pool: Decentralized Alternative
- Code Reading Strategy
EigenLayer & Restaking
LST Integration Patterns
- Deep Dive: LST Oracle Pricing Pipeline
- De-Peg Scenarios and the Dual Oracle Pattern
- LSTs as Collateral in Lending
- LSTs in AMMs
- LSTs in Vaults
- Build Exercise: LST Collateral Lending Pool
Wrap Up
π‘ Liquid Staking Fundamentals
π‘ Concept: Why Liquid Staking Exists
The problem: Ethereum staking requires 32 ETH and running a validator. Staked ETH is locked β you canβt use it as DeFi collateral, you canβt trade it, you canβt LP with it. For an asset class worth billions, thatβs a massive capital efficiency problem.
The solution: Liquid staking protocols pool user deposits, run validators on their behalf, and issue a liquid receipt token (LST) that represents the staked position. The LST accrues staking rewards (~3-4% APR) while remaining freely tradeable and composable with DeFi.
Why this matters for DeFi developers: LSTs are the largest DeFi sector by TVL (~$50B+). wstETH is the most popular collateral type on Aave. Every major lending protocol, AMM, and vault must handle LSTs correctly β and βcorrectlyβ means understanding exchange rates, rebasing mechanics, oracle pricing, and de-peg risk. If youβre building DeFi, youβre integrating with LSTs.
Without liquid staking: With liquid staking:
32 ETH β Validator 10 ETH β Lido
β β
β Locked. Earning ~3.5% β Receive 10 stETH
β Can't use in DeFi. β Earning ~3.5% (balance rebases daily)
β β
βΌ βΌ
No DeFi composability. Use stETH in DeFi:
β’ Collateral on Aave
β’ LP on Curve
β’ Deposit in Pendle (split yield)
β’ Collateral in CDPs
β’ Restake via EigenLayer
π‘ Concept: Two Models: Rebasing vs Non-Rebasing
LSTs represent staked ETH plus accumulated rewards. There are two fundamentally different approaches to reflecting those rewards.
Rebasing (stETH β Lido):
Your token balance increases daily. If you hold 10 stETH today, youβll hold 10.001 stETH tomorrow (assuming ~3.5% APR). The token always represents ~1 staked ETH β the balance adjusts to reflect accumulated rewards.
Day 0: balanceOf(you) = 10.000000 stETH
Day 1: balanceOf(you) = 10.000959 stETH (daily rebase at ~3.5% APR)
Day 30: balanceOf(you) = 10.028767 stETH
Day 365: balanceOf(you) = 10.350000 stETH (~3.5% growth)
The rebase happens automatically when Lidoβs oracle reports new validator balances. You donβt call any function β your balanceOf() return value simply changes.
The DeFi integration problem: Many contracts assume token balances donβt change between transactions. A vault that stores balanceOf(address(this)) on deposit will find a different balance later β breaking accounting. This is the βweird tokenβ callback issue from P2M1.
π Connection: This is exactly why P2M1 covered rebasing tokens as a βweird tokenβ category. Contracts that cache balances, emit transfer events, or calculate shares based on balance differences all break with stETH.
Non-Rebasing / Wrapped (wstETH, rETH):
Your token balance stays fixed. Instead, the exchange rate increases over time. 10 wstETH today might be worth 11.9 stETH, and 10 wstETH in a year will be worth ~12.3 stETH. Same number of tokens, more underlying value.
Day 0: balanceOf(you) = 10 wstETH β worth 11.900 stETH (at 1.190 rate)
Day 365: balanceOf(you) = 10 wstETH β worth 12.317 stETH (at 1.232 rate)
Your balance didn't change. The exchange rate did.
This is the ERC-4626 pattern. wstETH behaves exactly like vault shares β fixed balance, increasing exchange rate. rETH works the same way. This is why DeFi protocols overwhelmingly prefer wstETH over stETH.
π Connection: This maps directly to P2M7βs vault share math.
convertToAssets(shares)in ERC-4626 is analogous togetStETHByWstETH(wstETHAmount)in Lido. Same mental model, same integration patterns.
Comparison:
| Rebasing (stETH) | Non-Rebasing (wstETH, rETH) | |
|---|---|---|
| Balance changes? | Yes β daily rebase | No β fixed |
| Exchange rate? | Always ~1:1 by definition | Increases over time |
| DeFi-friendly? | No β breaks many integrations | Yes β standard ERC-20 behavior |
| Mental model | Like a bank account (balance grows) | Like vault shares (share price grows) |
| Internal tracking | Shares (hidden from user) | Shares ARE the token |
| Used in DeFi as | Rarely directly β wrapped to wstETH first | Directly β wstETH and rETH composable everywhere |
The pattern: In practice, stETH exists for user-facing simplicity (people understand βmy balance growsβ), while wstETH exists for DeFi composability. This is why Aave, Compound, Maker, and every lending protocol lists wstETH, not stETH.
π Deep Dive: The Exchange Rate
The exchange rate is how non-rebasing LSTs reflect accumulated rewards. Understanding the math is critical for pricing, oracles, and integration.
wstETH exchange rate:
stEthPerToken = totalPooledEther / totalShares
Where totalPooledEther is all ETH controlled by Lido (staked + buffered) and totalShares is the total internal shares issued. When validators earn rewards, totalPooledEther increases while totalShares stays the same β so stEthPerToken increases.
Numeric walkthrough:
Given (approximate values, early 2026):
totalPooledEther = 9,600,000 ETH
totalShares = 8,100,000 shares
stEthPerToken = 9,600,000 / 8,100,000 = 1.1852
So: 1 wstETH = 1.1852 stETH = 1.1852 ETH (at protocol rate)
After one year of ~3.5% staking rewards:
totalPooledEther = 9,600,000 Γ 1.035 = 9,936,000 ETH
totalShares = 8,100,000 (unchanged β no new deposits for simplicity)
stEthPerToken = 9,936,000 / 8,100,000 = 1.2267
So: 1 wstETH = 1.2267 stETH (3.5% increase in exchange rate)
Converting between wstETH and stETH:
Wrapping: wstETH amount = stETH amount / stEthPerToken
Unwrapping: stETH amount = wstETH amount Γ stEthPerToken
Example: Wrap 100 stETH when stEthPerToken = 1.1852
wstETH received = 100 / 1.1852 = 84.37 wstETH
Later: Unwrap 84.37 wstETH when stEthPerToken = 1.2267
stETH received = 84.37 Γ 1.2267 = 103.50 stETH
Gain: 3.50 stETH β the staking rewards accumulated while holding wstETH
rETH exchange rate:
Rocket Poolβs rETH uses a similar pattern but with different internals. The exchange rate is updated by Rocket Poolβs Oracle DAO rather than derived from beacon chain balances.
rETH exchange rate = total ETH backing rETH / total rETH supply
Approximate value (early 2026): ~1.12 ETH per rETH
(Rocket Pool launched Nov 2021, ~4 years of ~3% net yield after commission)
Example: 10 rETH Γ 1.12 = 11.2 ETH equivalent
Note: Rocket Pool takes a 14% commission on staking rewards (distributed to node operators as RPL). So if beacon chain yields 3.5%, rETH holders earn ~3.0% net. This commission is why rETHβs exchange rate grows slightly slower than wstETHβs.
π» Quick Try:
Fork mainnet in Foundry and check current exchange rates:
// In a Foundry test with mainnet fork
IWstETH wstETH = IWstETH(0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0);
uint256 rate = wstETH.stEthPerToken();
console.log("wstETH exchange rate:", rate); // ~1.19e18
IRocketTokenRETH rETH = IRocketTokenRETH(0xae78736Cd615f374D3085123A210448E74Fc6393);
uint256 rethRate = rETH.getExchangeRate();
console.log("rETH exchange rate:", rethRate); // ~1.12e18
Deploy, call these view functions, and observe both rates are > 1.0 β reflecting years of accumulated staking rewards.
π‘ Concept: Withdrawal Queue (Post-Shapella)
Before Ethereumβs Shapella upgrade (April 2023), staked ETH could not be withdrawn. LSTs traded at a discount to ETH because there was no redemption mechanism β the only way to exit was selling on a DEX.
After Shapella: Lido and Rocket Pool implemented withdrawal queues. Users can request to redeem their LST for underlying ETH, but the process takes time:
Request flow:
User calls requestWithdrawals(stETHAmount)
β
βΌ
Protocol queues withdrawal
User receives NFT receipt (Lido uses ERC-721)
β
βΌ
Wait for validators to exit + ETH to become available
(typically 1-5 days, can be longer during high demand)
β
βΌ
Withdrawal finalized
User calls claimWithdrawal(requestId)
ETH returned to user
Impact on LST/ETH peg:
- The withdrawal queue creates an arbitrage loop: if stETH trades below 1 ETH on a DEX, arbitrageurs buy cheap stETH β request withdrawal β receive 1 ETH β profit. This keeps the peg tight.
- During extreme demand (mass exits), the queue lengthens and the peg can weaken β arbitrageurs must lock capital longer, reducing their incentive.
- Post-Shapella, stETH has traded very close to 1:1 with ETH. The June 2022 de-peg (0.93 ETH) happened pre-Shapella when no withdrawal mechanism existed.
π― Build Exercise: LST Oracle Consumer
Workspace: workspace/src/part3/module1/
Build a WstETHOracle contract that correctly prices wstETH in USD using a two-step pipeline.
What youβll implement:
getWstETHValueUSD(uint256 wstETHAmount)β exchange rate Γ Chainlink ETH/USD, with staleness checks on both data sourcesgetWstETHValueUSDSafe(uint256 wstETHAmount)β same pipeline but with dual oracle pattern: usesmin(protocolRate, marketRate)for the stETH β ETH conversion- Staleness checks on both Chainlink feeds (ETH/USD and stETH/ETH)
- Decimal normalization across the pipeline
Whatβs provided:
- Mock wstETH contract with configurable exchange rate (
stEthPerToken) - Mock Chainlink aggregator for ETH/USD and stETH/ETH feeds
- Interfaces for
IWstETHand ChainlinkAggregatorV3Interface
Tests verify:
- Basic pricing matches manual calculation (known exchange rate Γ known price)
- Dual oracle uses market price during simulated de-peg (stETH/ETH < 1.0)
- Staleness check reverts on stale ETH/USD feed
- Staleness check reverts on stale stETH/ETH feed
- Exchange rate growth over time produces correct price increase
- Zero amount reverts with
ZeroAmounterror - Decimal normalization is correct across the pipeline
π― Goal: Internalize the two-step LST pricing pipeline and the dual oracle safety pattern. This is the exact oracle design used by Aave, Morpho, and every lending protocol that accepts wstETH.
π Summary: Liquid Staking Fundamentals
Covered:
- Why liquid staking exists β capital efficiency for staked ETH
- Two models β rebasing (stETH, balance changes) vs non-rebasing (wstETH/rETH, exchange rate changes)
- Exchange rate math β
stEthPerTokenandgetExchangeRate()with numeric walkthroughs - Why DeFi prefers non-rebasing β same ERC-4626 mental model, no integration surprises
- Withdrawal queue β post-Shapella redemption mechanism and its peg stabilization role
Key insight: Non-rebasing LSTs are conceptually identical to ERC-4626 vault shares. If you understand convertToAssets(shares), you understand getStETHByWstETH(wstETHAmount). The pricing pipeline, the manipulation concerns, and the oracle integration patterns all carry over from P2M7 and P2M9.
Next: How Lido and Rocket Pool actually implement this β the contract architecture that makes liquid staking work.
πΌ Job Market Context
What DeFi teams expect you to know:
-
βHow would you integrate wstETH as collateral in a lending protocol?β
- Good answer: βUse the exchange rate to convert wstETH to ETH, then Chainlink for ETH/USD.β
- Great answer: βTwo-step pricing:
getStETHByWstETH()for the exchange rate, then Chainlink ETH/USD. But Iβd also use a Chainlink stETH/ETH market feed as a second oracle, taking the minimum β the dual oracle pattern. During a de-peg (like June 2022), the exchange rate says 1:1 but the market says 0.93. Without the dual oracle, positions appear healthier than they really are, and liquidations donβt fire when they should.β
-
βExplain the difference between stETH and wstETH and when youβd use each.β
- Good answer: βstETH rebases, wstETH doesnβt.β
- Great answer: βBoth represent the same underlying staked ETH. stETH uses rebasing β your balance grows daily as oracle reports update
totalPooledEther. Internally, stETH tracks shares, andbalanceOf()returnsshares Γ totalPooledEther / totalShares. wstETH is a wrapper that exposes those shares directly as a standard ERC-20 β your balance is fixed, and the exchange ratestEthPerTokengrows instead. Youβd use wstETH for any DeFi integration β lending, vaults, AMMs β because rebasing breaks contracts that cache balances.β
Interview Red Flags:
- π© Saying βstETH is always worth 1 ETHβ without qualifying that this is the protocol exchange rate, not the market rate
- π© Not knowing why DeFi protocols prefer wstETH over stETH (rebasing breaks balance caching)
- π© Treating the exchange rate as a simple constant rather than understanding itβs derived from
totalPooledEther / totalShares
Pro tip: When discussing LSTs in interviews, lead with the two-model distinction (rebasing vs non-rebasing) and immediately connect it to DeFi composability. Saying βwstETH exists because rebasing breaks DeFiβ shows you understand the real engineering constraint, not just the token names.
π‘ Protocol Architecture
π‘ Concept: Lido Architecture
Lido is the largest liquid staking protocol (~70% market share of ETH LSTs). Understanding its architecture is essential because most DeFi LST integrations target wstETH.
User Lido Protocol Beacon Chain
β β β
βββ submit(ETH) ββββββ Lido (stETH) β
β β β’ mint shares to user β
β β β’ buffer ETH β
β β β β
β β StakingRouter β
β β β’ allocate to Node Operators βββββββββ Validators
β β β
β β AccountingOracle β
β β β CL balance report βββββββββββββββββ β
β β β’ update totalPooledEther β
β β β’ triggers rebase for all holders β
β β β
βββ wrap(stETH) βββ WstETH β
β β β’ holds stETH shares internally β
β β β’ user gets fixed-balance wstETH β
β β β
βββ requestWithdrawals β WithdrawalQueueERC721 β
β β β’ mint NFT receipt β
β β β’ finalized when ETH available βββββββ β
βββ claimWithdrawal ββ β’ return ETH to user β
Key contracts:
| Contract | Role | Key functions |
|---|---|---|
Lido.sol (stETH) | Main contract β ERC-20 rebasing token + deposit | submit(), getSharesByPooledEth(), getPooledEthByShares() |
WstETH.sol | Non-rebasing wrapper | wrap(), unwrap(), stEthPerToken(), getStETHByWstETH() |
AccountingOracle.sol | Reports beacon chain state | submitReportData() β triggers handleOracleReport() |
StakingRouter.sol | Routes ETH to node operators | deposit(), module-based operator allocation |
WithdrawalQueueERC721.sol | Withdrawal requests as NFTs | requestWithdrawals(), claimWithdrawals() |
NodeOperatorsRegistry.sol | Curated operator set | Operator management (permissioned β centralization point) |
π Deep Dive: Shares-Based Accounting in Lido
Lidoβs stETH looks like a simple rebasing token from the outside, but internally it uses shares-based accounting β the same pattern as Aaveβs aTokens and ERC-4626 vaults.
The core math:
// Internal: every stETH holder has a shares balance
mapping(address => uint256) private shares;
uint256 public totalShares;
uint256 public totalPooledEther; // updated by oracle
// External: balanceOf returns stETH (not shares)
function balanceOf(address account) public view returns (uint256) {
return shares[account] * totalPooledEther / totalShares;
}
// Deposit: ETH β shares
function submit(address referral) external payable returns (uint256) {
uint256 sharesToMint = msg.value * totalShares / totalPooledEther;
shares[msg.sender] += sharesToMint;
totalShares += sharesToMint;
totalPooledEther += msg.value;
return sharesToMint;
}
How the rebase works:
Before oracle report:
totalPooledEther = 1,000,000 ETH
totalShares = 900,000
Alice has = 9,000 shares
Alice's balance = 9,000 Γ 1,000,000 / 900,000 = 10,000 stETH
Oracle reports: validators earned 100 ETH in rewards.
After oracle report:
totalPooledEther = 1,000,100 ETH (increased by 100)
totalShares = 900,000 (unchanged)
Alice has = 9,000 shares (unchanged)
Alice's balance = 9,000 Γ 1,000,100 / 900,000 = 10,001.00 stETH
Alice's balance increased by 1 stETH without any transaction. That's the rebase.
Why shares internally? Because updating totalPooledEther once (O(1)) is far cheaper than iterating over every holderβs balance (O(n)). The math resolves everything at read time. This is the same insight behind ERC-4626 and Aaveβs scaled balances β one global variable update serves all holders.
π Connection: This is the exact pattern from P2M7βs vault share math. The only difference is naming: ERC-4626 calls it
totalAssets / totalSupply, Lido calls ittotalPooledEther / totalShares. Same math, same O(1) rebase mechanism.
π‘ Concept: wstETH: The Non-Rebasing Wrapper
wstETH is a thin wrapper around stETH shares. When you βwrapβ stETH, youβre converting from the rebasing representation to the shares representation. When you βunwrap,β you convert back.
// Simplified from Lido's WstETH.sol
contract WstETH is ERC20 {
IStETH public stETH;
function wrap(uint256 stETHAmount) external returns (uint256) {
// Convert stETH amount to shares
uint256 wstETHAmount = stETH.getSharesByPooledEth(stETHAmount);
// Transfer stETH in (as shares internally)
stETH.transferFrom(msg.sender, address(this), stETHAmount);
// Mint wstETH 1:1 with shares
_mint(msg.sender, wstETHAmount);
return wstETHAmount;
}
function unwrap(uint256 wstETHAmount) external returns (uint256) {
// Convert shares back to stETH amount
uint256 stETHAmount = stETH.getPooledEthByShares(wstETHAmount);
// Burn wstETH
_burn(msg.sender, wstETHAmount);
// Transfer stETH out
stETH.transfer(msg.sender, stETHAmount);
return stETHAmount;
}
// The exchange rate β how much stETH one wstETH is worth
function stEthPerToken() external view returns (uint256) {
return stETH.getPooledEthByShares(1 ether); // 1 share β X stETH
}
// Conversion helpers
function getWstETHByStETH(uint256 stETHAmount) external view returns (uint256) {
return stETH.getSharesByPooledEth(stETHAmount);
}
function getStETHByWstETH(uint256 wstETHAmount) external view returns (uint256) {
return stETH.getPooledEthByShares(wstETHAmount);
}
}
The key insight: 1 wstETH = 1 Lido share. The βwrappingβ is conceptual β wstETH simply exposes shares as a standard ERC-20 instead of hiding them behind the rebasing balanceOf(). This is why wstETH is DeFi-compatible: its balance never changes, only the rate returned by stEthPerToken() grows.
π‘ Concept: Oracle Reporting & the Rebase Mechanism
The oracle is how Lido learns about validator performance on the beacon chain (consensus layer). This is a trust assumption worth understanding.
The flow:
Beacon Chain validators earn rewards
β
βΌ
Oracle committee (5/9 quorum in V1; V2 uses HashConsensus)
reports new total CL balance
β
βΌ
AccountingOracle.submitReportData()
β
βΌ
Lido._handleOracleReport()
β’ Updates totalPooledEther
β’ Applies sanity checks:
- APR can't exceed a configured max (~10%)
- Balance can't drop more than configured limit (slashing protection)
β’ Mints fee shares (10% of rewards β treasury + node operators)
β’ All stETH holders' balanceOf() now returns updated values
The trust model: Lido relies on a permissioned oracle committee to report beacon chain balances accurately. This is a centralization point β if the oracle reports inflated balances, stETH becomes over-valued. The sanity checks (max APR cap, max balance drop) limit the damage from a compromised oracle, but the trust assumption exists.
Sanity check example:
Last reported: totalPooledEther = 9,600,000 ETH
New report claims: totalPooledEther = 10,500,000 ETH
APR implied: (10,500,000 - 9,600,000) / 9,600,000 = 9.375%
Max allowed APR: 10%
9.375% < 10% β passes sanity check
But if new report claimed 11,000,000 ETH:
APR implied: 14.6% β exceeds 10% cap β REJECTED
(Simplified β Lido's actual checks use per-report balance limits, not annualized rates.
This annualized framing illustrates the concept.)
Frequency: Oracle reports happen roughly once per day. (Lido V1 used a fixed ~225-epoch cadence; V2 uses configurable reporting frames that can vary.) Between reports, the exchange rate is stale β it doesnβt reflect the latest beacon chain rewards. This staleness is normally negligible but matters during rapid market changes.
π Connection: This oracle sanity check pattern is analogous to the rate cap you saw in P2M9βs vault share pricing β both limit how fast an exchange rate can grow to prevent manipulation. Lidoβs cap is built into the protocol itself; your P2M9 stablecoin cap was external.
π‘ Concept: Rocket Pool: Decentralized Alternative
Rocket Pool takes a different approach to decentralization. Where Lido uses a curated set of professional operators, Rocket Pool is permissionless β anyone can run a validator.
The minipool model:
Traditional staking: Validator needs 32 ETH from one source
Rocket Pool minipool: Validator needs:
β’ 8 ETH from node operator (+ RPL stake as insurance)
β’ 24 ETH from rETH depositors (pooled)
Or:
β’ 16 ETH from node operator (+ RPL stake)
β’ 16 ETH from rETH depositors
ββββββββββββββββββββββββββββββββββββββββββββ
β 32 ETH Validator β
ββββββββββββββ¬ββββββββββββββββββββββββββββββ€
β 8 ETH β 24 ETH β
β (operator) β (rETH depositors pool) β
β + RPL bond β β
ββββββββββββββ΄ββββββββββββββββββββββββββββββ
rETH exchange rate:
// Simplified from RocketTokenRETH.sol
function getExchangeRate() public view returns (uint256) {
uint256 totalEth = address(rocketDepositPool).balance
+ totalStakedEthInMinipools
+ rewardsAccumulated;
uint256 rethSupply = totalSupply();
if (rethSupply == 0) return 1 ether;
return totalEth * 1 ether / rethSupply;
}
The rate is updated by Rocket Poolβs Oracle DAO (a set of trusted nodes) rather than derived directly from the contractβs beacon chain view. This introduces a similar trust assumption to Lidoβs oracle, but with a different governance structure.
Trade-offs: Lido vs Rocket Pool
| Lido (stETH/wstETH) | Rocket Pool (rETH) | |
|---|---|---|
| Market share | ~70% of LST market | ~5-8% |
| Operator model | Curated (permissioned) | Permissionless (8 ETH + RPL) |
| Oracle | Oracle committee (5/9) | Oracle DAO (trusted node set) |
| DeFi liquidity | Deep (Curve, Aave, Uniswap, etc.) | Thinner but growing |
| Commission | 10% of rewards | 14% of rewards |
| Exchange rate (approx. early 2026) | ~1.19 | ~1.12 |
| Governance | LDO token + dual governance | pDAO + oDAO |
| Centralization concern | Operator set concentration | Oracle DAO trust |
Why this matters for integration: When you build a protocol that accepts LST collateral, youβll likely support both wstETH and rETH. The oracle pricing pattern is the same (exchange rate Γ underlying price), but the liquidity profiles differ. wstETH can be liquidated against deep Curve/Uniswap pools; rETH has thinner secondary market liquidity, so youβd set a lower LTV for rETH collateral.
π Code Reading Strategy
Lido β reading order:
| # | File | Why Read | Key Functions |
|---|---|---|---|
| 1 | WstETH.sol | Simplest entry point β clean wrapper | wrap(), unwrap(), stEthPerToken() |
| 2 | Lido.sol (stETH) | Core token β shares-based accounting | submit(), _transferShares(), getPooledEthByShares() |
| 3 | AccountingOracle.sol | How rebase is triggered | submitReportData(), sanity checks |
| 4 | WithdrawalQueueERC721.sol | Exit mechanism | requestWithdrawals(), _finalize() |
Donβt get stuck on: Lidoβs governance contracts, the Burner contract (handles cover/slashing accounting), or the StakingRouter module system. These are protocol-governance concerns, not DeFi integration concerns.
Rocket Pool β reading order:
| # | File | Why Read | Key Functions |
|---|---|---|---|
| 1 | RocketTokenRETH.sol | The token β exchange rate | getExchangeRate(), mint(), burn() |
| 2 | RocketDepositPool.sol | Deposit entry point | deposit() β allocates to minipools |
Donβt get stuck on: Rocket Poolβs minipool lifecycle contracts (RocketMinipoolManager, RocketMinipoolDelegate). These are validator-operations concerns, not DeFi integration concerns.
Repos: Lido | Rocket Pool
π Summary: Protocol Architecture
Covered:
- Lido architecture β 6 key contracts with roles and data flow
- Shares-based accounting β internal shares +
totalPooledEtherenables O(1) rebase - wstETH wrapper β exposes shares as standard ERC-20 (no rebase surprises)
- Oracle reporting β how beacon chain rewards become stETH balance changes, including sanity checks
- Rocket Pool β permissionless minipool model, rETH exchange rate, trade-offs vs Lido
- Code reading strategy with file-level specifics
Key insight: Both Lido and Rocket Pool use the same underlying math (shares Γ rate = value) but expose it differently. Lido shows it as a rebasing balance (stETH) with a wrapper option (wstETH). Rocket Pool only offers the non-rebasing form (rETH). For DeFi integration, both are βexchange rate Γ underlying priceβ β the same pipeline.
Next: Restaking β the layer built on top of liquid staking, and the new risk frontier.
π§ Checkpoint β Before Moving On: Can you explain the difference between stETH and wstETH in terms of how they represent staking rewards? Can you calculate a wstETH β stETH conversion given a
stEthPerTokenvalue? If you can, you understand the foundation that everything else in this module builds on.
πΌ Job Market Context
What DeFi teams expect you to know:
- βHow does Lidoβs oracle work, and what are the trust assumptions?β
- Good answer: βOracle committee reports beacon chain balances, triggering rebase.β
- Great answer: βA permissioned oracle committee (5/9 quorum) submits beacon chain balance reports to
AccountingOracle. The report updatestotalPooledEther, which changes every stETH holderβsbalanceOf()return value. Sanity checks cap the maximum APR and maximum balance drop to limit damage from a compromised oracle. The trust assumption is that the oracle committee honestly reports balances β if they inflate the report, stETH becomes temporarily overvalued. This is similar to how Chainlink oracles are a trust assumption for price feeds.β
Interview Red Flags:
- π© Not being able to explain the oracle reporting mechanism β itβs a critical trust assumption, not a minor detail
- π© Describing the rebase as βautomaticβ without explaining that itβs triggered by an oracle committee report
- π© Ignoring the sanity checks (APR cap, max balance drop) that limit oracle manipulation damage
Pro tip: When teams ask about Lidoβs oracle, mention the sanity bounds unprompted. Showing you know that AccountingOracle caps max APR and max balance drop per report signals that youβve read the actual code, not just the docs.
π‘ EigenLayer & Restaking
π‘ Concept: What is Restaking?
Staked ETH secures Ethereumβs consensus layer. Restaking extends this security to additional protocols by allowing stakers to opt in to securing additional services with the same stake.
The concept:
Traditional staking:
32 ETH β Secures Ethereum β Earns ~3.5% APR
Restaking:
32 ETH β Secures Ethereum β Earns ~3.5% APR
β ALSO secures Oracle Network β Earns +0.5% APR
β ALSO secures Bridge Protocol β Earns +0.3% APR
β ALSO secures Data Availability β Earns +0.4% APR
Same capital, multiple revenue streams.
Trade-off: additional slashing risk for each service.
Why it matters: Before EigenLayer, every new protocol that needed economic security had to bootstrap its own staking system β recruit validators, create a token, incentivize staking. Restaking lets protocols βrentβ Ethereumβs existing security. This is a fundamental shift in how decentralized infrastructure is bootstrapped.
π» Quick Try (read-only, optional):
If you have an Ethereum mainnet RPC (e.g., Alchemy/Infura), you can inspect EigenLayerβs live state:
// In Foundry's cast:
// cast call 0x858646372CC42E1A627fcE94aa7A7033e7CF075A "getTotalShares(address)(uint256)" 0x93c4b944D05dfe6df7645A86cd2206016c51564D --rpc-url $RPC
// (StrategyManager β stETH strategy shares)
This is a read-only peek at how much stETH is restaked in EigenLayer. No testnet deployment needed β just a mainnet RPC call.
π‘ Concept: EigenLayer Architecture
EigenLayer is the dominant restaking protocol. It has four core components:
βββββββββββββββββββββββββ
β AVS Contracts β
β (EigenDA, oracles, β
β bridges, sequencers) β
βββββββββββββ¬ββββββββββββ
β registers + validates
βββββββββββββ΄ββββββββββββ
β Operators β
β (run AVS software, β
β sign attestations) β
βββββββββββββ¬ββββββββββββ
β delegation
βββββββββββββ΄ββββββββββββ
β DelegationManager β
β (stakers β operators) β
βββββββ¬ββββββββββββ¬ββββββ
β β
ββββββββββββββ΄βββ βββββββ΄βββββββββββββ
βStrategyManagerβ β EigenPodManager β
β (LST deposit)β β (native ETH β
β wstETH, rETHβ β restaking via β
β cbETH, etc. β β beacon proofs) β
βββββββββββββββββ ββββββββββββββββββββ
StrategyManager β Handles LST restaking. Users deposit LSTs (wstETH, rETH, etc.) into strategies. Each strategy holds one token type. The deposited tokens become the stakerβs restaked capital.
EigenPodManager β Handles native ETH restaking. Validators point their withdrawal credentials to an EigenPod contract. The pod verifies beacon chain proofs to confirm the validatorβs balance and status. No LST needed β raw staked ETH is restaked.
DelegationManager β The bridge between stakers and operators. Stakers delegate their restaked assets to operators who actually run AVS infrastructure. Stakers earn rewards but also bear slashing risk from the operatorβs behavior.
AVS (Actively Validated Services) β The protocols secured by restaked ETH. Each AVS defines its own:
- What operators must do (run specific software, provide attestations)
- What constitutes misbehavior (triggers slashing)
- How rewards are distributed
Major AVSes include EigenDA (data availability), various oracle networks, and bridge validation services.
The delegation and slashing flow:
Staker deposits 100 wstETH into StrategyManager
β
βΌ
Staker delegates to Operator A via DelegationManager
β
βΌ
Operator A opts into EigenDA AVS + Oracle AVS
β
βββ Operator runs EigenDA node β earns rewards β distributed to staker
β
βββ Operator runs Oracle node β earns rewards β distributed to staker
If Operator A misbehaves on either AVS:
β
βΌ
AVS triggers slashing β portion of staker's 100 wstETH is seized
Key point for DeFi developers: You donβt need to understand EigenLayerβs internals deeply to integrate with it. What matters is understanding that restaked assets have additional slashing risk beyond normal staking β and this risk affects how you should value LRTs (liquid restaking tokens) as collateral.
π‘ Concept: Liquid Restaking Tokens (LRTs)
LRTs are to restaking what LSTs are to staking β liquid receipt tokens for restaked positions.
Staking: Restaking:
ETH β Lido β stETH (LST) stETH β EigenLayer β deposit receipt
β
βββ Not liquid! Locked in EigenLayer.
Liquid Restaking:
ETH β EtherFi β weETH (LRT)
Internally: EtherFi stakes ETH β restakes via EigenLayer β issues weETH
User gets: liquid token representing staked + restaked ETH
Major LRTs (early 2026):
| LRT | Protocol | Strategy | Notes |
|---|---|---|---|
| weETH | EtherFi | Native restaking | Largest LRT by TVL |
| ezETH | Renzo | Multi-AVS restaking | Diversified operator set |
| rsETH | KelpDAO | LST restaking | Accepts multiple LSTs |
| pufETH | Puffer | Native + anti-slashing | Uses Secure-Signer TEE technology |
LRT exchange rates reflect both staking rewards AND restaking rewards (minus fees). Theyβre more complex than LST exchange rates because the yield sources are more diverse and the risk profile is different.
Integration caution: LRTs are newer and less battle-tested than LSTs. Their exchange rate mechanisms vary more across protocols, their oracle infrastructure is less mature, and their liquidity on DEXes is thinner. For DeFi integration (lending, collateral), LRTs warrant lower LTVs and more conservative oracle designs than wstETH or rETH.
β οΈ The Risk Landscape
Risk stacking visualization:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β LRT (weETH, ezETH) β β LRT contract risk
β β’ Smart contract bugs in LRT protocol β + liquidity risk
β β’ Exchange rate oracle accuracy β + de-peg risk
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Restaking (EigenLayer) β β AVS slashing risk
β β’ Operator misbehavior β slashing β + operator risk
β β’ AVS-specific failure modes β + smart contract risk
β β’ Correlated slashing across AVSes β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β LST (wstETH, rETH) β β Protocol risk
β β’ Lido/Rocket Pool smart contract bug β + oracle risk
β β’ Oracle committee compromise β + de-peg risk
β β’ Validator slashing (minor β diversified) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ETH Staking (Beacon Chain) β β Validator risk
β β’ Individual validator slashing β (minor if diversified)
β β’ Inactivity penalties β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ETH (Base Asset) β β Market risk only
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Each layer ADDS risk. You inherit ALL layers below you.
ETH holder: 1 risk layer
wstETH holder: 3 risk layers
weETH holder: 5 risk layers
Why this matters for DeFi integration:
When you accept an asset as collateral, you must account for ALL risk layers. This directly affects:
- LTV ratios: ETH might get 85% LTV, wstETH 80%, rETH 75%, weETH 65%
- Oracle design: More risk layers β more defensive pricing needed
- Liquidation parameters: Thinner liquidity β higher liquidation bonus needed
- Debt ceilings: Higher risk β lower maximum exposure
This is not theoretical β Aave, Morpho, and every lending protocol that lists these assets goes through exactly this analysis.
The systemic risk: If many AVSes use the same operator set, and that operator set gets slashed on one AVS, the collateral damage cascades β all LRTs backed by those operators lose value simultaneously. This correlated slashing risk is the restaking-specific systemic concern.
π Summary: EigenLayer & Restaking
Covered:
- Restaking concept β recycling economic security, additional yield for additional risk
- EigenLayerβs 4 core components β StrategyManager, EigenPodManager, DelegationManager, AVS
- The delegation and slashing flow β how stakers, operators, and AVSes interact
- LRTs β liquid receipt tokens for restaked positions (weETH, ezETH, rsETH, pufETH)
- Risk stacking β each layer adds risk, directly affecting DeFi integration parameters
Key insight: The risk stacking diagram is what DeFi integration comes down to. Every LTV ratio, oracle design choice, and liquidation parameter for LSTs and LRTs is ultimately a judgment about which risk layers youβre willing to accept and at what discount. This is the analysis that protocol risk teams perform β and being able to articulate it is a strong interview signal.
Next: Putting it all together β how to actually integrate LSTs into DeFi protocols.
πΌ Job Market Context
What DeFi teams expect you to know:
- βWhat are the risks of accepting LRTs as collateral?β
- Good answer: βSmart contract risk, slashing risk, liquidity risk.β
- Great answer: βRisk stacking β an LRT like weETH carries five layers of risk: ETH market risk, validator slashing, LST protocol risk, EigenLayer smart contract and AVS slashing risk, and the LRT protocolβs own risk. Each layer compounds. Iβd set LTV significantly lower than for plain wstETH (maybe 65% vs 80%), require deeper liquidity on DEX for liquidation viability, set higher liquidation bonus to compensate bidders for the added complexity of selling an LRT, and impose tighter debt ceilings.β
Interview Red Flags:
- π© Treating LSTs and LRTs as having the same risk profile β LRTs stack additional slashing and smart contract layers
- π© Listing risks without quantifying the impact on protocol parameters (LTV, liquidation bonus, debt ceilings)
- π© Not mentioning correlated slashing β if an AVS slashes, it can affect all LRTs delegated to that operator simultaneously
Pro tip: If asked about EigenLayer/restaking, focus on the risk analysis (risk stacking, correlated slashing, LTV implications) rather than trying to explain the full architecture. Teams care more about how youβd evaluate the risk of accepting restaked assets than about memorizing contract names.
π‘ LST Integration Patterns
π Deep Dive: LST Oracle Pricing Pipeline
Pricing LSTs requires a two-step pipeline β convert to underlying ETH via exchange rate, then price ETH in USD via Chainlink. This is the same pattern you saw in P2M9βs vault share pricing.
The pipeline:
wstETH pricing (two steps):
ββββββββββββ getStETHByWstETH ββββββββββββββ Chainlink βββββββββββββ
β wstETH β βββββββββββββββββ β ETH equiv β βββββββββββββ β USD value β
β (18 dec) β exchange rate β (18 dec) β ETH/USD β (8 dec) β
ββββββββββββ ββββββββββββββ (8 dec) βββββββββββββ
rETH pricing (two steps):
ββββββββββββ getExchangeRate ββββββββββββββ Chainlink βββββββββββββ
β rETH β βββββββββββββββββ β ETH equiv β βββββββββββββ β USD value β
β (18 dec) β exchange rate β (18 dec) β ETH/USD β (8 dec) β
ββββββββββββ ββββββββββββββ (8 dec) βββββββββββββ
Compare to ETH pricing (one step):
ββββββββββββ Chainlink βββββββββββββ
β ETH β βββββββββββββββββββββββββββββββ β USD value β
β (18 dec) β ETH/USD β (8 dec) β
ββββββββββββ (8 dec) βββββββββββββ
π Connection: This is the exact same two-step pattern from P2M9βs vault share collateral pricing.
getStETHByWstETH()isconvertToAssets()by another name. The decimal normalization, the manipulation concerns, and the code structure all carry over.
Numeric walkthrough β wstETH:
Given:
wstETH amount = 10 wstETH (18 decimals β 10e18)
stEthPerToken = 1.19e18 (exchange rate, 18 decimals)
ETH/USD price = $3,200 (Chainlink 8 decimals β 3200e8)
Step 1: wstETH β ETH equivalent
ethEquiv = wstETHAmount Γ stEthPerToken / 1e18
= 10e18 Γ 1.19e18 / 1e18
= 11.9e18 ETH
Step 2: ETH β USD
valueUSD = ethEquiv Γ ethPrice / 1e18
= 11.9e18 Γ 3200e8 / 1e18
= 38_080e8
10 wstETH = $38,080.00 USD
Numeric walkthrough β rETH:
Given:
rETH amount = 10 rETH (18 decimals β 10e18)
rETH exchange = 1.12e18 (ETH per rETH, 18 decimals)
ETH/USD price = $3,200 (Chainlink 8 decimals β 3200e8)
Step 1: rETH β ETH equivalent
ethEquiv = rETHAmount Γ exchangeRate / 1e18
= 10e18 Γ 1.12e18 / 1e18
= 11.2e18 ETH
Step 2: ETH β USD
valueUSD = ethEquiv Γ ethPrice / 1e18
= 11.2e18 Γ 3200e8 / 1e18
= 35_840e8
10 rETH = $35,840.00 USD
Solidity implementation:
function getLSTValueUSD(
address lstToken,
uint256 amount,
bool isWstETH
) public view returns (uint256 valueUSD) {
uint256 ethEquivalent;
if (isWstETH) {
// wstETH β ETH via Lido exchange rate
ethEquivalent = IWstETH(lstToken).getStETHByWstETH(amount);
} else {
// rETH β ETH via Rocket Pool exchange rate
uint256 rate = IRocketTokenRETH(lstToken).getExchangeRate();
ethEquivalent = amount * rate / 1e18;
}
// ETH β USD via Chainlink
(, int256 ethPrice,,uint256 updatedAt,) = ethUsdFeed.latestRoundData();
require(ethPrice > 0, "Invalid price");
require(block.timestamp - updatedAt <= STALENESS_THRESHOLD, "Stale price");
valueUSD = ethEquivalent * uint256(ethPrice) / 1e18;
// Result in 8 decimals (Chainlink ETH/USD decimals)
}
β οΈ De-Peg Scenarios and the Dual Oracle Pattern
The problem: The exchange rate from Lido/Rocket Pool always reflects the protocolβs view of the backing β stETH is always worth ~1 ETH according to the protocol. But the market price can diverge. If stETH trades at 0.95 ETH on Curve, a lending protocol using only the exchange rate would overvalue wstETH collateral by ~5%.
Historical precedent β June 2022 stETH de-peg:
Context: 3AC and Celsius facing insolvency, forced to sell stETH for ETH.
Pre-Shapella: No withdrawal queue. Only exit is selling on DEX.
Timeline:
May 2022: stETH/ETH β 1.00 (normal)
June 10: stETH/ETH β 0.97 (selling pressure begins)
June 13: stETH/ETH β 0.93 (peak de-peg, ~7% discount)
July 2022: stETH/ETH β 0.97 (partial recovery)
Post-Shapella: stETH/ETH β 1.00 (withdrawal queue eliminates structural de-peg)
Lending protocols using exchange-rate-only oracle:
Valued wstETH collateral at 1.00 ETH per stETH
Actual liquidation value on market: 0.93 ETH per stETH
Gap: 7% β enough to cause undercollateralization in tight positions
The dual oracle pattern:
Use the minimum of the protocol exchange rate and the market price. During normal times, both are ~1.0 and the minimum doesnβt matter. During a de-peg, the market price is lower, and the minimum correctly reflects the actual liquidation value of the collateral.
Normal times:
Exchange rate: 1 stETH = 1.00 ETH (protocol)
Market price: 1 stETH = 1.00 ETH (Curve/Chainlink)
min(1.00, 1.00) = 1.00 ETH β no difference
De-peg scenario:
Exchange rate: 1 stETH = 1.00 ETH (protocol β unchanged)
Market price: 1 stETH = 0.93 ETH (Curve/Chainlink)
min(1.00, 0.93) = 0.93 ETH β safely uses market price
Numeric impact on a lending position:
Position: 100 wstETH collateral, stEthPerToken = 1.19
= 119 stETH equivalent, borrowing 300,000 stablecoin
ETH/USD = $3,200, liquidation threshold = 82.5%
Exchange-rate-only valuation:
collateralUSD = 119 Γ 1.00 Γ $3,200 = $380,800
HF = $380,800 Γ 0.825 / $300,000 = 1.047 β looks healthy
Dual oracle during 7% de-peg:
collateralUSD = 119 Γ 0.93 Γ $3,200 = $354,144
HF = $354,144 Γ 0.825 / $300,000 = 0.974 β LIQUIDATABLE
The $26,656 difference is the de-peg discount. Without the dual oracle,
this position appears healthy when it should be liquidated.
Implementation sketch:
function getStETHToETHRate() public view returns (uint256) {
// Protocol rate: always ~1.0 (stETH is 1:1 with staked ETH by design)
uint256 protocolRate = 1e18;
// Market rate: Chainlink stETH/ETH feed
(, int256 marketRate,,uint256 updatedAt,) = stethEthFeed.latestRoundData();
require(marketRate > 0, "Invalid stETH price");
require(block.timestamp - updatedAt <= STETH_STALENESS, "Stale stETH price");
// Use the lower of the two β conservative for collateral valuation
uint256 safeRate = uint256(marketRate) < protocolRate
? uint256(marketRate)
: protocolRate;
return safeRate;
}
Note: Chainlink provides a stETH/ETH feed on mainnet. For rETH, Chainlink provides an rETH/ETH feed. Both are used by production protocols (Aave, Morpho) for exactly this dual-oracle pattern.
π‘ Concept: LSTs as Collateral in Lending
Aave V3 wstETH integration β how production does it:
Aave V3 lists wstETH as a collateral asset with specific parameters tuned for its risk profile:
Aave V3 Ethereum β wstETH parameters (approximate):
LTV: 80%
Liquidation Threshold: 83%
Liquidation Bonus: 5%
Supply Cap: ~1.2M wstETH
E-Mode (ETH-correlated):
LTV: 93% β much higher!
Liquidation Threshold: 95%
Liquidation Bonus: 1%
E-Mode (Efficiency Mode): Aave V3βs E-Mode allows higher LTV for assets that are highly correlated. wstETH and ETH are correlated β wstETH is backed 1:1 by staked ETH. So Aave creates an βETH-correlatedβ E-Mode category where wstETH collateral can borrow ETH (or WETH) at up to 93% LTV instead of 80%.
Why E-Mode works here: The risk of wstETH dropping significantly relative to ETH is low (theyβre fundamentally the same asset minus protocol risk). The primary risk is the de-peg scenario, which the dual oracle handles. With the dual oracle and high correlation, 93% LTV is defensible β but only for borrowing ETH-denominated assets, not stablecoins (where ETH price risk applies fully).
Liquidation with LSTs:
When a wstETH-collateralized position is liquidated, the liquidator receives wstETH. They have options:
- Hold wstETH β continue earning staking yield
- Sell on DEX β swap wstETH β ETH on Curve/Uniswap
- Unwrap + sell β unwrap wstETH β stETH β request withdrawal (slow but 1:1 rate)
In practice, liquidators sell on DEX for immediate ETH. This is why DEX liquidity depth for wstETH matters for liquidation parameter settings β the same concern as P2M9βs liquidation economics section.
π Connection: This mirrors exactly the liquidation economics discussion from P2M9 β bidder profitability depends on DEX liquidity depth, which determines whether liquidation actually works at the parameters youβve set.
π‘ Concept: LSTs in AMMs
The Curve stETH/ETH pool is the most important pool for LST liquidity. It uses Curveβs StableSwap invariant, which is optimized for assets that trade near 1:1.
Why StableSwap and not constant product (Uniswap)?
For assets near 1:1 peg:
Constant product (x Γ y = k):
Slippage for 1,000 ETH swap in $500M pool: ~0.4%
StableSwap (Curve):
Slippage for 1,000 ETH swap in $500M pool: ~0.01%
~40x less slippage for correlated assets β critical for liquidation efficiency
(illustrative β exact values depend on pool parameters and amplification factor)
π Connection: This connects to P2M2βs AMM module. The invariant choice (constant product vs StableSwap vs concentrated liquidity) directly determines slippage, which determines liquidation viability for LST collateral.
Yield-bearing LP positions: LPing in the stETH/ETH pool earns trading fees AND half the position earns staking yield (the stETH side). This βyield-bearing LPβ concept connects to P2M7βs yield stacking patterns.
π‘ Concept: LSTs in Vaults
wstETH is a natural fit for ERC-4626 vaults. Since wstETH already has an increasing exchange rate (staking yield), wrapping it in a vault adds another yield layer:
Nested yield stack:
ETH staking: ~3.5% APR (base layer β beacon chain rewards)
Vault strategy: +X% APR (additional yield from vault's strategy)
Example: A vault that deposits wstETH as collateral on Aave,
borrows ETH, and loops the leverage:
Base yield: 3.5% (staking)
Leveraged yield: 3.5% Γ leverage multiplier - borrow cost
wstETH as quasi-ERC-4626: wstETH itself behaves almost like an ERC-4626 vault. It has shares (wstETH tokens), assets (stETH), and an exchange rate (stEthPerToken). The main difference is that ERC-4626 defines deposit()/withdraw() with assets, while wstETH uses wrap()/unwrap(). Some protocols (like Morpho Blue) treat wstETH as an ERC-4626 by using adapter contracts.
π Connection: This directly links to P3M3 (Yield Tokenization) β Pendleβs most popular markets are wstETH and eETH, where users split LST staking yield into principal and yield tokens. Understanding LSTs as yield-bearing assets is the prerequisite for understanding yield tokenization.
π DeFi Pattern Connections
| Source | Concept | How It Connects |
|---|---|---|
| P2M1 | Rebasing tokens | stETH is the canonical rebasing token β the βweird tokenβ integration challenge |
| P2M3 | Chainlink integration | ETH/USD and stETH/ETH feeds for LST pricing pipeline |
| P2M4 | Health factor, liquidation | LST collateral health factor uses dual oracle, liquidation via DEX |
| P2M7 | ERC-4626 share math | wstETH exchange rate = vault share convertToAssets() |
| P2M7 | Inflation attack | Exchange rate manipulation concern applies to LST pricing |
| P2M8 | Oracle manipulation | De-peg scenario defense requires dual oracle pattern |
| P2M9 | Two-step vault share pricing | LST pricing pipeline is the same pattern (exchange rate Γ underlying price) |
| P2M9 | Rate cap | Lidoβs oracle sanity check serves the same role as P2M9βs rate cap |
| P3M3 | Yield tokenization | Pendle splits LST yield into PT/YT β LSTs are the primary input |
| P3M9 | Capstone (perp exchange) | LSTs as margin collateral β pricing and liquidation mechanics carry over |
π― Build Exercise: LST Collateral Lending Pool
Workspace: workspace/src/part3/module1/
Build a simplified lending pool that accepts wstETH as collateral, using the oracle from Exercise 1.
What youβll implement:
depositCollateral(uint256 wstETHAmount)β deposit wstETH as collateralborrow(uint256 stablecoinAmount)β borrow stablecoin against wstETH collateralrepay(uint256 stablecoinAmount)β repay borrowed stablecoinwithdrawCollateral(uint256 wstETHAmount)β withdraw collateral (health check after)liquidate(address user)β liquidate unhealthy position, transfer wstETH to liquidatorgetHealthFactor(address user)β calculate HF using safe (dual oracle) valuation- E-Mode toggle: when borrowing ETH-denominated assets, use higher LTV
Whatβs provided:
WstETHOraclefrom Exercise 1 (imported, already deployed)- Mock stablecoin ERC-20 for borrowing
- Mock wstETH with configurable exchange rate
- Mock Chainlink feeds for both price sources
Tests verify:
- Full lifecycle: deposit β borrow β repay β withdraw
- Health factor increases as wstETH exchange rate grows (staking rewards)
- De-peg scenario: stETH/ETH drops to 0.93, previously healthy position becomes liquidatable
- Liquidation transfers wstETH to liquidator, burns repaid stablecoin
- E-Mode allows higher LTV when borrowing ETH-denominated asset
- Cannot withdraw below minimum health factor
- Cannot borrow above debt ceiling
π― Goal: Practice building a lending integration that correctly handles LST-specific concerns β two-step pricing, de-peg risk, and E-Mode for correlated assets. These are production patterns used by every major lending protocol.
π Summary: LST Integration Patterns
Covered:
- Oracle pricing pipeline β two-step (exchange rate β Chainlink), with full numeric walkthroughs
- De-peg scenario β June 2022 stETH de-peg, numeric impact on lending positions
- Dual oracle pattern β min(protocol rate, market rate) for safe collateral valuation
- LSTs as collateral β Aave V3 parameters, E-Mode for correlated assets, liquidation considerations
- LSTs in AMMs β why StableSwap for correlated assets, yield-bearing LP
- LSTs in vaults β nested yield stacking, wstETH as quasi-ERC-4626
Key insight: LST integration is really about two things: (1) correctly converting to underlying value via the exchange rate, and (2) defensively handling the edge case where market price diverges from exchange rate (de-peg). The dual oracle pattern handles both. Everything else β LTV ratios, E-Mode, liquidation parameters β follows from understanding these two points.
πΌ Job Market Context
What DeFi teams expect you to know:
- βWhat happened during the June 2022 stETH de-peg and what did it teach us?β
- Good answer: βstETH traded below 1 ETH. It was caused by selling pressure.β
- Great answer: β3AC and Celsius faced insolvency and had to liquidate stETH positions. Pre-Shapella, there was no withdrawal queue β the only exit was selling on DEX. Massive sell pressure pushed stETH/ETH to 0.93. This wasnβt a protocol failure β Lidoβs backing was fine. It was a liquidity/market failure. The lesson: exchange rate and market price can diverge, so lending protocols need dual oracle pricing. Post-Shapella (April 2023), the withdrawal queue creates an arbitrage floor that prevents deep de-pegs.β
Interview Red Flags:
- π© Saying βjust use the exchange rateβ for collateral pricing without mentioning de-peg risk and the need for a market price check
- π© Not knowing the difference between pre-Shapella and post-Shapella withdrawal mechanics
- π© Treating the June 2022 de-peg as a protocol bug rather than a market/liquidity event
Pro tip: In interviews, when discussing LST integration, always mention the de-peg scenario unprompted. Saying βweβd use a dual oracle pattern because of the June 2022 de-peg riskβ signals real-world awareness, not just textbook knowledge. Protocol teams remember June 2022 β it shaped how every subsequent LST integration was designed.
π Cross-Module Concept Links
β Backward References (where these patterns were introduced):
- Exchange rate math β P1M1 ShareMath (shares/assets pattern), P2M7 ERC-4626
convertToShares/convertToAssetsβ LSTs use the same shares-proportional-to-underlying model - Oracle integration β P2M3 Chainlink patterns, staleness checks, heartbeat monitoring β LST oracles add beacon chain finality as an extra trust assumption
- Lending collateral β P2M4 health factor calculation, liquidation mechanics β LST collateral requires dual oracle pricing (exchange rate + market price)
- Rebasing tokens β P2M1 weird token behaviors β stETH rebasing breaks
balanceOfassumptions; wstETH wrapping solves this - Yield-bearing assets β P2M7 vault shares as collateral, ERC-4626 accounting β LSTs are essentially yield-bearing receipt tokens with the same math
β Forward References (where LST concepts appear next in Part 3):
- Restaking β P3M6 (Governance & Risk) β risk stacking from restaked assets, correlated slashing conditions
- LST as perp collateral β P3M2 (Perpetuals) β yield-bearing margin, funding rate interaction with staking yield
- LST yield tokenization β P3M3 (Yield Tokenization) β Pendle PT-stETH, fixed-rate staking exposure via PT/YT split
- LST price feeds β P3M5 (MEV & Frontrunning) β oracle manipulation vectors, sandwich attacks on LST swaps
π Production Study Order
Study these codebases in order β each builds on the previous oneβs patterns:
| # | Repository | Why Study This | Key Files |
|---|---|---|---|
| 1 | Lido stETH/wstETH | The canonical LST β shares accounting, rebase mechanics, wrap/unwrap pattern | contracts/0.4.24/Lido.sol, contracts/0.6.12/WstETH.sol |
| 2 | Lido AccountingOracle | Beacon chain reporting, quorum, finalization delay β understand the trust model | contracts/0.8.9/oracle/AccountingOracle.sol, contracts/0.8.9/oracle/HashConsensus.sol |
| 3 | Aave V3 wstETH integration | E-Mode configuration, oracle adapter wrapping exchange rate + Chainlink feed | contracts/misc/PriceOracleSentinel.sol, Aave wstETH oracle adapter |
| 4 | EigenLayer StrategyManager | Restaking deposit flow, delegation, withdrawal queue β see how risk stacks | src/contracts/core/StrategyManager.sol, src/contracts/core/DelegationManager.sol |
| 5 | Rocket Pool rETH | Alternative exchange rate model β decentralized node operator set, minipool architecture | contracts/contract/token/RocketTokenRETH.sol, contracts/contract/deposit/RocketDepositPool.sol |
Reading strategy: Start with Lido β itβs the most widely integrated LST. Read Lido.sol for the shares/pooledEth accounting, then WstETH.sol for the non-rebasing wrapper (this is what DeFi protocols actually integrate). Study the oracle next to understand the trust assumptions. Then see how Aave wraps the exchange rate into a price feed. EigenLayer shows restaking as a layer on top. Rocket Pool shows the decentralized alternative.
π Resources
Production Code
| Repository | What to Study | Key Files |
|---|---|---|
| Lido stETH | Shares accounting, oracle, rebase | Lido.sol, WstETH.sol, AccountingOracle.sol |
| Rocket Pool | rETH exchange rate, minipool model | RocketTokenRETH.sol, RocketDepositPool.sol |
| EigenLayer | Restaking architecture | StrategyManager.sol, DelegationManager.sol |
| EtherFi | LRT implementation | weETH.sol, LiquidityPool.sol |
Documentation
- Lido docs β comprehensive, well-maintained
- Lido stETH integration guide β essential reading for any integration
- Rocket Pool docs
- EigenLayer docs
Further Reading
- stETH depeg analysis (June 2022) β post-mortem and market analysis
- EigenLayer whitepaper β restaking design rationale
- Aave V3 wstETH risk parameters β search for wstETH listing proposals to see risk team analysis
Navigation: Part 3 Overview | Next: Module 2 β Perpetuals & Derivatives β