The Generalised Oracle is broken for the external tokens that use Uniswap. This is happening for two reasons:
The token passed as a base token for the OracleLibrary.getQuoteAtTick
is incorrect. The base token should be the token the protocol wants to fetch the price from, not the quote token. Take into consideration the following scenario: Fetching the price for WBTC.
The function getTwap:
Due to this, the protocol is trying to fetch the price of the amount 1e8 in USDC, using as quote price WBTC
, instead of the intended behavior that should be quoting the price of 1 WBTC(1e8) in USDC.
The second issue is that the getTwap
function can return values with varying decimals. The protocol assumes a 6-decimal return value, but some stablecoins, like DAI
, have 18 decimals.
Notice that at the end of the flow for returning the price on the getTokenPriceFromExternal
the token price is divided by 6.
If the quote token is DAI, for instance, the value will be significantly higher than expected in the LibUsdOracle
. All other oracles in the protocol, such as LibChainlinkOracle
and LibWsethUsdOracle
, return values based on 6 decimals. The LibUniswapOracle
has worked well so far because Beanstalk hasn't introduced stablecoins with decimals != 6. Therefore, the getTwap
function should be modified to return values quoted with 6 decimals.
LibUsdOracle can't return the correct price for any external token using Uniswap as Oracle.
Manual Review
1st: Use token
as the base token to ensure the chainlinkToken
(quote token) returns the correct price.
2nd: Modify the getTwap
function to always return the value in 6 decimal precision. Additionally, rename the variables for better clarity and usability.
Unit tests
Change the OracleDeployer
file to use the correct values(ticks, price) for the pools. The values for the WBTC/USDC for instance are not correct, which leads to a faulty test on oracle.t.sol
to pass. This data can be extracted here: https://etherscan.io/address/0x99ac8cA7087fA4A2A1FB6357269965A2014ABc35#readContract
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.