βDivision Precision Loss
What are they?
Solidity use Fixed Point Arithmetic, that mean it doesn't support decimal value. As a result, any non-integer value is truncated downward. This characteristic of Solidity can lead to precision loss during numerical operations, especially when division is performed before multiplication, adversely affecting the accuracy of calculations.
Different Kind of Division Precision Loss
Division precision loss can manifest in several ways within Solidity. This article focuses on the two most prevalent issues:
Division Before Multiplication
Rounding Down To Zero
Division Before Multiplication
Solidity truncates any non-integer result to the nearest lower integer. If a division occurs before a multiplication, the operation may result in precision loss due to truncation.
This is a common rule to follow:
"Always Multiply Before Dividing"
Although many developers follow this rule, "Hidden Precision Loss" can still occur, resulting from complex calculations across different functions or contracts. These scenarios are trickier to identify but pose a significant risk if overlooked.
Let's take an example of the USSD Contest on C4:
At first glance, the calculation appears correct, let's take a look at the BuyUSSDSellCollateral
function
But the BuyUSSDSellCollateral
function multiplies the input by 1e12, leading to potential precision loss.
So it will first do the calculation inside the parenthesis (USSDamount - DAIamount / 1e12)/2
Then call the 'BuyUSSDSellCollateral' function and multiply the result by 1e12.
But mutiply a number that might has been round down by 1 Trillion seems not to be a good idea.
Rounding Down To Zero
In Solidity, due to the same feature, if the Numerator is Lower that the Denominator, the result will be 0 In regular math:
If $A < B$ with $A, B > 0$
Then $\frac{A}{B} < 1$
So here, the common rule is:
"Always make sure that the Numerator is greater than the Denominator"
Here's an example in the Cooler Contest on Sherlock:
If loanCollaterral * repaid
< loanAmount
-> decollateralized == 0
That's bad, we don't want that to happen.
It can be tricky sometime to always make sure of that rule. That how Security Reasearchers came up with a sanity check.
Conclusion
While division rounding errors might seem minor, they can lead to significant fund risks if overlooked. This overview only scratches the surface of common division rounding errors in Solidity. Researcher are encouraged to delve deeper into the subject to understand and mitigate potential precision losses in their audit.
Last updated