@0x:contracts-exchange Added protocol fees to fillOrders and matchOrders
				
					
				
			This commit is contained in:
		@@ -52,12 +52,10 @@ library LibFillResults {
 | 
				
			|||||||
    /// @dev Calculates amounts filled and fees paid by maker and taker.
 | 
					    /// @dev Calculates amounts filled and fees paid by maker and taker.
 | 
				
			||||||
    /// @param order to be filled.
 | 
					    /// @param order to be filled.
 | 
				
			||||||
    /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.
 | 
					    /// @param takerAssetFilledAmount Amount of takerAsset that will be filled.
 | 
				
			||||||
    /// @param protocolFeeMultiplier The multiplier used to calculate protocol fees.
 | 
					 | 
				
			||||||
    /// @return fillResults Amounts filled and fees paid by maker and taker.
 | 
					    /// @return fillResults Amounts filled and fees paid by maker and taker.
 | 
				
			||||||
    function calculateFillResults(
 | 
					    function calculateFillResults(
 | 
				
			||||||
        LibOrder.Order memory order,
 | 
					        LibOrder.Order memory order,
 | 
				
			||||||
        uint256 takerAssetFilledAmount,
 | 
					        uint256 takerAssetFilledAmount
 | 
				
			||||||
        uint256 protocolFeeMultiplier
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        internal
 | 
					        internal
 | 
				
			||||||
        view
 | 
					        view
 | 
				
			||||||
@@ -81,9 +79,6 @@ library LibFillResults {
 | 
				
			|||||||
            order.takerFee
 | 
					            order.takerFee
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Compute the protocol fee for a single fill.
 | 
					 | 
				
			||||||
        fillResults.protocolFeePaid = tx.gasprice.safeMul(protocolFeeMultiplier);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return fillResults;
 | 
					        return fillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -95,7 +90,6 @@ library LibFillResults {
 | 
				
			|||||||
    /// @param rightOrder Second order to match.
 | 
					    /// @param rightOrder Second order to match.
 | 
				
			||||||
    /// @param leftOrderTakerAssetFilledAmount Amount of left order already filled.
 | 
					    /// @param leftOrderTakerAssetFilledAmount Amount of left order already filled.
 | 
				
			||||||
    /// @param rightOrderTakerAssetFilledAmount Amount of right order already filled.
 | 
					    /// @param rightOrderTakerAssetFilledAmount Amount of right order already filled.
 | 
				
			||||||
    /// @param protocolFeeMultiplier The multiplier used to calculate protocol fees.
 | 
					 | 
				
			||||||
    /// @param shouldMaximallyFillOrders A value that indicates whether or not this calculation should use
 | 
					    /// @param shouldMaximallyFillOrders A value that indicates whether or not this calculation should use
 | 
				
			||||||
    ///                                  the maximal fill order matching strategy.
 | 
					    ///                                  the maximal fill order matching strategy.
 | 
				
			||||||
    /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
 | 
					    /// @param matchedFillResults Amounts to fill and fees to pay by maker and taker of matched orders.
 | 
				
			||||||
@@ -104,7 +98,6 @@ library LibFillResults {
 | 
				
			|||||||
        LibOrder.Order memory rightOrder,
 | 
					        LibOrder.Order memory rightOrder,
 | 
				
			||||||
        uint256 leftOrderTakerAssetFilledAmount,
 | 
					        uint256 leftOrderTakerAssetFilledAmount,
 | 
				
			||||||
        uint256 rightOrderTakerAssetFilledAmount,
 | 
					        uint256 rightOrderTakerAssetFilledAmount,
 | 
				
			||||||
        uint256 protocolFeeMultiplier,
 | 
					 | 
				
			||||||
        bool shouldMaximallyFillOrders
 | 
					        bool shouldMaximallyFillOrders
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        internal
 | 
					        internal
 | 
				
			||||||
@@ -170,11 +163,6 @@ library LibFillResults {
 | 
				
			|||||||
            rightOrder.takerFee
 | 
					            rightOrder.takerFee
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Compute the protocol fees
 | 
					 | 
				
			||||||
        uint256 protocolFee = tx.gasprice.safeMul(protocolFeeMultiplier);
 | 
					 | 
				
			||||||
        matchedFillResults.left.protocolFeePaid = protocolFee;
 | 
					 | 
				
			||||||
        matchedFillResults.right.protocolFeePaid = protocolFee;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Return fill results
 | 
					        // Return fill results
 | 
				
			||||||
        return matchedFillResults;
 | 
					        return matchedFillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,14 +29,13 @@ contract TestLibFillResults {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    function calculateFillResults(
 | 
					    function calculateFillResults(
 | 
				
			||||||
        LibOrder.Order memory order,
 | 
					        LibOrder.Order memory order,
 | 
				
			||||||
        uint256 takerAssetFilledAmount,
 | 
					        uint256 takerAssetFilledAmount
 | 
				
			||||||
        uint256 protocolFeeMultiplier
 | 
					 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        view
 | 
					        view
 | 
				
			||||||
        returns (LibFillResults.FillResults memory fillResults)
 | 
					        returns (LibFillResults.FillResults memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        fillResults = LibFillResults.calculateFillResults(order, takerAssetFilledAmount, protocolFeeMultiplier);
 | 
					        fillResults = LibFillResults.calculateFillResults(order, takerAssetFilledAmount);
 | 
				
			||||||
        return fillResults;
 | 
					        return fillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -45,7 +44,6 @@ contract TestLibFillResults {
 | 
				
			|||||||
        LibOrder.Order memory rightOrder,
 | 
					        LibOrder.Order memory rightOrder,
 | 
				
			||||||
        uint256 leftOrderTakerAssetFilledAmount,
 | 
					        uint256 leftOrderTakerAssetFilledAmount,
 | 
				
			||||||
        uint256 rightOrderTakerAssetFilledAmount,
 | 
					        uint256 rightOrderTakerAssetFilledAmount,
 | 
				
			||||||
        uint256 protocolFeeMultiplier,
 | 
					 | 
				
			||||||
        bool shouldMaximallyFillOrders
 | 
					        bool shouldMaximallyFillOrders
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
@@ -57,7 +55,6 @@ contract TestLibFillResults {
 | 
				
			|||||||
            rightOrder,
 | 
					            rightOrder,
 | 
				
			||||||
            leftOrderTakerAssetFilledAmount,
 | 
					            leftOrderTakerAssetFilledAmount,
 | 
				
			||||||
            rightOrderTakerAssetFilledAmount,
 | 
					            rightOrderTakerAssetFilledAmount,
 | 
				
			||||||
            protocolFeeMultiplier,
 | 
					 | 
				
			||||||
            shouldMaximallyFillOrders
 | 
					            shouldMaximallyFillOrders
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return matchedFillResults;
 | 
					        return matchedFillResults;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
        "evmVersion": "constantinople",
 | 
					        "evmVersion": "constantinople",
 | 
				
			||||||
        "optimizer": {
 | 
					        "optimizer": {
 | 
				
			||||||
            "enabled": true,
 | 
					            "enabled": true,
 | 
				
			||||||
            "runs": 1000000,
 | 
					            "runs": 15000,
 | 
				
			||||||
            "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
 | 
					            "details": { "yul": true, "deduplicate": true, "cse": true, "constantOptimizer": true }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "outputSelection": {
 | 
					        "outputSelection": {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pragma solidity ^0.5.5;
 | 
					pragma solidity ^0.5.9;
 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					pragma experimental ABIEncoderV2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "../src/interfaces/IExchange.sol";
 | 
					import "../src/interfaces/IExchange.sol";
 | 
				
			||||||
@@ -89,7 +89,7 @@ contract ExchangeWrapper is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        address takerAddress = msg.sender;
 | 
					        address takerAddress = msg.sender;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pragma solidity ^0.5.5;
 | 
					pragma solidity ^0.5.9;
 | 
				
			||||||
pragma experimental ABIEncoderV2;
 | 
					pragma experimental ABIEncoderV2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "../src/interfaces/IExchange.sol";
 | 
					import "../src/interfaces/IExchange.sol";
 | 
				
			||||||
@@ -104,7 +104,7 @@ contract Whitelist is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        address takerAddress = msg.sender;
 | 
					        address takerAddress = msg.sender;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,12 +35,12 @@ import "./MixinSignatureValidator.sol";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
contract MixinExchangeCore is
 | 
					contract MixinExchangeCore is
 | 
				
			||||||
 | 
					    IExchangeCore,
 | 
				
			||||||
    Refundable,
 | 
					    Refundable,
 | 
				
			||||||
    LibEIP712ExchangeDomain,
 | 
					    LibEIP712ExchangeDomain,
 | 
				
			||||||
    IExchangeCore,
 | 
					 | 
				
			||||||
    MixinAssetProxyDispatcher,
 | 
					    MixinAssetProxyDispatcher,
 | 
				
			||||||
    MixinSignatureValidator,
 | 
					    MixinProtocolFees,
 | 
				
			||||||
    MixinProtocolFees
 | 
					    MixinSignatureValidator
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    using LibOrder for LibOrder.Order;
 | 
					    using LibOrder for LibOrder.Order;
 | 
				
			||||||
    using LibSafeMath for uint256;
 | 
					    using LibSafeMath for uint256;
 | 
				
			||||||
@@ -103,7 +103,7 @@ contract MixinExchangeCore is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.FillResults memory fillResults)
 | 
					        returns (LibFillResults.FillResults memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        fillResults = _fillOrder(
 | 
					        fillResults = _fillOrder(
 | 
				
			||||||
@@ -217,10 +217,18 @@ contract MixinExchangeCore is
 | 
				
			|||||||
        uint256 takerAssetFilledAmount = LibSafeMath.min256(takerAssetFillAmount, remainingTakerAssetAmount);
 | 
					        uint256 takerAssetFilledAmount = LibSafeMath.min256(takerAssetFillAmount, remainingTakerAssetAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Compute proportional fill amounts
 | 
					        // Compute proportional fill amounts
 | 
				
			||||||
        fillResults = LibFillResults.calculateFillResults(order, takerAssetFilledAmount, protocolFeeMultiplier);
 | 
					        fillResults = LibFillResults.calculateFillResults(order, takerAssetFilledAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bytes32 orderHash = orderInfo.orderHash;
 | 
					        bytes32 orderHash = orderInfo.orderHash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Settle order
 | 
				
			||||||
 | 
					        _settleOrder(
 | 
				
			||||||
 | 
					            orderHash,
 | 
				
			||||||
 | 
					            order,
 | 
				
			||||||
 | 
					            takerAddress,
 | 
				
			||||||
 | 
					            fillResults
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Update exchange internal state
 | 
					        // Update exchange internal state
 | 
				
			||||||
        _updateFilledState(
 | 
					        _updateFilledState(
 | 
				
			||||||
            order,
 | 
					            order,
 | 
				
			||||||
@@ -230,14 +238,6 @@ contract MixinExchangeCore is
 | 
				
			|||||||
            fillResults
 | 
					            fillResults
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Settle order
 | 
					 | 
				
			||||||
        _settleOrder(
 | 
					 | 
				
			||||||
            orderHash,
 | 
					 | 
				
			||||||
            order,
 | 
					 | 
				
			||||||
            takerAddress,
 | 
					 | 
				
			||||||
            fillResults
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return fillResults;
 | 
					        return fillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -462,25 +462,26 @@ contract MixinExchangeCore is
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Transfer protocol fee -> staking if the fee should be paid
 | 
					        // Transfer protocol fee -> staking if the fee should be paid
 | 
				
			||||||
        if (staking != address(0)) {
 | 
					        address feeCollector = protocolFeeCollector;
 | 
				
			||||||
            // If sufficient ether was sent to the contract, the protocol fee should be paid in ETH.
 | 
					        if (feeCollector != address(0)) {
 | 
				
			||||||
            // Otherwise the fee should be paid in WETH.
 | 
					            // Create a stack variable to hold the value that will be sent so that the gas optimization of
 | 
				
			||||||
            uint256 protocolFee = fillResults.protocolFeePaid;
 | 
					            // only having one call statement can be implemented.
 | 
				
			||||||
            if (address(this).balance >= protocolFee) {
 | 
					            uint256 valuePaid = 0;
 | 
				
			||||||
                IStaking(staking).payProtocolFee.value(protocolFee)(order.makerAddress);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // Transfer the Weth
 | 
					 | 
				
			||||||
                _dispatchTransferFrom(
 | 
					 | 
				
			||||||
                    orderHash,
 | 
					 | 
				
			||||||
                    WETH_ASSET_DATA,
 | 
					 | 
				
			||||||
                    takerAddress,
 | 
					 | 
				
			||||||
                    staking,
 | 
					 | 
				
			||||||
                    protocolFee
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Attribute the protocol fee to the maker
 | 
					            // Calculate the protocol fee that should be paid and populate the `protocolFeePaid` field in `fillResults`.
 | 
				
			||||||
                IStaking(staking).recordProtocolFee(order.makerAddress, protocolFee);
 | 
					            // It's worth noting that we leave this calculation until now so that work isn't wasted if a fee collector
 | 
				
			||||||
 | 
					            // is not registered in the exchange.
 | 
				
			||||||
 | 
					            uint256 protocolFee = tx.gasprice.safeMul(protocolFeeMultiplier);
 | 
				
			||||||
 | 
					            fillResults.protocolFeePaid = protocolFee;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // If sufficient ether was sent to the contract, the protocol fee should be paid in ETH.
 | 
				
			||||||
 | 
					            // Otherwise the fee should be paid in WETH. Since the exchange doesn't actually handle
 | 
				
			||||||
 | 
					            // this case, it will just forward the procotolFee in ether in case 1 and will send zero
 | 
				
			||||||
 | 
					            // value in case 2.
 | 
				
			||||||
 | 
					            if (address(this).balance >= protocolFee) {
 | 
				
			||||||
 | 
					                valuePaid = protocolFee;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            IStaking(feeCollector).payProtocolFee.value(valuePaid)(order.makerAddress, takerAddress, protocolFee);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,7 @@ contract MixinMatchOrders is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults)
 | 
					        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _batchMatchOrders(
 | 
					        return _batchMatchOrders(
 | 
				
			||||||
@@ -77,7 +77,7 @@ contract MixinMatchOrders is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults)
 | 
					        returns (LibFillResults.BatchMatchedFillResults memory batchMatchedFillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _batchMatchOrders(
 | 
					        return _batchMatchOrders(
 | 
				
			||||||
@@ -107,7 +107,7 @@ contract MixinMatchOrders is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.MatchedFillResults memory matchedFillResults)
 | 
					        returns (LibFillResults.MatchedFillResults memory matchedFillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _matchOrders(
 | 
					        return _matchOrders(
 | 
				
			||||||
@@ -137,7 +137,7 @@ contract MixinMatchOrders is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.MatchedFillResults memory matchedFillResults)
 | 
					        returns (LibFillResults.MatchedFillResults memory matchedFillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _matchOrders(
 | 
					        return _matchOrders(
 | 
				
			||||||
@@ -385,10 +385,19 @@ contract MixinMatchOrders is
 | 
				
			|||||||
            rightOrder,
 | 
					            rightOrder,
 | 
				
			||||||
            leftOrderInfo.orderTakerAssetFilledAmount,
 | 
					            leftOrderInfo.orderTakerAssetFilledAmount,
 | 
				
			||||||
            rightOrderInfo.orderTakerAssetFilledAmount,
 | 
					            rightOrderInfo.orderTakerAssetFilledAmount,
 | 
				
			||||||
            protocolFeeMultiplier,
 | 
					 | 
				
			||||||
            shouldMaximallyFillOrders
 | 
					            shouldMaximallyFillOrders
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Settle matched orders. Succeeds or throws.
 | 
				
			||||||
 | 
					        _settleMatchedOrders(
 | 
				
			||||||
 | 
					            leftOrderInfo.orderHash,
 | 
				
			||||||
 | 
					            rightOrderInfo.orderHash,
 | 
				
			||||||
 | 
					            leftOrder,
 | 
				
			||||||
 | 
					            rightOrder,
 | 
				
			||||||
 | 
					            takerAddress,
 | 
				
			||||||
 | 
					            matchedFillResults
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Update exchange state
 | 
					        // Update exchange state
 | 
				
			||||||
        _updateFilledState(
 | 
					        _updateFilledState(
 | 
				
			||||||
            leftOrder,
 | 
					            leftOrder,
 | 
				
			||||||
@@ -405,16 +414,6 @@ contract MixinMatchOrders is
 | 
				
			|||||||
            matchedFillResults.right
 | 
					            matchedFillResults.right
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Settle matched orders. Succeeds or throws.
 | 
					 | 
				
			||||||
        _settleMatchedOrders(
 | 
					 | 
				
			||||||
            leftOrderInfo.orderHash,
 | 
					 | 
				
			||||||
            rightOrderInfo.orderHash,
 | 
					 | 
				
			||||||
            leftOrder,
 | 
					 | 
				
			||||||
            rightOrder,
 | 
					 | 
				
			||||||
            takerAddress,
 | 
					 | 
				
			||||||
            matchedFillResults
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return matchedFillResults;
 | 
					        return matchedFillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -490,39 +489,27 @@ contract MixinMatchOrders is
 | 
				
			|||||||
            matchedFillResults.profitInRightMakerAsset
 | 
					            matchedFillResults.profitInRightMakerAsset
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Pay protocol fees
 | 
					        // Pay the protocol fees if there is a registered `protocolFeeCollector` address.
 | 
				
			||||||
        if (staking != address(0)) {
 | 
					        address feeCollector = protocolFeeCollector;
 | 
				
			||||||
            // matchedFillResults.left.protocolFeePaid == matchedFillResults.right.protocolFeePaid
 | 
					        if (feeCollector != address(0)) {
 | 
				
			||||||
            // so we only use matchedFillResults.left.protocolFeePaid as a gas optimization.
 | 
					            // Calculate the protocol fee that should be paid and populate the `protocolFeePaid` field in the left and
 | 
				
			||||||
            uint256 protocolFee = matchedFillResults.left.protocolFeePaid;
 | 
					            // right `fillResults` of `matchedFillResults`. It's worth noting that we leave this calculation until now
 | 
				
			||||||
 | 
					            // so that work isn't wasted if a fee collector is not registered in the exchange.
 | 
				
			||||||
 | 
					            uint256 protocolFee = tx.gasprice.safeMul(protocolFeeMultiplier);
 | 
				
			||||||
 | 
					            matchedFillResults.left.protocolFeePaid = protocolFee;
 | 
				
			||||||
 | 
					            matchedFillResults.right.protocolFeePaid = protocolFee;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Construct an array of makers and fee amounts so that the staking contract will only need to be called once.
 | 
					            // Create a stack variable for the value that will be sent to the feeCollector when `payProtocolFee` is called.
 | 
				
			||||||
            address[] memory makers = new address[](2);
 | 
					            // This allows a gas optimization where the `leftOrder.makerAddress` only needs be loaded onto the stack once AND
 | 
				
			||||||
            makers[0] = leftOrder.makerAddress;
 | 
					            // a stack variable does not need to be allocated for the call.
 | 
				
			||||||
            makers[1] = rightOrder.makerAddress;
 | 
					            uint256 valuePaid = 0;
 | 
				
			||||||
            uint256[] memory fees = new uint256[](2);
 | 
					 | 
				
			||||||
            fees[0] = protocolFee;
 | 
					 | 
				
			||||||
            fees[1] = protocolFee;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // If sufficient ether was sent to the contract, the protocol fee should be paid in ETH.
 | 
					            // Pay the left order's protocol fee.
 | 
				
			||||||
            // Otherwise the fee should be paid in WETH.
 | 
					 | 
				
			||||||
            if (address(this).balance >= 2 * protocolFee) {
 | 
					            if (address(this).balance >= 2 * protocolFee) {
 | 
				
			||||||
                // Forward the protocol fees
 | 
					                valuePaid = 2 * protocolFee;
 | 
				
			||||||
                IStaking(staking).batchPayProtocolFees.value(2 * protocolFee)(makers, fees);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // Transfer the weth from the takerAddress.
 | 
					 | 
				
			||||||
                // Note: `_dispatchTransferFrom` is only called once as a gas optimization.
 | 
					 | 
				
			||||||
                _dispatchTransferFrom(
 | 
					 | 
				
			||||||
                    leftOrderHash,
 | 
					 | 
				
			||||||
                    WETH_ASSET_DATA,
 | 
					 | 
				
			||||||
                    takerAddress,
 | 
					 | 
				
			||||||
                    staking,
 | 
					 | 
				
			||||||
                    2 * protocolFee
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // Attribute the protocol fees to the maker addresses
 | 
					 | 
				
			||||||
                IStaking(staking).batchRecordProtocolFees(makers, fees);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            IStaking(feeCollector).payProtocolFee.value(valuePaid)(leftOrder.makerAddress, takerAddress, protocolFee);
 | 
				
			||||||
 | 
					            IStaking(feeCollector).payProtocolFee.value(valuePaid)(rightOrder.makerAddress, takerAddress, protocolFee);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Settle taker fees.
 | 
					        // Settle taker fees.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,67 +0,0 @@
 | 
				
			|||||||
/*
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Copyright 2019 ZeroEx Intl.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Licensed under the Apache License, Version 2.0 (the "License");
 | 
					 | 
				
			||||||
  you may not use this file except in compliance with the License.
 | 
					 | 
				
			||||||
  You may obtain a copy of the License at
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    http://www.apache.org/licenses/LICENSE-2.0
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  Unless required by applicable law or agreed to in writing, software
 | 
					 | 
				
			||||||
  distributed under the License is distributed on an "AS IS" BASIS,
 | 
					 | 
				
			||||||
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 | 
				
			||||||
  See the License for the specific language governing permissions and
 | 
					 | 
				
			||||||
  limitations under the License.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pragma solidity ^0.5.9;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import "@0x/contracts-utils/contracts/src/Ownable.sol";
 | 
					 | 
				
			||||||
import "./interfaces/IStakingManager.sol";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
contract MixinStakingManager is
 | 
					 | 
				
			||||||
    IStakingManager,
 | 
					 | 
				
			||||||
    Ownable
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    // The protocol fee multiplier -- the owner can update this field.
 | 
					 | 
				
			||||||
    uint256 public protocolFeeMultiplier;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // The address of the registered staking contract -- the owner can update this field.
 | 
					 | 
				
			||||||
    address public staking;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // The address of the wrapped ether contract -- the owner can update this field.
 | 
					 | 
				
			||||||
    address public weth;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Allows the owner to update the protocol fee multiplier.
 | 
					 | 
				
			||||||
    /// @param updatedProtocolFeeMultiplier The updated protocol fee multiplier.
 | 
					 | 
				
			||||||
    function updateProtocolFeeMultiplier(uint256 updatedProtocolFeeMultiplier)
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        onlyOwner()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        emit UpdatedProtocolFeeMultiplier(protocolFeeMultiplier, updatedProtocolFeeMultiplier);
 | 
					 | 
				
			||||||
        protocolFeeMultiplier = updatedProtocolFeeMultiplier;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Allows the owner to update the staking address.
 | 
					 | 
				
			||||||
    /// @param updatedStaking The updated staking contract address.
 | 
					 | 
				
			||||||
    function updateStakingAddress(address updatedStaking)
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        onlyOwner()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        emit UpdatedStakingAddress(staking, updatedStaking);
 | 
					 | 
				
			||||||
        staking = updatedStaking;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Allows the owner to update the WETH address.
 | 
					 | 
				
			||||||
    /// @param updatedWeth The updated WETH contract address.
 | 
					 | 
				
			||||||
    function updateWethAddress(address updatedWeth)
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        onlyOwner()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        emit UpdatedWethAddress(weth, updatedWeth);
 | 
					 | 
				
			||||||
        weth = updatedWeth;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -53,7 +53,7 @@ contract MixinTransactions is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        disableRefundUntilEnd
 | 
				
			||||||
        returns (bytes memory)
 | 
					        returns (bytes memory)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return _executeTransaction(transaction, signature);
 | 
					        return _executeTransaction(transaction, signature);
 | 
				
			||||||
@@ -69,7 +69,7 @@ contract MixinTransactions is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        disableRefundUntilEnd
 | 
				
			||||||
        returns (bytes[] memory)
 | 
					        returns (bytes[] memory)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint256 length = transactions.length;
 | 
					        uint256 length = transactions.length;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -47,7 +47,7 @@ contract MixinTransferSimulator is
 | 
				
			|||||||
        uint256 length = assetData.length;
 | 
					        uint256 length = assetData.length;
 | 
				
			||||||
        for (uint256 i = 0; i != length; i++) {
 | 
					        for (uint256 i = 0; i != length; i++) {
 | 
				
			||||||
            _dispatchTransferFrom(
 | 
					            _dispatchTransferFrom(
 | 
				
			||||||
                // The index is passed in as `orderHash` so that a failed transfer can be quickly identified when catching the error 
 | 
					                // The index is passed in as `orderHash` so that a failed transfer can be quickly identified when catching the error
 | 
				
			||||||
                bytes32(i),
 | 
					                bytes32(i),
 | 
				
			||||||
                assetData[i],
 | 
					                assetData[i],
 | 
				
			||||||
                fromAddresses[i],
 | 
					                fromAddresses[i],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.FillResults memory fillResults)
 | 
					        returns (LibFillResults.FillResults memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        fillResults = _fillOrKillOrder(
 | 
					        fillResults = _fillOrKillOrder(
 | 
				
			||||||
@@ -59,6 +59,10 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
        return fillResults;
 | 
					        return fillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// Note: This function only needs `refundFinalBalance` modifier because ether will not
 | 
				
			||||||
 | 
					    //        be returned in the event that the delegatecall fails. This said, there is no
 | 
				
			||||||
 | 
					    //        reason to invoke `disableRefundUntilEnd` because it is cheaper to use this modifier
 | 
				
			||||||
 | 
					    //        and the inner refund will not affect the logic of this call.
 | 
				
			||||||
    /// @dev Fills the input order.
 | 
					    /// @dev Fills the input order.
 | 
				
			||||||
    ///      Returns a null FillResults instance if the transaction would otherwise revert.
 | 
					    ///      Returns a null FillResults instance if the transaction would otherwise revert.
 | 
				
			||||||
    /// @param order Order struct containing order specifications.
 | 
					    /// @param order Order struct containing order specifications.
 | 
				
			||||||
@@ -72,7 +76,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        refundFinalBalance
 | 
				
			||||||
        returns (LibFillResults.FillResults memory fillResults)
 | 
					        returns (LibFillResults.FillResults memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // ABI encode calldata for `fillOrder`
 | 
					        // ABI encode calldata for `fillOrder`
 | 
				
			||||||
@@ -85,7 +89,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        (bool didSucceed, bytes memory returnData) = address(this).delegatecall(fillOrderCalldata);
 | 
					        (bool didSucceed, bytes memory returnData) = address(this).delegatecall(fillOrderCalldata);
 | 
				
			||||||
        if (didSucceed) {
 | 
					        if (didSucceed) {
 | 
				
			||||||
            assert(returnData.length == 128);
 | 
					            assert(returnData.length == 160);
 | 
				
			||||||
            fillResults = abi.decode(returnData, (LibFillResults.FillResults));
 | 
					            fillResults = abi.decode(returnData, (LibFillResults.FillResults));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // fillResults values will be 0 by default if call was unsuccessful
 | 
					        // fillResults values will be 0 by default if call was unsuccessful
 | 
				
			||||||
@@ -105,7 +109,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        disableRefundUntilEnd
 | 
				
			||||||
        returns (LibFillResults.FillResults[] memory fillResults)
 | 
					        returns (LibFillResults.FillResults[] memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint256 ordersLength = orders.length;
 | 
					        uint256 ordersLength = orders.length;
 | 
				
			||||||
@@ -133,7 +137,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        nonReentrant
 | 
					        nonReentrant
 | 
				
			||||||
        refund
 | 
					        disableRefundUntilEnd
 | 
				
			||||||
        returns (LibFillResults.FillResults[] memory fillResults)
 | 
					        returns (LibFillResults.FillResults[] memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint256 ordersLength = orders.length;
 | 
					        uint256 ordersLength = orders.length;
 | 
				
			||||||
@@ -160,7 +164,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        // disableRefundUntilEnd
 | 
				
			||||||
        returns (LibFillResults.FillResults[] memory fillResults)
 | 
					        returns (LibFillResults.FillResults[] memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        uint256 ordersLength = orders.length;
 | 
					        uint256 ordersLength = orders.length;
 | 
				
			||||||
@@ -187,7 +191,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        disableRefundUntilEnd
 | 
				
			||||||
        returns (LibFillResults.FillResults memory fillResults)
 | 
					        returns (LibFillResults.FillResults memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        bytes memory takerAssetData = orders[0].takerAssetData;
 | 
					        bytes memory takerAssetData = orders[0].takerAssetData;
 | 
				
			||||||
@@ -233,7 +237,7 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
    )
 | 
					    )
 | 
				
			||||||
        public
 | 
					        public
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
        refund
 | 
					        disableRefundUntilEnd
 | 
				
			||||||
        returns (LibFillResults.FillResults memory fillResults)
 | 
					        returns (LibFillResults.FillResults memory fillResults)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        bytes memory makerAssetData = orders[0].makerAssetData;
 | 
					        bytes memory makerAssetData = orders[0].makerAssetData;
 | 
				
			||||||
@@ -333,22 +337,6 @@ contract MixinWrapperFunctions is
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Fetches information for all passed in orders.
 | 
					 | 
				
			||||||
    /// @param orders Array of order specifications.
 | 
					 | 
				
			||||||
    /// @return Array of OrderInfo instances that correspond to each order.
 | 
					 | 
				
			||||||
    function getOrdersInfo(LibOrder.Order[] memory orders)
 | 
					 | 
				
			||||||
        public
 | 
					 | 
				
			||||||
        view
 | 
					 | 
				
			||||||
        returns (LibOrder.OrderInfo[] memory)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        uint256 ordersLength = orders.length;
 | 
					 | 
				
			||||||
        LibOrder.OrderInfo[] memory ordersInfo = new LibOrder.OrderInfo[](ordersLength);
 | 
					 | 
				
			||||||
        for (uint256 i = 0; i != ordersLength; i++) {
 | 
					 | 
				
			||||||
            ordersInfo[i] = getOrderInfo(orders[i]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return ordersInfo;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
 | 
					    /// @dev Fills the input order. Reverts if exact takerAssetFillAmount not filled.
 | 
				
			||||||
    /// @param order Order struct containing order specifications.
 | 
					    /// @param order Order struct containing order specifications.
 | 
				
			||||||
    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
 | 
					    /// @param takerAssetFillAmount Desired amount of takerAsset to sell.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,9 @@ import "@0x/contracts-exchange-libs/contracts/src/LibFillResults.sol";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
contract IExchangeCore {
 | 
					contract IExchangeCore {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // keccak256("Fill(address,address,bytes32,address,address,uint256,uint256,uint256,uint256,uint256,bool,bytes,bytes,bytes,bytes)")
 | 
				
			||||||
 | 
					    bytes32 internal constant FILL_EVENT_TOPIC = 0x266de417a663e51231ccdf89b2794cea06fde5e2c433d76473160b32d31fd867;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Fill event is emitted whenever an order is filled.
 | 
					    // Fill event is emitted whenever an order is filled.
 | 
				
			||||||
    event Fill(
 | 
					    event Fill(
 | 
				
			||||||
        address indexed makerAddress,         // Address that created the order.
 | 
					        address indexed makerAddress,         // Address that created the order.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,6 +21,9 @@ pragma solidity ^0.5.9;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
contract IProtocolFees {
 | 
					contract IProtocolFees {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The proxy id of the weth asset proxy.
 | 
				
			||||||
 | 
					    bytes internal constant WETH_ASSET_DATA = hex"f47261b0";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Logs updates to the protocol fee multiplier.
 | 
					    // Logs updates to the protocol fee multiplier.
 | 
				
			||||||
    event UpdatedProtocolFeeMultiplier(uint256 oldProtocolFeeMultiplier, uint256 updatedProtocolFeeMultiplier);
 | 
					    event UpdatedProtocolFeeMultiplier(uint256 oldProtocolFeeMultiplier, uint256 updatedProtocolFeeMultiplier);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -154,12 +154,4 @@ contract IWrapperFunctions {
 | 
				
			|||||||
    /// @param orders Array of order specifications.
 | 
					    /// @param orders Array of order specifications.
 | 
				
			||||||
    function batchCancelOrders(LibOrder.Order[] memory orders)
 | 
					    function batchCancelOrders(LibOrder.Order[] memory orders)
 | 
				
			||||||
        public;
 | 
					        public;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Fetches information for all passed in orders
 | 
					 | 
				
			||||||
    /// @param orders Array of order specifications.
 | 
					 | 
				
			||||||
    /// @return Array of OrderInfo instances that correspond to each order.
 | 
					 | 
				
			||||||
    function getOrdersInfo(LibOrder.Order[] memory orders)
 | 
					 | 
				
			||||||
        public
 | 
					 | 
				
			||||||
        view
 | 
					 | 
				
			||||||
        returns (LibOrder.OrderInfo[] memory);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -92,6 +92,7 @@ contract TestWrapperFunctions is
 | 
				
			|||||||
        fillResults.takerAssetFilledAmount = order.takerAssetAmount;
 | 
					        fillResults.takerAssetFilledAmount = order.takerAssetAmount;
 | 
				
			||||||
        fillResults.makerFeePaid = order.makerFee;
 | 
					        fillResults.makerFeePaid = order.makerFee;
 | 
				
			||||||
        fillResults.takerFeePaid = order.takerFee;
 | 
					        fillResults.takerFeePaid = order.takerFee;
 | 
				
			||||||
 | 
					        fillResults.protocolFeePaid = protocolFeeMultiplier;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Overridden to only log arguments and revert with certain inputs.
 | 
					    /// @dev Overridden to only log arguments and revert with certain inputs.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,6 @@ import * as MixinExchangeCore from '../generated-artifacts/MixinExchangeCore.jso
 | 
				
			|||||||
import * as MixinMatchOrders from '../generated-artifacts/MixinMatchOrders.json';
 | 
					import * as MixinMatchOrders from '../generated-artifacts/MixinMatchOrders.json';
 | 
				
			||||||
import * as MixinProtocolFees from '../generated-artifacts/MixinProtocolFees.json';
 | 
					import * as MixinProtocolFees from '../generated-artifacts/MixinProtocolFees.json';
 | 
				
			||||||
import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
 | 
					import * as MixinSignatureValidator from '../generated-artifacts/MixinSignatureValidator.json';
 | 
				
			||||||
import * as MixinStakingManager from '../generated-artifacts/MixinStakingManager.json';
 | 
					 | 
				
			||||||
import * as MixinTransactions from '../generated-artifacts/MixinTransactions.json';
 | 
					import * as MixinTransactions from '../generated-artifacts/MixinTransactions.json';
 | 
				
			||||||
import * as MixinTransferSimulator from '../generated-artifacts/MixinTransferSimulator.json';
 | 
					import * as MixinTransferSimulator from '../generated-artifacts/MixinTransferSimulator.json';
 | 
				
			||||||
import * as MixinWrapperFunctions from '../generated-artifacts/MixinWrapperFunctions.json';
 | 
					import * as MixinWrapperFunctions from '../generated-artifacts/MixinWrapperFunctions.json';
 | 
				
			||||||
@@ -49,7 +48,6 @@ export const artifacts = {
 | 
				
			|||||||
    MixinMatchOrders: MixinMatchOrders as ContractArtifact,
 | 
					    MixinMatchOrders: MixinMatchOrders as ContractArtifact,
 | 
				
			||||||
    MixinProtocolFees: MixinProtocolFees as ContractArtifact,
 | 
					    MixinProtocolFees: MixinProtocolFees as ContractArtifact,
 | 
				
			||||||
    MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
 | 
					    MixinSignatureValidator: MixinSignatureValidator as ContractArtifact,
 | 
				
			||||||
    MixinStakingManager: MixinStakingManager as ContractArtifact,
 | 
					 | 
				
			||||||
    MixinTransactions: MixinTransactions as ContractArtifact,
 | 
					    MixinTransactions: MixinTransactions as ContractArtifact,
 | 
				
			||||||
    MixinTransferSimulator: MixinTransferSimulator as ContractArtifact,
 | 
					    MixinTransferSimulator: MixinTransferSimulator as ContractArtifact,
 | 
				
			||||||
    MixinWrapperFunctions: MixinWrapperFunctions as ContractArtifact,
 | 
					    MixinWrapperFunctions: MixinWrapperFunctions as ContractArtifact,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,6 @@ export * from '../generated-wrappers/mixin_exchange_core';
 | 
				
			|||||||
export * from '../generated-wrappers/mixin_match_orders';
 | 
					export * from '../generated-wrappers/mixin_match_orders';
 | 
				
			||||||
export * from '../generated-wrappers/mixin_protocol_fees';
 | 
					export * from '../generated-wrappers/mixin_protocol_fees';
 | 
				
			||||||
export * from '../generated-wrappers/mixin_signature_validator';
 | 
					export * from '../generated-wrappers/mixin_signature_validator';
 | 
				
			||||||
export * from '../generated-wrappers/mixin_staking_manager';
 | 
					 | 
				
			||||||
export * from '../generated-wrappers/mixin_transactions';
 | 
					export * from '../generated-wrappers/mixin_transactions';
 | 
				
			||||||
export * from '../generated-wrappers/mixin_transfer_simulator';
 | 
					export * from '../generated-wrappers/mixin_transfer_simulator';
 | 
				
			||||||
export * from '../generated-wrappers/mixin_wrapper_functions';
 | 
					export * from '../generated-wrappers/mixin_wrapper_functions';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ import {
 | 
				
			|||||||
    Web3ProviderEngine,
 | 
					    Web3ProviderEngine,
 | 
				
			||||||
} from '@0x/contracts-test-utils';
 | 
					} from '@0x/contracts-test-utils';
 | 
				
			||||||
import { orderHashUtils } from '@0x/order-utils';
 | 
					import { orderHashUtils } from '@0x/order-utils';
 | 
				
			||||||
import { AssetProxyId, FillResults, SignedOrder } from '@0x/types';
 | 
					import { FillResults, SignedOrder } from '@0x/types';
 | 
				
			||||||
import { BigNumber } from '@0x/utils';
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
					import { Web3Wrapper } from '@0x/web3-wrapper';
 | 
				
			||||||
import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
 | 
					import { TransactionReceiptWithDecodedLogs, ZeroExProvider } from 'ethereum-types';
 | 
				
			||||||
@@ -33,6 +33,8 @@ export class FillOrderWrapper {
 | 
				
			|||||||
    private readonly _blockchainBalanceStore: BlockchainBalanceStore;
 | 
					    private readonly _blockchainBalanceStore: BlockchainBalanceStore;
 | 
				
			||||||
    private readonly _web3Wrapper: Web3Wrapper;
 | 
					    private readonly _web3Wrapper: Web3Wrapper;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					    //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Simulates matching two orders by transferring amounts defined in
 | 
					     * Simulates matching two orders by transferring amounts defined in
 | 
				
			||||||
     * `transferAmounts` and returns the results.
 | 
					     * `transferAmounts` and returns the results.
 | 
				
			||||||
@@ -47,23 +49,18 @@ export class FillOrderWrapper {
 | 
				
			|||||||
        takerAddress: string,
 | 
					        takerAddress: string,
 | 
				
			||||||
        opts: { takerAssetFillAmount?: BigNumber } = {},
 | 
					        opts: { takerAssetFillAmount?: BigNumber } = {},
 | 
				
			||||||
        initBalanceStore: BalanceStore,
 | 
					        initBalanceStore: BalanceStore,
 | 
				
			||||||
        stakingOpts: {
 | 
					        // stakingOpts: {
 | 
				
			||||||
            gasPrice: BigNumber;
 | 
					        //     gasPrice: BigNumber;
 | 
				
			||||||
            messageValue: BigNumber;
 | 
					        //     messageValue: BigNumber;
 | 
				
			||||||
            protocolFeeMultiplier: BigNumber;
 | 
					        //     protocolFeeMultiplier: BigNumber;
 | 
				
			||||||
            stakingAddress: string;
 | 
					        //     stakingAddress: string;
 | 
				
			||||||
            wethAddress: string;
 | 
					        //     wethAddress: string;
 | 
				
			||||||
        },
 | 
					        // },
 | 
				
			||||||
    ): [FillResults, FillEventArgs, BalanceStore] {
 | 
					    ): [FillResults, FillEventArgs, BalanceStore] {
 | 
				
			||||||
        const balanceStore = LocalBalanceStore.create(initBalanceStore);
 | 
					        const balanceStore = LocalBalanceStore.create(initBalanceStore);
 | 
				
			||||||
        const takerAssetFillAmount =
 | 
					        const takerAssetFillAmount =
 | 
				
			||||||
            opts.takerAssetFillAmount !== undefined ? opts.takerAssetFillAmount : signedOrder.takerAssetAmount;
 | 
					            opts.takerAssetFillAmount !== undefined ? opts.takerAssetFillAmount : signedOrder.takerAssetAmount;
 | 
				
			||||||
        const fillResults = LibReferenceFunctions.calculateFillResults(
 | 
					        const fillResults = LibReferenceFunctions.calculateFillResults(signedOrder, takerAssetFillAmount);
 | 
				
			||||||
            signedOrder,
 | 
					 | 
				
			||||||
            takerAssetFillAmount,
 | 
					 | 
				
			||||||
            stakingOpts.protocolFeeMultiplier,
 | 
					 | 
				
			||||||
            stakingOpts.gasPrice,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        const fillEvent = FillOrderWrapper.simulateFillEvent(signedOrder, takerAddress, fillResults);
 | 
					        const fillEvent = FillOrderWrapper.simulateFillEvent(signedOrder, takerAddress, fillResults);
 | 
				
			||||||
        // Taker -> Maker
 | 
					        // Taker -> Maker
 | 
				
			||||||
        balanceStore.transferAsset(
 | 
					        balanceStore.transferAsset(
 | 
				
			||||||
@@ -93,18 +90,20 @@ export class FillOrderWrapper {
 | 
				
			|||||||
            fillResults.makerFeePaid,
 | 
					            fillResults.makerFeePaid,
 | 
				
			||||||
            signedOrder.makerFeeAssetData,
 | 
					            signedOrder.makerFeeAssetData,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        if (stakingOpts.messageValue.isGreaterThanOrEqualTo(fillResults.protocolFeePaid)) {
 | 
					        // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
            // Pay the protocol fee in ETH.
 | 
					        //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
            balanceStore.transferAsset(takerAddress, stakingOpts.stakingAddress, fillResults.protocolFeePaid, '');
 | 
					        // if (stakingOpts.messageValue.isGreaterThanOrEqualTo(fillResults.protocolFeePaid)) {
 | 
				
			||||||
        } else {
 | 
					        //     // Pay the protocol fee in ETH.
 | 
				
			||||||
            // Pay the protocol fee in WETH.
 | 
					        //     balanceStore.transferAsset(takerAddress, stakingOpts.stakingAddress, fillResults.protocolFeePaid, '');
 | 
				
			||||||
            balanceStore.transferAsset(
 | 
					        // } else {
 | 
				
			||||||
                takerAddress,
 | 
					        //     // Pay the protocol fee in WETH.
 | 
				
			||||||
                stakingOpts.stakingAddress,
 | 
					        //     balanceStore.transferAsset(
 | 
				
			||||||
                fillResults.protocolFeePaid,
 | 
					        //         takerAddress,
 | 
				
			||||||
                AssetProxyId.ERC20,
 | 
					        //         stakingOpts.stakingAddress,
 | 
				
			||||||
            );
 | 
					        //         fillResults.protocolFeePaid,
 | 
				
			||||||
        }
 | 
					        //         AssetProxyId.ERC20,
 | 
				
			||||||
 | 
					        //     );
 | 
				
			||||||
 | 
					        // }
 | 
				
			||||||
        return [fillResults, fillEvent, balanceStore];
 | 
					        return [fillResults, fillEvent, balanceStore];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -168,6 +167,8 @@ export class FillOrderWrapper {
 | 
				
			|||||||
        return this._blockchainBalanceStore;
 | 
					        return this._blockchainBalanceStore;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					    //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Fills an order and asserts the effects. This includes
 | 
					     * Fills an order and asserts the effects. This includes
 | 
				
			||||||
     * 1. The order info (via `getOrderInfo`)
 | 
					     * 1. The order info (via `getOrderInfo`)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -589,11 +589,11 @@ blockchainTests.resets('Exchange core', () => {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('should cancel only orders with a orderEpoch less than existing orderEpoch', async () => {
 | 
					        it('should cancel only orders with a orderEpoch less than existing orderEpoch', async () => {
 | 
				
			||||||
            // Cancel all transactions with a orderEpoch less than 1
 | 
					            // Cancel all transactions with a orderEpoch less than 2
 | 
				
			||||||
            const orderEpoch = new BigNumber(1);
 | 
					            const orderEpoch = new BigNumber(1);
 | 
				
			||||||
            await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
 | 
					            await exchangeWrapper.cancelOrdersUpToAsync(orderEpoch, makerAddress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Create 3 orders with orderEpoch values: 0,1,2,3
 | 
					            // Create 4 orders with orderEpoch values: 0,1,2,3
 | 
				
			||||||
            // Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed
 | 
					            // Since we cancelled with orderEpoch=1, orders with orderEpoch<=1 will not be processed
 | 
				
			||||||
            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
					            erc20Balances = await erc20Wrapper.getBalancesAsync();
 | 
				
			||||||
            const signedOrders = [
 | 
					            const signedOrders = [
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -164,26 +164,22 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
            return _.assign({}, ORDER_DEFAULTS, details);
 | 
					            return _.assign({}, ORDER_DEFAULTS, details);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // FIXME - This test definitely needs to be updated
 | 
				
			||||||
        async function testUpdateFilledStateAsync(
 | 
					        async function testUpdateFilledStateAsync(
 | 
				
			||||||
            order: OrderWithoutDomain,
 | 
					            order: OrderWithoutDomain,
 | 
				
			||||||
            orderTakerAssetFilledAmount: BigNumber,
 | 
					            orderTakerAssetFilledAmount: BigNumber,
 | 
				
			||||||
            takerAddress: string,
 | 
					            takerAddress: string,
 | 
				
			||||||
            takerAssetFillAmount: BigNumber,
 | 
					            takerAssetFillAmount: BigNumber,
 | 
				
			||||||
            protocolFeeMultiplier: BigNumber,
 | 
					            // protocolFeeMultiplier: BigNumber,
 | 
				
			||||||
            gasPrice: BigNumber,
 | 
					            // gasPrice: BigNumber,
 | 
				
			||||||
            isProtocolFeePaidInEth: boolean,
 | 
					            // isProtocolFeePaidInEth: boolean,
 | 
				
			||||||
        ): Promise<void> {
 | 
					        ): Promise<void> {
 | 
				
			||||||
            const orderHash = randomHash();
 | 
					            const orderHash = randomHash();
 | 
				
			||||||
            const fillResults = LibReferenceFunctions.calculateFillResults(
 | 
					            const fillResults = LibReferenceFunctions.calculateFillResults(order, takerAssetFillAmount);
 | 
				
			||||||
                order,
 | 
					 | 
				
			||||||
                takerAssetFillAmount,
 | 
					 | 
				
			||||||
                protocolFeeMultiplier,
 | 
					 | 
				
			||||||
                gasPrice,
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
            const expectedFilledState = orderTakerAssetFilledAmount.plus(takerAssetFillAmount);
 | 
					            const expectedFilledState = orderTakerAssetFilledAmount.plus(takerAssetFillAmount);
 | 
				
			||||||
            const opts = isProtocolFeePaidInEth
 | 
					            // const opts = isProtocolFeePaidInEth
 | 
				
			||||||
                ? { value: fillResults.protocolFeePaid }
 | 
					            //    ? { value: fillResults.protocolFeePaid }
 | 
				
			||||||
                : { value: constants.ZERO_AMOUNT };
 | 
					            //    : { value: constants.ZERO_AMOUNT };
 | 
				
			||||||
            // CAll `testUpdateFilledState()`, which will set the `filled`
 | 
					            // CAll `testUpdateFilledState()`, which will set the `filled`
 | 
				
			||||||
            // state for this order to `orderTakerAssetFilledAmount` before
 | 
					            // state for this order to `orderTakerAssetFilledAmount` before
 | 
				
			||||||
            // calling `_updateFilledState()`.
 | 
					            // calling `_updateFilledState()`.
 | 
				
			||||||
@@ -194,7 +190,7 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                    orderHash,
 | 
					                    orderHash,
 | 
				
			||||||
                    orderTakerAssetFilledAmount,
 | 
					                    orderTakerAssetFilledAmount,
 | 
				
			||||||
                    fillResults,
 | 
					                    fillResults,
 | 
				
			||||||
                    opts,
 | 
					                    // opts, // FIXME
 | 
				
			||||||
                ),
 | 
					                ),
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            // Grab the new `filled` state for this order.
 | 
					            // Grab the new `filled` state for this order.
 | 
				
			||||||
@@ -214,8 +210,8 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
            expect(fillEvent.args.takerAssetFilledAmount).to.bignumber.eq(fillResults.takerAssetFilledAmount);
 | 
					            expect(fillEvent.args.takerAssetFilledAmount).to.bignumber.eq(fillResults.takerAssetFilledAmount);
 | 
				
			||||||
            expect(fillEvent.args.makerFeePaid).to.bignumber.eq(fillResults.makerFeePaid);
 | 
					            expect(fillEvent.args.makerFeePaid).to.bignumber.eq(fillResults.makerFeePaid);
 | 
				
			||||||
            expect(fillEvent.args.takerFeePaid).to.bignumber.eq(fillResults.takerFeePaid);
 | 
					            expect(fillEvent.args.takerFeePaid).to.bignumber.eq(fillResults.takerFeePaid);
 | 
				
			||||||
            expect(fillEvent.args.protocolFeePaid).to.bignumber.eq(fillResults.protocolFeePaid);
 | 
					            // expect(fillEvent.args.protocolFeePaid).to.bignumber.eq(fillResults.protocolFeePaid);
 | 
				
			||||||
            expect(fillEvent.args.isProtocolFeePaidInEth).to.eq(isProtocolFeePaidInEth);
 | 
					            // expect(fillEvent.args.isProtocolFeePaidInEth).to.eq(isProtocolFeePaidInEth);
 | 
				
			||||||
            expect(fillEvent.args.makerAssetData).to.eq(order.makerAssetData);
 | 
					            expect(fillEvent.args.makerAssetData).to.eq(order.makerAssetData);
 | 
				
			||||||
            expect(fillEvent.args.takerAssetData).to.eq(order.takerAssetData);
 | 
					            expect(fillEvent.args.takerAssetData).to.eq(order.takerAssetData);
 | 
				
			||||||
            expect(fillEvent.args.makerFeeAssetData).to.eq(order.makerFeeAssetData);
 | 
					            expect(fillEvent.args.makerFeeAssetData).to.eq(order.makerFeeAssetData);
 | 
				
			||||||
@@ -229,9 +225,6 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                order.takerAssetAmount.times(0.1),
 | 
					                order.takerAssetAmount.times(0.1),
 | 
				
			||||||
                randomAddress(),
 | 
					                randomAddress(),
 | 
				
			||||||
                order.takerAssetAmount.times(0.25),
 | 
					                order.takerAssetAmount.times(0.25),
 | 
				
			||||||
                new BigNumber(150000),
 | 
					 | 
				
			||||||
                new BigNumber(100000),
 | 
					 | 
				
			||||||
                true,
 | 
					 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -242,9 +235,6 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                order.takerAssetAmount.times(0.1),
 | 
					                order.takerAssetAmount.times(0.1),
 | 
				
			||||||
                randomAddress(),
 | 
					                randomAddress(),
 | 
				
			||||||
                order.takerAssetAmount.times(0.25),
 | 
					                order.takerAssetAmount.times(0.25),
 | 
				
			||||||
                new BigNumber(100000),
 | 
					 | 
				
			||||||
                new BigNumber(150000),
 | 
					 | 
				
			||||||
                true,
 | 
					 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -252,11 +242,13 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
            const order = makeOrder();
 | 
					            const order = makeOrder();
 | 
				
			||||||
            const orderTakerAssetFilledAmount = constants.MAX_UINT256.dividedToIntegerBy(2);
 | 
					            const orderTakerAssetFilledAmount = constants.MAX_UINT256.dividedToIntegerBy(2);
 | 
				
			||||||
            const takerAssetFillAmount = constants.MAX_UINT256.dividedToIntegerBy(2).plus(2);
 | 
					            const takerAssetFillAmount = constants.MAX_UINT256.dividedToIntegerBy(2).plus(2);
 | 
				
			||||||
 | 
					            // FIXME
 | 
				
			||||||
            const fillResults = {
 | 
					            const fillResults = {
 | 
				
			||||||
                makerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
					                makerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
                takerAssetFilledAmount: takerAssetFillAmount,
 | 
					                takerAssetFilledAmount: takerAssetFillAmount,
 | 
				
			||||||
                makerFeePaid: constants.ZERO_AMOUNT,
 | 
					                makerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
                takerFeePaid: constants.ZERO_AMOUNT,
 | 
					                takerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					                protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            const expectedError = new SafeMathRevertErrors.Uint256BinOpError(
 | 
					            const expectedError = new SafeMathRevertErrors.Uint256BinOpError(
 | 
				
			||||||
                SafeMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
 | 
					                SafeMathRevertErrors.BinOpErrorCodes.AdditionOverflow,
 | 
				
			||||||
@@ -297,11 +289,13 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
            const order = DEFAULT_ORDER;
 | 
					            const order = DEFAULT_ORDER;
 | 
				
			||||||
            const orderHash = randomHash();
 | 
					            const orderHash = randomHash();
 | 
				
			||||||
            const takerAddress = randomAddress();
 | 
					            const takerAddress = randomAddress();
 | 
				
			||||||
 | 
					            // FIXME
 | 
				
			||||||
            const fillResults = {
 | 
					            const fillResults = {
 | 
				
			||||||
                makerAssetFilledAmount: ONE_ETHER.times(2),
 | 
					                makerAssetFilledAmount: ONE_ETHER.times(2),
 | 
				
			||||||
                takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
					                takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
				
			||||||
                makerFeePaid: ONE_ETHER.times(0.01),
 | 
					                makerFeePaid: ONE_ETHER.times(0.01),
 | 
				
			||||||
                takerFeePaid: ONE_ETHER.times(0.025),
 | 
					                takerFeePaid: ONE_ETHER.times(0.025),
 | 
				
			||||||
 | 
					                protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
            const receipt = await logDecoder.getTxWithDecodedLogsAsync(
 | 
					            const receipt = await logDecoder.getTxWithDecodedLogsAsync(
 | 
				
			||||||
                await testExchange.settleOrder.sendTransactionAsync(orderHash, order, takerAddress, fillResults),
 | 
					                await testExchange.settleOrder.sendTransactionAsync(orderHash, order, takerAddress, fillResults),
 | 
				
			||||||
@@ -371,12 +365,14 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
				
			||||||
                    takerFeePaid: constants.MAX_UINT256,
 | 
					                    takerFeePaid: constants.MAX_UINT256,
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                right: {
 | 
					                right: {
 | 
				
			||||||
                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
				
			||||||
                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
					                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
				
			||||||
                    takerFeePaid: constants.MAX_UINT256_ROOT,
 | 
					                    takerFeePaid: constants.MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                profitInLeftMakerAsset: ONE_ETHER,
 | 
					                profitInLeftMakerAsset: ONE_ETHER,
 | 
				
			||||||
                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
					                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
				
			||||||
@@ -418,12 +414,14 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
				
			||||||
                    takerFeePaid: constants.MAX_UINT256,
 | 
					                    takerFeePaid: constants.MAX_UINT256,
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                right: {
 | 
					                right: {
 | 
				
			||||||
                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
				
			||||||
                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
					                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
				
			||||||
                    takerFeePaid: constants.MAX_UINT256_ROOT,
 | 
					                    takerFeePaid: constants.MAX_UINT256_ROOT,
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                profitInLeftMakerAsset: ONE_ETHER,
 | 
					                profitInLeftMakerAsset: ONE_ETHER,
 | 
				
			||||||
                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
					                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
				
			||||||
@@ -454,12 +452,14 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
				
			||||||
                    takerFeePaid: ONE_ETHER.times(0.025),
 | 
					                    takerFeePaid: ONE_ETHER.times(0.025),
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                right: {
 | 
					                right: {
 | 
				
			||||||
                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
				
			||||||
                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
					                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
				
			||||||
                    takerFeePaid: ONE_ETHER.times(0.05),
 | 
					                    takerFeePaid: ONE_ETHER.times(0.05),
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                profitInLeftMakerAsset: ONE_ETHER,
 | 
					                profitInLeftMakerAsset: ONE_ETHER,
 | 
				
			||||||
                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
					                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
				
			||||||
@@ -550,12 +550,14 @@ blockchainTests('Exchange core internal functions', env => {
 | 
				
			|||||||
                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(10),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.01),
 | 
				
			||||||
                    takerFeePaid: ONE_ETHER.times(0.025),
 | 
					                    takerFeePaid: ONE_ETHER.times(0.025),
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                right: {
 | 
					                right: {
 | 
				
			||||||
                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
					                    takerAssetFilledAmount: ONE_ETHER.times(20),
 | 
				
			||||||
                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
					                    makerAssetFilledAmount: ONE_ETHER.times(4),
 | 
				
			||||||
                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
					                    makerFeePaid: ONE_ETHER.times(0.02),
 | 
				
			||||||
                    takerFeePaid: ONE_ETHER.times(0.05),
 | 
					                    takerFeePaid: ONE_ETHER.times(0.05),
 | 
				
			||||||
 | 
					                    protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                profitInLeftMakerAsset: ONE_ETHER,
 | 
					                profitInLeftMakerAsset: ONE_ETHER,
 | 
				
			||||||
                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
					                profitInRightMakerAsset: ONE_ETHER.times(2),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,8 +5,6 @@ import { OrderWithoutDomain as Order } from '@0x/types';
 | 
				
			|||||||
import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
 | 
					import { BigNumber, SafeMathRevertErrors } from '@0x/utils';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { calculateFillResults } from '../src/reference_functions';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
describe('Reference functions', () => {
 | 
					describe('Reference functions', () => {
 | 
				
			||||||
    const ONE_ETHER = constants.ONE_ETHER;
 | 
					    const ONE_ETHER = constants.ONE_ETHER;
 | 
				
			||||||
    const EMPTY_ORDER: Order = {
 | 
					    const EMPTY_ORDER: Order = {
 | 
				
			||||||
@@ -44,7 +42,9 @@ describe('Reference functions', () => {
 | 
				
			|||||||
                takerAssetFilledAmount,
 | 
					                takerAssetFilledAmount,
 | 
				
			||||||
                order.makerAssetAmount,
 | 
					                order.makerAssetAmount,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(
 | 
				
			||||||
 | 
					                expectedError.message,
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if computing `fillResults.makerFeePaid` overflows', () => {
 | 
					        it('reverts if computing `fillResults.makerFeePaid` overflows', () => {
 | 
				
			||||||
@@ -65,7 +65,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
                makerAssetFilledAmount,
 | 
					                makerAssetFilledAmount,
 | 
				
			||||||
                order.makerFee,
 | 
					                order.makerFee,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if computing `fillResults.takerFeePaid` overflows', () => {
 | 
					        it('reverts if computing `fillResults.takerFeePaid` overflows', () => {
 | 
				
			||||||
@@ -81,7 +81,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
                takerAssetFilledAmount,
 | 
					                takerAssetFilledAmount,
 | 
				
			||||||
                order.takerFee,
 | 
					                order.takerFee,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if `order.makerAssetAmount` is 0', () => {
 | 
					        it('reverts if `order.makerAssetAmount` is 0', () => {
 | 
				
			||||||
@@ -91,7 +91,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
            const takerAssetFilledAmount = ONE_ETHER;
 | 
					            const takerAssetFilledAmount = ONE_ETHER;
 | 
				
			||||||
            const expectedError = new LibMathRevertErrors.DivisionByZeroError();
 | 
					            const expectedError = new LibMathRevertErrors.DivisionByZeroError();
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if `order.takerAssetAmount` is 0', () => {
 | 
					        it('reverts if `order.takerAssetAmount` is 0', () => {
 | 
				
			||||||
@@ -101,7 +101,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
            const takerAssetFilledAmount = ONE_ETHER;
 | 
					            const takerAssetFilledAmount = ONE_ETHER;
 | 
				
			||||||
            const expectedError = new LibMathRevertErrors.DivisionByZeroError();
 | 
					            const expectedError = new LibMathRevertErrors.DivisionByZeroError();
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if there is a rounding error computing `makerAsssetFilledAmount`', () => {
 | 
					        it('reverts if there is a rounding error computing `makerAsssetFilledAmount`', () => {
 | 
				
			||||||
@@ -115,7 +115,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
                order.takerAssetAmount,
 | 
					                order.takerAssetAmount,
 | 
				
			||||||
                order.makerAssetAmount,
 | 
					                order.makerAssetAmount,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if there is a rounding error computing `makerFeePaid`', () => {
 | 
					        it('reverts if there is a rounding error computing `makerFeePaid`', () => {
 | 
				
			||||||
@@ -135,7 +135,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
                order.makerAssetAmount,
 | 
					                order.makerAssetAmount,
 | 
				
			||||||
                order.makerFee,
 | 
					                order.makerFee,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('reverts if there is a rounding error computing `takerFeePaid`', () => {
 | 
					        it('reverts if there is a rounding error computing `takerFeePaid`', () => {
 | 
				
			||||||
@@ -155,7 +155,7 @@ describe('Reference functions', () => {
 | 
				
			|||||||
                order.makerAssetAmount,
 | 
					                order.makerAssetAmount,
 | 
				
			||||||
                order.takerFee,
 | 
					                order.takerFee,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return expect(() => calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
					            return expect(() => LibReferenceFunctions.calculateFillResults(order, takerAssetFilledAmount)).to.throw(expectedError.message);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,143 +0,0 @@
 | 
				
			|||||||
import { blockchainTests, constants, expect, LogDecoder } from '@0x/contracts-test-utils';
 | 
					 | 
				
			||||||
import { BigNumber, OwnableRevertErrors } from '@0x/utils';
 | 
					 | 
				
			||||||
import { LogWithDecodedArgs } from 'ethereum-types';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
    artifacts,
 | 
					 | 
				
			||||||
    ExchangeContract,
 | 
					 | 
				
			||||||
    ExchangeUpdatedProtocolFeeMultiplierEventArgs,
 | 
					 | 
				
			||||||
    ExchangeUpdatedStakingAddressEventArgs,
 | 
					 | 
				
			||||||
    ExchangeUpdatedWethAddressEventArgs,
 | 
					 | 
				
			||||||
} from '../src';
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
blockchainTests.resets('MixinStakingManager', env => {
 | 
					 | 
				
			||||||
    let accounts: string[];
 | 
					 | 
				
			||||||
    let exchange: ExchangeContract;
 | 
					 | 
				
			||||||
    let logDecoder: LogDecoder;
 | 
					 | 
				
			||||||
    let nonOwner: string;
 | 
					 | 
				
			||||||
    let owner: string;
 | 
					 | 
				
			||||||
    let staking: string;
 | 
					 | 
				
			||||||
    let weth: string;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // The protocolFeeMultiplier that will be used to test the update functions.
 | 
					 | 
				
			||||||
    const protocolFeeMultiplier = new BigNumber(15000);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    before(async () => {
 | 
					 | 
				
			||||||
        accounts = await env.web3Wrapper.getAvailableAddressesAsync();
 | 
					 | 
				
			||||||
        owner = accounts[0];
 | 
					 | 
				
			||||||
        nonOwner = accounts[1];
 | 
					 | 
				
			||||||
        staking = accounts[2];
 | 
					 | 
				
			||||||
        weth = accounts[3];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Update the from address of the txDefaults. This is the address that will become the owner.
 | 
					 | 
				
			||||||
        env.txDefaults.from = owner;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Deploy the exchange contract.
 | 
					 | 
				
			||||||
        exchange = await ExchangeContract.deployFrom0xArtifactAsync(
 | 
					 | 
				
			||||||
            artifacts.Exchange,
 | 
					 | 
				
			||||||
            env.provider,
 | 
					 | 
				
			||||||
            env.txDefaults,
 | 
					 | 
				
			||||||
            {},
 | 
					 | 
				
			||||||
            new BigNumber(1337),
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Configure the log decoder
 | 
					 | 
				
			||||||
        logDecoder = new LogDecoder(env.web3Wrapper, artifacts);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    blockchainTests.resets('updateProtocolFeeMultiplier', () => {
 | 
					 | 
				
			||||||
        it('should revert if msg.sender != owner', async () => {
 | 
					 | 
				
			||||||
            const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Ensure that the transaction reverts with the expected rich error.
 | 
					 | 
				
			||||||
            const tx = exchange.updateStakingAddress.sendTransactionAsync(staking, {
 | 
					 | 
				
			||||||
                from: nonOwner,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(expectedError);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('should succeed and emit an UpdatedProtocolFeeMultiplier event if msg.sender == owner', async () => {
 | 
					 | 
				
			||||||
            // Call the `updateProtocolFeeMultiplier()` function and get the receipt.
 | 
					 | 
				
			||||||
            const receipt = await logDecoder.getTxWithDecodedLogsAsync(
 | 
					 | 
				
			||||||
                await exchange.updateProtocolFeeMultiplier.sendTransactionAsync(protocolFeeMultiplier, {
 | 
					 | 
				
			||||||
                    from: owner,
 | 
					 | 
				
			||||||
                }),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Verify that the staking address was actually updated to the correct address.
 | 
					 | 
				
			||||||
            const updated = await exchange.protocolFeeMultiplier.callAsync();
 | 
					 | 
				
			||||||
            expect(updated).bignumber.to.be.eq(protocolFeeMultiplier);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Ensure that the correct `UpdatedStakingAddress` event was logged.
 | 
					 | 
				
			||||||
            // tslint:disable:no-unnecessary-type-assertion
 | 
					 | 
				
			||||||
            const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedProtocolFeeMultiplierEventArgs>;
 | 
					 | 
				
			||||||
            expect(updatedEvent.event).to.be.eq('UpdatedProtocolFeeMultiplier');
 | 
					 | 
				
			||||||
            expect(updatedEvent.args.oldProtocolFeeMultiplier).bignumber.to.be.eq(constants.ZERO_AMOUNT);
 | 
					 | 
				
			||||||
            expect(updatedEvent.args.updatedProtocolFeeMultiplier).bignumber.to.be.eq(protocolFeeMultiplier);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    blockchainTests.resets('updateStakingAddress', () => {
 | 
					 | 
				
			||||||
        it('should revert if msg.sender != owner', async () => {
 | 
					 | 
				
			||||||
            const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Ensure that the transaction reverts with the expected rich error.
 | 
					 | 
				
			||||||
            const tx = exchange.updateStakingAddress.sendTransactionAsync(staking, {
 | 
					 | 
				
			||||||
                from: nonOwner,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(expectedError);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('should succeed and emit an UpdatedStakingAddress event if msg.sender == owner', async () => {
 | 
					 | 
				
			||||||
            // Call the `updateStakingAddress()` function and get the receipt.
 | 
					 | 
				
			||||||
            const receipt = await logDecoder.getTxWithDecodedLogsAsync(
 | 
					 | 
				
			||||||
                await exchange.updateStakingAddress.sendTransactionAsync(staking, {
 | 
					 | 
				
			||||||
                    from: owner,
 | 
					 | 
				
			||||||
                }),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Verify that the staking address was actually updated to the correct address.
 | 
					 | 
				
			||||||
            const updated = await exchange.staking.callAsync();
 | 
					 | 
				
			||||||
            expect(updated).to.be.eq(staking);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Ensure that the correct `UpdatedStakingAddress` event was logged.
 | 
					 | 
				
			||||||
            // tslint:disable:no-unnecessary-type-assertion
 | 
					 | 
				
			||||||
            const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedStakingAddressEventArgs>;
 | 
					 | 
				
			||||||
            expect(updatedEvent.event).to.be.eq('UpdatedStakingAddress');
 | 
					 | 
				
			||||||
            expect(updatedEvent.args.oldStaking).to.be.eq(constants.NULL_ADDRESS);
 | 
					 | 
				
			||||||
            expect(updatedEvent.args.updatedStaking).to.be.eq(staking);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    blockchainTests.resets('updateWethAddress', () => {
 | 
					 | 
				
			||||||
        it('should revert if msg.sender != owner', async () => {
 | 
					 | 
				
			||||||
            const expectedError = new OwnableRevertErrors.OnlyOwnerError(nonOwner, owner);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Ensure that the transaction reverts with the expected rich error.
 | 
					 | 
				
			||||||
            const tx = exchange.updateWethAddress.sendTransactionAsync(weth, {
 | 
					 | 
				
			||||||
                from: nonOwner,
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            return expect(tx).to.revertWith(expectedError);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('should succeed and emit an UpdatedStakingAddress event if msg.sender == owner', async () => {
 | 
					 | 
				
			||||||
            // Call the `updateWethAddress()` function and get the receipt.
 | 
					 | 
				
			||||||
            const receipt = await logDecoder.getTxWithDecodedLogsAsync(
 | 
					 | 
				
			||||||
                await exchange.updateWethAddress.sendTransactionAsync(weth, {
 | 
					 | 
				
			||||||
                    from: owner,
 | 
					 | 
				
			||||||
                }),
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Verify that the staking address was actually updated to the correct address.
 | 
					 | 
				
			||||||
            const updated = await exchange.weth.callAsync();
 | 
					 | 
				
			||||||
            expect(updated).to.be.eq(weth);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            // Ensure that the correct `UpdatedStakingAddress` event was logged.
 | 
					 | 
				
			||||||
            // tslint:disable:no-unnecessary-type-assertion
 | 
					 | 
				
			||||||
            const updatedEvent = receipt.logs[0] as LogWithDecodedArgs<ExchangeUpdatedWethAddressEventArgs>;
 | 
					 | 
				
			||||||
            expect(updatedEvent.event).to.be.eq('UpdatedWethAddress');
 | 
					 | 
				
			||||||
            expect(updatedEvent.args.oldWeth).to.be.eq(constants.NULL_ADDRESS);
 | 
					 | 
				
			||||||
            expect(updatedEvent.args.updatedWeth).to.be.eq(weth);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
@@ -1037,13 +1037,14 @@ blockchainTests.resets('Exchange transactions', env => {
 | 
				
			|||||||
                    const cancelTransaction = await makerTransactionFactory.newSignedTransactionAsync({
 | 
					                    const cancelTransaction = await makerTransactionFactory.newSignedTransactionAsync({
 | 
				
			||||||
                        data: cancelData,
 | 
					                        data: cancelData,
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    await exchangeWrapperContract.cancelOrdersUpTo.awaitTransactionSuccessAsync(
 | 
					                    await exchangeWrapperContract.cancelOrdersUpTo.awaitTransactionSuccessAsync(
 | 
				
			||||||
                        targetOrderEpoch,
 | 
					                        targetOrderEpoch,
 | 
				
			||||||
                        cancelTransaction.salt,
 | 
					                        cancelTransaction.salt,
 | 
				
			||||||
                        cancelTransaction.expirationTimeSeconds,
 | 
					                        cancelTransaction.expirationTimeSeconds,
 | 
				
			||||||
                        cancelTransaction.signature,
 | 
					                        cancelTransaction.signature,
 | 
				
			||||||
 | 
					                        // { from: makerAddress },
 | 
				
			||||||
                        { from: makerAddress },
 | 
					                        { from: makerAddress },
 | 
				
			||||||
                        constants.AWAIT_TRANSACTION_MINED_MS,
 | 
					 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const takerAssetFillAmount = signedOrder.takerAssetAmount;
 | 
					                    const takerAssetFillAmount = signedOrder.takerAssetAmount;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,35 +43,35 @@ export class ExchangeWrapper {
 | 
				
			|||||||
    public async fillOrKillOrderAsync(
 | 
					    public async fillOrKillOrderAsync(
 | 
				
			||||||
        signedOrder: SignedOrder,
 | 
					        signedOrder: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmount?: BigNumber } = {},
 | 
					        opts: { takerAssetFillAmount?: BigNumber; gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
					        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
				
			||||||
        const txReceipt = await this._exchange.fillOrKillOrder.awaitTransactionSuccessAsync(
 | 
					        const txReceipt = await this._exchange.fillOrKillOrder.awaitTransactionSuccessAsync(
 | 
				
			||||||
            params.order,
 | 
					            params.order,
 | 
				
			||||||
            params.takerAssetFillAmount,
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
            params.signature,
 | 
					            params.signature,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return txReceipt;
 | 
					        return txReceipt;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async fillOrderNoThrowAsync(
 | 
					    public async fillOrderNoThrowAsync(
 | 
				
			||||||
        signedOrder: SignedOrder,
 | 
					        signedOrder: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmount?: BigNumber; gas?: number } = {},
 | 
					        opts: { takerAssetFillAmount?: BigNumber; gas?: number; gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
					        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
				
			||||||
        const txReceipt = await this._exchange.fillOrderNoThrow.awaitTransactionSuccessAsync(
 | 
					        const txReceipt = await this._exchange.fillOrderNoThrow.awaitTransactionSuccessAsync(
 | 
				
			||||||
            params.order,
 | 
					            params.order,
 | 
				
			||||||
            params.takerAssetFillAmount,
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
            params.signature,
 | 
					            params.signature,
 | 
				
			||||||
            { from, gas: opts.gas },
 | 
					            { from, gas: opts.gas, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return txReceipt;
 | 
					        return txReceipt;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async batchFillOrdersAsync(
 | 
					    public async batchFillOrdersAsync(
 | 
				
			||||||
        orders: SignedOrder[],
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmounts?: BigNumber[] } = {},
 | 
					        opts: { takerAssetFillAmounts?: BigNumber[]; gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.batchFillOrders.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchFillOrders.awaitTransactionSuccessAsync(
 | 
				
			||||||
            orders,
 | 
					            orders,
 | 
				
			||||||
@@ -79,13 +79,13 @@ export class ExchangeWrapper {
 | 
				
			|||||||
                ? orders.map(signedOrder => signedOrder.takerAssetAmount)
 | 
					                ? orders.map(signedOrder => signedOrder.takerAssetAmount)
 | 
				
			||||||
                : opts.takerAssetFillAmounts,
 | 
					                : opts.takerAssetFillAmounts,
 | 
				
			||||||
            orders.map(signedOrder => signedOrder.signature),
 | 
					            orders.map(signedOrder => signedOrder.signature),
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async batchFillOrKillOrdersAsync(
 | 
					    public async batchFillOrKillOrdersAsync(
 | 
				
			||||||
        orders: SignedOrder[],
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmounts?: BigNumber[] } = {},
 | 
					        opts: { takerAssetFillAmounts?: BigNumber[]; gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.batchFillOrKillOrders.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchFillOrKillOrders.awaitTransactionSuccessAsync(
 | 
				
			||||||
            orders,
 | 
					            orders,
 | 
				
			||||||
@@ -93,13 +93,13 @@ export class ExchangeWrapper {
 | 
				
			|||||||
                ? orders.map(signedOrder => signedOrder.takerAssetAmount)
 | 
					                ? orders.map(signedOrder => signedOrder.takerAssetAmount)
 | 
				
			||||||
                : opts.takerAssetFillAmounts,
 | 
					                : opts.takerAssetFillAmounts,
 | 
				
			||||||
            orders.map(signedOrder => signedOrder.signature),
 | 
					            orders.map(signedOrder => signedOrder.signature),
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async batchFillOrdersNoThrowAsync(
 | 
					    public async batchFillOrdersNoThrowAsync(
 | 
				
			||||||
        orders: SignedOrder[],
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmounts?: BigNumber[]; gas?: number } = {},
 | 
					        opts: { takerAssetFillAmounts?: BigNumber[]; gas?: number; gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.batchFillOrdersNoThrow.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchFillOrdersNoThrow.awaitTransactionSuccessAsync(
 | 
				
			||||||
            orders,
 | 
					            orders,
 | 
				
			||||||
@@ -107,25 +107,25 @@ export class ExchangeWrapper {
 | 
				
			|||||||
                ? orders.map(signedOrder => signedOrder.takerAssetAmount)
 | 
					                ? orders.map(signedOrder => signedOrder.takerAssetAmount)
 | 
				
			||||||
                : opts.takerAssetFillAmounts,
 | 
					                : opts.takerAssetFillAmounts,
 | 
				
			||||||
            orders.map(signedOrder => signedOrder.signature),
 | 
					            orders.map(signedOrder => signedOrder.signature),
 | 
				
			||||||
            { from, gas: opts.gas },
 | 
					            { from, gas: opts.gas, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async marketSellOrdersNoThrowAsync(
 | 
					    public async marketSellOrdersNoThrowAsync(
 | 
				
			||||||
        orders: SignedOrder[],
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmount: BigNumber; gas?: number },
 | 
					        opts: { takerAssetFillAmount: BigNumber; gas?: number; gasPrice?: BigNumber },
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.marketSellOrdersNoThrow.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.marketSellOrdersNoThrow.awaitTransactionSuccessAsync(
 | 
				
			||||||
            orders,
 | 
					            orders,
 | 
				
			||||||
            opts.takerAssetFillAmount,
 | 
					            opts.takerAssetFillAmount,
 | 
				
			||||||
            orders.map(signedOrder => signedOrder.signature),
 | 
					            orders.map(signedOrder => signedOrder.signature),
 | 
				
			||||||
            { from, gas: opts.gas },
 | 
					            { from, gas: opts.gas, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async marketBuyOrdersNoThrowAsync(
 | 
					    public async marketBuyOrdersNoThrowAsync(
 | 
				
			||||||
        orders: SignedOrder[],
 | 
					        orders: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { makerAssetFillAmount: BigNumber; gas?: number },
 | 
					        opts: { makerAssetFillAmount: BigNumber; gas?: number; gasPrice?: BigNumber },
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.marketBuyOrdersNoThrow.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.marketBuyOrdersNoThrow.awaitTransactionSuccessAsync(
 | 
				
			||||||
            orders,
 | 
					            orders,
 | 
				
			||||||
@@ -180,22 +180,23 @@ export class ExchangeWrapper {
 | 
				
			|||||||
    public async executeTransactionAsync(
 | 
					    public async executeTransactionAsync(
 | 
				
			||||||
        signedTransaction: SignedZeroExTransaction,
 | 
					        signedTransaction: SignedZeroExTransaction,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.executeTransaction.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.executeTransaction.awaitTransactionSuccessAsync(
 | 
				
			||||||
            signedTransaction,
 | 
					            signedTransaction,
 | 
				
			||||||
            signedTransaction.signature,
 | 
					            signedTransaction.signature,
 | 
				
			||||||
            {
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
                from,
 | 
					 | 
				
			||||||
            },
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async batchExecuteTransactionsAsync(
 | 
					    public async batchExecuteTransactionsAsync(
 | 
				
			||||||
        signedTransactions: SignedZeroExTransaction[],
 | 
					        signedTransactions: SignedZeroExTransaction[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const signatures = signedTransactions.map(signedTransaction => signedTransaction.signature);
 | 
					        const signatures = signedTransactions.map(signedTransaction => signedTransaction.signature);
 | 
				
			||||||
        return this._exchange.batchExecuteTransactions.awaitTransactionSuccessAsync(signedTransactions, signatures, {
 | 
					        return this._exchange.batchExecuteTransactions.awaitTransactionSuccessAsync(signedTransactions, signatures, {
 | 
				
			||||||
            from,
 | 
					            from,
 | 
				
			||||||
 | 
					            gasPrice: opts.gasPrice,
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
 | 
					    public async getTakerAssetFilledAmountAsync(orderHashHex: string): Promise<BigNumber> {
 | 
				
			||||||
@@ -214,14 +215,11 @@ export class ExchangeWrapper {
 | 
				
			|||||||
        const orderInfo = await this._exchange.getOrderInfo.callAsync(signedOrder);
 | 
					        const orderInfo = await this._exchange.getOrderInfo.callAsync(signedOrder);
 | 
				
			||||||
        return orderInfo;
 | 
					        return orderInfo;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async getOrdersInfoAsync(signedOrders: SignedOrder[]): Promise<OrderInfo[]> {
 | 
					 | 
				
			||||||
        const ordersInfo = (await this._exchange.getOrdersInfo.callAsync(signedOrders)) as OrderInfo[];
 | 
					 | 
				
			||||||
        return ordersInfo;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public async batchMatchOrdersAsync(
 | 
					    public async batchMatchOrdersAsync(
 | 
				
			||||||
        signedOrdersLeft: SignedOrder[],
 | 
					        signedOrdersLeft: SignedOrder[],
 | 
				
			||||||
        signedOrdersRight: SignedOrder[],
 | 
					        signedOrdersRight: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
					        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
				
			||||||
        return this._exchange.batchMatchOrders.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchMatchOrders.awaitTransactionSuccessAsync(
 | 
				
			||||||
@@ -229,25 +227,27 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.rightOrders,
 | 
					            params.rightOrders,
 | 
				
			||||||
            params.leftSignatures,
 | 
					            params.leftSignatures,
 | 
				
			||||||
            params.rightSignatures,
 | 
					            params.rightSignatures,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async batchMatchOrdersRawAsync(
 | 
					    public async batchMatchOrdersRawAsync(
 | 
				
			||||||
        params: BatchMatchOrder,
 | 
					        params: BatchMatchOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.batchMatchOrders.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchMatchOrders.awaitTransactionSuccessAsync(
 | 
				
			||||||
            params.leftOrders,
 | 
					            params.leftOrders,
 | 
				
			||||||
            params.rightOrders,
 | 
					            params.rightOrders,
 | 
				
			||||||
            params.leftSignatures,
 | 
					            params.leftSignatures,
 | 
				
			||||||
            params.rightSignatures,
 | 
					            params.rightSignatures,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async getBatchMatchOrdersResultsAsync(
 | 
					    public async getBatchMatchOrdersResultsAsync(
 | 
				
			||||||
        signedOrdersLeft: SignedOrder[],
 | 
					        signedOrdersLeft: SignedOrder[],
 | 
				
			||||||
        signedOrdersRight: SignedOrder[],
 | 
					        signedOrdersRight: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<BatchMatchedFillResults> {
 | 
					    ): Promise<BatchMatchedFillResults> {
 | 
				
			||||||
        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
					        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
				
			||||||
        const batchMatchedFillResults = await this._exchange.batchMatchOrders.callAsync(
 | 
					        const batchMatchedFillResults = await this._exchange.batchMatchOrders.callAsync(
 | 
				
			||||||
@@ -255,7 +255,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.rightOrders,
 | 
					            params.rightOrders,
 | 
				
			||||||
            params.leftSignatures,
 | 
					            params.leftSignatures,
 | 
				
			||||||
            params.rightSignatures,
 | 
					            params.rightSignatures,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return batchMatchedFillResults;
 | 
					        return batchMatchedFillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -263,6 +263,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
        signedOrdersLeft: SignedOrder[],
 | 
					        signedOrdersLeft: SignedOrder[],
 | 
				
			||||||
        signedOrdersRight: SignedOrder[],
 | 
					        signedOrdersRight: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
					        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
				
			||||||
        return this._exchange.batchMatchOrdersWithMaximalFill.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchMatchOrdersWithMaximalFill.awaitTransactionSuccessAsync(
 | 
				
			||||||
@@ -270,25 +271,27 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.rightOrders,
 | 
					            params.rightOrders,
 | 
				
			||||||
            params.leftSignatures,
 | 
					            params.leftSignatures,
 | 
				
			||||||
            params.rightSignatures,
 | 
					            params.rightSignatures,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async batchMatchOrdersWithMaximalFillRawAsync(
 | 
					    public async batchMatchOrdersWithMaximalFillRawAsync(
 | 
				
			||||||
        params: BatchMatchOrder,
 | 
					        params: BatchMatchOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        return this._exchange.batchMatchOrdersWithMaximalFill.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.batchMatchOrdersWithMaximalFill.awaitTransactionSuccessAsync(
 | 
				
			||||||
            params.leftOrders,
 | 
					            params.leftOrders,
 | 
				
			||||||
            params.rightOrders,
 | 
					            params.rightOrders,
 | 
				
			||||||
            params.leftSignatures,
 | 
					            params.leftSignatures,
 | 
				
			||||||
            params.rightSignatures,
 | 
					            params.rightSignatures,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async getBatchMatchOrdersWithMaximalFillResultsAsync(
 | 
					    public async getBatchMatchOrdersWithMaximalFillResultsAsync(
 | 
				
			||||||
        signedOrdersLeft: SignedOrder[],
 | 
					        signedOrdersLeft: SignedOrder[],
 | 
				
			||||||
        signedOrdersRight: SignedOrder[],
 | 
					        signedOrdersRight: SignedOrder[],
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<BatchMatchedFillResults> {
 | 
					    ): Promise<BatchMatchedFillResults> {
 | 
				
			||||||
        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
					        const params = orderUtils.createBatchMatchOrders(signedOrdersLeft, signedOrdersRight);
 | 
				
			||||||
        const batchMatchedFillResults = await this._exchange.batchMatchOrdersWithMaximalFill.callAsync(
 | 
					        const batchMatchedFillResults = await this._exchange.batchMatchOrdersWithMaximalFill.callAsync(
 | 
				
			||||||
@@ -296,7 +299,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.rightOrders,
 | 
					            params.rightOrders,
 | 
				
			||||||
            params.leftSignatures,
 | 
					            params.leftSignatures,
 | 
				
			||||||
            params.rightSignatures,
 | 
					            params.rightSignatures,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return batchMatchedFillResults;
 | 
					        return batchMatchedFillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -304,6 +307,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
        signedOrderLeft: SignedOrder,
 | 
					        signedOrderLeft: SignedOrder,
 | 
				
			||||||
        signedOrderRight: SignedOrder,
 | 
					        signedOrderRight: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
					        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
				
			||||||
        const txReceipt = await this._exchange.matchOrders.awaitTransactionSuccessAsync(
 | 
					        const txReceipt = await this._exchange.matchOrders.awaitTransactionSuccessAsync(
 | 
				
			||||||
@@ -311,7 +315,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.right,
 | 
					            params.right,
 | 
				
			||||||
            params.leftSignature,
 | 
					            params.leftSignature,
 | 
				
			||||||
            params.rightSignature,
 | 
					            params.rightSignature,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return txReceipt;
 | 
					        return txReceipt;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -319,6 +323,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
        signedOrderLeft: SignedOrder,
 | 
					        signedOrderLeft: SignedOrder,
 | 
				
			||||||
        signedOrderRight: SignedOrder,
 | 
					        signedOrderRight: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<MatchedFillResults> {
 | 
					    ): Promise<MatchedFillResults> {
 | 
				
			||||||
        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
					        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
				
			||||||
        const matchedFillResults = await this._exchange.matchOrders.callAsync(
 | 
					        const matchedFillResults = await this._exchange.matchOrders.callAsync(
 | 
				
			||||||
@@ -326,7 +331,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.right,
 | 
					            params.right,
 | 
				
			||||||
            params.leftSignature,
 | 
					            params.leftSignature,
 | 
				
			||||||
            params.rightSignature,
 | 
					            params.rightSignature,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return matchedFillResults;
 | 
					        return matchedFillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -334,6 +339,7 @@ export class ExchangeWrapper {
 | 
				
			|||||||
        signedOrderLeft: SignedOrder,
 | 
					        signedOrderLeft: SignedOrder,
 | 
				
			||||||
        signedOrderRight: SignedOrder,
 | 
					        signedOrderRight: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
					    ): Promise<TransactionReceiptWithDecodedLogs> {
 | 
				
			||||||
        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
					        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
				
			||||||
        return this._exchange.matchOrdersWithMaximalFill.awaitTransactionSuccessAsync(
 | 
					        return this._exchange.matchOrdersWithMaximalFill.awaitTransactionSuccessAsync(
 | 
				
			||||||
@@ -341,13 +347,14 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.right,
 | 
					            params.right,
 | 
				
			||||||
            params.leftSignature,
 | 
					            params.leftSignature,
 | 
				
			||||||
            params.rightSignature,
 | 
					            params.rightSignature,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async getMatchOrdersWithMaximalFillResultsAsync(
 | 
					    public async getMatchOrdersWithMaximalFillResultsAsync(
 | 
				
			||||||
        signedOrderLeft: SignedOrder,
 | 
					        signedOrderLeft: SignedOrder,
 | 
				
			||||||
        signedOrderRight: SignedOrder,
 | 
					        signedOrderRight: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
 | 
					        opts: { gasPrice?: BigNumber },
 | 
				
			||||||
    ): Promise<MatchedFillResults> {
 | 
					    ): Promise<MatchedFillResults> {
 | 
				
			||||||
        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
					        const params = orderUtils.createMatchOrders(signedOrderLeft, signedOrderRight);
 | 
				
			||||||
        const matchedFillResults = await this._exchange.matchOrdersWithMaximalFill.callAsync(
 | 
					        const matchedFillResults = await this._exchange.matchOrdersWithMaximalFill.callAsync(
 | 
				
			||||||
@@ -355,21 +362,21 @@ export class ExchangeWrapper {
 | 
				
			|||||||
            params.right,
 | 
					            params.right,
 | 
				
			||||||
            params.leftSignature,
 | 
					            params.leftSignature,
 | 
				
			||||||
            params.rightSignature,
 | 
					            params.rightSignature,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return matchedFillResults;
 | 
					        return matchedFillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public async getFillOrderResultsAsync(
 | 
					    public async getFillOrderResultsAsync(
 | 
				
			||||||
        signedOrder: SignedOrder,
 | 
					        signedOrder: SignedOrder,
 | 
				
			||||||
        from: string,
 | 
					        from: string,
 | 
				
			||||||
        opts: { takerAssetFillAmount?: BigNumber } = {},
 | 
					        opts: { takerAssetFillAmount?: BigNumber; gasPrice?: BigNumber } = {},
 | 
				
			||||||
    ): Promise<FillResults> {
 | 
					    ): Promise<FillResults> {
 | 
				
			||||||
        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
					        const params = orderUtils.createFill(signedOrder, opts.takerAssetFillAmount);
 | 
				
			||||||
        const fillResults = await this._exchange.fillOrder.callAsync(
 | 
					        const fillResults = await this._exchange.fillOrder.callAsync(
 | 
				
			||||||
            params.order,
 | 
					            params.order,
 | 
				
			||||||
            params.takerAssetFillAmount,
 | 
					            params.takerAssetFillAmount,
 | 
				
			||||||
            params.signature,
 | 
					            params.signature,
 | 
				
			||||||
            { from },
 | 
					            { from, gasPrice: opts.gasPrice },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return fillResults;
 | 
					        return fillResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import {
 | 
				
			|||||||
    ERC721Wrapper,
 | 
					    ERC721Wrapper,
 | 
				
			||||||
    MultiAssetProxyContract,
 | 
					    MultiAssetProxyContract,
 | 
				
			||||||
} from '@0x/contracts-asset-proxy';
 | 
					} from '@0x/contracts-asset-proxy';
 | 
				
			||||||
import { constants, expect, orderUtils, signingUtils } from '@0x/contracts-test-utils';
 | 
					import { constants, expect, LogDecoder, orderUtils, signingUtils } from '@0x/contracts-test-utils';
 | 
				
			||||||
import { BalanceAndProxyAllowanceLazyStore, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
 | 
					import { BalanceAndProxyAllowanceLazyStore, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
 | 
				
			||||||
import { FillResults, Order, SignatureType, SignedOrder } from '@0x/types';
 | 
					import { FillResults, Order, SignatureType, SignedOrder } from '@0x/types';
 | 
				
			||||||
import { BigNumber, errorUtils, providerUtils, RevertError, StringRevertError } from '@0x/utils';
 | 
					import { BigNumber, errorUtils, providerUtils, RevertError, StringRevertError } from '@0x/utils';
 | 
				
			||||||
@@ -40,6 +40,7 @@ const EMPTY_FILL_RESULTS = {
 | 
				
			|||||||
    makerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
					    makerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
    makerFeePaid: constants.ZERO_AMOUNT,
 | 
					    makerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
    takerFeePaid: constants.ZERO_AMOUNT,
 | 
					    takerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					    protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum TestOutlook {
 | 
					enum TestOutlook {
 | 
				
			||||||
@@ -48,6 +49,7 @@ enum TestOutlook {
 | 
				
			|||||||
    Failure,
 | 
					    Failure,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FIXME - Really punting on this for now. It's possible that this won't need to be changed.
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Instantiates a new instance of FillOrderCombinatorialUtils. Since this method has some
 | 
					 * Instantiates a new instance of FillOrderCombinatorialUtils. Since this method has some
 | 
				
			||||||
 * required async setup, a factory method is required.
 | 
					 * required async setup, a factory method is required.
 | 
				
			||||||
@@ -114,6 +116,8 @@ export async function fillOrderCombinatorialUtilsFactoryAsync(
 | 
				
			|||||||
        {},
 | 
					        {},
 | 
				
			||||||
        new BigNumber(chainId),
 | 
					        new BigNumber(chainId),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const logDecoder = new LogDecoder(web3Wrapper, artifacts);
 | 
				
			||||||
    const exchangeWrapper = new ExchangeWrapper(exchangeContract, provider);
 | 
					    const exchangeWrapper = new ExchangeWrapper(exchangeContract, provider);
 | 
				
			||||||
    await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, ownerAddress);
 | 
					    await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, ownerAddress);
 | 
				
			||||||
    await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, ownerAddress);
 | 
					    await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, ownerAddress);
 | 
				
			||||||
@@ -202,6 +206,7 @@ export async function fillOrderCombinatorialUtilsFactoryAsync(
 | 
				
			|||||||
        takerAddress,
 | 
					        takerAddress,
 | 
				
			||||||
        exchangeWrapper,
 | 
					        exchangeWrapper,
 | 
				
			||||||
        assetWrapper,
 | 
					        assetWrapper,
 | 
				
			||||||
 | 
					        logDecoder,
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
    return fillOrderCombinatorialUtils;
 | 
					    return fillOrderCombinatorialUtils;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -215,6 +220,7 @@ export class FillOrderCombinatorialUtils {
 | 
				
			|||||||
    public takerAddress: string;
 | 
					    public takerAddress: string;
 | 
				
			||||||
    public exchangeWrapper: ExchangeWrapper;
 | 
					    public exchangeWrapper: ExchangeWrapper;
 | 
				
			||||||
    public assetWrapper: AssetWrapper;
 | 
					    public assetWrapper: AssetWrapper;
 | 
				
			||||||
 | 
					    public logDecoder: LogDecoder;
 | 
				
			||||||
    public balanceAndProxyAllowanceFetcher: SimpleAssetBalanceAndProxyAllowanceFetcher;
 | 
					    public balanceAndProxyAllowanceFetcher: SimpleAssetBalanceAndProxyAllowanceFetcher;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public static generateFillOrderCombinations(): FillScenario[] {
 | 
					    public static generateFillOrderCombinations(): FillScenario[] {
 | 
				
			||||||
@@ -445,6 +451,7 @@ export class FillOrderCombinatorialUtils {
 | 
				
			|||||||
        takerAddress: string,
 | 
					        takerAddress: string,
 | 
				
			||||||
        exchangeWrapper: ExchangeWrapper,
 | 
					        exchangeWrapper: ExchangeWrapper,
 | 
				
			||||||
        assetWrapper: AssetWrapper,
 | 
					        assetWrapper: AssetWrapper,
 | 
				
			||||||
 | 
					        logDecoder: LogDecoder,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        this.provider = provider;
 | 
					        this.provider = provider;
 | 
				
			||||||
        this.orderFactory = orderFactory;
 | 
					        this.orderFactory = orderFactory;
 | 
				
			||||||
@@ -454,6 +461,7 @@ export class FillOrderCombinatorialUtils {
 | 
				
			|||||||
        this.takerAddress = takerAddress;
 | 
					        this.takerAddress = takerAddress;
 | 
				
			||||||
        this.exchangeWrapper = exchangeWrapper;
 | 
					        this.exchangeWrapper = exchangeWrapper;
 | 
				
			||||||
        this.assetWrapper = assetWrapper;
 | 
					        this.assetWrapper = assetWrapper;
 | 
				
			||||||
 | 
					        this.logDecoder = logDecoder;
 | 
				
			||||||
        this.balanceAndProxyAllowanceFetcher = new SimpleAssetBalanceAndProxyAllowanceFetcher(assetWrapper);
 | 
					        this.balanceAndProxyAllowanceFetcher = new SimpleAssetBalanceAndProxyAllowanceFetcher(assetWrapper);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -643,7 +651,7 @@ export class FillOrderCombinatorialUtils {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
        expect(exchangeLogs.length).to.be.equal(1, 'logs length');
 | 
					        expect(exchangeLogs.length).to.be.equal(1, 'logs length');
 | 
				
			||||||
        // tslint:disable-next-line:no-unnecessary-type-assertion
 | 
					        // tslint:disable-next-line:no-unnecessary-type-assertion
 | 
				
			||||||
        const log = txReceipt.logs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>;
 | 
					        const log = exchangeLogs[0] as LogWithDecodedArgs<ExchangeFillEventArgs>;
 | 
				
			||||||
        expect(log.args.makerAddress, 'log.args.makerAddress').to.be.equal(makerAddress);
 | 
					        expect(log.args.makerAddress, 'log.args.makerAddress').to.be.equal(makerAddress);
 | 
				
			||||||
        expect(log.args.takerAddress, 'log.args.takerAddress').to.be.equal(this.takerAddress);
 | 
					        expect(log.args.takerAddress, 'log.args.takerAddress').to.be.equal(this.takerAddress);
 | 
				
			||||||
        expect(log.args.feeRecipientAddress, 'log.args.feeRecipientAddress').to.be.equal(feeRecipient);
 | 
					        expect(log.args.feeRecipientAddress, 'log.args.feeRecipientAddress').to.be.equal(feeRecipient);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,7 @@ export enum FillOrderError {
 | 
				
			|||||||
    TransferFailed = 'TRANSFER_FAILED',
 | 
					    TransferFailed = 'TRANSFER_FAILED',
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FIXME - Punting on protocol fees for now
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * Simplified fill order simulator.
 | 
					 * Simplified fill order simulator.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -121,6 +122,7 @@ export class FillOrderSimulator {
 | 
				
			|||||||
            makerAssetFilledAmount: makerAssetFillAmount,
 | 
					            makerAssetFilledAmount: makerAssetFillAmount,
 | 
				
			||||||
            makerFeePaid,
 | 
					            makerFeePaid,
 | 
				
			||||||
            takerFeePaid,
 | 
					            takerFeePaid,
 | 
				
			||||||
 | 
					            protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
import { ERC1155ProxyWrapper, ERC20Wrapper, ERC721Wrapper } from '@0x/contracts-asset-proxy';
 | 
					import { ERC1155ProxyWrapper, ERC20Wrapper, ERC721Wrapper } from '@0x/contracts-asset-proxy';
 | 
				
			||||||
import { ERC1155HoldingsByOwner, expect, OrderStatus } from '@0x/contracts-test-utils';
 | 
					import { constants, ERC1155HoldingsByOwner, expect, OrderStatus } from '@0x/contracts-test-utils';
 | 
				
			||||||
import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
 | 
					import { assetDataUtils, orderHashUtils } from '@0x/order-utils';
 | 
				
			||||||
import { AssetProxyId, BatchMatchedFillResults, FillResults, MatchedFillResults, SignedOrder } from '@0x/types';
 | 
					import { AssetProxyId, BatchMatchedFillResults, FillResults, MatchedFillResults, SignedOrder } from '@0x/types';
 | 
				
			||||||
import { BigNumber } from '@0x/utils';
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
@@ -235,6 +235,7 @@ export class MatchOrderTester {
 | 
				
			|||||||
        return expectedBatchMatchResults;
 | 
					        return expectedBatchMatchResults;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // FIXME - Punting on protocol fees until later
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Matches two complementary orders and asserts results.
 | 
					     * Matches two complementary orders and asserts results.
 | 
				
			||||||
     * @param orders The matched orders and filled states.
 | 
					     * @param orders The matched orders and filled states.
 | 
				
			||||||
@@ -266,6 +267,7 @@ export class MatchOrderTester {
 | 
				
			|||||||
                orders.leftOrder,
 | 
					                orders.leftOrder,
 | 
				
			||||||
                orders.rightOrder,
 | 
					                orders.rightOrder,
 | 
				
			||||||
                takerAddress,
 | 
					                takerAddress,
 | 
				
			||||||
 | 
					                {}, // FIXME
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            transactionReceipt = await this._executeMatchOrdersWithMaximalFillAsync(
 | 
					            transactionReceipt = await this._executeMatchOrdersWithMaximalFillAsync(
 | 
				
			||||||
                orders.leftOrder,
 | 
					                orders.leftOrder,
 | 
				
			||||||
@@ -1198,12 +1200,14 @@ function convertToMatchResults(result: MatchResults): MatchedFillResults {
 | 
				
			|||||||
            takerAssetFilledAmount: result.fills[0].takerAssetFilledAmount,
 | 
					            takerAssetFilledAmount: result.fills[0].takerAssetFilledAmount,
 | 
				
			||||||
            makerFeePaid: result.fills[0].makerFeePaid,
 | 
					            makerFeePaid: result.fills[0].makerFeePaid,
 | 
				
			||||||
            takerFeePaid: result.fills[0].takerFeePaid,
 | 
					            takerFeePaid: result.fills[0].takerFeePaid,
 | 
				
			||||||
 | 
					            protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        right: {
 | 
					        right: {
 | 
				
			||||||
            makerAssetFilledAmount: result.fills[1].makerAssetFilledAmount,
 | 
					            makerAssetFilledAmount: result.fills[1].makerAssetFilledAmount,
 | 
				
			||||||
            takerAssetFilledAmount: result.fills[1].takerAssetFilledAmount,
 | 
					            takerAssetFilledAmount: result.fills[1].takerAssetFilledAmount,
 | 
				
			||||||
            makerFeePaid: result.fills[1].makerFeePaid,
 | 
					            makerFeePaid: result.fills[1].makerFeePaid,
 | 
				
			||||||
            takerFeePaid: result.fills[1].takerFeePaid,
 | 
					            takerFeePaid: result.fills[1].takerFeePaid,
 | 
				
			||||||
 | 
					            protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        profitInLeftMakerAsset,
 | 
					        profitInLeftMakerAsset,
 | 
				
			||||||
        profitInRightMakerAsset,
 | 
					        profitInRightMakerAsset,
 | 
				
			||||||
@@ -1222,6 +1226,7 @@ function convertToFillResults(result: FillEventArgs): FillResults {
 | 
				
			|||||||
        takerAssetFilledAmount: result.takerAssetFilledAmount,
 | 
					        takerAssetFilledAmount: result.takerAssetFilledAmount,
 | 
				
			||||||
        makerFeePaid: result.makerFeePaid,
 | 
					        makerFeePaid: result.makerFeePaid,
 | 
				
			||||||
        takerFeePaid: result.takerFeePaid,
 | 
					        takerFeePaid: result.takerFeePaid,
 | 
				
			||||||
 | 
					        protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    return fillResults;
 | 
					    return fillResults;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,6 @@ import {
 | 
				
			|||||||
    ERC20BalancesByOwner,
 | 
					    ERC20BalancesByOwner,
 | 
				
			||||||
    expect,
 | 
					    expect,
 | 
				
			||||||
    getLatestBlockTimestampAsync,
 | 
					    getLatestBlockTimestampAsync,
 | 
				
			||||||
    increaseTimeAndMineBlockAsync,
 | 
					 | 
				
			||||||
    OrderFactory,
 | 
					    OrderFactory,
 | 
				
			||||||
} from '@0x/contracts-test-utils';
 | 
					} from '@0x/contracts-test-utils';
 | 
				
			||||||
import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
 | 
					import { assetDataUtils, ExchangeRevertErrors, orderHashUtils } from '@0x/order-utils';
 | 
				
			||||||
@@ -48,11 +47,15 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
    let defaultTakerAssetAddress: string;
 | 
					    let defaultTakerAssetAddress: string;
 | 
				
			||||||
    let defaultFeeAssetAddress: string;
 | 
					    let defaultFeeAssetAddress: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const DEFAULT_GAS_PRICE = new BigNumber(2);
 | 
				
			||||||
 | 
					    const PROTOCOL_FEE_MULTIPLIER = new BigNumber(150);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const nullFillResults: FillResults = {
 | 
					    const nullFillResults: FillResults = {
 | 
				
			||||||
        makerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
					        makerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
        takerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
					        takerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
        makerFeePaid: constants.ZERO_AMOUNT,
 | 
					        makerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
        takerFeePaid: constants.ZERO_AMOUNT,
 | 
					        takerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
@@ -81,10 +84,16 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
        exchange = await ExchangeContract.deployFrom0xArtifactAsync(
 | 
					        exchange = await ExchangeContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
            artifacts.Exchange,
 | 
					            artifacts.Exchange,
 | 
				
			||||||
            env.provider,
 | 
					            env.provider,
 | 
				
			||||||
            env.txDefaults,
 | 
					            { ...env.txDefaults, from: owner },
 | 
				
			||||||
            {},
 | 
					            {},
 | 
				
			||||||
            new BigNumber(chainId),
 | 
					            new BigNumber(chainId),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set the protocol fee multiplier of the exchange
 | 
				
			||||||
 | 
					        await exchange.updateProtocolFeeMultiplier.awaitTransactionSuccessAsync(PROTOCOL_FEE_MULTIPLIER, {
 | 
				
			||||||
 | 
					            from: owner,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        exchangeWrapper = new ExchangeWrapper(exchange, env.provider);
 | 
					        exchangeWrapper = new ExchangeWrapper(exchange, env.provider);
 | 
				
			||||||
        await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
 | 
					        await exchangeWrapper.registerAssetProxyAsync(erc20Proxy.address, owner);
 | 
				
			||||||
        await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
 | 
					        await exchangeWrapper.registerAssetProxyAsync(erc721Proxy.address, owner);
 | 
				
			||||||
@@ -492,11 +501,14 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
					                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
					                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
				
			||||||
 | 
					                    // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					                    //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
                    expectedFillResults.push({
 | 
					                    expectedFillResults.push({
 | 
				
			||||||
                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
					                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
				
			||||||
                        makerAssetFilledAmount,
 | 
					                        makerAssetFilledAmount,
 | 
				
			||||||
                        makerFeePaid: makerFee,
 | 
					                        makerFeePaid: makerFee,
 | 
				
			||||||
                        takerFeePaid: takerFee,
 | 
					                        takerFeePaid: takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
					                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
				
			||||||
@@ -522,11 +534,13 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                    ].plus(makerFee.plus(takerFee));
 | 
					                    ].plus(makerFee.plus(takerFee));
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					                //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
                const fillResults = await exchange.batchFillOrders.callAsync(
 | 
					                const fillResults = await exchange.batchFillOrders.callAsync(
 | 
				
			||||||
                    signedOrders,
 | 
					                    signedOrders,
 | 
				
			||||||
                    takerAssetFillAmounts,
 | 
					                    takerAssetFillAmounts,
 | 
				
			||||||
                    signedOrders.map(signedOrder => signedOrder.signature),
 | 
					                    signedOrders.map(signedOrder => signedOrder.signature),
 | 
				
			||||||
                    { from: takerAddress },
 | 
					                    { from: takerAddress, gasPrice: DEFAULT_GAS_PRICE },
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
                await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, {
 | 
					                await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, {
 | 
				
			||||||
                    takerAssetFillAmounts,
 | 
					                    takerAssetFillAmounts,
 | 
				
			||||||
@@ -559,11 +573,14 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
					                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
					                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
				
			||||||
 | 
					                    // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					                    //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
                    expectedFillResults.push({
 | 
					                    expectedFillResults.push({
 | 
				
			||||||
                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
					                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
				
			||||||
                        makerAssetFilledAmount,
 | 
					                        makerAssetFilledAmount,
 | 
				
			||||||
                        makerFeePaid: makerFee,
 | 
					                        makerFeePaid: makerFee,
 | 
				
			||||||
                        takerFeePaid: takerFee,
 | 
					                        takerFeePaid: takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
					                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
				
			||||||
@@ -642,11 +659,14 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
					                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
					                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
				
			||||||
 | 
					                    // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					                    //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
                    expectedFillResults.push({
 | 
					                    expectedFillResults.push({
 | 
				
			||||||
                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
					                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
				
			||||||
                        makerAssetFilledAmount,
 | 
					                        makerAssetFilledAmount,
 | 
				
			||||||
                        makerFeePaid: makerFee,
 | 
					                        makerFeePaid: makerFee,
 | 
				
			||||||
                        takerFeePaid: takerFee,
 | 
					                        takerFeePaid: takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
					                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
				
			||||||
@@ -712,11 +732,14 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
					                        .dividedToIntegerBy(signedOrder.makerAssetAmount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
					                    takerAssetFillAmounts.push(takerAssetFillAmount);
 | 
				
			||||||
 | 
					                    // FIXME - Punting on these tests for now since no staking contract will be registered. This
 | 
				
			||||||
 | 
					                    //         should be revisited when the protocol fee testing has been unit tested well.
 | 
				
			||||||
                    expectedFillResults.push({
 | 
					                    expectedFillResults.push({
 | 
				
			||||||
                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
					                        takerAssetFilledAmount: takerAssetFillAmount,
 | 
				
			||||||
                        makerAssetFilledAmount,
 | 
					                        makerAssetFilledAmount,
 | 
				
			||||||
                        makerFeePaid: makerFee,
 | 
					                        makerFeePaid: makerFee,
 | 
				
			||||||
                        takerFeePaid: takerFee,
 | 
					                        takerFeePaid: takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
                    });
 | 
					                    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
					                    erc20Balances[makerAddress][makerAssetAddress] = erc20Balances[makerAddress][
 | 
				
			||||||
@@ -853,6 +876,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
					                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
				
			||||||
                        makerFeePaid: signedOrder.makerFee,
 | 
					                        makerFeePaid: signedOrder.makerFee,
 | 
				
			||||||
                        takerFeePaid: signedOrder.takerFee,
 | 
					                        takerFeePaid: signedOrder.takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT, // FIXME - This is what is being used now.
 | 
				
			||||||
                    }))
 | 
					                    }))
 | 
				
			||||||
                    .reduce(
 | 
					                    .reduce(
 | 
				
			||||||
                        (totalFillResults, currentFillResults) => ({
 | 
					                        (totalFillResults, currentFillResults) => ({
 | 
				
			||||||
@@ -864,6 +888,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                            ),
 | 
					                            ),
 | 
				
			||||||
                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
					                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
				
			||||||
                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
					                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
				
			||||||
 | 
					                            protocolFeePaid: totalFillResults.protocolFeePaid.plus(currentFillResults.protocolFeePaid),
 | 
				
			||||||
                        }),
 | 
					                        }),
 | 
				
			||||||
                        nullFillResults,
 | 
					                        nullFillResults,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
@@ -923,6 +948,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
					                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
				
			||||||
                        makerFeePaid: signedOrder.makerFee,
 | 
					                        makerFeePaid: signedOrder.makerFee,
 | 
				
			||||||
                        takerFeePaid: signedOrder.takerFee,
 | 
					                        takerFeePaid: signedOrder.takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                    }))
 | 
					                    }))
 | 
				
			||||||
                    .reduce(
 | 
					                    .reduce(
 | 
				
			||||||
                        (totalFillResults, currentFillResults) => ({
 | 
					                        (totalFillResults, currentFillResults) => ({
 | 
				
			||||||
@@ -934,6 +960,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                            ),
 | 
					                            ),
 | 
				
			||||||
                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
					                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
				
			||||||
                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
					                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
				
			||||||
 | 
					                            protocolFeePaid: totalFillResults.protocolFeePaid.plus(currentFillResults.protocolFeePaid),
 | 
				
			||||||
                        }),
 | 
					                        }),
 | 
				
			||||||
                        nullFillResults,
 | 
					                        nullFillResults,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
@@ -1037,6 +1064,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
					                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
				
			||||||
                        makerFeePaid: signedOrder.makerFee,
 | 
					                        makerFeePaid: signedOrder.makerFee,
 | 
				
			||||||
                        takerFeePaid: signedOrder.takerFee,
 | 
					                        takerFeePaid: signedOrder.takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                    }))
 | 
					                    }))
 | 
				
			||||||
                    .reduce(
 | 
					                    .reduce(
 | 
				
			||||||
                        (totalFillResults, currentFillResults) => ({
 | 
					                        (totalFillResults, currentFillResults) => ({
 | 
				
			||||||
@@ -1048,6 +1076,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                            ),
 | 
					                            ),
 | 
				
			||||||
                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
					                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
				
			||||||
                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
					                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
				
			||||||
 | 
					                            protocolFeePaid: totalFillResults.protocolFeePaid.plus(currentFillResults.protocolFeePaid),
 | 
				
			||||||
                        }),
 | 
					                        }),
 | 
				
			||||||
                        nullFillResults,
 | 
					                        nullFillResults,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
@@ -1108,6 +1137,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
					                        takerAssetFilledAmount: signedOrder.takerAssetAmount,
 | 
				
			||||||
                        makerFeePaid: signedOrder.makerFee,
 | 
					                        makerFeePaid: signedOrder.makerFee,
 | 
				
			||||||
                        takerFeePaid: signedOrder.takerFee,
 | 
					                        takerFeePaid: signedOrder.takerFee,
 | 
				
			||||||
 | 
					                        protocolFeePaid: constants.ZERO_AMOUNT, // FIXME
 | 
				
			||||||
                    }))
 | 
					                    }))
 | 
				
			||||||
                    .reduce(
 | 
					                    .reduce(
 | 
				
			||||||
                        (totalFillResults, currentFillResults) => ({
 | 
					                        (totalFillResults, currentFillResults) => ({
 | 
				
			||||||
@@ -1119,6 +1149,7 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                            ),
 | 
					                            ),
 | 
				
			||||||
                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
					                            makerFeePaid: totalFillResults.makerFeePaid.plus(currentFillResults.makerFeePaid),
 | 
				
			||||||
                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
					                            takerFeePaid: totalFillResults.takerFeePaid.plus(currentFillResults.takerFeePaid),
 | 
				
			||||||
 | 
					                            protocolFeePaid: totalFillResults.protocolFeePaid.plus(currentFillResults.protocolFeePaid),
 | 
				
			||||||
                        }),
 | 
					                        }),
 | 
				
			||||||
                        nullFillResults,
 | 
					                        nullFillResults,
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
@@ -1151,189 +1182,5 @@ blockchainTests.resets('Exchange wrappers', env => {
 | 
				
			|||||||
                });
 | 
					                });
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					 | 
				
			||||||
        describe('getOrdersInfo', () => {
 | 
					 | 
				
			||||||
            beforeEach(async () => {
 | 
					 | 
				
			||||||
                signedOrders = [
 | 
					 | 
				
			||||||
                    await orderFactory.newSignedOrderAsync(),
 | 
					 | 
				
			||||||
                    await orderFactory.newSignedOrderAsync(),
 | 
					 | 
				
			||||||
                    await orderFactory.newSignedOrderAsync(),
 | 
					 | 
				
			||||||
                ];
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple unfilled orders', async () => {
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.Fillable;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple partially filled orders', async () => {
 | 
					 | 
				
			||||||
                const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
 | 
					 | 
				
			||||||
                await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.Fillable;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple fully filled orders', async () => {
 | 
					 | 
				
			||||||
                await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress);
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount;
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.FullyFilled;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple cancelled and unfilled orders', async () => {
 | 
					 | 
				
			||||||
                await exchangeWrapper.batchCancelOrdersAsync(signedOrders, makerAddress);
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.Cancelled;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple cancelled and partially filled orders', async () => {
 | 
					 | 
				
			||||||
                const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
 | 
					 | 
				
			||||||
                await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
 | 
					 | 
				
			||||||
                await exchangeWrapper.batchCancelOrdersAsync(signedOrders, makerAddress);
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.Cancelled;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple expired and unfilled orders', async () => {
 | 
					 | 
				
			||||||
                const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
					 | 
				
			||||||
                const timeUntilExpiration = signedOrders[0].expirationTimeSeconds.minus(currentTimestamp).toNumber();
 | 
					 | 
				
			||||||
                await increaseTimeAndMineBlockAsync(timeUntilExpiration);
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = new BigNumber(0);
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.Expired;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for multiple expired and partially filled orders', async () => {
 | 
					 | 
				
			||||||
                const takerAssetFillAmounts = _.map(signedOrders, signedOrder => signedOrder.takerAssetAmount.div(2));
 | 
					 | 
				
			||||||
                await exchangeWrapper.batchFillOrdersAsync(signedOrders, takerAddress, { takerAssetFillAmounts });
 | 
					 | 
				
			||||||
                const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
					 | 
				
			||||||
                const timeUntilExpiration = signedOrders[0].expirationTimeSeconds.minus(currentTimestamp).toNumber();
 | 
					 | 
				
			||||||
                await increaseTimeAndMineBlockAsync(timeUntilExpiration);
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(3);
 | 
					 | 
				
			||||||
                _.forEach(signedOrders, (signedOrder, index) => {
 | 
					 | 
				
			||||||
                    const expectedOrderHash = orderHashUtils.getOrderHashHex(signedOrder);
 | 
					 | 
				
			||||||
                    const expectedTakerAssetFilledAmount = signedOrder.takerAssetAmount.div(2);
 | 
					 | 
				
			||||||
                    const expectedOrderStatus = OrderStatus.Expired;
 | 
					 | 
				
			||||||
                    const orderInfo = ordersInfo[index];
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderHash).to.be.equal(expectedOrderHash);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(expectedTakerAssetFilledAmount);
 | 
					 | 
				
			||||||
                    expect(orderInfo.orderStatus).to.equal(expectedOrderStatus);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
            it('should get the correct information for a mix of unfilled, partially filled, fully filled, cancelled, and expired orders', async () => {
 | 
					 | 
				
			||||||
                const unfilledOrder = await orderFactory.newSignedOrderAsync();
 | 
					 | 
				
			||||||
                const partiallyFilledOrder = await orderFactory.newSignedOrderAsync();
 | 
					 | 
				
			||||||
                await exchangeWrapper.fillOrderAsync(partiallyFilledOrder, takerAddress, {
 | 
					 | 
				
			||||||
                    takerAssetFillAmount: partiallyFilledOrder.takerAssetAmount.div(2),
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                const fullyFilledOrder = await orderFactory.newSignedOrderAsync();
 | 
					 | 
				
			||||||
                await exchangeWrapper.fillOrderAsync(fullyFilledOrder, takerAddress);
 | 
					 | 
				
			||||||
                const cancelledOrder = await orderFactory.newSignedOrderAsync();
 | 
					 | 
				
			||||||
                await exchangeWrapper.cancelOrderAsync(cancelledOrder, makerAddress);
 | 
					 | 
				
			||||||
                const currentTimestamp = await getLatestBlockTimestampAsync();
 | 
					 | 
				
			||||||
                const expiredOrder = await orderFactory.newSignedOrderAsync({
 | 
					 | 
				
			||||||
                    expirationTimeSeconds: new BigNumber(currentTimestamp),
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                signedOrders = [unfilledOrder, partiallyFilledOrder, fullyFilledOrder, cancelledOrder, expiredOrder];
 | 
					 | 
				
			||||||
                const ordersInfo = await exchangeWrapper.getOrdersInfoAsync(signedOrders);
 | 
					 | 
				
			||||||
                expect(ordersInfo.length).to.be.equal(5);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const expectedUnfilledOrderHash = orderHashUtils.getOrderHashHex(unfilledOrder);
 | 
					 | 
				
			||||||
                const expectedUnfilledTakerAssetFilledAmount = new BigNumber(0);
 | 
					 | 
				
			||||||
                const expectedUnfilledOrderStatus = OrderStatus.Fillable;
 | 
					 | 
				
			||||||
                const unfilledOrderInfo = ordersInfo[0];
 | 
					 | 
				
			||||||
                expect(unfilledOrderInfo.orderHash).to.be.equal(expectedUnfilledOrderHash);
 | 
					 | 
				
			||||||
                expect(unfilledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                    expectedUnfilledTakerAssetFilledAmount,
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                expect(unfilledOrderInfo.orderStatus).to.be.equal(expectedUnfilledOrderStatus);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const expectedPartialOrderHash = orderHashUtils.getOrderHashHex(partiallyFilledOrder);
 | 
					 | 
				
			||||||
                const expectedPartialTakerAssetFilledAmount = partiallyFilledOrder.takerAssetAmount.div(2);
 | 
					 | 
				
			||||||
                const expectedPartialOrderStatus = OrderStatus.Fillable;
 | 
					 | 
				
			||||||
                const partialOrderInfo = ordersInfo[1];
 | 
					 | 
				
			||||||
                expect(partialOrderInfo.orderHash).to.be.equal(expectedPartialOrderHash);
 | 
					 | 
				
			||||||
                expect(partialOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                    expectedPartialTakerAssetFilledAmount,
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                expect(partialOrderInfo.orderStatus).to.be.equal(expectedPartialOrderStatus);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const expectedFilledOrderHash = orderHashUtils.getOrderHashHex(fullyFilledOrder);
 | 
					 | 
				
			||||||
                const expectedFilledTakerAssetFilledAmount = fullyFilledOrder.takerAssetAmount;
 | 
					 | 
				
			||||||
                const expectedFilledOrderStatus = OrderStatus.FullyFilled;
 | 
					 | 
				
			||||||
                const filledOrderInfo = ordersInfo[2];
 | 
					 | 
				
			||||||
                expect(filledOrderInfo.orderHash).to.be.equal(expectedFilledOrderHash);
 | 
					 | 
				
			||||||
                expect(filledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                    expectedFilledTakerAssetFilledAmount,
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                expect(filledOrderInfo.orderStatus).to.be.equal(expectedFilledOrderStatus);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const expectedCancelledOrderHash = orderHashUtils.getOrderHashHex(cancelledOrder);
 | 
					 | 
				
			||||||
                const expectedCancelledTakerAssetFilledAmount = new BigNumber(0);
 | 
					 | 
				
			||||||
                const expectedCancelledOrderStatus = OrderStatus.Cancelled;
 | 
					 | 
				
			||||||
                const cancelledOrderInfo = ordersInfo[3];
 | 
					 | 
				
			||||||
                expect(cancelledOrderInfo.orderHash).to.be.equal(expectedCancelledOrderHash);
 | 
					 | 
				
			||||||
                expect(cancelledOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                    expectedCancelledTakerAssetFilledAmount,
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                expect(cancelledOrderInfo.orderStatus).to.be.equal(expectedCancelledOrderStatus);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                const expectedExpiredOrderHash = orderHashUtils.getOrderHashHex(expiredOrder);
 | 
					 | 
				
			||||||
                const expectedExpiredTakerAssetFilledAmount = new BigNumber(0);
 | 
					 | 
				
			||||||
                const expectedExpiredOrderStatus = OrderStatus.Expired;
 | 
					 | 
				
			||||||
                const expiredOrderInfo = ordersInfo[4];
 | 
					 | 
				
			||||||
                expect(expiredOrderInfo.orderHash).to.be.equal(expectedExpiredOrderHash);
 | 
					 | 
				
			||||||
                expect(expiredOrderInfo.orderTakerAssetFilledAmount).to.be.bignumber.equal(
 | 
					 | 
				
			||||||
                    expectedExpiredTakerAssetFilledAmount,
 | 
					 | 
				
			||||||
                );
 | 
					 | 
				
			||||||
                expect(expiredOrderInfo.orderStatus).to.be.equal(expectedExpiredOrderStatus);
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
}); // tslint:disable-line:max-file-line-count
 | 
					}); // tslint:disable-line:max-file-line-count
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -28,6 +28,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
 | 
				
			|||||||
    const { ONE_ETHER, MAX_UINT256 } = constants;
 | 
					    const { ONE_ETHER, MAX_UINT256 } = constants;
 | 
				
			||||||
    const { addFillResults, getPartialAmountFloor } = LibReferenceFunctions;
 | 
					    const { addFillResults, getPartialAmountFloor } = LibReferenceFunctions;
 | 
				
			||||||
    const { safeSub } = UtilReferenceFunctions;
 | 
					    const { safeSub } = UtilReferenceFunctions;
 | 
				
			||||||
 | 
					    const protocolFeeMultiplier = new BigNumber(150000);
 | 
				
			||||||
    const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH);
 | 
					    const randomAddress = () => hexRandom(constants.ADDRESS_LENGTH);
 | 
				
			||||||
    const randomAssetData = () => hexRandom(34);
 | 
					    const randomAssetData = () => hexRandom(34);
 | 
				
			||||||
    const randomAmount = (maxAmount: BigNumber = ONE_ETHER) => maxAmount.times(_.random(0, 100, true).toFixed(12));
 | 
					    const randomAmount = (maxAmount: BigNumber = ONE_ETHER) => maxAmount.times(_.random(0, 100, true).toFixed(12));
 | 
				
			||||||
@@ -40,20 +41,30 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
 | 
				
			|||||||
        takerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
					        takerAssetFilledAmount: constants.ZERO_AMOUNT,
 | 
				
			||||||
        makerFeePaid: constants.ZERO_AMOUNT,
 | 
					        makerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
        takerFeePaid: constants.ZERO_AMOUNT,
 | 
					        takerFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					        protocolFeePaid: constants.ZERO_AMOUNT,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let testContract: TestWrapperFunctionsContract;
 | 
					    let testContract: TestWrapperFunctionsContract;
 | 
				
			||||||
    let txHelper: TransactionHelper;
 | 
					    let txHelper: TransactionHelper;
 | 
				
			||||||
 | 
					    let owner: string;
 | 
				
			||||||
    let senderAddress: string;
 | 
					    let senderAddress: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        [senderAddress] = await env.getAccountAddressesAsync();
 | 
					        [owner, senderAddress] = await env.getAccountAddressesAsync();
 | 
				
			||||||
        txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
 | 
					        txHelper = new TransactionHelper(env.web3Wrapper, artifacts);
 | 
				
			||||||
        testContract = await TestWrapperFunctionsContract.deployFrom0xArtifactAsync(
 | 
					        testContract = await TestWrapperFunctionsContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
            artifacts.TestWrapperFunctions,
 | 
					            artifacts.TestWrapperFunctions,
 | 
				
			||||||
            env.provider,
 | 
					            env.provider,
 | 
				
			||||||
            env.txDefaults,
 | 
					            {
 | 
				
			||||||
 | 
					                ...env.txDefaults,
 | 
				
			||||||
 | 
					                from: owner,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
            {},
 | 
					            {},
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set the protocol fee multiplier.
 | 
				
			||||||
 | 
					        await testContract.updateProtocolFeeMultiplier.awaitTransactionSuccessAsync(protocolFeeMultiplier, {
 | 
				
			||||||
 | 
					            from: owner,
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function randomOrder(fields?: Partial<Order>): Order {
 | 
					    function randomOrder(fields?: Partial<Order>): Order {
 | 
				
			||||||
@@ -96,6 +107,7 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
 | 
				
			|||||||
            takerAssetFilledAmount: order.takerAssetAmount,
 | 
					            takerAssetFilledAmount: order.takerAssetAmount,
 | 
				
			||||||
            makerFeePaid: order.makerFee,
 | 
					            makerFeePaid: order.makerFee,
 | 
				
			||||||
            takerFeePaid: order.takerFee,
 | 
					            takerFeePaid: order.takerFee,
 | 
				
			||||||
 | 
					            protocolFeePaid: protocolFeeMultiplier,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1309,50 +1321,5 @@ blockchainTests('Exchange wrapper functions unit tests.', env => {
 | 
				
			|||||||
            return expect(tx).to.revertWith(expectedError);
 | 
					            return expect(tx).to.revertWith(expectedError);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					 | 
				
			||||||
    describe('getOrdersInfo', () => {
 | 
					 | 
				
			||||||
        // Computes the expected (fake) order info generated by the `TestWrapperFunctions` contract.
 | 
					 | 
				
			||||||
        function getExpectedOrderInfo(order: Order): OrderInfo {
 | 
					 | 
				
			||||||
            const MAX_ORDER_STATUS = OrderStatus.Cancelled as number;
 | 
					 | 
				
			||||||
            return {
 | 
					 | 
				
			||||||
                orderHash: getExpectedOrderHash(order),
 | 
					 | 
				
			||||||
                // Lower uint128 of `order.salt` is the `orderTakerAssetFilledAmount`.
 | 
					 | 
				
			||||||
                orderTakerAssetFilledAmount: order.salt.mod(new BigNumber(2).pow(128)),
 | 
					 | 
				
			||||||
                // High byte of `order.salt` is the `orderStatus`.
 | 
					 | 
				
			||||||
                orderStatus:
 | 
					 | 
				
			||||||
                    order.salt.dividedToIntegerBy(new BigNumber(2).pow(248)).toNumber() % (MAX_ORDER_STATUS + 1),
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('works with no orders', async () => {
 | 
					 | 
				
			||||||
            const infos = await testContract.getOrdersInfo.callAsync([]);
 | 
					 | 
				
			||||||
            expect(infos.length).to.eq(0);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('works with one order', async () => {
 | 
					 | 
				
			||||||
            const orders = [randomOrder()];
 | 
					 | 
				
			||||||
            const expectedResult = orders.map(getExpectedOrderInfo);
 | 
					 | 
				
			||||||
            const actualResult = await testContract.getOrdersInfo.callAsync(orders);
 | 
					 | 
				
			||||||
            expect(actualResult).to.deep.eq(expectedResult);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('works with many orders', async () => {
 | 
					 | 
				
			||||||
            const NUM_ORDERS = 16;
 | 
					 | 
				
			||||||
            const orders = _.times(NUM_ORDERS, () => randomOrder());
 | 
					 | 
				
			||||||
            const expectedResult = orders.map(getExpectedOrderInfo);
 | 
					 | 
				
			||||||
            const actualResult = await testContract.getOrdersInfo.callAsync(orders);
 | 
					 | 
				
			||||||
            expect(actualResult).to.deep.eq(expectedResult);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        it('works with duplicate orders', async () => {
 | 
					 | 
				
			||||||
            const NUM_UNIQUE_ORDERS = 4;
 | 
					 | 
				
			||||||
            const CLONE_COUNT = 2;
 | 
					 | 
				
			||||||
            const uniqueOrders = _.times(NUM_UNIQUE_ORDERS, () => randomOrder());
 | 
					 | 
				
			||||||
            const orders = _.shuffle(_.flatten(_.times(CLONE_COUNT, () => uniqueOrders)));
 | 
					 | 
				
			||||||
            const expectedResult = orders.map(getExpectedOrderInfo);
 | 
					 | 
				
			||||||
            const actualResult = await testContract.getOrdersInfo.callAsync(orders);
 | 
					 | 
				
			||||||
            expect(actualResult).to.deep.eq(expectedResult);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
// tslint:disable-next-line: max-file-line-count
 | 
					// tslint:disable-next-line: max-file-line-count
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,6 @@
 | 
				
			|||||||
        "generated-artifacts/MixinMatchOrders.json",
 | 
					        "generated-artifacts/MixinMatchOrders.json",
 | 
				
			||||||
        "generated-artifacts/MixinProtocolFees.json",
 | 
					        "generated-artifacts/MixinProtocolFees.json",
 | 
				
			||||||
        "generated-artifacts/MixinSignatureValidator.json",
 | 
					        "generated-artifacts/MixinSignatureValidator.json",
 | 
				
			||||||
        "generated-artifacts/MixinStakingManager.json",
 | 
					 | 
				
			||||||
        "generated-artifacts/MixinTransactions.json",
 | 
					        "generated-artifacts/MixinTransactions.json",
 | 
				
			||||||
        "generated-artifacts/MixinTransferSimulator.json",
 | 
					        "generated-artifacts/MixinTransferSimulator.json",
 | 
				
			||||||
        "generated-artifacts/MixinWrapperFunctions.json",
 | 
					        "generated-artifacts/MixinWrapperFunctions.json",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,37 +21,15 @@ pragma solidity ^0.5.9;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
interface IStaking {
 | 
					interface IStaking {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev Pays several protocols fee in ETH.
 | 
					 | 
				
			||||||
    /// @param makers The addresses of the order makers.
 | 
					 | 
				
			||||||
    /// @param fees The fee amounts paid by each of the makers.
 | 
					 | 
				
			||||||
    function batchPayProtocolFees(
 | 
					 | 
				
			||||||
        address[] calldata makers,
 | 
					 | 
				
			||||||
        uint256[] calldata fees
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external
 | 
					 | 
				
			||||||
        payable;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Pays a protocol fee in ETH.
 | 
					    /// @dev Pays a protocol fee in ETH.
 | 
				
			||||||
    /// @param makerAddress The address of the order's maker.
 | 
					    /// @param makerAddress The address of the order's maker.
 | 
				
			||||||
    function payProtocolFee(address makerAddress)
 | 
					    /// @param payerAddress The address that is responsible for paying the protocol fee.
 | 
				
			||||||
 | 
					    /// @param protocolFeePaid The amount of protocol fees that should be paid.
 | 
				
			||||||
 | 
					    function payProtocolFee(
 | 
				
			||||||
 | 
					        address makerAddress,
 | 
				
			||||||
 | 
					        address payerAddress,
 | 
				
			||||||
 | 
					        uint256 protocolFeePaid
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
        external
 | 
					        external
 | 
				
			||||||
        payable;
 | 
					        payable;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Records several protocol fees that were paid in WETH.
 | 
					 | 
				
			||||||
    /// @param makers The addresses of the order makers.
 | 
					 | 
				
			||||||
    /// @param fees The fee amounts paid by each of the makers.
 | 
					 | 
				
			||||||
    function batchRecordProtocolFees(
 | 
					 | 
				
			||||||
        address[] calldata makers,
 | 
					 | 
				
			||||||
        uint256[] calldata fees
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    /// @dev Records a protocol fee that was paid in WETH.
 | 
					 | 
				
			||||||
    /// @param makerAddress The address of the order's maker.
 | 
					 | 
				
			||||||
    /// @param fee The fee amount that was paid by the maker.
 | 
					 | 
				
			||||||
    function recordProtocolFee(
 | 
					 | 
				
			||||||
        address makerAddress,
 | 
					 | 
				
			||||||
        uint256 fee
 | 
					 | 
				
			||||||
    )
 | 
					 | 
				
			||||||
        external;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ contract Refundable {
 | 
				
			|||||||
    modifier refundFinalBalance {
 | 
					    modifier refundFinalBalance {
 | 
				
			||||||
        _;
 | 
					        _;
 | 
				
			||||||
        if (!shouldNotRefund) {
 | 
					        if (!shouldNotRefund) {
 | 
				
			||||||
            msg.sender.transfer(address(this).balance);
 | 
					            refundNonzeroBalance();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -38,7 +38,16 @@ contract Refundable {
 | 
				
			|||||||
            shouldNotRefund = true;
 | 
					            shouldNotRefund = true;
 | 
				
			||||||
            _;
 | 
					            _;
 | 
				
			||||||
            shouldNotRefund = false;
 | 
					            shouldNotRefund = false;
 | 
				
			||||||
            msg.sender.transfer(address(this).balance);
 | 
					            refundNonzeroBalance();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    function refundNonzeroBalance()
 | 
				
			||||||
 | 
					        internal
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        uint256 balance = address(this).balance;
 | 
				
			||||||
 | 
					        if (balance > 0) {
 | 
				
			||||||
 | 
					            msg.sender.transfer(balance);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,6 +24,13 @@ import "../src/Refundable.sol";
 | 
				
			|||||||
contract TestRefundable is
 | 
					contract TestRefundable is
 | 
				
			||||||
    Refundable
 | 
					    Refundable
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    function refundNonzeroBalanceExternal()
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        payable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        refundNonzeroBalance();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function setShouldNotRefund(bool shouldNotRefundNew)
 | 
					    function setShouldNotRefund(bool shouldNotRefundNew)
 | 
				
			||||||
        external
 | 
					        external
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,10 +24,33 @@ import "./TestRefundable.sol";
 | 
				
			|||||||
contract TestRefundableReceiver {
 | 
					contract TestRefundableReceiver {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev A payable fallback function is necessary to receive refunds from the `TestRefundable` contract.
 | 
					    /// @dev A payable fallback function is necessary to receive refunds from the `TestRefundable` contract.
 | 
				
			||||||
 | 
					    ///      This function ensures that zero value is not sent to the contract, which tests the feature of
 | 
				
			||||||
 | 
					    ///      of the `refundNonzeroBalance` that doesn't transfer if the balance is zero.
 | 
				
			||||||
    function ()
 | 
					    function ()
 | 
				
			||||||
        external
 | 
					        external
 | 
				
			||||||
        payable
 | 
					        payable
 | 
				
			||||||
    {} // solhint-disable-line no-empty-blocks
 | 
					    {
 | 
				
			||||||
 | 
					        // Ensure that a value of zero was not transferred to the contract.
 | 
				
			||||||
 | 
					        require(msg.value != 0, "Zero value should not be sent to this contract.");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// @dev This function tests the behavior of the `refundNonzeroBalance` function by checking whether or
 | 
				
			||||||
 | 
					    ///      not the `callCounter` state variable changes after the `refundNonzeroBalance` is called.
 | 
				
			||||||
 | 
					    /// @param testRefundable The TestRefundable that should be tested against.
 | 
				
			||||||
 | 
					    function testRefundNonzeroBalance(TestRefundable testRefundable)
 | 
				
			||||||
 | 
					        external
 | 
				
			||||||
 | 
					        payable
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Call `refundNonzeroBalance()` and forward all of the eth sent to the contract.
 | 
				
			||||||
 | 
					        testRefundable.refundNonzeroBalanceExternal.value(msg.value)();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // If the value sent was nonzero, a check that a refund was received will be executed. Otherwise, the fallback
 | 
				
			||||||
 | 
					        // function contains a check that will fail in the event that a value of zero was sent to the contract.
 | 
				
			||||||
 | 
					        if (msg.value > 0) {
 | 
				
			||||||
 | 
					            // Ensure that a full refund was provided to this contract.
 | 
				
			||||||
 | 
					            require(address(this).balance == msg.value, "A full refund was not provided by `refundNonzeroBalance`");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /// @dev This function tests the behavior to a simple call to `refundFinalBalanceFunction`. This
 | 
					    /// @dev This function tests the behavior to a simple call to `refundFinalBalanceFunction`. This
 | 
				
			||||||
    ///      test will verify that the correct refund was provided after the call (depending on whether
 | 
					    ///      test will verify that the correct refund was provided after the call (depending on whether
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
import { blockchainTests } from '@0x/contracts-test-utils';
 | 
					import { blockchainTests, constants } from '@0x/contracts-test-utils';
 | 
				
			||||||
import { BigNumber } from '@0x/utils';
 | 
					import { BigNumber } from '@0x/utils';
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -8,6 +8,9 @@ blockchainTests('Refundable', env => {
 | 
				
			|||||||
    let refundable: TestRefundableContract;
 | 
					    let refundable: TestRefundableContract;
 | 
				
			||||||
    let receiver: TestRefundableReceiverContract;
 | 
					    let receiver: TestRefundableReceiverContract;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const ONE_HUNDRED = new BigNumber(100);
 | 
				
			||||||
 | 
					    const ONE_THOUSAND = new BigNumber(1000);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    before(async () => {
 | 
					    before(async () => {
 | 
				
			||||||
        // Create the refundable contract.
 | 
					        // Create the refundable contract.
 | 
				
			||||||
        refundable = await TestRefundableContract.deployFrom0xArtifactAsync(
 | 
					        refundable = await TestRefundableContract.deployFrom0xArtifactAsync(
 | 
				
			||||||
@@ -26,13 +29,32 @@ blockchainTests('Refundable', env => {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // The contents of these typescript tests is not adequate to understand the assertions that are made during
 | 
				
			||||||
 | 
					    // these calls. For a more accurate picture, checkout out "./contracts/test/TestRefundableReceiver.sol". Specifically,
 | 
				
			||||||
 | 
					    // the function `testRefundNonzeroBalance()` is used in this test suite.
 | 
				
			||||||
 | 
					    blockchainTests.resets('refundNonzeroBalance', () => {
 | 
				
			||||||
 | 
					        it('should not send a refund when no value is sent', async () => {
 | 
				
			||||||
 | 
					            // Send 100 wei to the refundable contract that should be refunded.
 | 
				
			||||||
 | 
					            await receiver.testRefundNonzeroBalance.awaitTransactionSuccessAsync(refundable.address, {
 | 
				
			||||||
 | 
					                value: constants.ZERO_AMOUNT,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it('should send a full refund when nonzero value is sent', async () => {
 | 
				
			||||||
 | 
					            // Send 100 wei to the refundable contract that should be refunded.
 | 
				
			||||||
 | 
					            await receiver.testRefundNonzeroBalance.awaitTransactionSuccessAsync(refundable.address, {
 | 
				
			||||||
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The contents of these typescript tests is not adequate to understand the assertions that are made during
 | 
					    // The contents of these typescript tests is not adequate to understand the assertions that are made during
 | 
				
			||||||
    // these calls. For a more accurate picture, checkout out "./contracts/test/TestRefundableReceiver.sol".
 | 
					    // these calls. For a more accurate picture, checkout out "./contracts/test/TestRefundableReceiver.sol".
 | 
				
			||||||
    blockchainTests.resets('refundFinalBalance', async () => {
 | 
					    blockchainTests.resets('refundFinalBalance', () => {
 | 
				
			||||||
        it('should fully refund the sender when `shouldNotRefund` is false', async () => {
 | 
					        it('should fully refund the sender when `shouldNotRefund` is false', async () => {
 | 
				
			||||||
            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
					            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
				
			||||||
            await receiver.testRefundFinalBalance.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testRefundFinalBalance.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -40,7 +62,7 @@ blockchainTests('Refundable', env => {
 | 
				
			|||||||
        it('should fully refund the sender when `shouldNotRefund` is false for two calls in a row', async () => {
 | 
					        it('should fully refund the sender when `shouldNotRefund` is false for two calls in a row', async () => {
 | 
				
			||||||
            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
					            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
				
			||||||
            await receiver.testRefundFinalBalance.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testRefundFinalBalance.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Send 1000 wei to the refundable contract that should be refunded to the receiver contract.
 | 
					            // Send 1000 wei to the refundable contract that should be refunded to the receiver contract.
 | 
				
			||||||
@@ -59,11 +81,11 @@ blockchainTests('Refundable', env => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // The contents of these typescript tests is not adequate to understand the assertions that are made during
 | 
					    // The contents of these typescript tests is not adequate to understand the assertions that are made during
 | 
				
			||||||
    // these calls. For a more accurate picture, checkout out "./contracts/test/TestRefundableReceiver.sol".
 | 
					    // these calls. For a more accurate picture, checkout out "./contracts/test/TestRefundableReceiver.sol".
 | 
				
			||||||
    blockchainTests.resets('disableRefundUntilEnd', async () => {
 | 
					    blockchainTests.resets('disableRefundUntilEnd', () => {
 | 
				
			||||||
        it('should fully refund the sender when `shouldNotRefund` is false', async () => {
 | 
					        it('should fully refund the sender when `shouldNotRefund` is false', async () => {
 | 
				
			||||||
            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
					            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
				
			||||||
            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -71,47 +93,47 @@ blockchainTests('Refundable', env => {
 | 
				
			|||||||
        it('should fully refund the sender when `shouldNotRefund` is false for two calls in a row', async () => {
 | 
					        it('should fully refund the sender when `shouldNotRefund` is false for two calls in a row', async () => {
 | 
				
			||||||
            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
					            // Send 100 wei to the refundable contract that should be refunded to the receiver contract.
 | 
				
			||||||
            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // Send 1000 wei to the refundable contract that should be refunded to the receiver contract.
 | 
					            // Send 1000 wei to the refundable contract that should be refunded to the receiver contract.
 | 
				
			||||||
            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(1000),
 | 
					                value: ONE_THOUSAND,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('should not refund the sender if `shouldNotRefund` is true', async () => {
 | 
					        it('should not refund the sender if `shouldNotRefund` is true', async () => {
 | 
				
			||||||
            /// Send 100 wei to the refundable contract that should not be refunded.
 | 
					            /// Send 100 wei to the refundable contract that should not be refunded.
 | 
				
			||||||
            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('should disable the `disableRefundUntilEnd` modifier and refund when `shouldNotRefund` is false', async () => {
 | 
					        it('should disable the `disableRefundUntilEnd` modifier and refund when `shouldNotRefund` is false', async () => {
 | 
				
			||||||
            /// Send 100 wei to the refundable contract that should be refunded.
 | 
					            /// Send 100 wei to the refundable contract that should be refunded.
 | 
				
			||||||
            await receiver.testNestedDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testNestedDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('should disable the `refundFinalBalance` modifier and send no refund when `shouldNotRefund` is true', async () => {
 | 
					        it('should disable the `refundFinalBalance` modifier and send no refund when `shouldNotRefund` is true', async () => {
 | 
				
			||||||
            /// Send 100 wei to the refundable contract that should not be refunded.
 | 
					            /// Send 100 wei to the refundable contract that should not be refunded.
 | 
				
			||||||
            await receiver.testNestedDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, true, {
 | 
					            await receiver.testNestedDisableRefundUntilEnd.awaitTransactionSuccessAsync(refundable.address, true, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('should disable the `refundFinalBalance` modifier and refund when `shouldNotRefund` is false', async () => {
 | 
					        it('should disable the `refundFinalBalance` modifier and refund when `shouldNotRefund` is false', async () => {
 | 
				
			||||||
            /// Send 100 wei to the refundable contract that should be refunded.
 | 
					            /// Send 100 wei to the refundable contract that should be refunded.
 | 
				
			||||||
            await receiver.testMixedRefunds.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
					            await receiver.testMixedRefunds.awaitTransactionSuccessAsync(refundable.address, false, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        it('should disable the `refundFinalBalance` modifier and send no refund when `shouldNotRefund` is true', async () => {
 | 
					        it('should disable the `refundFinalBalance` modifier and send no refund when `shouldNotRefund` is true', async () => {
 | 
				
			||||||
            /// Send 100 wei to the refundable contract that should not be refunded.
 | 
					            /// Send 100 wei to the refundable contract that should not be refunded.
 | 
				
			||||||
            await receiver.testMixedRefunds.awaitTransactionSuccessAsync(refundable.address, true, {
 | 
					            await receiver.testMixedRefunds.awaitTransactionSuccessAsync(refundable.address, true, {
 | 
				
			||||||
                value: new BigNumber(100),
 | 
					                value: ONE_HUNDRED,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
export const constants = {
 | 
					export const constants = {
 | 
				
			||||||
    RPC_URL: 'http://localhost:8545',
 | 
					    RPC_URL: 'http://localhost:8545',
 | 
				
			||||||
    RPC_PORT: 8545,
 | 
					    RPC_PORT: 8545,
 | 
				
			||||||
    GAS_LIMIT: 7000000,
 | 
					    GAS_LIMIT: 8000000,
 | 
				
			||||||
    TESTRPC_FIRST_ADDRESS: '0x5409ed021d9299bf6814279a6a1411a7e866a631',
 | 
					    TESTRPC_FIRST_ADDRESS: '0x5409ed021d9299bf6814279a6a1411a7e866a631',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user