aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src/2.0.0/protocol/Exchange/libs
diff options
context:
space:
mode:
authorAmir Bandeali <abandeali1@gmail.com>2018-08-29 04:00:49 +0800
committerGitHub <noreply@github.com>2018-08-29 04:00:49 +0800
commit14fdb71a716cb95bc1f6933db9057d23f3c41909 (patch)
tree9690b583d128f419f292ef78f0a70be260e8babe /packages/contracts/src/2.0.0/protocol/Exchange/libs
parent2eab0e30b753fb33729db53d141c8e22017cadec (diff)
downloaddexon-0x-contracts-14fdb71a716cb95bc1f6933db9057d23f3c41909.tar.gz
dexon-0x-contracts-14fdb71a716cb95bc1f6933db9057d23f3c41909.tar.zst
dexon-0x-contracts-14fdb71a716cb95bc1f6933db9057d23f3c41909.zip
safeGetPartialAmount (#1035)
* Added Test "Should transfer correct amounts when left order is fully filled and values pass isRoundingErrorCeil but fail isRoundingErrorFloor" * Added RoundingError exception to reference function for getPartialAmount * Added RoundingError exception to reference function for getPartialAmount * Added isRoundingErrorCeil to getPartialAmountCeil reference funtion * Computed new values for "Should give right maker a better buy price when correct price is not integral" that does not have a rounding error * Almost all tests for match orders are passing after adding isRoundingErrorCeil check * WIP commit: Added rounding error checks to getPartialAmount * WIP commit: Added rounding error checks to getPartialAmount * Use safe versions of getPartialAmount * Update Exchange internals tests * Run linter * Found new values for "Should transfer correct amounts when right order fill amount deviates from amount derived by `Exchange.fillOrder`" * Fixed merge conflicts * Run all tests * Cleaned up some comments on match Orders tests * Fix tests for geth
Diffstat (limited to 'packages/contracts/src/2.0.0/protocol/Exchange/libs')
-rw-r--r--packages/contracts/src/2.0.0/protocol/Exchange/libs/LibMath.sol82
1 files changed, 80 insertions, 2 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 0e0fba5d2..57fd53f29 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
@@ -26,11 +26,48 @@ contract LibMath is
{
/// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// Reverts if rounding error is >= 0.1%
/// @param numerator Numerator.
/// @param denominator Denominator.
/// @param target Value to calculate partial of.
/// @return Partial value of target rounded down.
- function getPartialAmountFloor(
+ function safeGetPartialAmountFloor(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ )
+ internal
+ pure
+ returns (uint256 partialAmount)
+ {
+ require(
+ denominator > 0,
+ "DIVISION_BY_ZERO"
+ );
+
+ require(
+ !isRoundingErrorFloor(
+ numerator,
+ denominator,
+ target
+ ),
+ "ROUNDING_ERROR"
+ );
+
+ partialAmount = safeDiv(
+ safeMul(numerator, target),
+ denominator
+ );
+ return partialAmount;
+ }
+
+ /// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// Reverts if rounding error is >= 0.1%
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to calculate partial of.
+ /// @return Partial value of target rounded up.
+ function safeGetPartialAmountCeil(
uint256 numerator,
uint256 denominator,
uint256 target
@@ -43,7 +80,48 @@ contract LibMath is
denominator > 0,
"DIVISION_BY_ZERO"
);
+
+ require(
+ !isRoundingErrorCeil(
+ numerator,
+ denominator,
+ target
+ ),
+ "ROUNDING_ERROR"
+ );
+ // safeDiv computes `floor(a / b)`. We use the identity (a, b integer):
+ // ceil(a / b) = floor((a + b - 1) / b)
+ // To implement `ceil(a / b)` using safeDiv.
+ partialAmount = safeDiv(
+ safeAdd(
+ safeMul(numerator, target),
+ safeSub(denominator, 1)
+ ),
+ denominator
+ );
+ return partialAmount;
+ }
+
+ /// @dev Calculates partial value given a numerator and denominator rounded down.
+ /// @param numerator Numerator.
+ /// @param denominator Denominator.
+ /// @param target Value to calculate partial of.
+ /// @return Partial value of target rounded down.
+ function getPartialAmountFloor(
+ uint256 numerator,
+ uint256 denominator,
+ uint256 target
+ )
+ internal
+ pure
+ returns (uint256 partialAmount)
+ {
+ require(
+ denominator > 0,
+ "DIVISION_BY_ZERO"
+ );
+
partialAmount = safeDiv(
safeMul(numerator, target),
denominator
@@ -69,7 +147,7 @@ contract LibMath is
denominator > 0,
"DIVISION_BY_ZERO"
);
-
+
// safeDiv computes `floor(a / b)`. We use the identity (a, b integer):
// ceil(a / b) = floor((a + b - 1) / b)
// To implement `ceil(a / b)` using safeDiv.