Summary
The PriceOracle contract relies on the Chainlink Oracle FeedRegistry to get the price of tokens. However, the FeedRegistry is not available in L2 networks such as Arbitrum, Base and Optimism. This means that the PriceOracle contract will fail to return the price of tokens in these networks.
As detailed in the Chainlink docs https://docs.chain.link/data-feeds/feed-registry#contract-addresses
This feed is only compatibale on mainnet.
library LibUsdOracle {
address constant chainlinkRegistry = 0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf;
Vulnerability Details
The LibUsdOracle
library in Beanstalk relies on Chainlink's FeedRegistry to fetch token prices.
address constant chainlinkRegistry = 0x47Fb2585D2C56Fe188D0E6ec628a38b74fCeeeDf;
function getTokenPriceFromExternal(
address token,
uint256 lookback
) internal view returns (uint256 tokenPrice) {
AppStorage storage s = LibAppStorage.diamondStorage();
Implementation memory oracleImpl = s.sys.oracleImplementation[token];
if (oracleImpl.encodeType == bytes1(0x01)) {
address chainlinkOraclePriceAddress = oracleImpl.target;
if (chainlinkOraclePriceAddress == address(0)) {
chainlinkOraclePriceAddress = ChainlinkPriceFeedRegistry(chainlinkRegistry).getFeed(
token,
0x0000000000000000000000000000000000000348
);
}
return uint256(1e24).div(
LibChainlinkOracle.getTokenPrice(
chainlinkOraclePriceAddress,
LibChainlinkOracle.FOUR_HOUR_TIMEOUT,
lookback
)
);
}
}
Reseed Whitelist includes the oracle implementation when intializing on the L2 and passes the current oracle implementation
asset[i].oracleImplementation
contract ReseedWhitelist {
AppStorage internal s;
function init(address[] calldata tokens, AssetSettings[] calldata asset) external {
for (uint i; i < tokens.length; i++) {
LibWhitelist.whitelistToken(
tokens[i],
asset[i].selector,
asset[i].stalkIssuedPerBdv,
asset[i].stalkEarnedPerSeason,
asset[i].encodeType,
asset[i].gaugePointImplementation.selector,
asset[i].liquidityWeightImplementation.selector,
asset[i].gaugePoints,
asset[i].optimalPercentDepositedBdv,
asset[i].oracleImplementation
);
}
}
}
Impact
If the current oracle implemetation is used for the L2, any protocol functions that rely on this, the oracle service will fail to return token prices.
Tools Used
Manual Review
Recommendations
To ensure compatibility with L2 networks, it is recommended to modify the oracle implementation logic to use L2-compatible oracles, such as AggregatorV3Interface
, instead of relying on Chainlink's FeedRegistry.