Handle v2 order edge cases

This commit is contained in:
Amir Bandeali
2019-12-22 14:29:06 -08:00
committed by Amir
parent 0f151db355
commit b15a6290a7
4 changed files with 34 additions and 17 deletions

View File

@@ -55,7 +55,7 @@ contract MixinExchangeWrapper is
internal
returns (LibFillResults.FillResults memory fillResults)
{
if (order.makerFeeAssetData.readBytes4(0) == EXCHANGE_V2_ORDER_ID) {
if (_isV2Order(order)) {
return _fillV2OrderNoThrow(
order,
takerAssetFillAmount,
@@ -169,7 +169,7 @@ contract MixinExchangeWrapper is
// The remaining amount of WETH to sell
uint256 remainingTakerAssetFillAmount = wethSellAmount
.safeSub(totalWethSpentAmount)
.safeSub(protocolFee);
.safeSub(_isV2Order(orders[i]) ? 0 : protocolFee);
// If the maker asset is ERC20Bridge, take a snapshot of the Forwarder contract's balance.
bytes4 makerAssetProxyId = orders[i].makerAssetData.readBytes4(0);
@@ -390,8 +390,9 @@ contract MixinExchangeWrapper is
senderAddress: order.senderAddress,
makerAssetAmount: order.makerAssetAmount,
takerAssetAmount: order.takerAssetAmount,
makerFee: order.makerFee,
takerFee: order.makerFee,
// NOTE: We assume fees are 0 for all v2 orders. Orders with non-zero fees will fail to be filled.
makerFee: 0,
takerFee: 0,
expirationTimeSeconds: order.expirationTimeSeconds,
salt: order.salt,
makerAssetData: order.makerAssetData,
@@ -410,16 +411,8 @@ contract MixinExchangeWrapper is
(bool didSucceed, bytes memory returnData) = exchange.call(fillOrderCalldata);
if (didSucceed) {
assert(returnData.length == 128);
IExchangeV2.FillResults memory v2FillResults = abi.decode(returnData, (IExchangeV2.FillResults));
// Add `protocolFeePaid` field to v2 fill results
fillResults = LibFillResults.FillResults({
makerAssetFilledAmount: v2FillResults.makerAssetFilledAmount,
takerAssetFilledAmount: v2FillResults.takerAssetFilledAmount,
makerFeePaid: v2FillResults.makerFeePaid,
takerFeePaid: v2FillResults.takerFeePaid,
protocolFeePaid: 0
});
// NOTE: makerFeePaid, takerFeePaid, and protocolFeePaid will always be 0 for v2 orders
(fillResults.makerAssetFilledAmount, fillResults.takerAssetFilledAmount) = abi.decode(returnData, (uint256, uint256));
}
// fillResults values will be 0 by default if call was unsuccessful
@@ -490,4 +483,15 @@ contract MixinExchangeWrapper is
return false;
}
}
/// @dev Checks whether an order is a v2 order.
/// @param order Order struct containing order specifications.
/// @return True if the order's `makerFeeAssetData` is set to the v2 order id.
function _isV2Order(LibOrder.Order memory order)
internal
pure
returns (bool)
{
return order.makerFeeAssetData.readBytes4(0) == EXCHANGE_V2_ORDER_ID;
}
}

View File

@@ -85,7 +85,6 @@ contract MixinForwarderCore is
ethFeeAmounts,
feeRecipients
);
// Spends up to wethRemaining to fill orders, transfers purchased assets to msg.sender,
// and pays WETH order fees.
(

View File

@@ -109,7 +109,6 @@ contract MixinWeth is
if (wethRemaining > 0) {
// Convert remaining WETH to ETH
ETHER_TOKEN.withdraw(wethRemaining);
// Transfer remaining ETH to sender
msg.sender.transfer(wethRemaining);
}

View File

@@ -46,6 +46,12 @@ contract IExchangeV2 {
uint256 takerFeePaid; // Total amount of ZRX paid by taker to feeRecipients(s).
}
struct OrderInfo {
uint8 orderStatus; // Status that describes order's validity and fillability.
bytes32 orderHash; // EIP712 typed data hash of the order (see LibOrder.getTypedDataHash).
uint256 orderTakerAssetFilledAmount; // Amount of order that has already been filled.
}
/// @dev Fills the input order.
/// @param order Order struct containing order specifications.
/// @param takerAssetFillAmount Desired amount of takerAsset to sell.
@@ -56,5 +62,14 @@ contract IExchangeV2 {
uint256 takerAssetFillAmount,
bytes memory signature
)
public;
public
returns (FillResults memory fillResults);
/// @dev Gets information about an order: status, hash, and amount filled.
/// @param order Order to gather information on.
/// @return OrderInfo Information about the order and its state.
/// See LibOrder.OrderInfo for a complete description.
function getOrderInfo(Order memory order)
public
returns (OrderInfo memory orderInfo);
}