getTokenAmountFromUSD()
returns an incorrect amount for tokens with decimals != 18. It also returns an incorrect amount if chainlink oracle uses a different decimal than 8.
getTokenAmountFromUSD()
calculates the final amount as follows:
This is fine for current collaterals: WETH and WBTC. However, if new collateral is added in future with different decimals, the protocol will return incorrect amount to liquidator. Here is the derivation of correct formula:
Let C
be chainlink oracle decimal.
Let D
be token decimal.
price/1eC
USD gets 1eD tokens.
(price/1eC) * (usdAmountInWei/1e18)
USD gets 1eD * (usdAmountInWei/1e18)
tokens.
(usdAmountInWei/1e18)
USD gets:
usdAmountInWei * 1eD * 1eC / (price * 1e18)
which is the final formula to be used in getTokenAmountFromUsd()
.
C
and D
can be fetched by calling decimals()
on the collateral token and chainlink oracle. To save gas, you can also store these values permanently.
For tokens and chainlink oracle deviating from the 18 and 8 decimals respectively, protocol will work incorrectly.
Manual review.
Update the return value of getTokenAmountFromUsd()
to consider token decimals and chainlink decimals.
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.