Lucene search

K
code423n4Code4renaCODE423N4:2023-11-KELP-FINDINGS-ISSUES-865
HistoryNov 15, 2023 - 12:00 a.m.

stETH/ETH, rETH/ETH and cbETH/ETH chainlink oracles has too long of heartbeat and deviation threshold which can cause loss of funds

2023-11-1500:00:00
Code4rena
github.com
5
chainlink oracles
long heartbeat
deviation threshold
price calculation
loss of funds
vulnerability
proof of concept
sherlock audit

6.9 Medium

AI Score

Confidence

Low

Lines of code

Vulnerability details

ChainlinkPriceOracle fetches prices from the Chainlink contracts. But the price feeds in the consideration has a very long price heartbeat and deviation rate which might lead to wrong price calculation and loss of token to the user.

Impact

According to the chainlink docs, following are the Price feeds info for the assets that will be used initially:

Feed Heartbeat Deviation Docs link
RETH / ETH 2% 86400s Docs
CBETH / ETH 1% 86400s Docs
RETH / ETH 0.5% 86400s Docs

For Info, Heartbeat and Deviation are variables on which the update of the prices for price feeds depends. That mean the current price feed price will be updated for the token only if one of them is met. That means if we take the example of RETH here, the price feed will be update only when the market price for the RETH fluctuates by 2% or time equal to 86400s(1 day) has passed since last price update. This could be a very problematic thing. Let’s assume a following scenario:

-> Let’s say price feeds was updated at time T1 and price for RETH / ETH is [1]. And since then 43200s(half day) has passed and price has become [1.018] (up by 1.8 %).
-> Now Bob comes and decides to deposit 50 RETH by calling LSTDepositPool::depositAsset(…).
-> But the amount of RSETH token he will get is equal to:

depositAmount = 500 RETH

// balances
bob = 500 RETH
LRTDepositPool = 0
EigenStrategy = 0
NodeDelegator = 0

// RETH Price
RETHPrice = 1e18 // hasn't updated because heartbeat and deviation hasn't reached


// total ETH (assuming zero for the sake of simplicity)
totalETHInPool = 0
RSETHSupply = 0


///////////////////////////////////////////////////////////////
// functions calculations according to chainlink price feeds //
///////////////////////////////////////////////////////////////

rsETHPrice(...) = if -> 
                      (supply = 0) 1 ETH // this condition will met
                  else -> 
                      totalETHInPool / rsETHTotalSupply

rsEthAmountToMint(...) = depositAmount * RETHPrice / rsETHPrice()
                  = 500 * 1e18 / 1e18 = 500 rsETH


/////////////////////////////////////////////////////////
/// functions calculations according to market price ////
/////////////////////////////////////////////////////////

rsETHPrice(...) = if -> 
                      (supply = 0) 1 ETH // this condition will met
                  else -> 
                      totalETHInPool / rsETHTotalSupply

rsEthAmountToMint(...) = depositAmount * RETHPrice / rsETHPrice()
                  = 500 * (1.018 * 1e18) / 1e18 = ~509 rsETH

As you can see according to the market price, 9 rsETH should be minted extra to the user. But it will not happen as the price feed deviation and heartbeat threshold hasn’t passed. And that is why the prices will not be updated. Even if the checks are added in the future for staleness of price, this mechanism will not let anybody deposit token for a whole day because of staleness checks like maxTimestamp etc.

This is one of the valid issue founded in a sherlock audit. Here is a link: Link

Proof of Concept

Calculation and Link given in the above section.

Tools Used

  • Solodit
  • Manual Review

Recommended Mitigation Steps

It is recommended to use price feeds with less heartbeat and deviation rate. Although the deviation can be handled the heartbeat is still a thing that needs to be considered. Since the time of writing this, Chainlink only support few price feeds for the above tokens with high heartbeat and deviation rate. It is recommended to go for other price oracles or combine more than one together to get the average price.

Assessed type

Oracle

The text was updated successfully, but these errors were encountered:

All reactions

6.9 Medium

AI Score

Confidence

Low