The integration with Uniswap breaks the functionality of LibWstethEthOracle
. For the following reasons:
The pool has a different exchange rate from stETH:ETH as the pool is using wstETH:WETH. https://data.chain.link/feeds/arbitrum/mainnet/wsteth-steth exchangerate
The pool has quite low liquidity(30m): https://etherscan.io/address/0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0 and it is susceptible to higher volatility when compared with other pools that use stETH instead of wstETH like curve that has 10x more liquidity: https://classic.curve.fi/steth
Using an average price will not enhance security, in fact, it will do the opposite: by using a pool with a low liquidity, it will prevent many times the protocol from returning a healthy/valid price.
Due to the logic to fetch the average price, the wrong exchange rate stETH:wsETH, and the missing else
for the case that MAX_DIFFERENCE is >= 1 the function will return 0. Already reported here in my other finding: "Oracle will return 0 when price is correct".
Fetching the price from a low liquidity pool from Uniswap doesn't make the protocol safer or the price fair for users/protocol. It shouldn't be used.
STETH/ETH Price feed has a heartbeat of 24 hours. When not returning zero, oracle has a high probability of returning an outdated price due to heartbeat + pool with low liquidity(not reliable with the current market price).
Oracle will return 0 and when not returning zero:
Oracle will return the wrong price due to 24-hour heartbeat(outdated price) + low liquidity pool.
Update the MockWsteth.sol
so it can return the uniswap pool price:
Add the following test on WstethOracle.test.js
:
Then run: npx hardhat test test/WstethOracle.test.js --network hardhat
Output - price difference > 1%, oracle returns 0:
Manual Review & Hardhat
Remove completely the Uniswap integration
As the price feed for stETH/ETH has a heartbeat of 24 hours:
Add a 2nd price feed from chainlink stETH/USD: https://data.chain.link/feeds/ethereum/mainnet/steth-usd, it contains a heartbeat of 1 hour and at the same time it is another source of liquidity/price for stETH.
Add timeout for both oracles based on their heartbeats(STETH/ETH - 24 hours, STETH/USD - 1hour)
-(Optional) Recommended a fallback of the last healthy price as used on Liquity protocol: https://github.com/liquity/dev/blob/main/packages/contracts/contracts/PriceFeed.sol
https://docs.lido.fi/guides/lido-tokens-integration-guide/#sttokens-steth-and-wsteth
https://github.com/code-423n4/2023-11-kelp-findings/issues/609
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.