Post Mortem: Addressing the stale stETH price feed in A7

Sense Finance
Sense Finance
Published in
4 min readNov 23, 2022

On July 2nd, Sense received a smart contract vulnerability disclosure from Ayush Shukla regarding one of our old wstETH adapters (#7, or A7). We quickly validated the issue and began working on a fix. Because of the vulnerability’s nature & its latent impact on Sense users, we deployed a fix to production before disclosing the bug on Aug 3rd.

Furthermore, we airdropped roughly 11 ETH to Sense PT, YT, and LP token holders in proportion to their exposure to the bug, so if the bug was exploited before they migrated funds, they would still retain the value they expected from their positions. In other words, all user funds that even had the potential to be exposed to the old adapter (#7) have already been compensated in full.

All funds are SAFU.

Users can continue to safely earn fixed rates, go long/short future yields, and provide liquidity on Sense Space. This post describes the bug, its impact, and our resolution.

The bug

We launched a wstETH adapter without ensuring price feed liveliness. At the time of development and launch, the stETH price was at par (1 stETH/ETH), so it was especially difficult to detect the outdated feed without explicit liveness checks. Not having these checks was our mistake.

By the time we discovered its state, the Sense Protocol already digested stale price information, exposing some users to unexpected risk/return profiles.

While stETH/ETH was less than 1, an actor could have updated Lido’s safe_price_value() price feed, causing an immediate drop in Adapter #7’s scale value to function like a negative interest rate.

As of Nov 23rd, the stETH price feed is still stale, hovering around 0.999 ETH, so this risk is minimized for outstanding stakeholders of Adapter #7, but let’s dive into its potential impact, assuming stETH was still trading below 1 stETH/ETH:

Context & Impact

The wstETH Adapter #7 (A7) is a vanilla yield-stripping adapter with WETH as the underlying. PT holders expect a fixed yield in underlying terms, so the adapter’s scale function considers the stETH exchange rate to give them more wstETH and counteract stETH price risk. The amount of wstETH given to PT holders is capped by the amount in Sense, so a fixed yield in WETH can’t be promised in all market environments. However, this existence of stETH price risk wasn’t advertised to Sense users, hence we performed the airdrop, as described above.

When we discovered the issue, the oracle hadn’t been updated from its ~1 ETH price for over a year. If the price remained stale forever, there would be no problem, and Sense could continue using the feed as is — however, the problem is that the function to sync the feed’s price to the current moment is open and permissionless, so anyone can call it at any time.

Thus, if we didn’t call the function ourselves, there was a risk somebody else would, at a time of their choosing. This would cause an immediate jump down in the scale value, impacting the following users of Adapter #7:

  • YT holders: all holders could collect up to maxscale . Once collected, however, they would no longer be able to collect until the exchange rate is restored or the yield accrued from wstETH was high enough.
  • PT holders: they would receive more wstETH at maturity (when compared to an stETH underlying adapter), but would receive less value in WETH terms because YT holders collected from a stale price feed when YT holders shouldn’t have been able to collect.
  • LP holders: the price of PTs goes up because the Space Pool now thinks the value of wstETH has gone down, per the drop in scale.

The fix

We updated the adapter’s underlying from WETH to stETH by removing the price feed integration, redeploying the wstETH adapter, and onboarding it as Adapter #8. With this change, all users are aware of and exposed to stETH price risk.

Finally, we reached out to the Lido Dev team and received their acknowledgment of the stale price feed before publishing this post mortem.

Final thoughts

Security is our highest priority at Sense. The Sense Protocol has undergone various forms of QA, such as unit/integration/manual testing, fuzz testing, and multiple 3rd party audits.

In addition, we employ several internal dev processes (inspired by Nascent’s simple security toolkit) to increase our own confidence in the features we release. To catch post-launch bugs, we will continue to have a public bug bounty on ImmuneFi, and we have plans to Formally Verify future versions of Sense.

We want to thank Ayush once again for disclosing this vulnerability and working with us to understand its impact. If you’re a whitehat, check out our ImmuneFi Bug Bounty Program and help secure the Sense Protocol.

--

--

Sense Finance
Sense Finance

A decentralized, permissionless, fixed income protocol on Ethereum.