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 oracleImplementation
is set here:
Notice that the LibUsdOracle
relies 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 selector
set 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 LibUsdOracle
without 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 whitelistToken
and 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 oracleImplementation
is 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: BDVFacet
or a NatSpec could be added to the whitelist function to avoid having a selector that relies on LibUsdOracle
for 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.