Append -Floor to getPartialAmount and isRoundingError

This commit is contained in:
Remco Bloemen
2018-08-24 16:16:44 -07:00
parent f6080367fe
commit 80291caf7c
17 changed files with 59 additions and 59 deletions

View File

@@ -163,7 +163,7 @@ contract MixinExchangeWrapper is
// Convert the remaining amount of makerAsset to buy into remaining amount // Convert the remaining amount of makerAsset to buy into remaining amount
// of takerAsset to sell, assuming entire amount can be sold in the current order // of takerAsset to sell, assuming entire amount can be sold in the current order
uint256 remainingTakerAssetFillAmount = getPartialAmount( uint256 remainingTakerAssetFillAmount = getPartialAmountFloor(
orders[i].takerAssetAmount, orders[i].takerAssetAmount,
orders[i].makerAssetAmount, orders[i].makerAssetAmount,
remainingMakerAssetFillAmount remainingMakerAssetFillAmount
@@ -231,7 +231,7 @@ contract MixinExchangeWrapper is
// Convert the remaining amount of ZRX to buy into remaining amount // Convert the remaining amount of ZRX to buy into remaining amount
// of WETH to sell, assuming entire amount can be sold in the current order. // of WETH to sell, assuming entire amount can be sold in the current order.
uint256 remainingWethSellAmount = getPartialAmount( uint256 remainingWethSellAmount = getPartialAmountFloor(
orders[i].takerAssetAmount, orders[i].takerAssetAmount,
safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees safeSub(orders[i].makerAssetAmount, orders[i].takerFee), // our exchange rate after fees
remainingZrxBuyAmount remainingZrxBuyAmount

View File

@@ -87,7 +87,7 @@ contract MixinForwarderCore is
uint256 makerAssetAmountPurchased; uint256 makerAssetAmountPurchased;
if (orders[0].makerAssetData.equals(ZRX_ASSET_DATA)) { if (orders[0].makerAssetData.equals(ZRX_ASSET_DATA)) {
// Calculate amount of WETH that won't be spent on ETH fees. // Calculate amount of WETH that won't be spent on ETH fees.
wethSellAmount = getPartialAmount( wethSellAmount = getPartialAmountFloor(
PERCENTAGE_DENOMINATOR, PERCENTAGE_DENOMINATOR,
safeAdd(PERCENTAGE_DENOMINATOR, feePercentage), safeAdd(PERCENTAGE_DENOMINATOR, feePercentage),
msg.value msg.value
@@ -103,7 +103,7 @@ contract MixinForwarderCore is
makerAssetAmountPurchased = safeSub(orderFillResults.makerAssetFilledAmount, orderFillResults.takerFeePaid); makerAssetAmountPurchased = safeSub(orderFillResults.makerAssetFilledAmount, orderFillResults.takerFeePaid);
} else { } else {
// 5% of WETH is reserved for filling feeOrders and paying feeRecipient. // 5% of WETH is reserved for filling feeOrders and paying feeRecipient.
wethSellAmount = getPartialAmount( wethSellAmount = getPartialAmountFloor(
MAX_WETH_FILL_PERCENTAGE, MAX_WETH_FILL_PERCENTAGE,
PERCENTAGE_DENOMINATOR, PERCENTAGE_DENOMINATOR,
msg.value msg.value

View File

@@ -82,7 +82,7 @@ contract MixinWeth is
uint256 wethRemaining = safeSub(msg.value, wethSold); uint256 wethRemaining = safeSub(msg.value, wethSold);
// Calculate ETH fee to pay to feeRecipient. // Calculate ETH fee to pay to feeRecipient.
uint256 ethFee = getPartialAmount( uint256 ethFee = getPartialAmountFloor(
feePercentage, feePercentage,
PERCENTAGE_DENOMINATOR, PERCENTAGE_DENOMINATOR,
wethSoldExcludingFeeOrders wethSoldExcludingFeeOrders

View File

@@ -320,7 +320,7 @@ contract MixinExchangeCore is
// Validate fill order rounding // Validate fill order rounding
require( require(
!isRoundingError( !isRoundingErrorFloor(
takerAssetFilledAmount, takerAssetFilledAmount,
order.takerAssetAmount, order.takerAssetAmount,
order.makerAssetAmount order.makerAssetAmount
@@ -376,17 +376,17 @@ contract MixinExchangeCore is
{ {
// Compute proportional transfer amounts // Compute proportional transfer amounts
fillResults.takerAssetFilledAmount = takerAssetFilledAmount; fillResults.takerAssetFilledAmount = takerAssetFilledAmount;
fillResults.makerAssetFilledAmount = getPartialAmount( fillResults.makerAssetFilledAmount = getPartialAmountFloor(
takerAssetFilledAmount, takerAssetFilledAmount,
order.takerAssetAmount, order.takerAssetAmount,
order.makerAssetAmount order.makerAssetAmount
); );
fillResults.makerFeePaid = getPartialAmount( fillResults.makerFeePaid = getPartialAmountFloor(
takerAssetFilledAmount, takerAssetFilledAmount,
order.takerAssetAmount, order.takerAssetAmount,
order.makerFee order.makerFee
); );
fillResults.takerFeePaid = getPartialAmount( fillResults.takerFeePaid = getPartialAmountFloor(
takerAssetFilledAmount, takerAssetFilledAmount,
order.takerAssetAmount, order.takerAssetAmount,
order.takerFee order.takerFee

View File

@@ -183,7 +183,7 @@ contract MixinMatchOrders is
leftTakerAssetFilledAmount = leftTakerAssetAmountRemaining; leftTakerAssetFilledAmount = leftTakerAssetAmountRemaining;
// The right order receives an amount proportional to how much was spent. // The right order receives an amount proportional to how much was spent.
rightTakerAssetFilledAmount = getPartialAmount( rightTakerAssetFilledAmount = getPartialAmountFloor(
rightOrder.takerAssetAmount, rightOrder.takerAssetAmount,
rightOrder.makerAssetAmount, rightOrder.makerAssetAmount,
leftTakerAssetFilledAmount leftTakerAssetFilledAmount
@@ -193,7 +193,7 @@ contract MixinMatchOrders is
rightTakerAssetFilledAmount = rightTakerAssetAmountRemaining; rightTakerAssetFilledAmount = rightTakerAssetAmountRemaining;
// The left order receives an amount proportional to how much was spent. // The left order receives an amount proportional to how much was spent.
leftTakerAssetFilledAmount = getPartialAmount( leftTakerAssetFilledAmount = getPartialAmountFloor(
rightOrder.makerAssetAmount, rightOrder.makerAssetAmount,
rightOrder.takerAssetAmount, rightOrder.takerAssetAmount,
rightTakerAssetFilledAmount rightTakerAssetFilledAmount

View File

@@ -298,7 +298,7 @@ contract MixinWrapperFunctions is
// Convert the remaining amount of makerAsset to buy into remaining amount // Convert the remaining amount of makerAsset to buy into remaining amount
// of takerAsset to sell, assuming entire amount can be sold in the current order // of takerAsset to sell, assuming entire amount can be sold in the current order
uint256 remainingTakerAssetFillAmount = getPartialAmount( uint256 remainingTakerAssetFillAmount = getPartialAmountFloor(
orders[i].takerAssetAmount, orders[i].takerAssetAmount,
orders[i].makerAssetAmount, orders[i].makerAssetAmount,
remainingMakerAssetFillAmount remainingMakerAssetFillAmount
@@ -350,7 +350,7 @@ contract MixinWrapperFunctions is
// Convert the remaining amount of makerAsset to buy into remaining amount // Convert the remaining amount of makerAsset to buy into remaining amount
// of takerAsset to sell, assuming entire amount can be sold in the current order // of takerAsset to sell, assuming entire amount can be sold in the current order
uint256 remainingTakerAssetFillAmount = getPartialAmount( uint256 remainingTakerAssetFillAmount = getPartialAmountFloor(
orders[i].takerAssetAmount, orders[i].takerAssetAmount,
orders[i].makerAssetAmount, orders[i].makerAssetAmount,
remainingMakerAssetFillAmount remainingMakerAssetFillAmount

View File

@@ -25,12 +25,12 @@ contract LibMath is
SafeMath SafeMath
{ {
/// @dev Calculates partial value given a numerator and denominator. /// @dev Calculates partial value given a numerator and denominator rounded down.
/// @param numerator Numerator. /// @param numerator Numerator.
/// @param denominator Denominator. /// @param denominator Denominator.
/// @param target Value to calculate partial of. /// @param target Value to calculate partial of.
/// @return Partial value of target rounded down. /// @return Partial value of target rounded down.
function getPartialAmount( function getPartialAmountFloor(
uint256 numerator, uint256 numerator,
uint256 denominator, uint256 denominator,
uint256 target uint256 target
@@ -48,7 +48,7 @@ contract LibMath is
return partialAmount; return partialAmount;
} }
/// @dev Calculates partial value given a numerator and denominator. /// @dev Calculates partial value given a numerator and denominator rounded down.
/// @param numerator Numerator. /// @param numerator Numerator.
/// @param denominator Denominator. /// @param denominator Denominator.
/// @param target Value to calculate partial of. /// @param target Value to calculate partial of.
@@ -79,7 +79,7 @@ contract LibMath is
/// @param denominator Denominator. /// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator. /// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present. /// @return Rounding error is present.
function isRoundingError( function isRoundingErrorFloor(
uint256 numerator, uint256 numerator,
uint256 denominator, uint256 denominator,
uint256 target uint256 target

View File

@@ -67,7 +67,7 @@ contract TestExchangeInternals is
/// @param denominator Denominator. /// @param denominator Denominator.
/// @param target Value to calculate partial of. /// @param target Value to calculate partial of.
/// @return Partial value of target. /// @return Partial value of target.
function publicGetPartialAmount( function publicGetPartialAmountFloor(
uint256 numerator, uint256 numerator,
uint256 denominator, uint256 denominator,
uint256 target uint256 target
@@ -76,7 +76,7 @@ contract TestExchangeInternals is
pure pure
returns (uint256 partialAmount) returns (uint256 partialAmount)
{ {
return getPartialAmount(numerator, denominator, target); return getPartialAmountFloor(numerator, denominator, target);
} }
/// @dev Calculates partial value given a numerator and denominator. /// @dev Calculates partial value given a numerator and denominator.
@@ -101,7 +101,7 @@ contract TestExchangeInternals is
/// @param denominator Denominator. /// @param denominator Denominator.
/// @param target Value to multiply with numerator/denominator. /// @param target Value to multiply with numerator/denominator.
/// @return Rounding error is present. /// @return Rounding error is present.
function publicIsRoundingError( function publicIsRoundingErrorFloor(
uint256 numerator, uint256 numerator,
uint256 denominator, uint256 denominator,
uint256 target uint256 target
@@ -110,7 +110,7 @@ contract TestExchangeInternals is
pure pure
returns (bool isError) returns (bool isError)
{ {
return isRoundingError(numerator, denominator, target); return isRoundingErrorFloor(numerator, denominator, target);
} }
/// @dev Checks if rounding error >= 0.1%. /// @dev Checks if rounding error >= 0.1%.

View File

@@ -49,7 +49,7 @@ contract TestLibs is
return fillOrderCalldata; return fillOrderCalldata;
} }
function publicGetPartialAmount( function publicGetPartialAmountFloor(
uint256 numerator, uint256 numerator,
uint256 denominator, uint256 denominator,
uint256 target uint256 target
@@ -58,7 +58,7 @@ contract TestLibs is
pure pure
returns (uint256 partialAmount) returns (uint256 partialAmount)
{ {
partialAmount = getPartialAmount( partialAmount = getPartialAmountFloor(
numerator, numerator,
denominator, denominator,
target target
@@ -83,7 +83,7 @@ contract TestLibs is
return partialAmount; return partialAmount;
} }
function publicIsRoundingError( function publicIsRoundingErrorFloor(
uint256 numerator, uint256 numerator,
uint256 denominator, uint256 denominator,
uint256 target uint256 target
@@ -92,7 +92,7 @@ contract TestLibs is
pure pure
returns (bool isError) returns (bool isError)
{ {
isError = isRoundingError( isError = isRoundingErrorFloor(
numerator, numerator,
denominator, denominator,
target target

View File

@@ -75,7 +75,7 @@ describe('Exchange core internal functions', () => {
// Note(albrow): Don't forget to add beforeEach and afterEach calls to reset // Note(albrow): Don't forget to add beforeEach and afterEach calls to reset
// the blockchain state for any tests which modify it! // the blockchain state for any tests which modify it!
async function referenceGetPartialAmountAsync( async function referenceGetPartialAmountFloorAsync(
numerator: BigNumber, numerator: BigNumber,
denominator: BigNumber, denominator: BigNumber,
target: BigNumber, target: BigNumber,
@@ -165,18 +165,18 @@ describe('Exchange core internal functions', () => {
// implementation or the Solidity implementation of // implementation or the Solidity implementation of
// calculateFillResults. // calculateFillResults.
return { return {
makerAssetFilledAmount: await referenceGetPartialAmountAsync( makerAssetFilledAmount: await referenceGetPartialAmountFloorAsync(
takerAssetFilledAmount, takerAssetFilledAmount,
orderTakerAssetAmount, orderTakerAssetAmount,
otherAmount, otherAmount,
), ),
takerAssetFilledAmount, takerAssetFilledAmount,
makerFeePaid: await referenceGetPartialAmountAsync( makerFeePaid: await referenceGetPartialAmountFloorAsync(
takerAssetFilledAmount, takerAssetFilledAmount,
orderTakerAssetAmount, orderTakerAssetAmount,
otherAmount, otherAmount,
), ),
takerFeePaid: await referenceGetPartialAmountAsync( takerFeePaid: await referenceGetPartialAmountFloorAsync(
takerAssetFilledAmount, takerAssetFilledAmount,
orderTakerAssetAmount, orderTakerAssetAmount,
otherAmount, otherAmount,
@@ -199,18 +199,18 @@ describe('Exchange core internal functions', () => {
); );
}); });
describe('getPartialAmount', async () => { describe('getPartialAmountFloor', async () => {
async function testGetPartialAmountAsync( async function testGetPartialAmountFloorAsync(
numerator: BigNumber, numerator: BigNumber,
denominator: BigNumber, denominator: BigNumber,
target: BigNumber, target: BigNumber,
): Promise<BigNumber> { ): Promise<BigNumber> {
return testExchange.publicGetPartialAmount.callAsync(numerator, denominator, target); return testExchange.publicGetPartialAmountFloor.callAsync(numerator, denominator, target);
} }
await testCombinatoriallyWithReferenceFuncAsync( await testCombinatoriallyWithReferenceFuncAsync(
'getPartialAmount', 'getPartialAmount',
referenceGetPartialAmountAsync, referenceGetPartialAmountFloorAsync,
testGetPartialAmountAsync, testGetPartialAmountFloorAsync,
[uint256Values, uint256Values, uint256Values], [uint256Values, uint256Values, uint256Values],
); );
}); });
@@ -284,7 +284,7 @@ describe('Exchange core internal functions', () => {
denominator: BigNumber, denominator: BigNumber,
target: BigNumber, target: BigNumber,
): Promise<boolean> { ): Promise<boolean> {
return testExchange.publicIsRoundingError.callAsync(numerator, denominator, target); return testExchange.publicIsRoundingErrorFloor.callAsync(numerator, denominator, target);
} }
await testCombinatoriallyWithReferenceFuncAsync( await testCombinatoriallyWithReferenceFuncAsync(
'isRoundingError', 'isRoundingError',

View File

@@ -77,7 +77,7 @@ describe('Exchange libs', () => {
const denominator = new BigNumber(999); const denominator = new BigNumber(999);
const target = new BigNumber(50); const target = new BigNumber(50);
// rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1% // rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
const isRoundingError = await libs.publicIsRoundingError.callAsync(numerator, denominator, target); const isRoundingError = await libs.publicIsRoundingErrorFloor.callAsync(numerator, denominator, target);
expect(isRoundingError).to.be.true(); expect(isRoundingError).to.be.true();
}); });
it('should return false if there is a rounding of 0.09%', async () => { it('should return false if there is a rounding of 0.09%', async () => {
@@ -85,7 +85,7 @@ describe('Exchange libs', () => {
const denominator = new BigNumber(9991); const denominator = new BigNumber(9991);
const target = new BigNumber(500); const target = new BigNumber(500);
// rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09% // rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
const isRoundingError = await libs.publicIsRoundingError.callAsync(numerator, denominator, target); const isRoundingError = await libs.publicIsRoundingErrorFloor.callAsync(numerator, denominator, target);
expect(isRoundingError).to.be.false(); expect(isRoundingError).to.be.false();
}); });
it('should return true if there is a rounding error of 0.11%', async () => { it('should return true if there is a rounding error of 0.11%', async () => {
@@ -93,7 +93,7 @@ describe('Exchange libs', () => {
const denominator = new BigNumber(9989); const denominator = new BigNumber(9989);
const target = new BigNumber(500); const target = new BigNumber(500);
// rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011% // rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
const isRoundingError = await libs.publicIsRoundingError.callAsync(numerator, denominator, target); const isRoundingError = await libs.publicIsRoundingErrorFloor.callAsync(numerator, denominator, target);
expect(isRoundingError).to.be.true(); expect(isRoundingError).to.be.true();
}); });
}); });

View File

@@ -467,17 +467,17 @@ export class FillOrderCombinatorialUtils {
? remainingTakerAmountToFill ? remainingTakerAmountToFill
: alreadyFilledTakerAmount.add(takerAssetFillAmount); : alreadyFilledTakerAmount.add(takerAssetFillAmount);
const expFilledMakerAmount = orderUtils.getPartialAmount( const expFilledMakerAmount = orderUtils.getPartialAmountFloor(
expFilledTakerAmount, expFilledTakerAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
); );
const expMakerFeePaid = orderUtils.getPartialAmount( const expMakerFeePaid = orderUtils.getPartialAmountFloor(
expFilledTakerAmount, expFilledTakerAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerFee, signedOrder.makerFee,
); );
const expTakerFeePaid = orderUtils.getPartialAmount( const expTakerFeePaid = orderUtils.getPartialAmountFloor(
expFilledTakerAmount, expFilledTakerAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.takerFee, signedOrder.takerFee,
@@ -668,7 +668,7 @@ export class FillOrderCombinatorialUtils {
signedOrder: SignedOrder, signedOrder: SignedOrder,
takerAssetFillAmount: BigNumber, takerAssetFillAmount: BigNumber,
): Promise<void> { ): Promise<void> {
const makerAssetFillAmount = orderUtils.getPartialAmount( const makerAssetFillAmount = orderUtils.getPartialAmountFloor(
takerAssetFillAmount, takerAssetFillAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
@@ -705,7 +705,7 @@ export class FillOrderCombinatorialUtils {
); );
} }
const makerFee = orderUtils.getPartialAmount( const makerFee = orderUtils.getPartialAmountFloor(
takerAssetFillAmount, takerAssetFillAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerFee, signedOrder.makerFee,
@@ -829,7 +829,7 @@ export class FillOrderCombinatorialUtils {
); );
} }
const takerFee = orderUtils.getPartialAmount( const takerFee = orderUtils.getPartialAmountFloor(
takerAssetFillAmount, takerAssetFillAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.takerFee, signedOrder.takerFee,

View File

@@ -5,7 +5,7 @@ import { constants } from './constants';
import { CancelOrder, MatchOrder } from './types'; import { CancelOrder, MatchOrder } from './types';
export const orderUtils = { export const orderUtils = {
getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber { getPartialAmountFloor(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
const partialAmount = numerator const partialAmount = numerator
.mul(target) .mul(target)
.div(denominator) .div(denominator)

View File

@@ -81,7 +81,7 @@ export class OrderStateUtils {
const remainingTakerAssetAmount = signedOrder.takerAssetAmount.minus( const remainingTakerAssetAmount = signedOrder.takerAssetAmount.minus(
sidedOrderRelevantState.filledTakerAssetAmount, sidedOrderRelevantState.filledTakerAssetAmount,
); );
const isRoundingError = OrderValidationUtils.isRoundingError( const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(
remainingTakerAssetAmount, remainingTakerAssetAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
@@ -191,7 +191,7 @@ export class OrderStateUtils {
); );
const remainingFillableTakerAssetAmountGivenMakersStatus = signedOrder.makerAssetAmount.eq(0) const remainingFillableTakerAssetAmountGivenMakersStatus = signedOrder.makerAssetAmount.eq(0)
? new BigNumber(0) ? new BigNumber(0)
: utils.getPartialAmount( : utils.getPartialAmountFloor(
orderRelevantMakerState.remainingFillableAssetAmount, orderRelevantMakerState.remainingFillableAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,

View File

@@ -24,7 +24,7 @@ export class OrderValidationUtils {
* @param denominator Denominator value. When used to check an order, pass in `order.takerAssetAmount` * @param denominator Denominator value. When used to check an order, pass in `order.takerAssetAmount`
* @param target Target value. When used to check an order, pass in `order.makerAssetAmount` * @param target Target value. When used to check an order, pass in `order.makerAssetAmount`
*/ */
public static isRoundingError(numerator: BigNumber, denominator: BigNumber, target: BigNumber): boolean { public static isRoundingErrorFloor(numerator: BigNumber, denominator: BigNumber, target: BigNumber): boolean {
// Solidity's mulmod() in JS // Solidity's mulmod() in JS
// Source: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#mathematical-and-cryptographic-functions // Source: https://solidity.readthedocs.io/en/latest/units-and-global-variables.html#mathematical-and-cryptographic-functions
if (denominator.eq(0)) { if (denominator.eq(0)) {
@@ -58,7 +58,7 @@ export class OrderValidationUtils {
zrxAssetData: string, zrxAssetData: string,
): Promise<void> { ): Promise<void> {
try { try {
const fillMakerTokenAmount = utils.getPartialAmount( const fillMakerTokenAmount = utils.getPartialAmountFloor(
fillTakerAssetAmount, fillTakerAssetAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,
@@ -79,7 +79,7 @@ export class OrderValidationUtils {
TradeSide.Taker, TradeSide.Taker,
TransferType.Trade, TransferType.Trade,
); );
const makerFeeAmount = utils.getPartialAmount( const makerFeeAmount = utils.getPartialAmountFloor(
fillTakerAssetAmount, fillTakerAssetAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerFee, signedOrder.makerFee,
@@ -92,7 +92,7 @@ export class OrderValidationUtils {
TradeSide.Maker, TradeSide.Maker,
TransferType.Fee, TransferType.Fee,
); );
const takerFeeAmount = utils.getPartialAmount( const takerFeeAmount = utils.getPartialAmountFloor(
fillTakerAssetAmount, fillTakerAssetAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.takerFee, signedOrder.takerFee,
@@ -218,7 +218,7 @@ export class OrderValidationUtils {
zrxAssetData, zrxAssetData,
); );
const wouldRoundingErrorOccur = OrderValidationUtils.isRoundingError( const wouldRoundingErrorOccur = OrderValidationUtils.isRoundingErrorFloor(
desiredFillTakerTokenAmount, desiredFillTakerTokenAmount,
signedOrder.takerAssetAmount, signedOrder.takerAssetAmount,
signedOrder.makerAssetAmount, signedOrder.makerAssetAmount,

View File

@@ -12,7 +12,7 @@ export const utils = {
const milisecondsInSecond = 1000; const milisecondsInSecond = 1000;
return new BigNumber(Date.now() / milisecondsInSecond).round(); return new BigNumber(Date.now() / milisecondsInSecond).round();
}, },
getPartialAmount(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber { getPartialAmountFloor(numerator: BigNumber, denominator: BigNumber, target: BigNumber): BigNumber {
const fillMakerTokenAmount = numerator const fillMakerTokenAmount = numerator
.mul(target) .mul(target)
.div(denominator) .div(denominator)

View File

@@ -16,7 +16,7 @@ describe('OrderValidationUtils', () => {
const denominator = new BigNumber(999); const denominator = new BigNumber(999);
const target = new BigNumber(50); const target = new BigNumber(50);
// rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1% // rounding error = ((20*50/999) - floor(20*50/999)) / (20*50/999) = 0.1%
const isRoundingError = OrderValidationUtils.isRoundingError(numerator, denominator, target); const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
expect(isRoundingError).to.be.false(); expect(isRoundingError).to.be.false();
}); });
@@ -25,7 +25,7 @@ describe('OrderValidationUtils', () => {
const denominator = new BigNumber(9991); const denominator = new BigNumber(9991);
const target = new BigNumber(500); const target = new BigNumber(500);
// rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09% // rounding error = ((20*500/9991) - floor(20*500/9991)) / (20*500/9991) = 0.09%
const isRoundingError = OrderValidationUtils.isRoundingError(numerator, denominator, target); const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
expect(isRoundingError).to.be.false(); expect(isRoundingError).to.be.false();
}); });
@@ -34,7 +34,7 @@ describe('OrderValidationUtils', () => {
const denominator = new BigNumber(9989); const denominator = new BigNumber(9989);
const target = new BigNumber(500); const target = new BigNumber(500);
// rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011% // rounding error = ((20*500/9989) - floor(20*500/9989)) / (20*500/9989) = 0.011%
const isRoundingError = OrderValidationUtils.isRoundingError(numerator, denominator, target); const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
expect(isRoundingError).to.be.true(); expect(isRoundingError).to.be.true();
}); });
@@ -43,7 +43,7 @@ describe('OrderValidationUtils', () => {
const denominator = new BigNumber(7); const denominator = new BigNumber(7);
const target = new BigNumber(10); const target = new BigNumber(10);
// rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67% // rounding error = ((3*10/7) - floor(3*10/7)) / (3*10/7) = 6.67%
const isRoundingError = OrderValidationUtils.isRoundingError(numerator, denominator, target); const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
expect(isRoundingError).to.be.true(); expect(isRoundingError).to.be.true();
}); });
@@ -52,7 +52,7 @@ describe('OrderValidationUtils', () => {
const denominator = new BigNumber(2); const denominator = new BigNumber(2);
const target = new BigNumber(10); const target = new BigNumber(10);
const isRoundingError = OrderValidationUtils.isRoundingError(numerator, denominator, target); const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
expect(isRoundingError).to.be.false(); expect(isRoundingError).to.be.false();
}); });
@@ -63,7 +63,7 @@ describe('OrderValidationUtils', () => {
const target = new BigNumber(105762562); const target = new BigNumber(105762562);
// rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) / // rounding error = ((76564*105762562/676373677) - floor(76564*105762562/676373677)) /
// (76564*105762562/676373677) = 0.0007% // (76564*105762562/676373677) = 0.0007%
const isRoundingError = OrderValidationUtils.isRoundingError(numerator, denominator, target); const isRoundingError = OrderValidationUtils.isRoundingErrorFloor(numerator, denominator, target);
expect(isRoundingError).to.be.false(); expect(isRoundingError).to.be.false();
}); });
}); });