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

LibUsdOracle is completely broken for the to-deploy L2 chain

Summary

The LibUsdOracle library would be completely non-functional and incompatible with the intended L2 deployment of the Beanstalk protocol due to its reliance on a hardcoded Chainlink registry address that only functions on the Ethereum mainnet.

Vulnerability Details

The finale of the Beanstalk contests on Codehawks, also hinted how the protocol is to be deployed on an L2, there is no specific one at the moment but it should be an EVM compatible L2.

Issue however is that whichever L2 the protocol gets deployed on, be it an optimistic one or not, the LibUsdOracle is going to be broken, this is because the chainlink registry is being initialised as a constant: https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/8c8710df547f7d7c5dd82c5381eb6b34532e4484/protocol/contracts/libraries/Oracle/LibUsdOracle.sol#L36-L37

address constant chainlinkRegistry = 0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf;

Now would be key to note that from the official Chainlink docs on their feed registries: https://docs.chain.link/data-feeds/feed-registry#contract-addresses, we can see that the 0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf address is only active on the etheruem mainnnet

This would then mean that all the instances where the chainlinkRegistry is being queried in the LibUsdOracle would be broken, note that from the contract we can see that whatever token's price we are trying to get there is always a need to query the getTokenPriceFromExternal, i.e here is the instance on getting (Usd:token Price) https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/8c8710df547f7d7c5dd82c5381eb6b34532e4484/protocol/contracts/libraries/Oracle/LibUsdOracle.sol#L61-L64

// 1e18 * 1e6 = 1e24.
uint256 tokenPrice = getTokenPriceFromExternal(token, lookback);
if (tokenPrice == 0) return 0;
return uint256(1e24).div(tokenPrice);

There is also an instance on getting (token:Usd Price) here https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/8c8710df547f7d7c5dd82c5381eb6b34532e4484/protocol/contracts/libraries/Oracle/LibUsdOracle.sol#L91

Now, the implementation of getTokenPriceFromExternal() directly attempts to get the feed from the registry: https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/8c8710df547f7d7c5dd82c5381eb6b34532e4484/protocol/contracts/libraries/Oracle/LibUsdOracle.sol#L113-L118

// use the chainlink registry
chainlinkOraclePriceAddress = ChainlinkPriceFeedRegistry(chainlinkRegistry).getFeed(
token,
0x0000000000000000000000000000000000000348
); // 0x0348 is the address for USD
}

And even https://github.com/Cyfrin/2024-05-beanstalk-the-finale/blob/8c8710df547f7d7c5dd82c5381eb6b34532e4484/protocol/contracts/libraries/Oracle/LibUsdOracle.sol#L147-L152

if (chainlinkOraclePriceAddress == address(0)) {
// use the chainlink registry
chainlinkOraclePriceAddress = ChainlinkPriceFeedRegistry(chainlinkRegistry).getFeed(
chainlinkToken,
0x0000000000000000000000000000000000000348
); // 0x0348 is the address for USD

However all these attempts at querying the feed addresses would be broken.

Impact

LibUsdOracle is incompatible with the L2 chain that protocol is going to get deployed on.

Tools Used

  • Manual review.

  • Official Chainlink docs on their feed registries: https://docs.chain.link/data-feeds/feed-registry#contract-addresses.

Recommendations

Consider scrapping the idea of attempting to query feeds from the feed registry on L2s.

Updates

Lead Judging Commences

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

Chainlink Oracle FeedRegistry only available on L1

Support

FAQs

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