-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Precision loss in division #85
Comments
3 tasks
Made a PR that uses |
github-project-automation
bot
moved this from Needs Review
to Done
in Tasks - Smart Contracts
Dec 6, 2024
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Summary
Currently there is some difference in the calculations for MP due the precision loss of using SCALE_FACTOR.
General security recommendation is to use Math.mulDiv for these type of calculations, which also comes with advantage of reducing changes of integer overflow: SCALE_FACTOR scales values which can lead to uint256 overflow.
While it has an advantage in gas costs, finance applications generally should optimize precision over gas costs.
Details
Potential problems with SCALE_FACTOR
Using
SCALE_FACTOR
is a common technique to handle fixed-point arithmetic in Solidity, but it can fail in certain situations. Below are some examples where usingSCALE_FACTOR
might lead to failure due to precision loss, overflow, or inaccurate results:1. Overflow in Large Multiplications
One of the most significant risks with using
SCALE_FACTOR
is the possibility of overflow during multiplication when numbers are too large. Solidity operates on 256-bit integers, and multiplying large numbers without using techniques likemulDiv
can easily cause overflow.Example:
Let's assume we are using SCALE_FACTOR =$10^{18}$
Here, the product$x \times y = 6 \times 10^{76}$ , which exceeds Solidity's 256-bit integer limit. Without a function like
mulDiv
, this operation would result in an overflow, and the transaction would revert.2. Loss of Precision in Division
In Solidity, when you divide integers, the result is automatically floored to the nearest integer. If you multiply first by
SCALE_FACTOR
and then divide, the flooring can lead to precision loss, especially if the values are not perfectly divisible.Example:
Here,$\frac{3}{2}$ is expected to give $1.5$ , but since Solidity floors the result, you get $1 \times 10^{18}$ , which effectively represents $1$ . The fractional part is lost, leading to inaccurate calculations.
3. Precision Loss in Multiple Operations
When performing a sequence of operations, every time you apply a
SCALE_FACTOR
and then divide, you risk accumulating small errors due to repeated flooring, which can compound and lead to significant inaccuracies in complex calculations.Example:
Expected mathematical result:
However, due to the flooring effect after each division, the result is more likely to be 0.4×10180.4 \times 10^{18}0.4×1018, not capturing the full precision of the expected result. Each division results in some precision loss.
4. Error Due to Incorrect Use of SCALE_FACTOR
In some cases, developers might incorrectly apply
SCALE_FACTOR
in either the multiplication or division step, leading to highly inaccurate results.Example:
If a developer forgets to apply the
SCALE_FACTOR
consistently throughout a calculation:The result here will be much smaller than expected because the
SCALE_FACTOR
was incorrectly applied in the division step, leading to incorrect scaling.The correct way would have been:
5. Handling Very Small Fractions
When working with very small fractional values,
SCALE_FACTOR
might not provide enough precision to represent the result accurately. This is especially problematic when you need to represent values smaller than the smallest unit supported bySCALE_FACTOR
.Example:
Here, you are trying to represent a very small fraction ( 1/10191 / 10^{19}1/1019 ), but the result will be floored to zero because Solidity cannot represent such small values with a precision limited by
SCALE_FACTOR
.6. Complex Financial Calculations (e.g., Compound Interest)
For financial applications, even small precision errors can accumulate and lead to significant discrepancies. In calculations like compound interest or bond pricing, the cumulative effect of losing precision can result in large differences from the expected outcome.
Example:
Calculating compound interest for a series of periods:
After 10 periods, the accumulated rounding errors from multiple divisions can make the final result inaccurate compared to the expected result using exact math (like
mulDiv
).The text was updated successfully, but these errors were encountered: