aboutsummaryrefslogtreecommitdiffstats
path: root/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol
diff options
context:
space:
mode:
Diffstat (limited to 'packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol')
-rw-r--r--packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol499
1 files changed, 161 insertions, 338 deletions
diff --git a/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol b/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol
index eadeaf5ba..1164ae919 100644
--- a/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol
+++ b/packages/contracts/src/2.0.0/forwarder/MixinForwarderCore.sol
@@ -19,30 +19,30 @@
pragma solidity 0.4.24;
pragma experimental ABIEncoderV2;
-import "../utils/LibBytes/LibBytes.sol";
-import "./mixins/MFees.sol";
-import "./mixins/MMarketBuyZrx.sol";
-import "./mixins/MExpectedResults.sol";
-import "./mixins/MTransfer.sol";
-import "./mixins/MConstants.sol";
+import "./libs/LibConstants.sol";
+import "./mixins/MWeth.sol";
+import "./mixins/MAssets.sol";
+import "./mixins/MExchangeWrapper.sol";
import "./mixins/MForwarderCore.sol";
+import "../utils/LibBytes/LibBytes.sol";
import "../protocol/Exchange/libs/LibOrder.sol";
import "../protocol/Exchange/libs/LibFillResults.sol";
+import "../protocol/Exchange/libs/LibMath.sol";
contract MixinForwarderCore is
LibFillResults,
- MConstants,
- MExpectedResults,
- MFees,
- MMarketBuyZrx,
- MTransfer,
+ LibMath,
+ LibConstants,
+ MWeth,
+ MAssets,
+ MExchangeWrapper,
MForwarderCore
{
- bytes4 constant internal ERC20_DATA_ID = bytes4(keccak256("ERC20Token(address)"));
- bytes4 constant internal ERC721_DATA_ID = bytes4(keccak256("ERC721Token(address,uint256,bytes)"));
- uint256 constant internal MAX_UINT = 2**256 - 1;
+ using LibBytes for bytes;
+
+ /// @dev Constructor approves ERC20 proxy to transfer ZRX and WETH on this contract's behalf.
constructor ()
public
{
@@ -53,379 +53,202 @@ contract MixinForwarderCore is
}
}
- /// @dev Market sells ETH for ERC20 tokens, performing fee abstraction if required. This does not support ERC721 tokens. This function is payable
- /// and will convert all incoming ETH into WETH and perform the trade on behalf of the caller.
- /// This function allows for a deduction of a proportion of incoming ETH sent to the feeRecipient.
- /// The caller is sent all tokens from the operation.
- /// If the purchased token amount does not meet an acceptable threshold then this function reverts.
- /// @param orders An array of Order struct containing order specifications.
- /// @param signatures An array of Proof that order has been created by maker.
- /// @param feeOrders An array of Order struct containing order specifications for fees.
- /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders.
- /// @param feeProportion A proportion deducted off the incoming ETH and sent to feeRecipient. The maximum value for this
- /// is 1000, aka 10%. Supports up to 2 decimal places. I.e 0.59% is 59.
- /// @param feeRecipient An address of the fee recipient whom receives feeProportion of ETH.
- /// @return FillResults amounts filled and fees paid by maker and taker.
- function marketSellEthForERC20(
+ /// @dev Purchases as much of orders' makerAssets as possible by selling up to 95% of transaction's ETH value.
+ /// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
+ /// 5% of ETH value is reserved for paying fees to order feeRecipients (in ZRX) and forwarding contract feeRecipient (in ETH).
+ /// Any ETH not spent will be refunded to sender.
+ /// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
+ /// @param signatures Proofs that orders have been created by makers.
+ /// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
+ /// @param feeSignatures Proofs that feeOrders have been created by makers.
+ /// @param feePercentage Percentage of WETH sold that will payed as fee to forwarding contract feeRecipient.
+ /// @param feeRecipient Address that will receive ETH when orders are filled.
+ /// @return Amounts filled and fees paid by maker and taker for both sets of orders.
+ function marketSellOrdersWithEth(
LibOrder.Order[] memory orders,
bytes[] memory signatures,
LibOrder.Order[] memory feeOrders,
bytes[] memory feeSignatures,
- uint16 feeProportion,
+ uint256 feePercentage,
address feeRecipient
)
public
payable
- returns (FillResults memory totalFillResults)
+ returns (
+ FillResults memory orderFillResults,
+ FillResults memory feeOrderFillResults
+ )
{
- uint256 takerEthAmount = msg.value;
- require(
- takerEthAmount > 0,
- "VALUE_GREATER_THAN_ZERO"
- );
- // Deduct the fee from the total amount of ETH sent in
- uint256 ethFeeAmount = payEthFee(
- takerEthAmount,
- feeProportion,
- feeRecipient
- );
- uint256 wethSellAmount = safeSub(takerEthAmount, ethFeeAmount);
-
- // Deposit the remaining to be used for trading
- ETHER_TOKEN.deposit.value(wethSellAmount)();
- // Populate the known assetData, as it is always WETH the caller can provide null bytes to save gas
- // marketSellOrders fills the remaining
- address makerTokenAddress = LibBytes.readAddress(orders[0].makerAssetData, 16);
- orders[0].takerAssetData = WETH_ASSET_DATA;
- if (makerTokenAddress == address(ZRX_TOKEN)) {
- // If this is ZRX then we market sell from the orders, rather than a 2 step of buying ZRX fees from feeOrders
- // then buying ZRX from orders
- totalFillResults = marketSellEthForZRXInternal(
+ // Convert ETH to WETH.
+ convertEthToWeth();
+
+ uint256 wethSellAmount;
+ uint256 zrxBuyAmount;
+ uint256 makerAssetAmountPurchased;
+ if (orders[0].makerAssetData.equals(ZRX_ASSET_DATA)) {
+ // Calculate amount of WETH that won't be spent on ETH fees.
+ wethSellAmount = getPartialAmount(
+ PERCENTAGE_DENOMINATOR,
+ safeAdd(PERCENTAGE_DENOMINATOR, feePercentage),
+ msg.value
+ );
+ // Market sell available WETH.
+ // ZRX fees are paid with this contract's balance.
+ orderFillResults = marketSellWeth(
orders,
- signatures,
- wethSellAmount
+ wethSellAmount,
+ signatures
);
+ // The fee amount must be deducted from the amount transfered back to sender.
+ makerAssetAmountPurchased = safeSub(orderFillResults.makerAssetFilledAmount, orderFillResults.takerFeePaid);
} else {
- totalFillResults = marketSellEthForERC20Internal(
+ // 5% of WETH is reserved for filling feeOrders and paying feeRecipient.
+ wethSellAmount = getPartialAmount(
+ MAX_WETH_FILL_PERCENTAGE,
+ PERCENTAGE_DENOMINATOR,
+ msg.value
+ );
+ // Market sell 95% of WETH.
+ // ZRX fees are payed with this contract's balance.
+ orderFillResults = marketSellWeth(
orders,
- signatures,
+ wethSellAmount,
+ signatures
+ );
+ // Buy back all ZRX spent on fees.
+ zrxBuyAmount = orderFillResults.takerFeePaid;
+ feeOrderFillResults = marketBuyZrxWithWeth(
feeOrders,
- feeSignatures,
- wethSellAmount
+ zrxBuyAmount,
+ feeSignatures
);
+ makerAssetAmountPurchased = orderFillResults.makerAssetFilledAmount;
}
- // Prevent accidental WETH owned by this contract and it being spent
- require(
- takerEthAmount >= totalFillResults.takerAssetFilledAmount,
- "INVALID_MSG_VALUE"
- );
- // Ensure no WETH is left in this contract
- require(
- wethSellAmount == totalFillResults.takerAssetFilledAmount,
- "UNACCEPTABLE_THRESHOLD"
+
+ // Ensure that all ZRX fees have been repurchased and no extra WETH owned by this contract has been sold.
+ assertValidFillResults(
+ orderFillResults,
+ feeOrderFillResults,
+ zrxBuyAmount
);
- // Transfer all tokens to msg.sender
- transferERC20Token(
- makerTokenAddress,
- msg.sender,
- totalFillResults.makerAssetFilledAmount
+
+ // Transfer feePercentage of total ETH spent on primary orders to feeRecipient.
+ // Refund remaining ETH to msg.sender.
+ transferEthFeeAndRefund(
+ orderFillResults.takerAssetFilledAmount,
+ feeOrderFillResults.takerAssetFilledAmount,
+ feePercentage,
+ feeRecipient
);
- return totalFillResults;
+
+ // Transfer purchased assets to msg.sender.
+ transferPurchasedAssetToSender(orders[0].makerAssetData, makerAssetAmountPurchased);
}
- /// @dev Buys the exact amount of assets (ERC20 and ERC721), performing fee abstraction if required.
- /// All order assets must be of the same type. Deducts a proportional fee to fee recipient.
- /// This function is payable and will convert all incoming ETH into WETH and perform the trade on behalf of the caller.
- /// The caller is sent all assets from the fill of orders. This function will revert unless the requested amount of assets are purchased.
- /// Any excess ETH sent will be returned to the caller
- /// @param orders An array of Order struct containing order specifications.
- /// @param signatures An array of Proof that order has been created by maker.
- /// @param feeOrders An array of Order struct containing order specifications for fees.
- /// @param makerTokenFillAmount The amount of maker asset to buy.
- /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders.
- /// @param feeProportion A proportion deducted off the ETH spent and sent to feeRecipient. The maximum value for this
- /// is 1000, aka 10%. Supports up to 2 decimal places. I.e 0.59% is 59.
- /// @param feeRecipient An address of the fee recipient whom receives feeProportion of ETH.
- /// @return FillResults amounts filled and fees paid by maker and taker.
- function marketBuyTokensWithEth(
+ /// @dev Attempt to purchase makerAssetFillAmount of makerAsset by selling ETH provided with transaction.
+ /// Any ZRX required to pay fees for primary orders will automatically be purchased by this contract.
+ /// Any ETH not spent will be refunded to sender.
+ /// @param orders Array of order specifications used containing desired makerAsset and WETH as takerAsset.
+ /// @param makerAssetFillAmount Desired amount of makerAsset to purchase.
+ /// @param signatures Proofs that orders have been created by makers.
+ /// @param feeOrders Array of order specifications containing ZRX as makerAsset and WETH as takerAsset. Used to purchase ZRX for primary order fees.
+ /// @param feeSignatures Proofs that feeOrders have been created by makers.
+ /// @param feePercentage Percentage of WETH sold that will payed as fee to forwarding contract feeRecipient.
+ /// @param feeRecipient Address that will receive ETH when orders are filled.
+ /// @return Amounts filled and fees paid by maker and taker for both sets of orders.
+ function marketBuyOrdersWithEth(
LibOrder.Order[] memory orders,
+ uint256 makerAssetFillAmount,
bytes[] memory signatures,
LibOrder.Order[] memory feeOrders,
bytes[] memory feeSignatures,
- uint256 makerTokenFillAmount,
- uint16 feeProportion,
+ uint256 feePercentage,
address feeRecipient
)
public
payable
- returns (FillResults memory totalFillResults)
+ returns (
+ FillResults memory orderFillResults,
+ FillResults memory feeOrderFillResults
+ )
{
- uint256 takerEthAmount = msg.value;
- require(
- takerEthAmount > 0,
- "VALUE_GREATER_THAN_ZERO"
- );
- require(
- makerTokenFillAmount > 0,
- "VALUE_GREATER_THAN_ZERO"
- );
- bytes4 assetDataId = LibBytes.readBytes4(orders[0].makerAssetData, 0);
- require(
- assetDataId == ERC20_DATA_ID || assetDataId == ERC721_DATA_ID,
- "UNSUPPORTED_TOKEN_PROXY"
- );
-
- ETHER_TOKEN.deposit.value(takerEthAmount)();
- if (assetDataId == ERC20_DATA_ID) {
- totalFillResults = marketBuyERC20TokensInternal(
+ // Convert ETH to WETH.
+ convertEthToWeth();
+
+ uint256 zrxBuyAmount;
+ uint256 makerAssetAmountPurchased;
+ if (orders[0].makerAssetData.equals(ZRX_ASSET_DATA)) {
+ // If the makerAsset is ZRX, it is not necessary to pay fees out of this
+ // contracts's ZRX balance because fees are factored into the price of the order.
+ orderFillResults = marketBuyZrxWithWeth(
orders,
- signatures,
- feeOrders,
- feeSignatures,
- makerTokenFillAmount
+ makerAssetFillAmount,
+ signatures
);
- } else if (assetDataId == ERC721_DATA_ID) {
- totalFillResults = batchBuyERC721TokensInternal(
+ // The fee amount must be deducted from the amount transfered back to sender.
+ makerAssetAmountPurchased = safeSub(orderFillResults.makerAssetFilledAmount, orderFillResults.takerFeePaid);
+ } else {
+ // Attemp to purchase desired amount of makerAsset.
+ // ZRX fees are payed with this contract's balance.
+ orderFillResults = marketBuyWithWeth(
orders,
- signatures,
+ makerAssetFillAmount,
+ signatures
+ );
+ // Buy back all ZRX spent on fees.
+ zrxBuyAmount = orderFillResults.takerFeePaid;
+ feeOrderFillResults = marketBuyZrxWithWeth(
feeOrders,
+ zrxBuyAmount,
feeSignatures
);
+ makerAssetAmountPurchased = orderFillResults.makerAssetFilledAmount;
}
- // Prevent accidental WETH owned by this contract and it being spent
- require(
- takerEthAmount >= totalFillResults.takerAssetFilledAmount,
- "INVALID_MSG_VALUE"
+
+ // Ensure that all ZRX fees have been repurchased and no extra WETH owned by this contract has been sold.
+ assertValidFillResults(
+ orderFillResults,
+ feeOrderFillResults,
+ zrxBuyAmount
);
- withdrawPayAndDeductEthFee(
- safeSub(takerEthAmount, totalFillResults.takerAssetFilledAmount),
- totalFillResults.takerAssetFilledAmount,
- feeProportion,
+
+ // Transfer feePercentage of total ETH spent on primary orders to feeRecipient.
+ // Refund remaining ETH to msg.sender.
+ transferEthFeeAndRefund(
+ orderFillResults.takerAssetFilledAmount,
+ feeOrderFillResults.takerAssetFilledAmount,
+ feePercentage,
feeRecipient
);
- return totalFillResults;
- }
- /// @dev Market sells WETH for ERC20 tokens.
- /// @param orders An array of Order struct containing order specifications.
- /// @param signatures An array of Proof that order has been created by maker.
- /// @param feeOrders An array of Order struct containing order specifications for fees.
- /// @param feeSignatures An array of Proof that order has been created by maker for the fee orders.
- /// @param wethSellAmount The amount of WETH to sell.
- /// @return FillResults amounts filled and fees paid by maker and taker.
- function marketSellEthForERC20Internal(
- LibOrder.Order[] memory orders,
- bytes[] memory signatures,
- LibOrder.Order[] memory feeOrders,
- bytes[] memory feeSignatures,
- uint256 wethSellAmount
- )
- internal
- returns (FillResults memory totalFillResults)
- {
- uint256 remainingWethSellAmount = wethSellAmount;
- FillResults memory calculatedMarketSellResults = calculateMarketSellResults(orders, wethSellAmount);
- if (calculatedMarketSellResults.takerFeePaid > 0) {
- // Fees are required for these orders. Buy enough ZRX to cover the future market buy
- FillResults memory feeTokensResults = marketBuyZrxInternal(
- feeOrders,
- feeSignatures,
- calculatedMarketSellResults.takerFeePaid
- );
- // Ensure the token abstraction was fair if fees were proportionally too high, we fail
- require(
- isAcceptableThreshold(
- wethSellAmount,
- safeSub(wethSellAmount, feeTokensResults.takerAssetFilledAmount)
- ),
- "UNACCEPTABLE_THRESHOLD"
- );
- remainingWethSellAmount = safeSub(remainingWethSellAmount, feeTokensResults.takerAssetFilledAmount);
- totalFillResults.takerFeePaid = feeTokensResults.takerFeePaid;
- totalFillResults.takerAssetFilledAmount = feeTokensResults.takerAssetFilledAmount;
- }
- // Make our market sell to buy the requested tokens with the remaining balance
- FillResults memory requestedTokensResults = EXCHANGE.marketSellOrders(
- orders,
- remainingWethSellAmount,
- signatures
- );
- // Update our return FillResult with the market sell
- addFillResults(totalFillResults, requestedTokensResults);
- return totalFillResults;
+ // Transfer purchased assets to msg.sender.
+ transferPurchasedAssetToSender(orders[0].makerAssetData, makerAssetAmountPurchased);
}
- /// @dev Market sells WETH for ZRX tokens.
- /// @param orders An array of Order struct containing order specifications.
- /// @param signatures An array of Proof that order has been created by maker.
- /// @param wethSellAmount The amount of WETH to sell.
- /// @return FillResults amounts filled and fees paid by maker and taker.
- function marketSellEthForZRXInternal(
- LibOrder.Order[] memory orders,
- bytes[] memory signatures,
- uint256 wethSellAmount
+ /// @dev Ensures that all ZRX fees have been repurchased and no extra WETH owned by this contract has been sold.
+ /// @param orderFillResults Amounts filled and fees paid for primary orders.
+ /// @param feeOrderFillResults Amounts filled and fees paid for fee orders.
+ /// @param zrxBuyAmount The amount of ZRX that needed to be repurchased after filling primary orders.
+ function assertValidFillResults(
+ FillResults memory orderFillResults,
+ FillResults memory feeOrderFillResults,
+ uint256 zrxBuyAmount
)
internal
- returns (FillResults memory totalFillResults)
+ view
{
- // Make our market sell to buy the requested tokens with the remaining balance
- totalFillResults = EXCHANGE.marketSellOrders(
- orders,
- wethSellAmount,
- signatures
- );
- // Exchange does not special case ZRX in the makerAssetFilledAmount, if fees were deducted then using this amount
- // for future transfers is invalid.
- uint256 zrxAmountBought = safeSub(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid);
+ // Ensure that all ZRX spent while filling primary orders has been repurchased.
+ uint256 zrxPurchased = safeSub(feeOrderFillResults.makerAssetFilledAmount, feeOrderFillResults.takerFeePaid);
require(
- isAcceptableThreshold(totalFillResults.makerAssetFilledAmount, zrxAmountBought),
- "UNACCEPTABLE_THRESHOLD"
+ zrxPurchased >= zrxBuyAmount,
+ "COMPLETE_FILL_FAILED"
);
- totalFillResults.makerAssetFilledAmount = zrxAmountBought;
- return totalFillResults;
- }
- /// @dev Buys an exact amount of an ERC20 token using WETH.
- /// @param orders Orders to fill. The maker asset is the ERC20 token to buy. The taker asset is WETH.
- /// @param signatures Proof that the orders were created by their respective makers.
- /// @param feeOrders to fill. The maker asset is ZRX and the taker asset is WETH.
- /// @param feeSignatures Proof that the feeOrders were created by their respective makers.
- /// @param makerTokenFillAmount Amount of the ERC20 token to buy.
- /// @return totalFillResults Aggregated fill results of buying the ERC20 and ZRX tokens.
- function marketBuyERC20TokensInternal(
- LibOrder.Order[] memory orders,
- bytes[] memory signatures,
- LibOrder.Order[] memory feeOrders,
- bytes[] memory feeSignatures,
- uint256 makerTokenFillAmount
- )
- internal
- returns (LibFillResults.FillResults memory totalFillResults)
- {
- // We read the maker token address to check if it is ZRX and later use it for transfer
- address makerTokenAddress = LibBytes.readAddress(orders[0].makerAssetData, 16);
- // We assume that asset being bought by taker is the same for each order.
- // Rather than passing this in as calldata, we copy the makerAssetData from the first order onto all later orders.
- orders[0].takerAssetData = WETH_ASSET_DATA;
- // We can short cut here for effeciency and use buyFeeTokensInternal if maker asset token is ZRX
- // this buys us exactly that amount taking into account the fees. This saves gas and calculates the rate correctly
- FillResults memory marketBuyResults;
- if (makerTokenAddress == address(ZRX_TOKEN)) {
- marketBuyResults = marketBuyZrxInternal(
- orders,
- signatures,
- makerTokenFillAmount
- );
- // When buying ZRX we round up which can result in a small margin excess
- require(
- marketBuyResults.makerAssetFilledAmount >= makerTokenFillAmount,
- "UNACCEPTABLE_THRESHOLD"
- );
- addFillResults(totalFillResults, marketBuyResults);
- require(
- isAcceptableThreshold(
- safeAdd(totalFillResults.makerAssetFilledAmount, totalFillResults.takerFeePaid), // Total ZRX
- totalFillResults.makerAssetFilledAmount // amount going to msg.sender
- ),
- "UNACCEPTABLE_THRESHOLD"
- );
- } else {
- FillResults memory calculatedMarketBuyResults = calculateMarketBuyResults(orders, makerTokenFillAmount);
- if (calculatedMarketBuyResults.takerFeePaid > 0) {
- // Fees are required for these orders. Buy enough ZRX to cover the future market buy
- FillResults memory zrxMarketBuyResults = marketBuyZrxInternal(
- feeOrders,
- feeSignatures,
- calculatedMarketBuyResults.takerFeePaid
- );
- totalFillResults.takerAssetFilledAmount = zrxMarketBuyResults.takerAssetFilledAmount;
- totalFillResults.takerFeePaid = zrxMarketBuyResults.takerFeePaid;
- }
- // Make our market buy of the requested tokens with the remaining balance
- marketBuyResults = EXCHANGE.marketBuyOrders(
- orders,
- makerTokenFillAmount,
- signatures
- );
- require(
- marketBuyResults.makerAssetFilledAmount == makerTokenFillAmount,
- "UNACCEPTABLE_THRESHOLD"
- );
- addFillResults(totalFillResults, marketBuyResults);
- require(
- isAcceptableThreshold(
- totalFillResults.takerAssetFilledAmount,
- marketBuyResults.takerAssetFilledAmount
- ),
- "UNACCEPTABLE_THRESHOLD"
- );
- }
- // Transfer all purchased tokens to msg.sender
- transferERC20Token(
- makerTokenAddress,
- msg.sender,
- marketBuyResults.makerAssetFilledAmount
- );
- return totalFillResults;
- }
-
- /// @dev Buys an all of the ERC721 tokens in the orders.
- /// @param orders Orders to fill. The maker asset is the ERC721 token to buy. The taker asset is WETH.
- /// @param signatures Proof that the orders were created by their respective makers.
- /// @param feeOrders to fill. The maker asset is ZRX and the taker asset is WETH.
- /// @param feeSignatures Proof that the feeOrders were created by their respective makers.
- /// @return totalFillResults Aggregated fill results of buying the ERC721 tokens and ZRX tokens.
- function batchBuyERC721TokensInternal(
- LibOrder.Order[] memory orders,
- bytes[] memory signatures,
- LibOrder.Order[] memory feeOrders,
- bytes[] memory feeSignatures
- )
- internal
- returns (LibFillResults.FillResults memory totalFillResults)
- {
- uint256 totalZrxFeeAmount;
- uint256 ordersLength = orders.length;
- uint256[] memory takerAssetFillAmounts = new uint256[](ordersLength);
- for (uint256 i = 0; i < ordersLength; i++) {
- // Total up the fees
- totalZrxFeeAmount = safeAdd(totalZrxFeeAmount, orders[i].takerFee);
- // We assume that asset being bought by taker is the same for each order.
- // Rather than passing this in as calldata, we set the takerAssetData as WETH asset data
- orders[i].takerAssetData = WETH_ASSET_DATA;
- // Populate takerAssetFillAmounts for later batchFill
- takerAssetFillAmounts[i] = orders[i].takerAssetAmount;
- }
- if (totalZrxFeeAmount > 0) {
- // Fees are required for these orders. Buy enough ZRX to cover the future fill
- FillResults memory zrxMarketBuyResults = marketBuyZrxInternal(
- feeOrders,
- feeSignatures,
- totalZrxFeeAmount
- );
- totalFillResults.takerFeePaid = zrxMarketBuyResults.takerFeePaid;
- totalFillResults.takerAssetFilledAmount = zrxMarketBuyResults.takerAssetFilledAmount;
- }
- FillResults memory batchFillResults = EXCHANGE.batchFillOrKillOrders(
- orders,
- takerAssetFillAmounts,
- signatures
- );
- addFillResults(totalFillResults, batchFillResults);
+ // Ensure that no extra WETH owned by this contract has been sold.
+ uint256 wethSold = safeAdd(orderFillResults.takerAssetFilledAmount, feeOrderFillResults.takerAssetFilledAmount);
require(
- isAcceptableThreshold(
- totalFillResults.takerAssetFilledAmount,
- batchFillResults.takerAssetFilledAmount
- ),
- "UNACCEPTABLE_THRESHOLD"
+ wethSold <= msg.value,
+ "OVERSOLD_WETH"
);
- // Transfer all of the tokens filled from the batchFill
- for (i = 0; i < ordersLength; i++) {
- transferERC721Token(
- orders[i].makerAssetData,
- msg.sender
- );
- }
- return totalFillResults;
}
}