aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemco Bloemen <remco@wicked.ventures>2018-08-24 02:01:52 +0800
committerRemco Bloemen <remco@wicked.ventures>2018-08-25 04:45:10 +0800
commit92497d7df4b61ee62acfdd58bfb98569ff67214e (patch)
tree4dcbcf594d3e675270ba8b1efa4f798425f0cb2b
parent7f36574a57ced8ead0059b90673fe01f97f04827 (diff)
downloaddexon-sol-tools-92497d7df4b61ee62acfdd58bfb98569ff67214e.tar.gz
dexon-sol-tools-92497d7df4b61ee62acfdd58bfb98569ff67214e.tar.zst
dexon-sol-tools-92497d7df4b61ee62acfdd58bfb98569ff67214e.zip
Fix isRoundingError
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol27
1 files changed, 17 insertions, 10 deletions
diff --git a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol
index fa09da6ac..146bb9943 100644
--- a/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol
+++ b/packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol
@@ -46,7 +46,7 @@ contract LibMath is
return partialAmount;
}
- /// @dev Checks if rounding error > 0.1%.
+ /// @dev Checks if rounding error >= 0.1%.
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator.
@@ -60,16 +60,23 @@ contract LibMath is
pure
returns (bool isError)
{
+ // The absolute rounding error is the difference between the rounded
+ // value and the ideal value. The relative rounding error is the
+ // absolute rounding error divided by the absolute value of the
+ // ideal value. We want the relative rounding error to be strictly less
+ // than 0.1%.
+ // Let's call `numerator * target % denominator` the remainder.
+ // The ideal value is `numerator * target / denominator`.
+ // The absolute error is `remainder / denominator`.
+ // The relative error is `remainder / numerator * target`.
+ // We want the relative error less than 1 / 1000:
+ // remainder / numerator * denominator < 1 / 1000
+ // or equivalently:
+ // 1000 * remainder < numerator * target
+ // so we have a rounding error iff:
+ // 1000 * remainder >= numerator * target
uint256 remainder = mulmod(target, numerator, denominator);
- if (remainder == 0) {
- return false; // No rounding error.
- }
-
- uint256 errPercentageTimes1000000 = safeDiv(
- safeMul(remainder, 1000000),
- safeMul(numerator, target)
- );
- isError = errPercentageTimes1000000 > 1000;
+ isError = safeMul(1000, remainder) >= safeMul(numerator, target);
return isError;
}
}