Fixed-point Math
Solidity supports integers but not decimals
Solidity scales up decimals into integers, to sidestep its ability to offer floats. The number of decimals in ERC20 determines the factor by which decimals are scaled up.
For instance, 18 means that the value is stored in an uint as decimalValue * 10**18
1 unit of token is represented as 1e18.
10 units of token is represented as 10e18.
0.5 units of token is represented as 5e17.
100.103 => stored as uint 100103000000000000000 (100.103 *10**18)
0.000340 => stored as uint 340000000000000 (0.00034*10**18)
Converting 1 DAI to WETH (18 dp -> 18 dp)
Both DAI and WETH are of 18 decimal precision. Let us assume 1 DAI = 0.00039472576 ether.
Exchange rate on contract => DAI/ETH: 394725760000000 (0.00039472576 * 1e18)
Conversion
1 DAI * DAI/ETH = Qty of Ether
1e18
DAI x394725760000000
=394725760000000...0
(18 more '0's)1e18
x [0.00039472576
*1e18
] =0.00039472576
*1e18 *1e18
When multiplying two integers, and the resulting value is scaled up twice. Which is why we divide, to remove the extra scaling factor, after multiplication.
1e18
x [394725760000000
] / decimal_precision1e18
x [394725760000000
] /1e18
=394725760000000
394725760000000
represents0.00039472576
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.
Then we scale up by the TokenB (to token) decimals
Vice versa
Last updated