The LibUsdOracle component in the protocol incorrectly assumes all tokens used within a Well that leverages the Generalized Oracle are registered/whitelisted. When whitelisting a token, we can see that the value of the oracleImplementationis set here:
Notice that the LibUsdOraclerelies on the variable above to fetch the prices from a generalized oracle.
If a Well has one of the tokens let's say WBTC, and this token is not whitelisted, LibUsdOracle returns a price of zero due to missing oracleImplementation. However, the protocol assumes that whenever it fetches a price for a token from the well that is not Bean, it will be able to fetch the correct price, when in fact it will return zero if this token is not whitelisted with a proper oracleImplementation set.
Another hint that enhances the assumption that the tokens from the well are automatically whitelisted as external tokens is on the RessedWhitelist. It whitelist the internal(Silo) tokens, but there is no use for the function whitelistTokenWithExternalImplementation for external tokens.
Additionally, a potential DoS vulnerability exists:
In scenarios where the oracleImplementation has only the selectorset but not the target, will lead the library to assign the oracleImpl target to address(this).
The problem here is that if the current contract has a function(oracleImpl.selector) that relies on LibUsdOracle, it will lead the system to a DoS. Because all the paths for an external token price will lead to getTokenPriceFromExternal.
One example of a vulnerable facet that will lead to DoS in this scenario: OracleFacet. It consumes all the methods from LibUsdOraclewithout a reentrancy guard.
The protocol cannot correctly determine the USD price of non-Bean tokens from a Well if they are not whitelisted, returning 0.
The protocol will DoS whenever the selector from the Generalised Oracle relies on LibUsdOracle.
Manual Review & Foundry
Fix for whitelisting external tokens:
Add a new function i.e: whitelistWellWithExternalTokens that combines both whitelistTokenand whitelistTokenWithExternalImplementation. Whenever adding a new well that needs to have its tokens whitelisted automatically, this function should be used to avoid adding a Well without support for fetching the price of the Well's token.
(Additional) On getTokenPriceFromExternal check whether oracleImplementationis properly set otherwise return 0.
Fix for the DoS issue:
(Recommended) Add the reentrancy modifier for the contracts that use LibUsdOracle. Notice that in OracleFacet for instance, the ReentrancyGuard is inherited but the modifier nonReentrant is not used.
(Alternative) Input sanitization can be done by ensuring the selectors of a specific facet, i.e: BDVFacetor a NatSpec could be added to the whitelist function to avoid having a selector that relies on LibUsdOraclefor external tokens.
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.