Lido stETH vs wstETH Tracking: The Rebase Is the Whole Problem (2026)

Portfolio·

Lido stETH vs wstETH Tracking: The Rebase Is the Whole Problem (2026)

stETH is a rebasing token — your balance grows daily as staking rewards accrue. wstETH is non-rebasing — the balance is fixed and value rides an increasing exchange rate. Why the rebase is a stream of balance changes a portfolio must characterise, and why wstETH moves the same value into a price.
Author avatar Wag3s TeamEditorial team specializing in Web3 finance, crypto tax, and DAO operations. Based in Zurich, Switzerland.

Reviewed by Wag3s Editorial Team — verified against the Lido stETH rebasing model and the wstETH non-rebasing share/exchange-rate model · Last reviewed May 2026

Lido stETH vs wstETH Tracking: The Rebase Is the Whole Problem

What is unique here is that two tokens carry the identical staked-ETH exposure with opposite on-chain behaviour: stETH grows your balance every day through a rebase, while wstETH never changes its balance and pushes the same value into a rising exchange rate. A tracker that does not know which token it is holding produces either a stream of phantom inflows or a hidden gain. This guide is the rebase, the wrapper, and the tracking line between them, the staking-specific case of the general rebasing vs non-rebasing problem and one spoke of multi-wallet aggregation.

Why stETH and wstETH track differently

  • stETH is rebasing: the balance grows roughly daily as rewards accrue, with no transfer, a recurring rebase.
  • wstETH is non-rebasing: the balance is fixed and value rides an increasing wstETH↔stETH exchange rate via a share system.
  • The rebase is a stream to characterise (reward accrual versus a plain balance change), not a matchable receipt.
  • wstETH moves the value into a price, so the gain only surfaces on unwrap or disposal (rate then versus rate at acquisition).
  • Tax of a rebase is jurisdiction-specific: track the signal, confirm tax separately.
  • Same exposure, two behaviours, so a tracker must detect which token it actually holds.

stETH: a balance that rebases

stETH is rebasing: as Lido staking rewards accrue, the stETH balance in the wallet increases, typically daily, with no transfer. The economic meaning is "rewards accrued," but the on-chain signal is a recurring balance change. A tracker must:

It is a continuous stream, not an event matched to one transaction, and the recurring rebase is the defining tracking challenge.

How the stETH rebase works on-chain

Lido implements the rebase through the Lido contract's handleOracleReport function. When the Lido oracle submits a new beacon chain report, the contract calls _rebase(), which adjusts the _totalShares and _totalPooledEther values. The balanceOf(account) function derives the displayed balance dynamically:

balance = shares[account] × totalPooledEther / totalShares

The shares[account] value is fixed between rebases. Only totalPooledEther increases. So a tracker that caches shares[account] and the old totalPooledEther will show the wrong balance immediately after any oracle report. Correct tracking reads balanceOf() directly, or monitors the TokenRebased event emitted on each rebase and updates the derived balance.

wstETH: the value moves into a rate

wstETH is the non-rebasing wrapper: the balance is fixed, and rewards are reflected by an increasing wstETH→stETH exchange rate via an underlying share system. There is no daily rebalance to track, but the value still grows, hidden in the rate. The gain surfaces when you unwrap or dispose of wstETH, comparing the rate then against the rate at acquisition. wstETH is often preferred in DeFi lending, collateral and bridges precisely because fixed balances integrate more cleanly.

Computing the wstETH/stETH exchange rate

The wstETH contract exposes stEthPerToken() (also tokensPerStEth() for the inverse). These return the current conversion ratio. At any point in time:

stETH equivalent = wstETH balance × stEthPerToken() / 10^18

For cost-basis purposes, the acquisition cost of wstETH is the ETH (or stETH) value at the time of wrapping; the disposal gain is the difference between the stETH-equivalent value at disposal and the acquisition cost, converted to fiat at the disposal-date rate.

Two behaviours, one exposure

stETHwstETH
BalanceGrows (rebase, ~daily)Fixed
Where value livesUnitsExchange rate
Tracking signalStream of rebase increasesRate change at unwrap/disposal
DeFi integrationHarder (rebasing)Cleaner (fixed balance)

A tracker that assumes the wrong one produces either phantom inflows (treating wstETH as if it rebased) or a hidden gain (treating stETH as static). It must detect which token is held and apply the matching model.

Step-by-step: how to track stETH and wstETH

  1. Detect the token address. stETH is at 0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84 on Ethereum mainnet. wstETH is at 0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0. Any other address is neither — confirm before applying a model.
  2. For stETH: monitor the TokenRebased event on the Lido contract. Each event includes reportTimestamp, preTotalShares, preTotalEther, postTotalShares, postTotalEther, sharesMintedAsFees. Compute the per-holder balance change as shares[account] × (postTotalEther - preTotalEther) / postTotalShares.
  3. For stETH: read balanceOf() at each portfolio snapshot. Do not use the shares[account] raw value; use the derived balance that incorporates the current index.
  4. For wstETH: read balanceOf() once. The balance does not change without a transaction. Record the quantity at acquisition and the stEthPerToken() rate at that time as the reference rate.
  5. For wstETH: at disposal or unwrap, read stEthPerToken() again. The gain is the increase in stETH-equivalent value since acquisition, converted to fiat at the disposal-date ETH price.
  6. Track wrap and unwrap transactions. WstETH.wrap(stETHAmount) is a conversion, not a disposal in most frameworks — confirm per jurisdiction. The shares relationship is preserved.
  7. Apply the jurisdiction cost-basis method and confirm whether each stETH rebase is income, a balance adjustment, or deferred until disposal.

Common errors and how to fix them

Error 1 — Reading stETH balance from the Transfer event only. Rebases do not emit a Transfer event per holder. An ERC-20 transfer-based tracker will miss all daily rebase accruals and show the stETH balance frozen at the last transfer amount. Fix: read balanceOf() directly and compare to previous snapshot; or monitor the TokenRebased event and recompute per-holder balances.

Error 2 — Treating wstETH as rebasing. The wstETH balance never changes without a transaction. A tracker built for stETH that also monitors wstETH's Transfer events for rebases will find nothing and, if it then infers that the balance should be higher, may fabricate phantom inflows. Fix: apply the rate-change model exclusively to wstETH; read the exchange rate at acquisition and at disposal.

Error 3 — Ignoring the wstETH/stETH rate at wrap time. If the tracker records only the wstETH quantity at wrapping and not the stETH-per-token rate at that moment, it cannot compute the correct cost basis later. Fix: record both the wstETH quantity and stEthPerToken() at the time of wrapping as the cost-basis reference.

Error 4 — Booking a stETH→wstETH wrap as a disposal. Wrapping stETH into wstETH may not be a disposal in many frameworks (you continue to own the same economic exposure); unwrapping is similarly not necessarily an acquisition. Hard-coding wrap/unwrap as taxable events will over-report. Fix: leave the wrap/unwrap characterisation as a jurisdiction-confirmed flag, defaulting to non-disposal until confirmed otherwise.

Tax is jurisdiction-specific

Whether each rebase is taxable income, and when (the rebase complicates "received/controlled"), is jurisdiction-specific and must not be hard-coded either way (see staking rewards accounting and yield farming tracking). The rebase or rate is the tracking signal; the tax characterisation is a separate, adviser-confirmed question, and the cost-basis method remains the jurisdiction-mandated one.

Practical guidance

  1. Detect stETH versus wstETH; never assume, because the balance behaviour differs fundamentally.
  2. For stETH, model the rebase stream: read balances and characterise the accrual.
  3. For wstETH, track the exchange rate, since the gain realises on unwrap or disposal.
  4. Avoid booking rebases as acquisitions or inflows, or treating wstETH as static with no gain.
  5. Confirm rebase tax treatment per jurisdiction and apply the mandated cost-basis method.
  6. Reconcile to Lido (the rebase index or the wstETH rate) with an audit trail.

Choosing a tool for stETH and wstETH

Both Koinly and CoinTracker advertise support for rebasing and wrapped staking tokens, but the stETH/wstETH split is exactly where a generic model goes wrong. Before you rely on a Lido figure, check that the tool:

  • detects which token is held from the contract address, applying the rebase model to stETH and the rate model to wstETH rather than one default;
  • reads balanceOf() (or the TokenRebased event) for stETH instead of freezing the balance at the last transfer, so daily accrual is not lost;
  • records stEthPerToken() at the time of wrapping, so the wstETH cost basis is computable at unwrap or disposal;
  • treats a stETH↔wstETH wrap as a non-disposal by default, leaving the characterisation to the jurisdiction setting.

Assuming the wrong token model is the recurring Lido error, and it produces either invented inflows or a silently deferred gain.

How Wag3s handles it

Wag3s Folio detects stETH versus wstETH, models the stETH rebase as characterised accrual rather than phantom inflows, tracks the wstETH↔stETH rate so the gain surfaces correctly on unwrap or disposal, and applies your jurisdiction's cost-basis method and rebase tax treatment. See the Folio product page.


Further reading

Sources

  • Lido — stETH and wstETH: stETH is a rebasing token whose balance updates daily as staking rewards accrue, while wstETH is the non-rebasing wrapper with a fixed balance and value carried in an increasing exchange rate.
  • Lido — wstETH contract docs: the share-based wrapper, the stEthPerToken() rate, and the wrap/unwrap mechanics.
Editorial disclaimer
This article is informational and does not constitute tax or accounting advice. Whether a rebase is income is jurisdiction-specific. Confirm treatment with a qualified adviser.