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

Generalized oracle doesn't work on L2

Summary

Beanstalk now introduces a generalized oracle when whitelisting tokens.

There are two problems with the current implementation:

  • 1st: Beanstalk will be deployed on L2, but it can only function on Ethereum when using the Chainlink Registry to fetch the price feed. This is because the Chainlink Feed Registry is deployed exclusively on Ethereum: https://docs.chain.link/data-feeds/feed-registry.

  • 2nd: A hardcoded timeout is used for all added oracles. However, oracles have different heartbeats, and when comparing L1 and L2, even oracles with the same assets have different heartbeats. I.e: ETH / USD in Ethereum has a heartbeat of 1 hour / Arbitrum 24 hours / OP 20 minutes.

Reference:

https://data.chain.link/feeds/ethereum/mainnet/eth-usd

https://data.chain.link/feeds/arbitrum/mainnet/eth-usd

https://data.chain.link/feeds/optimism/mainnet/eth-usd

Vulnerability Details

Context: LibUsdOracle -> getTokenPriceFromExternal.

1st: Chainlink Registry is used to fetch price for both: encodeType 0x01 and 0x02:

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

2nd:
Hardcoded timeout:

uint256(1e24).div(
LibChainlinkOracle.getTokenPrice(
chainlinkOraclePriceAddress,
@> LibChainlinkOracle.FOUR_HOUR_TIMEOUT,
lookback
)
);
...
uint256 chainlinkTokenPrice = LibChainlinkOracle.getTokenPrice(
chainlinkOraclePriceAddress,
@> LibChainlinkOracle.FOUR_HOUR_TIMEOUT,
lookback
);

Notice there are hardcoded timeouts spreaded in other files like LibEthUsdOracle for instance.

Impact

  • Generalised Oracles will not work on L2s when price feed registry is used.

  • Hardcoded timeout creates a high risk of consuming staled price as it will not reflect the Oracle's heartbeat.

Tools Used

Manual Review

Recommendations

  1. Remove the price registry logic and work directly with price feeds when whitelisting tokens.

  2. Introduce a new field i.e. oracleTimeout per oracle and use this one instead of the hardcoded values.

Updates

Lead Judging Commences

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

Chainlink Oracle FeedRegistry only available on L1

Appeal created

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

Chainlink Oracle FeedRegistry only available on L1

Hardcoded Chainlink Heartbeats on L2

Support

FAQs

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