ID | Description | Severity |
---|---|---|
M-01 | ChainlinkOracle assumes 1:1 ratio for stETH/ETH |
Medium |
ChainlinkOracle will use the wstETH/stETH
exchange rate for pricing lpTokens
, meaning it assumes a 1:1 ratio for stETH/ETH
, which is not true most of the time (Ξ0.999900 at the time of writing).
The issue stems from the priceX96
implementations and the fact that there is no way to derive A/B token prices when there is no direct price feed:
function priceX96(
address vault,
address token
) external view returns (uint256 priceX96_) {
...MORE CODE
priceX96_ = FullMath.mulDiv(
tokenPrice * 10 ** baseDecimals,//getAnswer
Q96,
baseTokenPrice * 10 ** decimals
);
}
Indeed the first Vault deployment will be only with wstETH as underlying token and in order to calculate its price in terms of ETH we should first derive the rate of wstETH/stETH
- wsteth::getStETHByWstETH
function getAnswer() public view returns (int256) {
return int256(IWSteth(wsteth).getStETHByWstETH(10 ** decimals));
}
Then stETH/ETH chainlink price feed should be used to multiply and then normalize the decimals. The exact same primer can be found in Lido’s github - https://github.com/lidofinance/wsteth-eth-price-feed/blob/main/contracts/AAVECompatWstETHToETHPriceFeed.sol#L39-L45 Issue with mellow is that wstETH price is calculated in terms of stETH only, and used like that, wrongly assuming stETH and ETH will trade at 1:1 ratio forever.
Arbitrage opportunities in Mellow due to miss-calculated wstETH price in terms of ETH.
Similar issues:
Manual Review
Chainlink oracle should be extended to support wstETH as performed in the Lido finance example.