DeFiHardhatFoundry
250,000 USDC
View results
Submission Details
Severity: high
Valid

LibUsdOracle confuses between baseToken and quoteToken leading to incorrect price quotes

Summary

LibUsdOracle.sol is passing the wrong token as base token which leads to complete bogus price calculations and loss of funds

Vulnerability Details

} else if (oracleImpl.encodeType == bytes1(0x02)) {
// assumes a dollar stablecoin is passed in
// if the encodeType is type 2, use a uniswap oracle implementation.
address chainlinkToken = IUniswapV3PoolImmutables(oracleImpl.target).token0();
chainlinkToken = chainlinkToken == token
? IUniswapV3PoolImmutables(oracleImpl.target).token1()
: token;
tokenPrice = LibUniswapOracle.getTwap(
lookback == 0 ? LibUniswapOracle.FIFTEEN_MINUTES : uint32(lookback),
oracleImpl.target,
chainlinkToken, ///@audit this should be token
token, ///@audit this sould be chainlinkToken
uint128(10) ** uint128(IERC20Decimals(token).decimals())
);
...
uint256 chainlinkTokenPrice = LibChainlinkOracle.getTokenPrice(
chainlinkOraclePriceAddress,
LibChainlinkOracle.FOUR_HOUR_TIMEOUT,
lookback
);
return tokenPrice.mul(chainlinkTokenPrice).div(1e6);

in the marked lines baseToken & quoteToken are interchanged. Which leads to totally wrong price. Lets understand with an example
Lets suppose uni pool of BAL/DAI is used to calculate price of BAL , assume legit 1 BAL = 2.5 DAI
chainLinkToken = DAI as its a USD stable
so now looking at
https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/4e0ad0b964f74a1b4880114f4dd5b339bc69cd3e/protocol/contracts/libraries/Oracle/LibUniswapOracle.sol#L38
&
https://github.com/Uniswap/v3-periphery/blob/697c2474757ea89fec12a4e6db16a574fe259610/contracts/libraries/OracleLibrary.sol#L49-L69

we can see that chainlinkToken = token1 & token = token2 which in turn leads to
ChainlinkToken being the base token & token being the quote token in OracleLibrary
So it would return the price of DAI in terms of BAL
leading to token price = 0.4
Now price DAI is fetched from chainlink which equal 1e6(as its stablecoin assumed)
hence the final price of token(BAL) would be returned 0.4 usd which is wrong

Code snippet - https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/4e0ad0b964f74a1b4880114f4dd5b339bc69cd3e/protocol/contracts/libraries/Oracle/LibUsdOracle.sol#L128-L161

Impact

Incorrect price, loss of funds

Tools Used

Manual review

Recommendations

tokenPrice = LibUniswapOracle.getTwap(
lookback == 0 ? LibUniswapOracle.FIFTEEN_MINUTES : uint32(lookback),
oracleImpl.target,
-- chainlinkToken,
-- token,
++ token,
++ chainlinkToken,
uint128(10) ** uint128(IERC20Decimals(token).decimals())
);

which leads to correct prices.

Updates

Lead Judging Commences

inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Validated
Assigned finding tags:

LibUsdOracle confuses between baseToken and quoteToken leading to incorrect price quotes

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.