diff options
author | Amir Bandeali <abandeali1@gmail.com> | 2018-08-29 04:00:49 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-29 04:00:49 +0800 |
commit | 14fdb71a716cb95bc1f6933db9057d23f3c41909 (patch) | |
tree | 9690b583d128f419f292ef78f0a70be260e8babe /packages/contracts/src/2.0.0/protocol/Exchange/libs | |
parent | 2eab0e30b753fb33729db53d141c8e22017cadec (diff) | |
download | dexon-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.sol | 82 |
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. |