Open hats-bug-reporter[bot] opened 5 months ago
Oracles were marked as already audited and thus, OOS
The issue isn't with the oracles themselves, it's how LMPStrategy, verifyLSTPriceGap and lstPriceGapTolerance
integrate with said oracles is the issue.
The default in the test .1%. We are currently testing out this value starting at .05%. Having this low of a value is key to ensure those possible price deviations do not have a material impact on the vault. If the execution is delayed while Chainlink price is updated this is OK. Should there be consistent poor pricing or execution the strategy will tighten its execution in other ways to recuperate. This is its design.
Hey there,
From what I understand you are ok with Chainlink giving you incorrect prices and stopping the execution of verifyRebalance
?
If such a low tolerance is used, the function will almost always revert, that's why I recommended a minimum of a 2% tolerance (since most price feeds on mainnet have a 2% deviation threshold), allowing for such a low tolerance will make the function almost unusable.
Maybe I don't understand something, if so, please correct me.
Cheers.
Github username: -- Twitter username: -- Submission hash (on-chain): 0xfe5fbdd4b5d7e311a16e24d88e6430b1f49dca089bb4c7647cea693ec5d9b343 Severity: medium
Description: Description\
verifyLSTPriceGap
is used to that the difference between the safe price and the spot price isn't higher thanlstPriceGapTolerance
.To get both
priceSafe
andpriceSpot
we use theRootPriceOracle
which will forward the call to the correct oracle provider, so that that specific oracle provider can return the price.Specifically
ChainlinkOracle
can be used to retrieve the prices.Each Chainlink price feed has 2 trigger parameters: Deviation threshold and heartbeat.
You can see that for example for the rETH/ETH price feed, the heartbeat is 24 hours, meaning that the price will be updated every 24 hours and the deviation threshold is 2%, meaning that if the price moves up/down more than 2%, the oracle will refresh and return the new price.
Many other price feeds on mainnet have 2% deviation and 24 hour heartbeats.
Knowing this, if
lstPriceGapTolerance
is set to something like 1% which is currently used in the tests, Chainlink will not update unless the price moves by 2%, which means there can be situations when the actual price of the asset surpasseslstPriceGapTolerance
and should causeverifyRebalance
to revert, but doesn't becausegetPriceInEth
returns an answer from Chainlink that is old, and the opossite can happen too, the price of the asset doesn't surpasslstPriceGapTolerance
, but because Chainlink hasn't updated it's price andgetPriceInEth
returns an older value,lstPriceGapTolerance
isn't surpassed andverifyRebalance
doesn't revert.At best this will cause
verifyLSTPriceGap
to returntrue
and a rebalance that shouldn't have taken place, takes place.At worst, this will cause a DoS on
verifyRebalance
, until Chainlink's answer gets updated, which for most assets is 24 hours.Keep in mind that
lstPriceGapTolerance
is immutable, so it can't be changed and there is no way to skipverifyLSTPriceGap
, unlessparams.destinationIn == address(lmpVault)
.Attack Scenario
Attachments
Proof of Concept (PoC) File
Revised Code File (Optional) Either make
lstPriceGapTolerance
mutable, add a new variable that forces a skip onverifyLSTPriceGap
or enforce insideLMPStrategyConfig
thatlstPriceGapTolerance
is at least 20 bps or more.