Throw if the left or right orders do not compute the correct fill results. I like this better than just logging an error and failing silently.
This commit is contained in:
@@ -78,19 +78,14 @@ contract MixinMatchOrders is
|
||||
validateMatchOrThrow(leftOrder, rightOrder);
|
||||
|
||||
// Compute proportional fill amounts
|
||||
uint8 matchedFillResultsStatus;
|
||||
( matchedFillResultsStatus,
|
||||
matchedFillResults
|
||||
) = calculateMatchedFillResults(
|
||||
matchedFillResults = calculateMatchedFillResults(
|
||||
leftOrder,
|
||||
rightOrder,
|
||||
leftOrderInfo.orderStatus,
|
||||
rightOrderInfo.orderStatus,
|
||||
leftOrderInfo.orderFilledAmount,
|
||||
rightOrderInfo.orderFilledAmount);
|
||||
if (matchedFillResultsStatus != uint8(Status.SUCCESS)) {
|
||||
return matchedFillResults;
|
||||
}
|
||||
rightOrderInfo.orderFilledAmount
|
||||
);
|
||||
|
||||
// Validate fill contexts
|
||||
validateFillOrRevert(
|
||||
@@ -231,7 +226,6 @@ contract MixinMatchOrders is
|
||||
/// @param rightOrderStatus Order status of right order.
|
||||
/// @param leftOrderFilledAmount Amount of left order already filled.
|
||||
/// @param rightOrderFilledAmount Amount of right order already filled.
|
||||
/// @return status Return status of calculating fill amounts. Returns Status.SUCCESS on success.
|
||||
/// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
|
||||
function calculateMatchedFillResults(
|
||||
Order memory leftOrder,
|
||||
@@ -242,10 +236,7 @@ contract MixinMatchOrders is
|
||||
uint256 rightOrderFilledAmount
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint8 status,
|
||||
MatchedFillResults memory matchedFillResults
|
||||
)
|
||||
returns (MatchedFillResults memory matchedFillResults)
|
||||
{
|
||||
// We settle orders at the price point defined by the right order (profit goes to the order taker)
|
||||
// The constraint can be either on the left or on the right.
|
||||
@@ -286,15 +277,17 @@ contract MixinMatchOrders is
|
||||
}
|
||||
|
||||
// Calculate fill results for left order
|
||||
uint8 status;
|
||||
(status, matchedFillResults.left) = calculateFillResults(
|
||||
leftOrder,
|
||||
leftOrderStatus,
|
||||
leftOrderFilledAmount,
|
||||
leftOrderAmountToFill
|
||||
);
|
||||
if (status != uint8(Status.SUCCESS)) {
|
||||
return (status, matchedFillResults);
|
||||
}
|
||||
require(
|
||||
status == uint8(Status.SUCCESS),
|
||||
FAILED_TO_CALCULATE_FILL_RESULTS_FOR_LEFT_ORDER
|
||||
);
|
||||
|
||||
// Calculate fill results for right order
|
||||
(status, matchedFillResults.right) = calculateFillResults(
|
||||
@@ -303,9 +296,10 @@ contract MixinMatchOrders is
|
||||
rightOrderFilledAmount,
|
||||
rightOrderAmountToFill
|
||||
);
|
||||
if (status != uint8(Status.SUCCESS)) {
|
||||
return (status, matchedFillResults);
|
||||
}
|
||||
require(
|
||||
status == uint8(Status.SUCCESS),
|
||||
FAILED_TO_CALCULATE_FILL_RESULTS_FOR_RIGHT_ORDER
|
||||
);
|
||||
|
||||
// Calculate amount given to taker
|
||||
matchedFillResults.takerFillAmount = safeSub(
|
||||
@@ -316,7 +310,7 @@ contract MixinMatchOrders is
|
||||
// Validate the fill results
|
||||
validateMatchOrThrow(matchedFillResults);
|
||||
|
||||
// Return status & fill results
|
||||
return (status, matchedFillResults);
|
||||
// Return fill results
|
||||
return matchedFillResults;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,4 +55,6 @@ contract LibExchangeErrors {
|
||||
string constant NEGATIVE_SPREAD = "Matched orders must have a positive spread.";
|
||||
string constant MISCALCULATED_TRANSFER_AMOUNTS = "A miscalculation occurred: the left maker would receive more than the right maker would spend.";
|
||||
string constant ROUNDING_ERROR_TRANSFER_AMOUNTS = "A rounding error occurred when calculating transfer amounts for matched orders.";
|
||||
string constant FAILED_TO_CALCULATE_FILL_RESULTS_FOR_LEFT_ORDER = "Failed to calculate fill results for left order.";
|
||||
string constant FAILED_TO_CALCULATE_FILL_RESULTS_FOR_RIGHT_ORDER = "Failed to calculate fill results for right order.";
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ contract LibMath is
|
||||
require(
|
||||
!isRoundingError(numerator, denominator, target),
|
||||
ROUNDING_ERROR_ON_PARTIAL_AMOUNT
|
||||
);
|
||||
);
|
||||
return getPartialAmount(numerator, denominator, target);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@ contract MMatchOrders is
|
||||
/// @param rightOrderStatus Order status of right order.
|
||||
/// @param leftOrderFilledAmount Amount of left order already filled.
|
||||
/// @param rightOrderFilledAmount Amount of right order already filled.
|
||||
/// @return status Return status of calculating fill amounts. Returns Status.SUCCESS on success.
|
||||
/// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
|
||||
function calculateMatchedFillResults(
|
||||
LibOrder.Order memory leftOrder,
|
||||
@@ -70,8 +69,5 @@ contract MMatchOrders is
|
||||
uint256 rightOrderFilledAmount
|
||||
)
|
||||
internal
|
||||
returns (
|
||||
uint8 status,
|
||||
LibFillResults.MatchedFillResults memory matchedFillResults
|
||||
);
|
||||
returns (LibFillResults.MatchedFillResults memory matchedFillResults);
|
||||
}
|
||||
|
||||
@@ -647,7 +647,7 @@ describe('matchOrders', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('Should not transfer any amounts if left order is not fillable', async () => {
|
||||
it('Should throw if left order is not fillable', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
makerAddress: makerAddressLeft,
|
||||
@@ -668,13 +668,12 @@ describe('matchOrders', () => {
|
||||
// Cancel left order
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrderLeft, signedOrderLeft.makerAddress);
|
||||
// Match orders
|
||||
await exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||
// Verify balances did not change
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newBalances).to.be.deep.equal(erc20BalancesByOwner);
|
||||
return expect(
|
||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||
).to.be.rejectedWith(constants.REVERT);
|
||||
});
|
||||
|
||||
it('Should not transfer any amounts if right order is not fillable', async () => {
|
||||
it('Should throw if right order is not fillable', async () => {
|
||||
// Create orders to match
|
||||
const signedOrderLeft = orderFactoryLeft.newSignedOrder({
|
||||
makerAddress: makerAddressLeft,
|
||||
@@ -695,10 +694,9 @@ describe('matchOrders', () => {
|
||||
// Cancel right order
|
||||
await exchangeWrapper.cancelOrderAsync(signedOrderRight, signedOrderRight.makerAddress);
|
||||
// Match orders
|
||||
await exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress);
|
||||
// Verify balances did not change
|
||||
const newBalances = await erc20Wrapper.getBalancesAsync();
|
||||
expect(newBalances).to.be.deep.equal(erc20BalancesByOwner);
|
||||
return expect(
|
||||
exchangeWrapper.matchOrdersAsync(signedOrderLeft, signedOrderRight, takerAddress),
|
||||
).to.be.rejectedWith(constants.REVERT);
|
||||
});
|
||||
|
||||
it('should throw if there is not a positive spread', async () => {
|
||||
|
||||
Reference in New Issue
Block a user