Pricing + Decimal scaling
Solidity cannot handle decimals -> are scaled up to integers
The number of decimals in ERC20 determines the factor used to represent the decimal number as uint.
For instance 18 means that the value is stored in an uint as
decimalValue * 10**18
.100.103 => is stored as uint 100103000000000000000 (100.103 *10**18)
0.000340 => stored as uint 340000000000000 (0.00034*10**18)
Let us refer to this as the 'solidity decimal scale up effect'
Converting 1 DAI to WETH (18 dp -> 18 dp)
assume DAI/ETH: 394725760000000
1e18 x 394725760000000 = 394725760000000...(18 more '0's)
1e18 x 0.00039472576e18 = 0.00039472576 *e18 *e18
*e18 is the factor to represent the number of decimal places.
when multiplying two integers (both have solidity decimal scale up effect), and the scale up effect is applied twice
which is why we divide by decimals after multiplication.
1e18 x 0.00039472576e18 = 0.00039472576 *e18
this is a result of using the scale up approach, due to the inability of Solidity to handle decimals.
Converting between different decimal representations
TokenA is set up with 18 decimals
TokenB is set up with 6 decimals
If you want to convert between different representations you have to multiply or divide depending on the difference in decimals count:
Normalize the from_token by stripping it of its decimal places. (because of the solidity decimal scale up effect)
Then we scale up by the TokenB (to token) decimals
Vice versa
naturally division will lead to precision loss.
Weaving pricing into scaling
getMaxDebt() | how much DAI for WETH?
getMaxDebt() | how much USDC for WETH?
For two tokens with different decimals precision, the decimal precision of their price would match the token with the larger decimal precision Example: TokenA -> 6 dp TokenB -> 18 dp TokenA /TokenB price is returned as 18 dp; else we would incorrectly truncate the precision of tokenB,
This is why the chainlink pricefeed for USDC/ETH is in 18dp.
Last updated