The USD pricing of collateral breaks if any of the collateral tokens don't use 18 decimals of precision. For example any collateral which has < 18 decimals of precision will be severely undervalued in USD terms. This is because the getUsdValue
function does not convert the USD value of the amount
of collateral token
to 18 decimals of precision, which matches the precision of the DSC token.
The getUsdValue
is called to return the USD value of any collateral token
and is defined as follows:
To gather the total collateral value in USD for a user, the getAccountCollateralValue
is then run:
Let's consider the case where we have two collateral tokens: USDT with 6 decimals of precision, and wETH which has 18 decimals of precision. In the getUsdValue
function, the amount
of token
will be using the native precision of the underlying collateral token (e.g. 1e6 for USDT and 1e18 for wETH). Since we know the precision of USD prices from chainlink is 1e8, we can calculate the precision for each token as returned by getUsdValue
:
USDT: ((1e8 * 1e10) * 1e6) / 1e18 = 1e6
wETH: ((1e8 * 1e10) * 1e18) / 1e18 = 1e18
As we can see, the precision of the USD price returned for each asset differs, and so when they are added together in the getAccountCollateralValue
, the value of the USDT collateral for the user is being severely undervalued.
All collateral which has < 18 decimals of precision will be undervalued in USD terms, while all collateral with > 18 decimals of precision will be overvalued in USD terms. This breaks the entire protocol design.
Manual review
Assuming the case in which precision of collateral is constrained to <= 18 decimals & we assume all collateral supports the decimals
function, we can make the following change in the getUsdValue
function:
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.